Git - Worktrees

Advanced

Git worktrees allow you to have multiple working directories for a single repository, enabling parallel development on different branches without the overhead of multiple clones.

What are Git Worktrees?

A worktree is an additional working directory associated with the same Git repository:

Main Repository (.git)
├── main-worktree/     (main branch)
├── feature-worktree/  (feature/auth branch)
└── hotfix-worktree/   (hotfix/security branch)

Benefits:

  • Parallel Development: Work on multiple branches simultaneously
  • Shared History: One .git directory, multiple working trees
  • Fast Switching: No need to stash or commit incomplete work
  • Testing: Compare branches side-by-side

Basic Worktree Operations

Creating Worktrees

# Create worktree for existing branch
git worktree add ../feature-work feature/authentication

# Create worktree with new branch
git worktree add ../hotfix-work -b hotfix/security-fix

# Create worktree from specific commit
git worktree add ../review-work abc1234
Preparing worktree (new branch 'hotfix/security-fix')
HEAD is now at abc1234 Initial commit

Listing Worktrees

# List all worktrees
git worktree list

# List with verbose details
git worktree list --verbose

# List with porcelain format
git worktree list --porcelain
/home/user/project                abc1234 [main]
/home/user/feature-work          def5678 [feature/authentication]
/home/user/hotfix-work           ghi9012 [hotfix/security-fix]

Removing Worktrees

# Remove worktree (must be clean)
git worktree remove ../feature-work

# Force remove (even with modifications)
git worktree remove --force ../feature-work

# Prune deleted worktrees from list
git worktree prune

Practical Workflows

Parallel Feature Development

# Setup multiple features
git worktree add ../auth-feature -b feature/authentication
git worktree add ../ui-feature -b feature/new-ui
git worktree add ../api-feature -b feature/api-v2

# Work in each directory independently
cd ../auth-feature
# Develop authentication feature

cd ../ui-feature  
# Develop UI improvements

cd ../api-feature
# Develop API changes

Release Preparation

# Main development continues
cd main-repo
git checkout main

# Prepare release in separate worktree
git worktree add ../release-v2.0 -b release/v2.0
cd ../release-v2.0

# Stabilize release
git cherry-pick <commit>
git revert <bad-commit>

# Test and package release
npm run build
npm run test

Hotfix Workflow

# Continue main development
cd main-repo

# Create hotfix worktree from production
git worktree add ../hotfix-urgent -b hotfix/urgent-fix origin/production

cd ../hotfix-urgent
# Fix critical issue
git add .
git commit -m "Fix critical security vulnerability"

# Deploy hotfix
git push origin hotfix/urgent-fix

# Merge back to main
cd ../main-repo
git merge hotfix/urgent-fix

Advanced Worktree Usage

Worktree with Different Remotes

# Create worktree tracking different remote
git worktree add ../upstream-work -b upstream-main origin/main

# Add another remote in worktree
cd ../upstream-work
git remote add upstream https://github.com/original/project.git
git fetch upstream
git branch --set-upstream-to=upstream/main

Temporary Worktrees

# Create temporary worktree for testing
git worktree add --detach ../temp-test HEAD~5

cd ../temp-test
# Test specific commit
make test

# Clean up
cd ../main-repo
git worktree remove ../temp-test

Worktree for Bisecting

# Create worktree for bisecting
git worktree add ../bisect-work -b bisect-session

cd ../bisect-work
git bisect start
git bisect bad HEAD
git bisect good v1.0

# Continue bisecting in isolation
# while main development continues

Configuration and Customization

Worktree-specific Configuration

# Configure worktree-specific settings
cd ../feature-work
git config core.editor vim
git config user.email [email protected]

# Check configuration
git config --list

Shared vs Independent Configs

# Shared configurations (affects all worktrees)
git config --global user.name "Your Name"
git config branch.main.remote origin

# Worktree-specific configurations
git config --local core.filemode false
git config --local push.default current

Integration with Development Tools

IDE/Editor Integration

# Open different features in separate editors
code ../main-repo        # Main development
code ../feature-work     # Feature development  
code ../release-work     # Release preparation

# Each instance maintains separate:
# - File history
# - Search indexes  
# - Debug sessions
# - Terminal sessions

Build and Test Isolation

# Independent build directories
cd ../main-repo
npm run build    # Builds to ./dist

cd ../feature-work  
npm run build    # Builds to ./dist (separate)

# Parallel testing
cd ../main-repo && npm test &
cd ../feature-work && npm test &
wait

Best Practices

Naming Conventions

# Descriptive worktree names
git worktree add ../main-development main
git worktree add ../feature-auth-system feature/authentication
git worktree add ../release-v2.1-prep release/v2.1
git worktree add ../hotfix-security-patch hotfix/cve-2023-001

Directory Organization

# Organized structure
project/
├── main/                 # Main repository
├── worktrees/
│   ├── feature-auth/     # Feature development
│   ├── feature-ui/       # UI improvements
│   ├── release-v2.0/     # Release preparation
│   └── hotfix-urgent/    # Critical fixes
└── builds/
    ├── main/             # Main build outputs
    ├── feature-auth/     # Feature build outputs
    └── release-v2.0/     # Release build outputs

Cleanup Strategies

# Regular cleanup script
#!/bin/bash
# cleanup-worktrees.sh

# Remove merged feature worktrees
for worktree in $(git worktree list --porcelain | grep '^worktree' | cut -d' ' -f2)
do
  cd "$worktree"
  branch=$(git branch --show-current)
  
  if git merge-base --is-ancestor HEAD origin/main; then
    echo "Removing merged worktree: $worktree"
    cd ..
    git worktree remove "$worktree"
  fi  
done

# Prune stale worktrees
git worktree prune

Troubleshooting

Common Issues

Branch Checkout Conflicts: Each branch can only be checked out in one worktree at a time.
# Error: branch is already checked out
git worktree add ../duplicate-work main
# fatal: 'main' is already checked out at '/path/to/main'

# Solution: Use different branch or detached HEAD
git worktree add --detach ../duplicate-work main

Disk Space Management

# Check worktree disk usage
du -sh ../*/

# Share object database (already shared)
# But working directories are separate

# Clean build artifacts across worktrees
find ../*/node_modules -name "*.cache" -delete
find ../*/dist -type f -delete

Recovering Corrupted Worktrees

# Fix worktree references
git worktree repair

# Remove and recreate problematic worktree
git worktree remove --force ../broken-work
git worktree add ../fixed-work existing-branch

Performance Considerations

  • Memory: Each worktree uses separate memory for file system cache
  • Storage: Working directories are separate, but objects shared
  • I/O: Multiple worktrees can cause disk contention
  • Indexing: IDE indexing multiplied by number of worktrees

Comparison with Alternatives

ApproachProsConsUse Case
Git WorktreesShared history, fast setupComplex managementParallel development
Multiple ClonesComplete isolationDisk space, sync overheadIndependent projects
Branch SwitchingSimple, familiarContext switching overheadSequential development
Git StashLightweightLimited to uncommitted workBrief interruptions

Integration Examples

CI/CD Pipeline

# CI script using worktrees
#!/bin/bash
# ci-parallel-tests.sh

# Create test worktrees
git worktree add ci-unit-tests $COMMIT_SHA
git worktree add ci-integration-tests $COMMIT_SHA  
git worktree add ci-e2e-tests $COMMIT_SHA

# Run tests in parallel
(cd ci-unit-tests && npm run test:unit) &
(cd ci-integration-tests && npm run test:integration) &
(cd ci-e2e-tests && npm run test:e2e) &

wait

# Cleanup
git worktree remove ci-unit-tests
git worktree remove ci-integration-tests  
git worktree remove ci-e2e-tests

Code Review Workflow

# Review script
#!/bin/bash
# review-pr.sh PR_NUMBER

PR_BRANCH="pr-$1"
git fetch origin pull/$1/head:$PR_BRANCH

# Create review worktree
git worktree add ../review-pr-$1 $PR_BRANCH

echo "Review environment ready at ../review-pr-$1"
echo "Compare with main: diff -r . ../review-pr-$1"
Pro Tip: Use worktrees for maintaining multiple development environments, comparing branches, and isolating experimental work without losing context.

Key Takeaways

  • Parallel Development: Work on multiple branches simultaneously
  • Shared Repository: One .git directory, multiple working trees
  • Branch Isolation: Each worktree can have different branch checked out
  • Resource Sharing: Objects and history shared, working directories separate
  • Flexible Workflows: Supports complex development patterns

Git worktrees provide a powerful way to manage multiple parallel workflows while maintaining the efficiency of a single repository. Master this tool to boost productivity in complex development scenarios.