Understanding Git Worktrees
Git worktrees allow you to have multiple working directories attached to the same repository. This means you can work on different branches simultaneously without constantly switching branches and rebuilding dependencies.
bash
# Traditional workflow
my-project/
└── .git/
# With worktrees
my-project/
├── .git/
my-project-feature-a/
my-project-hotfix/
my-project-experiment/Why Use Worktrees?
Common Use Cases
bash
# 1. Parallel feature development
- Work on feature A while building feature B
- No need to stash or commit changes
# 2. Hotfix management
- Keep working on feature branch
- Quickly create worktree for hotfix
# 3. Code review
- Review PR in separate worktree
- Keep your work untouched
# 4. Testing different branches
- Test different solutions simultaneously
- Compare behavior across branchesBasic Worktree Commands
Creating Worktrees
bash
# Create new worktree for branch
git worktree add ../my-project-feature feature-branch
# Create new worktree with new branch
git worktree add ../my-project-feature -b feature/new-feature
# Create worktree from specific commit
git worktree add ../my-project-fix abc1234
# Create worktree from detached HEAD
git worktree add ../my-project-test HEAD~1
# Create worktree with specific branch
git worktree add ../my-project-hotfix hotfix/critical-bugWorktree Structure
bash
# Main repository
~/projects/my-project/
├── .git/
├── src/
└── package.json
# Worktree directories
~/projects/my-project-feature/
├── src/
└── package.json
~/projects/my-project-hotfix/
├── src/
└── package.json
# All share the same .git directoryManaging Worktrees
Listing Worktrees
bash
# List all worktrees
git worktree list
# Output:
# /Users/user/projects/my-project 1234567 [main]
# /Users/user/projects/my-project-feature abcdef0 [feature/new-ui]
# /Users/user/projects/my-project-hotfix 9876543 [hotfix/critical]
# List with prune
git worktree list --porcelain
# Show worktree details
git worktree list --verboseRemoving Worktrees
bash
# Remove worktree after work is done
git worktree remove ../my-project-feature
# Or manually
cd ../my-project-feature
git worktree remove .
# Force remove if worktree has uncommitted changes
git worktree remove -f ../my-project-feature
# Prune stale worktree references
git worktree prune
# Clean up all worktrees
git worktree prune --verboseMoving Worktrees
bash
# Move worktree to new location
git worktree move ../my-project-feature ../my-project-feature-new
# Or use mv command
git worktree move my-project-feature my-project-feature-renamedAdvanced Worktree Workflows
Hotfix Workflow
bash
# Working on feature branch
git branch
# * feature/new-ui
# Critical bug reported - create hotfix worktree
git worktree add ../my-project-hotfix -b hotfix/critical-bug main
# Fix bug in hotfix
cd ../my-project-hotfix
# Make changes
git add .
git commit -m "Fix critical bug"
git push origin hotfix/critical-bug
# Return to feature work
cd ../my-project
# Continue working on featureCode Review Workflow
bash
# Review PR while working on feature
git worktree add ../my-project-review origin/pr/123
cd ../my-project-review
# Review changes
npm install
npm test
# Make suggestions or fixes
# When done
cd ../my-project
git worktree remove ../my-project-reviewParallel Development
bash
# Work on multiple features simultaneously
git worktree add ../feature-auth -b feature/authentication
git worktree add ../feature-ui -b feature/redesign
git worktree add ../feature-api -b feature/api-v2
# Work on any feature without switching
cd ../feature-auth
# Work on auth
cd ../feature-ui
# Work on UI
cd ../feature-api
# Work on APIWorktree Operations
Syncing Worktrees
bash
# Update all worktrees
for dir in ../my-project-*; do
cd $dir
git pull origin $(git branch --show-current)
done
# Or use git worktree foreach
git worktree foreach git pull origin $(git branch --show-current)
# Fetch in all worktrees
git worktree foreach git fetch originChecking Worktree Status
bash
# Check status of all worktrees
git worktree foreach 'echo "=== $(git branch --show-current) ===" && git status --short'
# Check for uncommitted changes
git worktree foreach 'if [ -n "$(git status --porcelain)" ]; then echo "Changes in $(pwd)"; fi'Merging Between Worktrees
bash
# Merge feature worktree into main
cd ../my-project # Main worktree
git merge feature/new-ui
# Or merge from feature worktree
cd ../my-project-feature
git checkout main
git merge feature/new-uiWorktree Best Practices
1. Organize Worktree Locations
bash
# Create projects directory
~/projects/
├── my-project/ # Main repository
├── my-project-feature-1/
├── my-project-feature-2/
└── my-project-hotfixes/
# Consistent naming
git worktree add ../my-project-f1 -b feature/1
git worktree add ../my-project-f2 -b feature/22. Auto-Cleanup Script
bash
# cleanup-worktrees.sh
#!/bin/bash
# Remove worktrees for merged branches
git worktree list --porcelain | while read -r line; do
if [[ $line == branch* ]]; then
branch=${line#branch }
if git merge-base --is-ancestor $branch main 2>/dev/null; then
worktree=$(git worktree list --porcelain | grep -B1 "branch $branch" | head -1 | cut -d' ' -f2)
echo "Removing $worktree ($branch)"
git worktree remove $worktree
fi
fi
done3. Worktree Aliases
bash
# .gitconfig
[alias]
wt = worktree
wt-add = worktree add
wt-list = worktree list
wt-remove = worktree remove
wt-prune = worktree pruneIDE Integration
VS Code
bash
# Open worktree in new VS Code window
code ../my-project-feature
# Or use VS Code workspaces
code --workspace-worktree ~/projects/my-project.code-workspaceJetBrains IDEs
bash
# Open worktree as new project
idea ../my-project-feature
# Or attach to existing project
File → Open → Select worktree directoryTroubleshooting Worktrees
Worktree Won't Remove
bash
# Problem: Can't remove worktree
git worktree remove ../my-project-feature
# error: The worktree '../my-project-feature' is locked
# Solution: Remove lock file
rm -f ../my-project-feature/.git/worktrees/feature/locked.lock
git worktree remove ../my-project-featureDetached Worktree
bash
# Problem: Worktree in detached HEAD state
cd ../my-project-feature
git status
# HEAD detached at abc1234
# Solution: Create branch from commit
git checkout -b feature/new-featureCorrupted Worktree
bash
# Problem: Worktree directory corrupted
git worktree list
# shows worktree but directory doesn't exist
# Solution: Prune worktrees
git worktree prune --verbose
# Or manually remove reference
rm -rf .git/worktrees/feature-nameWorktrees vs Alternatives
Comparison
bash
# Git Worktrees
✓ Multiple working directories
✓ Fast switching
✓ Share .git directory
✓ No branch switching needed
✗ Multiple directories to manage
# Stashing
✓ Single directory
✗ Switching overhead
✗ Conflict resolution
✗ Lost context
# Branch Switching
✓ Single directory
✗ Rebuild dependencies
✗ Lost editor state
✗ Context switching costCI/CD with Worktrees
Testing Multiple Branches
yaml
# .github/workflows/test.yml
name: Test Multiple Branches
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Create worktrees for testing
run: |
git worktree add ../test-main main
git worktree add ../test-develop develop
- name: Test main branch
run: |
cd ../test-main
npm install
npm test
- name: Test develop branch
run: |
cd ../test-develop
npm install
npm testPerformance Considerations
Disk Space
bash
# Worktrees share .git directory
# Each worktree has its own working directory
# Disk usage = .git + working directories
# Check disk usage
du -sh ~/projects/my-project*
# my-project 500M
# my-project-f1 50M
# my-project-f2 50M
# Total: 600M (not 1000M!)Repository Performance
bash
# Too many worktrees can slow git operations
# Recommended: < 10 active worktrees
# Clean up regularly
git worktree prune
# Remove old worktrees
git worktree foreach 'if [ "$(git branch --show-current)" = "old-branch" ]; then git worktree remove .; fi'Conclusion
Git worktrees eliminate the overhead of branch switching by allowing you to work on multiple branches simultaneously. They're perfect for parallel development, hotfixes, and code review workflows.
Key takeaways:
- Use worktrees for parallel branch work
- Organize worktrees with consistent naming
- Clean up worktrees regularly
- Integrate with your existing workflow
- Combine with CI/CD for testing
Boost your productivity with Git worktrees today!