Session worktrees are cut from origin/main, not the repo's actual default branch
Summary
When a session creates a worktree, its branch is cut from origin/main rather than the repository's actual default branch. In a repo whose default branch is not main, every such worktree starts hundreds of commits behind trunk — on a branch whose auto-generated name implies it contains recent work.
worktree.baseRef is documented as defaulting to fresh, which "branches from origin/<default-branch> for a clean tree". That is not the observed behaviour.
Environment
| | |
|---|---|
| Claude Code | 2.1.220 |
| OS | macOS 26.5.2 (arm64) |
| git | 2.50.1 (Apple Git-155) |
| Remote host | GitLab |
| Repo default branch | feat/post-launch-build-queue (not main) |
Expected
New session worktrees branch from origin/feat/post-launch-build-queue — the default branch.
Actual
They branch from 4629183, the tip of origin/main, currently 888 commits behind the default branch and not an ancestor of it.
$ git rev-parse --short origin/main
4629183
$ git rev-list --count 4629183..origin/feat/post-launch-build-queue
888
$ git branch -a --contains 4629183
main
remotes/origin/main
Branch-creation evidence from the reflog:
$ git reflog show claude/supabase-billing-analysis-1f51f9 --date=iso
4629183 ...@{2026-07-23 16:52:09}: branch: Created from 462918373f4247d8a34dd061dab05a1383626d7f
At peak this affected 7 of 22 worktrees simultaneously. It is still reproducing: a worktree created 2026-08-03 was 876 commits behind on first use.
This is not user misconfiguration
Both the remote's declared default and the local symbolic ref agree, and have since 2026-07-02 — three weeks before the first affected worktree:
$ git remote show origin | grep 'HEAD branch'
HEAD branch: feat/post-launch-build-queue
$ git symbolic-ref --short refs/remotes/origin/HEAD
origin/feat/post-launch-build-queue
Ruled out
worktree.baseRefoverride — absent from user, project and local settings (jq '.worktree'→nullin all three), so the documentedfreshdefault applies.- Stale local
origin/HEAD— set 2026-07-02, predating every affected worktree. - Remote default actually being
main—git remote show originreports the trunk branch live.
Impact
The failure is quiet and it compounds:
- The branch name is auto-slugged from the current session's topic, so a worktree named
claude/rel-008-handoff-snapshot-…contains none of that work. The name implies currency the base does not have. - In-repo files a session treats as ground truth —
TRACKER.md,README, docs — are whatever they were at the stale base. In our caseTRACKER.mdwas four weeks out of date and described work items that had long since shipped. - Nothing surfaces the discrepancy. A session that does not happen to run
git rev-list --left-right --count HEAD...origin/HEADbefore working will produce confidently wrong output against a month-old view of the repo.
We hit exactly this, and only caught it because the session ran that comparison as its first action. We have since added a local hook that warns at SessionStart and denies the first Edit/Write when HEAD is far behind origin/HEAD — it has fired repeatedly since, which is how we know the behaviour is ongoing rather than a one-off.
Reproduction
Not reproducible on demand from outside — this is reconstructed from the artifacts of independently-created worktrees plus branch reflogs. Suggested check:
- Take a repo whose default branch is not
main, wheremainexists and has diverged. - Confirm
git remote show originandgit symbolic-ref refs/remotes/origin/HEADboth report the non-maindefault. - Start a session that creates a worktree.
- In the new worktree:
git rev-list --left-right --count HEAD...origin/HEAD.
Expected 0 behind; we observe several hundred.
Suggested fix
Resolve the base from origin/HEAD (or the remote's reported default) rather than assuming main. Failing that, warn when a newly created worktree is significantly behind origin/HEAD — the silence is what makes this expensive.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗