Repository navigation
feat(branch): reopen or refuse a branch name that already has a worktree - #178
Merged
Merged
Conversation
…121) Add gitFindBranchCheckout, which reads `git worktree list --porcelain` through parseWorktreeRecords and reports, for an exact branch-name match, the path, whether the directory still exists, whether it sits under <root>.worktrees/, and whether it is the current worktree. gitGetWorktrees is unchanged. Phase 1 of #121. Gate 1: pnpm check, pnpm typecheck, pnpm --filter docs typecheck, pnpm build, pnpm test (1357 passed), pnpm docs:test (69 passed) and the test-markers check all exit 0. Gate 2 (reviewer subagent): PASS WITH NOTES after one loopback (type alias -> interface).
…ree (#121) Before assignment, source resolution and creation, `branch` now looks the final branch name up in `git worktree list --porcelain`: - A worktree under <root>.worktrees/: on a terminal, ask and open it with the run's own open/agent/brief options (declining exits 1). A non-interactive run refuses with invalid_value (exit 2), naming the path and `worktree open <branch>`. - The branch is checked out outside the worktrees directory, has a stale worktree record, or exists with no worktree: refuse with invalid_value in both modes, naming the path or the command to run. Git's raw `fatal: a branch named ... already exists` no longer reaches the user for these cases. The --json document and the error-code set are unchanged. The docs page, the worktree skill and context7.json are updated. Phase 2 of #121. Gate 1: pnpm check, pnpm typecheck, pnpm --filter docs typecheck, pnpm build, pnpm test (1370 passed), pnpm docs:test (69 passed) and the test-markers check all exit 0. Plan §8.1 was run against real git with the built CLI: cases A-D exit 2 with no `fatal:`, and a fresh name still creates its worktree. Gate 2 (reviewer subagent): PASS WITH NOTES after one loopback, which pinned the lookup order and the edited-name check in tests.
Closed
craig-o-curtis
approved these changes
Oct 28, 2026
craig-o-curtis
left a comment
Contributor
There was a problem hiding this comment.
Approving. I read the diff with CI green and did not rerun gates. The four collision states line up with the plan (D1–D4, D6). The check sits after the final name and before assignment, source and creation, and the tests cover each state plus the edited-name and --github orderings. This branch merges cleanly with #180, and #180's Jira tests stay safe under the new top-level gitFindBranchCheckout / gitGetLocalBranches defaults.
Non-blocking notes:
- The prompt doesn't mention the brief.
src/commands/branch.ts:366: with--agent/--agent-file/--agent-stdin, a "y" toOpen it instead?also starts an agent and delivers the brief in a tree that may already have one running. That is the exact risk D2 gives for refusing to open unasked. Consider saying so in the prompt when a brief is present (e.g.Open it and hand it the brief?). Or warn whenhasLiveAgentis true for that tree. isCurrentis never read.src/lib/git.ts:334:gitFindBranchCheckoutcomputes it (an extragit branch --show-currentper run), but nothing inbranch.tsuses it. Drop it, or keep it on purpose for a later caller.- Misleading output line. A reopen with
opener: noneor--no-openprintsWorktree created at <path>even though nothing was created.worktree openalready does the same, so this is cosmetic and could be a follow-up.
craig-o-curtis
added a commit
that referenced
this pull request
Oct 28, 2026
Merging main brought in `run(): Promise<BranchDocument | undefined>` from #178, and the Jira assign tests still read the result as a plain `BranchDocument`, so `pnpm typecheck` failed with TS18048 and TS2769. They now use `document?.`, as the other provider tests do, and the `--json` keys test reads `Object.keys(document ?? {})`, so an undefined result still fails it.
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 #121
Running
worktree brancha second time for a name that already has a worktree used to fail inside git with a barefatal: a branch named ... already exists, after the assign prompt had already run. The check now runs once the final name is known, before assignment, source resolution and creation.gitFindBranchCheckoutfinds the worktree a branch name is checked out in, fromgit worktree list --porcelain.branchreopens (interactive, after a confirm) or refuses (InvalidValueError, exit2,invalid_value) for the four collision cases; docs, skill andcontext7.jsonupdated.BranchDocumentis unchanged.Release note:
minor,.changeset/branch-reopen-existing-worktree.md. Waiting on the release PR to ship.Plan and ledger: #121. Owner check for the prompt on a real terminal: #177.