Skip to main content
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

git worktree list
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

1
Remove the worktree
2
git worktree remove <path>
3
Example:
4
git worktree remove ../project-feature
5
Or manually delete and prune
6
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:
1
Create hotfix worktree
2
git worktree add -b hotfix ../project-hotfix main
3
Switch to hotfix directory
4
cd ../project-hotfix
5
Fix the bug
6
# Fix code
git commit -am "Fix critical bug"
git push origin hotfix
7
Return to feature work
8
cd ../project
# Continue where you left off
9
Clean up when done
10
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 [email protected]

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

  1. Organize worktree directories - Keep them in a consistent location:
    ~/projects/myapp/          # Main worktree
    ~/projects/myapp-feature/  # Linked worktrees
    ~/projects/myapp-hotfix/
    
  2. Use descriptive paths - Name worktree directories after their branches
  3. Clean up regularly - Remove worktrees when done:
    git worktree list
    git worktree remove <unused-worktree>
    
  4. Lock portable worktrees - If on removable media:
    git worktree lock <path> --reason "On USB drive"
    
  5. Use for parallel tasks - Not for tiny context switches (use stash instead)
  6. Check worktree status - Before major operations:
    git worktree list --verbose
    

Worktrees vs. Alternatives

ApproachProsCons
WorktreesMultiple branches simultaneously, shared objectsMore disk space, complexity
StashQuick context switch, simpleCan’t work on both branches simultaneously
Multiple clonesComplete isolationWastes disk space, no shared objects
Bare repo + clonesFlexible setupComplex, 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

Build docs developers (and LLMs) love