Skip to content

Fix git worktree add DWIM when base exists only on remote - #62

Open
leogdion wants to merge 1 commit into
release-1.0.3from
claude/issue-61-tulrri
Open

Fix git worktree add DWIM when base exists only on remote#62
leogdion wants to merge 1 commit into
release-1.0.3from
claude/issue-61-tulrri

Conversation

@leogdion

Copy link
Copy Markdown
Member

Summary

Fixes a critical bug where git worktree add with a base branch existing only on the remote would silently create a worktree on the wrong branch, leave a stray local ref, and exit successfully.

Root Cause

git worktree add -b <new> <dir> <base> performs DWIM (Do What I Mean) on the base argument. When <base> is a bare name matching a branch that exists only on the remote, git interprets it as "create a local branch tracking origin/<base>" and overrides the -b <new> flag entirely. This results in:

  • Worktree checked out on <base> instead of <new>
  • <new> branch never created
  • Stray local <base> ref left behind to go stale
  • Exit status 0 (silent success)

The --no-track flag does not prevent this, as it only governs the upstream, not the branch name.

Changes

git-trees:

  • Added _base_sha() helper function that resolves a base argument to a commit SHA by:
    1. First trying the argument as-is (handles local branches and explicit refs)
    2. Falling back to origin/<arg> (handles remote-only branches)
    3. Returning error if neither resolves
  • Modified cmd_add() to:
    • Call _base_sha() to resolve the base before creating the worktree
    • Pass the resolved SHA to git worktree add instead of the bare name (eliminates DWIM)
    • Validate that the created worktree's HEAD matches the requested branch name
    • Report clear error if base is unresolvable or if worktree ends up on wrong branch

Tests (smoke.sh):

  • Added comprehensive test section "add — remote-only base" covering:
    • Remote-only base creates worktree on requested branch, not base
    • New branch starts at origin/<base> commit
    • No stray local ref left behind
    • New branch tracks its own remote, not the base
    • Explicit origin/<base> form behaves identically
    • Unresolvable base fails with clear error and creates no worktree

Documentation:

  • Updated AGENTS.md with new "Git pitfall: a start-point can override -b" section explaining the issue and solution
  • Updated README.md to document base resolution behavior
  • Updated test coverage documentation in AGENTS.md

Implementation Details

The fix uses two layers of defense:

  1. Resolution layer: Convert the base to a SHA before git worktree add sees it, eliminating the DWIM trigger
  2. Assertion layer: Verify the worktree's HEAD matches the requested branch, catching any future regressions

This approach is robust because:

  • A SHA cannot trigger DWIM (no branch name to match)
  • The assertion makes any future regression loud rather than silent
  • Error messages clearly identify the problematic base
  • No stray refs are created even if something goes wrong

https://claude.ai/code/session_01XvKtUT9b739chxgKFLKAKL

`git worktree add --no-track -b <new> <dir> <base>` DWIMs a base naming a
branch that exists only on the remote: it creates a local branch tracking
`origin/<base>` and overrides `-b <new>` entirely. The worktree came up on
the base branch, the requested branch was never created, a stray local ref
was left behind to go stale as origin advanced, and `add` exited 0.

`cmd_add` now resolves the base through `_base_sha` — local commit-ish,
else `origin/<base>` — and passes the sha, so there is nothing for the DWIM
to latch onto and no local ref named after the base. A base that resolves
to nothing is now a clear error instead of a worktree on something else.
After creating the worktree, `add` asserts its HEAD really is the requested
branch, so a future DWIM change cannot silently reintroduce this.

Smoke coverage for the remote-only base, the explicit `origin/<base>`
spelling, and an unresolvable base; README and AGENTS.md updated.
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e2df535-b873-4d44-b373-062bb0d18c80

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant