Repository navigation
fix(remove): remove a worktree by its path, not its branch name - #97
Merged
baldurpan merged 3 commits intoOct 3, 2026
Merged
Conversation
`git worktree remove <branch>` resolves its argument by the trailing path components of every worktree. When two end in the same name (a checkout directory named like the branch, or branches `demo` and `x/demo` side by side) git falls back to a cwd-relative path and fails with "is not a working tree". Every removal path now hands git the worktree's path, and keeps the branch name for `git branch -D` and the messages. Closes #77
baldurpan
enabled auto-merge (squash)
October 2, 2026 21:54
craig-o-curtis
approved these changes
Oct 3, 2026
craig-o-curtis
left a comment
Contributor
There was a problem hiding this comment.
Well that's a sneaky one, git quietly matching a bare name against the tail end of every worktree path. Nice find, and a tidy fix. Looks real good to me.
Went through the whole diff:
gitNukeWorktreeCmdandgitNukeWorktreetake{ branchName, path }now.git worktree removegets the path, andgit branch -D, the spinner and the error text still get the branch name. All three callers (gitRemoveWorktree,gitRemoveWorktreesWithProgress, andgitNukeWorktreeitself) hand over the list entry they already had, so single remove, multi-select andcleanupare all covered, and there's no othergit worktree removehiding insrc/.- The path passed back is the one
git worktree listprinted in the first place, so git is being handed its own spelling of it. - The unit tests use a path that looks nothing like the branch (
/repo/project.worktrees/some-dir), so swapping the two would show up right away. That's a thoughtful touch. - Two real-git cases in
agent-mode.test.ts, one per reproduction, and the old comment that worked around the bug by naming the checkoutcheckoutis put right. patchchangeset, and no CLI surface or--jsonshape changes, so that level's just right.
I didn't want to take git's word for it secondhand, so I tried it in a scratch repo on git 2.54:
| Case | By branch name | By path |
|---|---|---|
checkout dir demo + branch demo |
fatal: 'demo' is not a working tree |
removed |
branches demo and x/demo side by side |
fatal: 'demo' is not a working tree |
both removed |
worktree directory already deleted (prunable) |
n/a | removed, using the listed path |
| run from a subdirectory of the checkout | n/a | removed |
The third row was the one I was a little worried about, since cleanup treats a missing directory as safe to remove and would send that path along. It's fine.
Couple things to know, neither worth holding it up over:
- It's one commit behind
mainnow (#98, the worker URL). I trial-merged it into currentmainand alongside #95 (they both touchsrc/lib/git.test.ts) and it all comes out clean. - The "962 passed" in the description won't match once #95 lands too, so whichever goes second may want to give the snapshot in
context/verify.mda glance.
ci and changeset are green on this head. I ran the git reproductions above myself, but not the project's own suite.
That'll do just fine. Thanks a bunch!
baldurpan
deleted the
77-worktree-remove-fails-when-another-worktree-path
branch
October 3, 2026 10:40
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #77
What was wrong
gitNukeWorktreeCmdrangit worktree remove <branchName>. Git resolves that argument by matching it against the trailing path components of every worktree. When two worktrees end in the same name, the match is ambiguous and git falls back to a path relative to the cwd. The removal then fails withfatal: '<name>' is not a working tree. Two ways to hit it:demoand branchdemodemoandx/demoare checked out side by sideThe fix
src/lib/git.ts:gitNukeWorktreeCmdandgitNukeWorktreenow take the worktree's list entry (branchName+path) instead of a branch string.git worktree removenow gets the path.git branch -Dand the spinner and error messages still use the branch name.worktree remove, multi-select remove andworktree cleanup.src/lib/git.test.ts: the pinned command lines use a path that does not look like the branch name, so a swap would show.src/agent-mode.test.ts: two new real-git end-to-end cases, one per reproduction above. Both fail when the remove call is switched back to the branch name. The scenario comment that named the checkoutcheckoutto work around this bug is corrected..changeset/brave-paths-match.md: apatchnote.Verification
pnpm check,pnpm typecheckandpnpm build: all exit 0.pnpm test: 962 passed.pnpm docs:test: 68 passed.