Skip to content

fix(vcs): open a worktree for a branch a deleted worktree still claims - #60

Open
enisze wants to merge 1 commit into
mainfrom
feature/fix-open-archived-worktree
Open

enisze wants to merge 1 commit into
mainfrom
feature/fix-open-archived-worktree

Conversation

@enisze

@enisze enisze commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Problem

Opening an existing branch failed with an opaque error:

Git command failed in GitVcsDriver.createWorktree (/Users/enis/smartNsales): git worktree add failed

The branch was still claimed by a worktree whose directory no longer exists (a /private/tmp checkout wiped by tmp cleanup, or any hand-deleted worktree dir):

/private/tmp/portal-split   6b187f80 [pr/11-matecorner-triage-backoffice] prunable

Git keeps that administrative entry — and keeps refusing the branch a second worktree — until it is pruned. listRefs deliberately drops prunable worktrees, so the branch shows as a free "Existing branch" in the picker, the dialog takes the create path, and git worktree add fails. The general executeGit failure is redacted, so git's actual reason ("already checked out in ...") never reached the user.

switchRef already recovered from exactly this stale claim; createWorktree never got it.

Change

  • Extracted switchRef's recovery into a shared resolveWorktreeClaimRecovery(operation, cwd, branch): on the failure path it reads git worktree list --porcelain and either prunes a stale holder so the caller can retry, or reports the live worktree that holds the branch.
  • createWorktree runs worktree add with allowNonZeroExit and, on failure, prunes + retries once when a prunable worktree holds the target branch. A live holder now produces an actionable message instead of "git worktree add failed":

    Branch "…" is already checked out in the worktree at /path. Open the branch there, or switch that worktree to another branch first.

  • Both call sites share one gitCommandResultFailure helper, so the error shape is unchanged.

git worktree prune only drops entries whose working tree is already gone, so it never discards work. Everything runs on the failure path only — a successful worktree add is still a single git spawn.

Tests

Two new tests in GitVcsDriverCore.test.ts: creating a worktree for a branch a deleted worktree still claims, and naming the live worktree that blocks a second one. Both fail on the old code (verified by stashing the fix). 202 tests across src/git + src/vcs pass; typecheck and lint show no new findings.

🤖 Generated with Claude Code

A worktree whose directory is gone keeps its branch claim until the
administrative entry is pruned, so `git worktree add` refuses the branch
forever. `listRefs` drops prunable worktrees, so the branch looks free in
the picker and the failure only surfaced as "git worktree add failed".

Give `createWorktree` the stale-claim recovery `switchRef` already had,
shared as `resolveWorktreeClaimRecovery`: prune and retry when the holder
is stale, and otherwise name the live worktree that holds the branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Sep 7, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant