Worktree A has feat/dark-mode checked out. You rebase
feat/dark-mode onto the latest main from the
main worktree. Now Worktree A's working tree is stale โ it still
reflects the pre-rebase commits.
# In Worktree A:
git status
# "Your branch and 'origin/feat/dark-mode' have diverged..."
# The fix: reset to the new rebased state
git reset --hard feat/dark-mode
# Or, if you're not sure what happened:
git reflog # see what changed
git reset --hard <correct-commit>
You amend a commit and force-push feat/dark-mode from the
main worktree. Worktree A still has the old version of the branch
checked out. Git reports the branch has diverged.
# In Worktree A:
git fetch origin
git status
# "Your branch is behind 'origin/feat/dark-mode' by 1 commit..."
# Option 1: Accept the remote version (discard local):
git reset --hard origin/feat/dark-mode
# Option 2: Rebase local work on top of remote:
git rebase origin/feat/dark-mode
You created a worktree at a specific commit instead of a branch. This is useful for reviewing a PR or testing an old release, but it means you're in detached HEAD โ commits made here will be lost if you switch away.
# Check if you're in detached HEAD:
git worktree list
# Shows the worktree with a commit hash instead of a branch name
# To save your work, create a branch from the current position:
git switch -c my-new-branch
# Alternatively, if you meant to be on a branch:
git worktree add --detach ../path/to/worktree abc1234 # intentional
git worktree add ../path/to/worktree existing-branch # safer: on a branch
rm -rf)
You (or a script, or an agent) deleted a worktree directory with
rm -rf instead of git worktree remove. The
metadata in .git/worktrees/ still exists, and
git worktree list shows a "prunable" entry.
# Check what's prunable:
git worktree list
# Shows something like:
# /path/to/deleted/worktree abc1234 [feat/dark-mode] prunable
# Clean up all prunable entries:
git worktree prune
# Or be explicit about what to prune:
git worktree prune --expire 1.minute.ago # prune entries older than 1 minute
# Verify clean state:
git worktree list
You try to create a worktree for a branch that's already checked out in another worktree (or in the main worktree). Git refuses.
# Find which worktree has the branch:
git worktree list | grep branch-name
# Option 1: Remove the conflicting worktree:
git worktree remove /path/to/conflicting/worktree
# Option 2: Switch the conflicting worktree to a different branch:
cd /path/to/conflicting/worktree
git switch other-branch
# Option 3 (rarely recommended): Create the new worktree
# in detached HEAD at the same commit, then switch to the branch later:
git worktree add --detach ../path/to/new/worktree $(git rev-parse branch-name)
A worktree exists for a branch that has since been deleted. The worktree
is now on a dangling branch reference โ it still works, but
git worktree list might show a detached state or an error.
# Diagnose:
git worktree list
# Worktree at /path abc1234 (detached HEAD)
# or shows the old branch name with a warning
# Recovery depends on what you want:
# If the commits were merged โ just remove the worktree:
git worktree remove /path/to/worktree
# If you need to keep the work:
cd /path/to/worktree
git switch -c resurrected-branch # re-attach to a new branch
Two agents, in two worktrees, modified the same file on different
branches. When you try to merge one into main, you get a
conflict. The conflict exists in the worktree where you ran the merge โ
the other worktree is unaffected.
# The merge worktree (usually main) shows the conflict:
cd ~/dev/my-project
git merge feat/dark-mode
# CONFLICT (content): Merge conflict in src/styles.css
# Resolve the conflict normally:
# Edit src/styles.css, remove conflict markers
git add src/styles.css
git commit -m "merge: resolve dark mode style conflict"
# The other worktree (feat/dark-mode) is unaware of the conflict.
# It still has the pre-merge version of the file.
# This is correct behavior โ each worktree is independent.
When something feels wrong, these commands will diagnose the issue 90% of the time:
| Command | What it tells you |
|---|---|
git worktree list |
All worktrees, their branches, and whether any are prunable or detached |
git worktree list --porcelain |
Same info in parseable format โ useful in scripts that check worktree health |
cat .git (in the linked worktree) |
Confirms the pointer file is intact and pointing to the right metadata |
ls .git/worktrees/ (in the main worktree) |
Shows all registered worktree metadata โ cross-reference with
worktree list
|
git branch --list |
See if the branch still exists (Scenario 6) |
git reflog (in the suspect worktree) |
Trace what happened to HEAD in that specific worktree |
git status (in the suspect worktree) |
Check for divergence, detached HEAD, or dirty state |
Make these habits and most edge cases never arise:
git worktree remove, never
rm -rf.
This single habit prevents Scenario 4.
git worktree list before rebasing or
force-pushing.
If the branch is checked out elsewhere, either remove that worktree or
coordinate.
git worktree prune in your main repos catches orphaned
metadata before it accumulates.
~/dev/worktrees/fix-login-timeout in
git worktree list, you know exactly what it is. When you
see ~/dev/worktrees/temp3, you have to investigate.
git reset --hard to
realign.
git switch -c to create a branch if you need to save
work.
rm -rf instead of git worktree remove; fix
with git worktree prune.
git worktree list | grep.
git worktree list, ls .git/worktrees/, and
cat .git.
Primary source: git-worktree โ BUGS section and the DETAILS section which covers the internal mechanics that explain most edge cases.
Ask questions: "What happens if I delete the .git/worktrees/ metadata directory manually?" or "Can I recover a worktree after the branch was force-pushed and I have uncommitted changes?" โ bring your weird scenarios to your agent-teacher.