getDefaultBranch returns wrong branch in git worktrees
Summary
claude --print injects an incorrect "Main branch" into the system prompt when running inside a git worktree. It detects main instead of the repo's actual default branch (e.g. develop).
Root cause
getDefaultBranch resolves the .git directory and reads refs/remotes/origin/HEAD relative to it. In worktrees, .git is a file pointing to .git/worktrees/<name>/, which does not contain remote refs. Remote refs are shared via the commondir file (per gitrepository-layout):
# .git in a worktree:
gitdir: /repo/.git/worktrees/implementer-1
# worktree git dir has commondir pointing to the shared git dir:
$ cat /repo/.git/worktrees/implementer-1/commondir
../..
# origin/HEAD lives in the shared git dir, not the worktree:
$ ls /repo/.git/worktrees/implementer-1/refs/remotes/origin/HEAD
# No such file
$ ls /repo/.git/refs/remotes/origin/HEAD
# Exists → ref: refs/remotes/origin/develop
Because the ref lookup fails, the function falls through to the candidate check (main, master). Since origin/main exists as a branch in this repo, it incorrectly returns main instead of develop.
Steps to reproduce
# In a repo where default branch is "develop" and "main" also exists
git worktree add /tmp/test-wt -b test-branch origin/develop
cd /tmp/test-wt
claude --print "What is the main branch?"
# System context says "Main branch: main" instead of "develop"
Expected behavior
getDefaultBranch should follow the commondir indirection when resolving shared refs (remotes, tags, etc.) in worktrees, matching how git symbolic-ref refs/remotes/origin/HEAD works.
Workaround
None that's transparent to the user. The ref is correct in the shared git dir — only Claude Code's file-based lookup misses it.
Version
Claude Code 2.1.77, macOS arm64
This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗