Git Worktrees

Multiple working directories: work on branches simultaneously without stashing or switching.

Worktree Fundamentals

# WHAT ARE WORKTREES?
# Multiple working directories sharing ONE .git repository
# Each worktree checks out a different branch simultaneously
# No stashing, no context switching -- just cd to the other directory

# CREATE WORKTREE
git worktree add ../repo-feature feature  # Existing branch
git worktree add ../repo-hotfix -b hotfix # Create new branch
git worktree add ../repo-review HEAD~5    # Detached HEAD at commit

# WORKTREE NAMING CONVENTION
# Keep worktrees adjacent to main repo:
# ~/project/           ← main worktree
# ~/project-feature/   ← feature worktree
# ~/project-review/    ← review worktree

# LIST WORKTREES
git worktree list                        # All worktrees
git worktree list --porcelain            # Machine-readable

# EXAMPLE OUTPUT:
# /home/user/repo           abc1234 [main]
# /home/user/repo-feature   def5678 [feature]
# /home/user/repo-review    ghi9012 (detached HEAD)

# REMOVE WORKTREE
git worktree remove ../repo-feature      # Remove cleanly
git worktree remove --force ../repo-feature  # Force if dirty

# PRUNE STALE WORKTREES
git worktree prune                       # Clean up after manual deletion
git worktree prune --dry-run             # Preview what would be pruned

# WORKTREE CONSTRAINTS
# Each branch can only be checked out in ONE worktree
# Can't check out main in two worktrees simultaneously
# Worktrees share: objects, refs, hooks, config
# Worktrees don't share: index, working tree, HEAD

Worktree Workflows

# WORKFLOW 1: REVIEW PR WHILE WORKING
# You're deep in feature work, teammate asks for review
# OLD WAY: stash → checkout → review → checkout → stash pop
# NEW WAY:
git worktree add ../repo-review pr-branch
cd ../repo-review
# Review code, run tests, leave comments
cd ../repo
git worktree remove ../repo-review
# Never left your feature branch

# WORKFLOW 2: HOTFIX WITHOUT LOSING CONTEXT
git worktree add ../repo-hotfix -b hotfix/urgent main
cd ../repo-hotfix
# Fix the bug
git commit -am "fix(auth): patch token expiry"
git push -u origin hotfix/urgent
cd ../repo
git worktree remove ../repo-hotfix
# Back to feature work, zero context switch cost

# WORKFLOW 3: COMPARE TWO BRANCHES SIDE BY SIDE
git worktree add ../repo-v1 v1.0
git worktree add ../repo-v2 v2.0
# Open both in separate editor windows
# diff, compare, document differences
git worktree remove ../repo-v1
git worktree remove ../repo-v2

# WORKFLOW 4: PARALLEL BUILDS
git worktree add ../repo-build main
cd ../repo-build
make build                               # Build main
cd ../repo
make build                               # Build feature
# Compare outputs, run benchmarks

# WORKFLOW 5: LONG-RUNNING TASK IN BACKGROUND
git worktree add ../repo-rebase -b rebase-cleanup main
cd ../repo-rebase
git rebase -i HEAD~20                    # Time-consuming rebase
# Meanwhile, main repo continues normal development

Infrastructure Worktree Patterns

# DOMUS-* REVIEW WORKFLOW
# Review a PR in domus-infra-ops without leaving current work
git -C ~/atelier/_bibliotheca/domus-infra-ops \
  worktree add /tmp/infra-review pr-branch
cd /tmp/infra-review
make 2>&1 | grep -E "WARN|ERROR"         # Test build
cd -
git -C ~/atelier/_bibliotheca/domus-infra-ops \
  worktree remove /tmp/infra-review

# ANTORA BUILD TESTING
# Test documentation changes in isolation
git worktree add /tmp/docs-test feature-docs
cd /tmp/docs-test
make serve                               # Local build + serve
# Verify in browser, then clean up
cd -
git worktree remove /tmp/docs-test

# MULTI-REPO WORKTREE STATUS
for repo in ~/atelier/_bibliotheca/domus-*/; do
  wt_count=$(git -C "$repo" worktree list | wc -l)
  if [[ "$wt_count" -gt 1 ]]; then
    echo "=== $(basename "$repo") ==="
    git -C "$repo" worktree list
  fi
done

# CLEANUP STALE WORKTREES ACROSS REPOS
for repo in ~/atelier/_bibliotheca/domus-*/; do
  git -C "$repo" worktree prune
done

Worktree Gotchas

# WRONG: Checking out same branch in two worktrees
git worktree add ../repo2 main
# Error: 'main' is already checked out

# CORRECT: Each branch in only one worktree
git worktree add ../repo2 -b main-copy main  # New branch from main

# WRONG: Deleting worktree directory manually
rm -rf ../repo-feature
# Git still thinks the worktree exists!

# CORRECT: Use git worktree remove
git worktree remove ../repo-feature
# OR if already deleted manually:
git worktree prune                       # Clean up stale entries

# WRONG: Running git commands in worktree expecting main's state
cd ../repo-feature
git stash list                           # Shows SHARED stash list
# Stash is shared across all worktrees!

# CORRECT: Understand what's shared
# Shared: stash, tags, remotes, objects, config
# Not shared: index (staging), working tree, HEAD, branch checkout

# WRONG: Forgetting worktrees exist
# Weeks later, disk space mystery...
git worktree list                        # Oh right, 5 worktrees!

# CORRECT: Clean up when done
git worktree remove ../done-worktree
git worktree prune                       # Periodically prune

# WRONG: Creating worktree with relative paths carelessly
git worktree add ./nested-worktree branch
# Creates worktree INSIDE your repo -- messy!

# CORRECT: Use paths outside the repo
git worktree add ../repo-branch branch   # Adjacent, not nested
git worktree add /tmp/quick-review branch  # Temp location for reviews

Quick Reference

# CREATE
git worktree add ../path branch          # Existing branch
git worktree add ../path -b new branch   # New branch from base
git worktree add ../path HEAD~5          # Detached HEAD

# LIST
git worktree list                        # All worktrees
git worktree list --porcelain            # Machine-readable

# REMOVE
git worktree remove ../path              # Clean removal
git worktree remove --force ../path      # Force if dirty
git worktree prune                       # Clean up stale entries

# KEY RULES
# One branch per worktree (can't duplicate)
# Shared: stash, tags, remotes, objects, config
# Not shared: index, working tree, HEAD
# Always clean up when done

See Also

  • Stash — alternative for quick context switches

  • Branches — branch management

  • Config — worktree-specific configuration