Skip to content

docs(remove): correct the detached-worktree case in the removal planner - #3796

Open
worktrunk-bot wants to merge 2 commits into
mainfrom
nightly/clean-31363066936
Open

docs(remove): correct the detached-worktree case in the removal planner#3796
worktrunk-bot wants to merge 2 commits into
mainfrom
nightly/clean-31363066936

Conversation

@worktrunk-bot

Copy link
Copy Markdown
Collaborator

Comment-only. Two adjacent comments in prepare_worktree_removal's WorktreePath arm describe a routing that cf822f7 ("guard a registered path that no longer holds its worktree", #3785) changed underneath them.

The branch-only cleanup's comment still ends with "A detached worktree has no branch to fall back to, so it proceeds and surfaces the removal error." It no longer proceeds. A detached worktree whose directory is gone fails the first arm's wt.branch.as_deref() test, and git reports exactly that registration as prunable — verified against git directly:

$ git worktree add --detach ../det HEAD && rm -rf ../det && git worktree list --porcelain
worktree /tmp/gt/det
HEAD 7c8964f04dc09ce2dff86351d5b63906ac4de41e
detached
prunable gitdir file points to non-existent location

So it lands in the else if wt.is_prunable() arm added by that commit and is refused at planning with WorktreeMissing plus the git worktree prune hint. Behavior is unchanged by this PR; the old path also ended in an error, just git's raw one.

That second arm's own comment has the mirror-image gap: it opens "Registered, directory present", which names only the deleted-and-recreated shape, while the detached-and-absent shape reaches it too. It also says the cleanup above "needs the directory gone" when that arm wants a branch and an absent directory — the missing half is precisely why the detached case falls through.

Both comments now name the two shapes the arm catches and what each cleanup actually requires.

No regression test: the change is comments, and the routing it describes is already pinned by the prunable-registration tests that landed with #3785.

Deliberately narrow. The asymmetry it exposes — a stale branch-carrying registration is cleaned up by wt remove while a stale detached one is refused — overlaps #3769 and #3791, so it is left to those rather than folded in here.

@worktrunk-bot worktrunk-bot added the nightly-cleanup Issues found by nightly code quality sweep label Aug 10, 2026

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review, so this is a comment rather than a verdict.

The routing claim checks out — a detached worktree whose directory is gone is reported prunable, so it lands in the second arm exactly as the PR describes. One line in the rewritten comment doesn't: extending "Only the repo-wide git worktree prune clears this one" to "clears these" makes an "only" claim that is false for the shape the PR adds. A targeted git worktree remove <path> clears the detached-and-absent registration (exit 0) — that's the same "git skips its validation while the directory is absent" mechanism the comment 20 lines above already names. It's only the present-but-foreign directory that nothing but a prune clears. Since the PR's whole subject is the accuracy of these two comments, the inline suggestion narrows both that line and the exit 128 mechanism to the shape each actually describes.

This is the removal planner (prepare_worktree_removal in src/commands/repository_ext.rs), which routes into branch deletion, so per the project's data-loss policy the arm isn't one for the bot to sign off on even for a comment-only diff — leaving that to @max-sixty.

Verification

Against git 2.x in a scratch repo, worktree add --detach ../det HEAD then rm -rf ../det:

$ git worktree list --porcelain
worktree /tmp/gt/det
HEAD 4cf5dbe76f25522edc41fd586b7495b0f79c3db6
detached
prunable gitdir file points to non-existent location

$ git worktree remove ../det ; echo exit=$?
exit=0

The deleted-and-recreated shape, for contrast:

$ git worktree remove ../feat
fatal: validation failed, cannot remove working tree: '/tmp/gt/feat/.git' does not exist
exit=128

So git worktree prune clears both, but it is only the second shape for which it is the only thing that does.

Comment thread src/commands/repository_ext.rs Outdated
…hape

A targeted `git worktree remove <path>` clears the detached-and-absent registration (verified exit 0), so "only a repo-wide prune clears these" held for the recreated-directory shape but not for the one this PR adds. The `exit 128` mechanism is likewise that shape's.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

nightly-cleanup Issues found by nightly code quality sweep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant