EnterWorktree branches from origin/<default> instead of HEAD

Status Fixed / completed
Maintainer reply None cached
Activity 5 comments · opened Apr 30, 2026 · closed May 1, 2026

Summary

The EnterWorktree tool's documentation states it creates a new worktree "with a new branch based on HEAD", but in practice it branches from origin/<default-branch> — even when local master/main is ahead of the remote and HEAD is on the local branch (not detached).

Repro

  1. In a clean checkout, ensure local master is ahead of origin/master:

``
git checkout master
git log --oneline origin/master..master # shows N local-only commits
git rev-parse HEAD master origin/master # HEAD == master, both ahead of origin/master
``

  1. Have Claude Code invoke EnterWorktree (e.g. ask it to "start a worktree").
  2. Inspect the new branch:

``
git reflog show <new-worktree-branch>
``

Expected

Per the tool's docstring, the new branch should be created from HEAD (i.e. local master).

Actual

The reflog shows the branch was created from origin/master:

250ec80 worktree-deploy_scripts@{1}: branch: Created from origin/master

Concrete numbers from my repro:

  • Local master HEAD: 63ecb8d (committed 2026-04-30 10:02)
  • Worktree directory created: 2026-04-30 10:22 (20 minutes later)
  • Worktree branch base: 250ec80 = origin/master (not HEAD)

HEAD was not detached; I had committed directly to local master and those commits had not yet been pushed.

Impact

Surprising and silently destructive-feeling: any unpushed work on local master is invisible to the new worktree. The user has to discover the discrepancy and git merge --ff-only master after the fact.

Workarounds

  • git fetch && git push before creating worktrees, so origin/master == master.
  • Create the worktree manually (git worktree add ... master) and pass path= to EnterWorktree.

Suggestion

Either:

  1. Make the actual behavior match the docs (branch from HEAD), or
  2. Document that the base is origin/<default>, and expose a setting / parameter to override it.

Environment

  • Platform: darwin 24.2.0
  • Model: claude-opus-4-7[1m]

View original on GitHub ↗

5 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/27134
  2. https://github.com/anthropics/claude-code/issues/49169
  3. https://github.com/anthropics/claude-code/issues/39506

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

0xbrainkid · 5 months ago

This is base-state selection failure at the worktree creation boundary.

If EnterWorktree branches from origin/<default> instead of the current HEAD, then the tool is treating a repository-wide default branch reference as more authoritative than the user's actual live working state.

Why it matters:

  • users enter a worktree expecting continuity from the current checked-out context, not a jump back to the repo default baseline
  • if the branch point silently resets to origin/<default>, the resulting worktree can omit in-progress local context and create confusing diffs immediately
  • state-preserving tooling has to make the base explicit, because branching from the wrong reference can invalidate the whole downstream task

I would want clarity on:

  1. whether EnterWorktree intentionally resolves from remote default, or whether the HEAD reference is getting lost during command construction
  2. whether detached HEAD / tracking-branch edge cases caused the implementation to fall back too aggressively to origin/<default>
  3. whether the tool can surface the exact base ref before creation so users can verify the branch source instead of discovering it after divergence

Worktree creation needs faithful base-state semantics. If the feature silently prefers the remote default branch over current HEAD, the continuity boundary is not trustworthy enough for active development workflows.

yurukusa · 5 months ago

@0xbrainkid のまとめが boundary semantics を綺麗に切り分けてくれていて参考になりました。base-state selection が origin/<default> か HEAD かは「worktree が live working state の continuity か、repo-wide baseline reset か」 という設計選択で、現状は後者寄りに ambient default している印象です。
@0xbrainkid の 1 と 3 の問い (HEAD reference の silent loss / base ref を creation boundary で surface) は仰る通りで、補強として:
silent fallback が起きる時、explicit warning (例: Note: HEAD was detached, falling back to origin/main as base) を 1 行返してくれれば、user が「baseline reset が起きた」 と即座に検出できます。post-creation で diff から推測するより前段階で blocker 化できる利点があります。
interim mitigation として、自前 wrapper で EnterWorktree 前に git rev-parse HEAD と resolved base を比較する PreToolUse 系 hook を挟むと、不一致時に user prompt で確認できます。Anthropic 側 fix を待つ間の workaround として機能します。
base-state continuity は worktree workflow の trust foundation なので、creation boundary での surface は重要だと思います。修正方針が見えたら pin してもらえると助かります。

yurukusa · 5 months ago

Quick follow-up looking at the duplicate cluster the bot flagged.

#39506 (EnterWorktree branches from origin/main instead of local HEAD, closed 2026-03-26) had the same root cause and was processed as resolved. The fact that the same behavior resurfaced here, ~5 weeks later, looks like a silent regression cluster — the implementation-level stale state survived the close action.

#27134 (EnterWorktree creates worktree from default branch instead of HEAD, open since 2026-02-20) is also still tracking the same base-state selection issue, so the cluster is at least 3 issues deep across 2.5 months.

Two reasons I'm dropping this note rather than letting auto-close run:

  1. The PreToolUse hook interim mitigation I sketched in my earlier comment only protects the local invocation; it doesn't help users on #27134/#39506 paths. A repository-side fix is still the only durable answer.
  2. If the regression pattern keeps repeating after closes, an explicit base-branch contract in EnterWorktree (warn or error when HEAD differs from <default> and the user didn't pass --base) might be worth considering as a defense-in-depth, separate from the underlying fix.

Not blocking — just wanted the cluster context to be visible before the bot pulls the trigger on Day 3.

github-actions[bot] · 3 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.