Documentation Index
Fetch the complete documentation index at: https://mintlify.com/git/git/llms.txt
Use this file to discover all available pages before exploring further.
Git worktrees allow you to check out multiple branches at the same time in different directories, all sharing the same repository.
What Are Worktrees?
A worktree is an additional working directory linked to the same repository. Instead of switching branches and losing your current state, you can work on multiple branches in parallel.
Traditional workflow:
# Work on feature
git checkout feature
# ... work work work ...
# Urgent fix needed!
git stash
git checkout main
# Fix, commit
git checkout feature
git stash pop
With worktrees:
# Work on feature in main directory
# ... work work work ...
# Urgent fix needed!
cd ../main-worktree
# Fix, commit
cd ../feature-worktree
# Continue working
Repository Structure
A repository with worktrees:
project/ # Main worktree
├── .git/
│ ├── worktrees/
│ │ ├── feature/ # Linked worktree metadata
│ │ └── hotfix/ # Linked worktree metadata
│ └── ...
└── src/
../project-feature/ # Linked worktree
└── .git # File pointing to main .git
../project-hotfix/ # Linked worktree
└── .git # File pointing to main .git
Basic Operations
Creating a Worktree
Create a new worktree for an existing branch:
git worktree add <path> <branch>
Example:
# Create worktree for feature branch
git worktree add ../project-feature feature-branch
Creating a Worktree with a New Branch
git worktree add -b <new-branch> <path> <base-branch>
Example:
# Create new branch and worktree from main
git worktree add -b new-feature ../project-new-feature main
Creating a Worktree Without Branch Name
Git infers the branch name from the directory:
# Creates and checks out branch 'bugfix-123'
git worktree add ../bugfix-123
Listing Worktrees
Output:
/path/to/project abc123 [main]
/path/to/project-feature def456 [feature-branch]
/path/to/project-hotfix ghi789 [hotfix]
Verbose output:
git worktree list --verbose
Removing a Worktree
git worktree remove <path>
git worktree remove ../project-feature
Or manually delete and prune
rm -rf ../project-feature
git worktree prune
Advanced Usage
Detached HEAD Worktree
Create a worktree at a specific commit:
git worktree add --detach <path> <commit>
Example:
git worktree add --detach ../test-commit abc123
Orphan Worktree
Create a worktree with no commit history:
git worktree add --orphan -b <branch> <path>
Useful for GitHub Pages or separate documentation.
Force Creation
Override safety checks:
# Force create even if branch is checked out elsewhere
git worktree add --force <path> <branch>
# Force twice to override a locked worktree
git worktree add --force --force <path> <branch>
Locking Worktrees
Prevent a worktree from being pruned:
# Lock a worktree
git worktree lock <path> --reason "Working on portable drive"
# Unlock
git worktree unlock <path>
Common Workflows
Emergency Hotfix
You’re deep in feature work when a critical bug is reported:
git worktree add -b hotfix ../project-hotfix main
Switch to hotfix directory
# Fix code
git commit -am "Fix critical bug"
git push origin hotfix
cd ../project
# Continue where you left off
git worktree remove ../project-hotfix
Parallel Development
Work on multiple features simultaneously:
# Main worktree: ongoing feature development
# First linked worktree: code review
git worktree add ../review feature-to-review
# Second linked worktree: experiment
git worktree add -b experiment ../experiment main
# Work in all three directories as needed
Testing Different Versions
# Test current version
make test
# Test release version in parallel
git worktree add --detach ../test-release v1.0.0
cd ../test-release
make test
# Compare results
Long-Running Branches
# Maintain permanent worktrees for stable branches
git worktree add ../project-stable stable
git worktree add ../project-dev develop
git worktree add ../project-main main
# Lock them to prevent accidental removal
git worktree lock ../project-stable --reason "Stable branch worktree"
Managing Worktrees
Moving a Worktree
git worktree move <old-path> <new-path>
Example:
git worktree move ../project-feature ../project-new-feature
Repairing Worktrees
If you manually move a worktree or the main repository:
# Run in the moved worktree
git worktree repair
# Or run in main repository
git worktree repair <path>
Pruning Stale Worktrees
Remove metadata for worktrees that no longer exist:
# Show what would be pruned
git worktree prune --dry-run
# Actually prune
git worktree prune
# Prune older than 3 months
git worktree prune --expire 3.months.ago
Worktree Details
Shared vs. Per-Worktree
Shared between all worktrees:
- Commits and objects
- Branches and tags
- Configuration (except worktree-specific config)
- Most refs under
refs/
Per-worktree:
HEAD position
- Index (staging area)
- Working directory state
refs/bisect/, refs/worktree/, refs/rewritten/
Accessing Other Worktree Refs
# Reference main worktree's HEAD
git show main-worktree/HEAD
# Reference specific linked worktree
git show worktrees/feature/HEAD
Worktree-Specific Configuration
Enable worktree-specific config:
git config extensions.worktreeConfig true
Then set per-worktree config:
git config --worktree user.email developer@example.com
Limitations and Caveats
Submodules: Worktrees with submodules cannot be moved automatically. You must use git worktree repair after manual moves.Bare repositories: The main worktree of a bare repository has special restrictions.Same branch limitation: You cannot check out the same branch in multiple worktrees simultaneously (unless using --force).
Working Around Limitations
# To work on the same branch in two places:
# Create a temporary branch pointing to the same commit
git worktree add -b temp-feature ../project-temp feature
# When done, merge or rebase back to feature
cd ../project-temp
git checkout feature
git merge temp-feature
git branch -d temp-feature
Best Practices
-
Organize worktree directories - Keep them in a consistent location:
~/projects/myapp/ # Main worktree
~/projects/myapp-feature/ # Linked worktrees
~/projects/myapp-hotfix/
-
Use descriptive paths - Name worktree directories after their branches
-
Clean up regularly - Remove worktrees when done:
git worktree list
git worktree remove <unused-worktree>
-
Lock portable worktrees - If on removable media:
git worktree lock <path> --reason "On USB drive"
-
Use for parallel tasks - Not for tiny context switches (use stash instead)
-
Check worktree status - Before major operations:
git worktree list --verbose
Worktrees vs. Alternatives
| Approach | Pros | Cons |
|---|
| Worktrees | Multiple branches simultaneously, shared objects | More disk space, complexity |
| Stash | Quick context switch, simple | Can’t work on both branches simultaneously |
| Multiple clones | Complete isolation | Wastes disk space, no shared objects |
| Bare repo + clones | Flexible setup | Complex, more maintenance |
Troubleshooting
Cannot Create Worktree
Error: “branch ‘feature’ is already checked out”
Solution: The branch is checked out in another worktree:
# Find where it's checked out
git worktree list
# Remove that worktree or use a different branch
Worktree Pruned Accidentally
Problem: Administrative files removed, but directory still exists.
Solution:
# Repair the connection
cd <worktree-directory>
git worktree repair
Cannot Remove Worktree
Error: “contains modified or untracked files”
Solution:
# Force remove
git worktree remove --force <path>
# Or clean the worktree first
cd <worktree>
git clean -fd
git reset --hard
cd ..
git worktree remove <worktree>
Commands Reference
# Create worktree
git worktree add <path> [<branch>]
git worktree add -b <new-branch> <path> [<base>]
git worktree add --detach <path> [<commit>]
# List worktrees
git worktree list
git worktree list --verbose
git worktree list --porcelain
# Remove worktree
git worktree remove <worktree>
git worktree remove --force <worktree>
# Move worktree
git worktree move <worktree> <new-path>
# Lock/unlock worktree
git worktree lock <worktree> --reason <string>
git worktree unlock <worktree>
# Repair worktrees
git worktree repair [<path>...]
# Prune stale administrative files
git worktree prune
git worktree prune --dry-run
git worktree prune --verbose
Configuration
Useful configurations:
[worktree]
# Use relative paths for portability
useRelativePaths = true
# Guess remote branch when creating worktree
guessRemote = true
[alias]
# Convenient worktree aliases
wt = worktree
wta = worktree add
wtl = worktree list
wtr = worktree remove