# Fix Git Worktree Checkout Leaving Detached HEAD and Lost Commits
You create a Git worktree to work on a feature branch alongside your main branch:
git worktree add ../fix-bug fix-bugBut after committing changes in the worktree, the commits seem to disappear. Running git log in the worktree shows a detached HEAD:
cd ../fix-bug
git status
# HEAD detached at abc1234And your commits are not on any branch.
Understanding Git Worktrees
Git worktrees allow you to check out multiple branches simultaneously in separate directories. Each worktree shares the same .git directory but has its own working directory and HEAD.
# List all worktrees
git worktree list
# /path/to/repo main [active]
# /path/to/fix-bug abc1234 [detached HEAD]The Problem: Worktree Created From Commit, Not Branch
When you create a worktree from a commit hash instead of a branch name, Git checks out a detached HEAD:
```bash # WRONG: Creates detached HEAD git worktree add ../fix-bug abc1234
# CORRECT: Creates a new branch git worktree add -b fix-bug ../fix-bug main ```
The -b flag creates a new branch. Without it, Git checks out the specified commit directly.
Recovering Commits From Detached HEAD
If you already committed to a detached HEAD worktree, the commits are not lost:
```bash # Find the detached HEAD commit git log --oneline -5 # abc1234 Fix critical bug # def5678 Previous commit
# Create a branch at this commit git branch fix-bug-recovered ```
Then link it to the worktree:
# In the main repo
git worktree remove ../fix-bug
git worktree add -B fix-bug ../fix-bug fix-bug-recoveredStep 1: Creating Worktrees Correctly
Always create a branch when adding a worktree:
```bash # Create a new branch from main git worktree add -b feature-x ../worktree-feature-x main
# Create a new branch from a specific commit git worktree add -b hotfix ../worktree-hotfix v1.2.3
# Check out an existing branch git worktree add ../worktree-release release-v2.0 ```
Step 2: Worktree and Branch Naming
If you omit -b and the argument looks like a branch name, Git checks out that existing branch:
```bash # If release-v2.0 exists as a branch: git worktree add ../worktree-release release-v2.0 # This checks out the existing branch (not detached)
# If release-v2.0 does NOT exist: git worktree add ../worktree-release release-v2.0 # Git creates a new branch "release-v2.0" from HEAD ```
Step 3: Worktree Removal
When done with a worktree, remove it properly:
```bash # Remove the worktree git worktree remove ../fix-bug
# If the worktree has uncommitted changes git worktree remove ../fix-bug --force
# Clean up stale worktree references git worktree prune ```
If you delete the worktree directory manually without using git worktree remove, Git keeps a stale reference:
git worktree list
# /path/to/deleted-dir (missing) [main]Clean it up with git worktree prune.
Step 4: Worktrees With Bare Repositories
For CI/CD pipelines, use worktrees with bare repositories:
```bash # Create a bare clone git clone --bare https://github.com/user/repo.git repo.git
# Create a worktree from the bare repo git --git-dir=repo.git worktree add /tmp/build main ```
This allows building and testing without a full clone in the working directory.
Step 5: Worktree Limitations
Be aware of worktree limitations:
- You cannot check out the same branch in multiple worktrees simultaneously
- Submodules are not fully supported in worktrees (Git 2.36+ improved this)
- Some Git commands behave differently in worktrees
Check the current worktree context:
git rev-parse --is-inside-work-tree
git rev-parse --git-common-dirStep 6: Finding Lost Worktree Commits
If a worktree was deleted and you lost commits:
```bash # Check reflog for worktree-specific entries git reflog show refs/worktrees/fix-bug/HEAD
# Or check all reflogs git reflog --all | grep fix-bug ```
Worktree reflogs are stored separately from the main reflog, so git reflog in the main directory does not show them by default.
Best Practice: Worktree Naming Convention
Use a consistent naming convention for worktree directories:
# Directory name matches branch name
git worktree add ../wt-feature-x feature-x
git worktree add ../wt-hotfix-123 hotfix-123
git worktree add ../wt-release-2.0 release-v2.0The wt- prefix makes it clear these are worktree directories, not regular checkouts.