A file-based task manager
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

tsk remote: drop add/remove/list, validate set-default

Per follow-up: `tsk remote add` and `tsk remote remove` were thin
wrappers around git's own commands; users can run `git remote add`
themselves and follow with `tsk git-setup -r <name>` when they want
the tsk refspecs configured. `tsk remote list` was equivalent to
`git remote`. All three are gone.

What's left is the tsk-specific state:

- `tsk remote default` — print the persisted default
- `tsk remote set-default <n>` — persist `<n>` as the default;
validates against `git remote` first so we can't be pointed at a
remote the host repo doesn't know about.

Workspace::git_remotes survives as the validation helper; the
git_remote_add / git_remote_remove wrappers are gone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+18 -44
+1 -2
AGENTS.md
··· 91 91 Local refs aren't visible to the user until pushed: 92 92 93 93 ``` 94 - tsk remote add <name> <url> # add a git remote + configure tsk refspecs in one step 95 - tsk remote set-default <name> # use this remote for git-push/pull and the auto-push paths 94 + tsk remote set-default <name> # use this git remote for git-push/pull and the auto-push paths 96 95 tsk git-push # push refs/tsk/* to default remote (also runs after assign/reject) 97 96 tsk git-pull # fetch + reconcile divergent task histories 98 97 tsk git-pull --rebase # replay local commits on the remote tip instead of merging
+3 -16
src/lib.rs
··· 325 325 326 326 #[derive(Subcommand)] 327 327 enum RemoteAction { 328 - /// List configured git remotes (delegates to `git remote`). 329 - List, 330 328 /// Print the active default remote (the one used when no `-R` is given). 331 329 Default, 332 - /// Add a git remote and configure the tsk refspecs on it in one step. 333 - Add { name: String, url: String }, 334 - /// Remove a git remote. 335 - Remove { name: String }, 336 - /// Persist the active default remote for this clone. 330 + /// Persist the active default remote for this clone. Must already be 331 + /// a git remote — use `git remote add ...` (and `tsk git-setup -r 332 + /// <name>` to configure refspecs) first. 337 333 SetDefault { name: String }, 338 334 } 339 335 ··· 962 958 fn command_remote(dir: PathBuf, action: RemoteAction) -> Result<()> { 963 959 let ws = Workspace::from_path(dir)?; 964 960 match action { 965 - RemoteAction::List => print_lines(ws.git_remotes()?), 966 961 RemoteAction::Default => println!("{}", ws.default_remote()), 967 - RemoteAction::Add { name, url } => { 968 - ws.git_remote_add(&name, &url)?; 969 - println!("Added remote '{name}' (refspecs configured)"); 970 - } 971 - RemoteAction::Remove { name } => { 972 - ws.git_remote_remove(&name)?; 973 - println!("Removed remote '{name}'"); 974 - } 975 962 RemoteAction::SetDefault { name } => { 976 963 ws.set_default_remote(&name)?; 977 964 println!("Default remote set to '{name}'");
+14 -26
src/workspace.rs
··· 215 215 self.read_selector(REMOTE_FILE, DEFAULT_REMOTE) 216 216 } 217 217 218 + /// Persist `name` as the default remote. Errors if `name` isn't a 219 + /// configured git remote — tsk only ever uses remotes the host repo 220 + /// already knows about. 218 221 pub fn set_default_remote(&self, name: &str) -> Result<()> { 219 - std::fs::write(self.path.join(REMOTE_FILE), name.as_bytes())?; 220 - Ok(()) 221 - } 222 - 223 - /// Wrap `git remote add` and immediately configure the tsk refspecs 224 - /// on it. Idempotent on the refspec side; errors on duplicate remote. 225 - pub fn git_remote_add(&self, name: &str, url: &str) -> Result<()> { 226 - if !self 227 - .git() 228 - .args(["remote", "add", name, url]) 229 - .status()? 230 - .success() 231 - { 232 - return Err(Error::Parse(format!("git remote add {name} failed"))); 233 - } 234 - self.configure_git_remote_refspecs(name) 235 - } 236 - 237 - pub fn git_remote_remove(&self, name: &str) -> Result<()> { 238 - if !self 239 - .git() 240 - .args(["remote", "remove", name]) 241 - .status()? 242 - .success() 243 - { 244 - return Err(Error::Parse(format!("git remote remove {name} failed"))); 222 + let known = self.git_remotes()?; 223 + if !known.iter().any(|r| r == name) { 224 + return Err(Error::Parse(format!( 225 + "no such git remote '{name}'; configured: {}", 226 + if known.is_empty() { 227 + "<none>".into() 228 + } else { 229 + known.join(", ") 230 + } 231 + ))); 245 232 } 233 + std::fs::write(self.path.join(REMOTE_FILE), name.as_bytes())?; 246 234 Ok(()) 247 235 } 248 236