This error occurs when Git prevents checking out a branch that's already in use by another worktree. Learn how to prune stale worktrees, use the --force flag, or work with detached HEAD.
When you see the error "fatal: '<branch>' is already checked out at '<path>'", Git is preventing you from checking out a branch that is already active in another worktree. This is an intentional safety mechanism, not a bug. Git worktrees allow you to have multiple working directories attached to the same repository, each with its own checked-out branch. However, Git enforces a rule that the same branch cannot be checked out in more than one worktree simultaneously. If it allowed this, making a commit in one worktree would put the other worktree in a confusing state - its branch reference would have moved without any changes to its working directory or index. In Git 2.43 and later, the error message was updated to say "is already used by worktree at" instead of "is already checked out at". This newer message also covers cases where a branch is being rebased or bisected, not just checked out. Regardless of the exact wording, the solution approaches remain the same.
First, see what worktrees Git knows about and which branches they have checked out:
git worktree listThis will show output like:
/home/user/project abc1234 [main]
/home/user/project-feature def5678 [feature]Check if the branch mentioned in the error is actually in use by one of these worktrees, or if the listed path no longer exists on disk.
If a worktree directory was deleted manually (not using git worktree remove), Git still thinks it exists. Prune these stale references:
# See what would be pruned without actually doing it
git worktree prune --dry-run
# Actually prune stale worktree information
git worktree pruneAfter pruning, try your checkout or worktree add command again. This fixes the error in most cases where the worktree was manually deleted.
If the worktree still exists and you no longer need it, remove it properly:
# Remove the worktree (safer than manual deletion)
git worktree remove /path/to/worktree
# Force remove if there are untracked files or modifications
git worktree remove --force /path/to/worktreeThis removes both the directory and Git's internal reference to the worktree.
If you intentionally want the same branch checked out in multiple worktrees (understanding the risks), use the --force flag:
# Force checkout even if branch is used elsewhere
git worktree add --force /path/to/new/worktree feature
# Force also works with git checkout in some scenarios
git checkout --force featureWarning: Having the same branch in multiple worktrees can cause confusion. If you commit in one worktree, the other will have an outdated branch reference and may show unexpected behavior.
If you just need to view or test code at the same commit as the branch, use a detached HEAD:
# Create worktree with detached HEAD at the same commit
git worktree add --detach /path/to/new/worktree feature
# Or checkout in detached HEAD mode
git checkout --detach featureWith detached HEAD, you're at the same commit but not on the branch, so there's no conflict. Any commits you make will need to be explicitly saved to a branch.
Create a new branch pointing to the same commit as the one you can't check out:
# Create a new branch at the same point as 'feature'
git worktree add -b feature-worktree2 /path/to/new/worktree featureThis creates a new worktree with a branch called feature-worktree2 that starts at the same commit as feature. You can work independently and merge or cherry-pick changes later.
In Git 2.43+, a branch can be "in use" if it's in the middle of a rebase or bisect in another worktree:
# Check for rebase or bisect state in worktrees
ls .git/worktrees/*/rebase-merge 2>/dev/null
ls .git/worktrees/*/BISECT_LOG 2>/dev/nullIf found, go to that worktree and complete or abort the operation:
# Abort rebase in the other worktree
git -C /path/to/other/worktree rebase --abort
# Or abort bisect
git -C /path/to/other/worktree bisect resetIf nothing else works, you can manually remove Git's worktree tracking data:
# List worktree metadata directories
ls .git/worktrees/
# Remove the stale worktree reference (be careful!)
rm -rf .git/worktrees/worktree-nameWarning: Only do this if you're certain the worktree no longer exists on disk. This directly modifies Git's internal state.
### Why Git Enforces This Restriction
The one-branch-per-worktree rule exists because each worktree has its own HEAD file but shares the same refs (branches and tags) with all other worktrees. If two worktrees had the same branch checked out and you made a commit in one, the branch ref would advance, but the other worktree's index and working directory wouldn't update. That worktree would appear to be "behind" its own branch with no obvious reason - a confusing and error-prone situation.
### Worktree Locking
Git supports locking worktrees to prevent accidental removal:
# Lock a worktree (e.g., when on removable media)
git worktree lock /path/to/worktree --reason "On USB drive"
# Unlock when accessible again
git worktree unlock /path/to/worktreeWhen a worktree is locked, git worktree prune won't remove it even if the path is inaccessible. Use --force --force with git worktree add to override a locked worktree.
### Automatic Pruning
Git automatically prunes stale worktree data during garbage collection based on gc.worktreePruneExpire (default: 3 months). You can trigger this manually:
git gc### Worktrees and Bare Repositories
Worktrees are especially useful with bare repositories (common on servers):
# In a bare repo, create a worktree to make changes
git worktree add ../working-copy mainThis pattern is useful for CI/CD systems that need to build different branches concurrently from the same repository clone.
warning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server