Git Worktree - Multiple Working Directories for Enhanced Productivity
Git Worktree
๐ก Intermediate
๐ด Advanced
Learn to use Git worktree for managing multiple working directories from a single repository. Perfect for parallel development workflows and efficient context switching.
Table of Contents
Understanding Git Worktree
What is Git Worktree?
Git worktree allows you to have multiple working directories from a single Git repository. Each worktree can be on a different branch, enabling parallel development without the overhead of multiple repository clones.
Key Benefits:
- Parallel Development - Work on multiple features simultaneously
- Fast Context Switching - No need to stash or commit incomplete work
- Efficient Comparisons - Compare branches in separate directories
- Shared Object Store - All worktrees share the same Git objects
Worktree vs Traditional Approaches
Approach | Pros | Cons | Best For |
---|---|---|---|
Branch Switching | Simple, familiar workflow | Need to stash/commit; slower switching | Sequential development |
Multiple Clones | Complete isolation | Disk space; separate histories | Independent projects |
Git Worktree | Shared history; parallel work; efficient | Learning curve; path management | Parallel development |
๐ก For Intermediate Users: When to Use Worktree
- Working on multiple features that might conflict
- Maintaining multiple release branches
- Running tests on different branches simultaneously
- Comparing implementations side by side
๐ด For Advanced Users: Complex Scenarios
- CI/CD pipelines with parallel testing
- Multi-version documentation maintenance
- Large-scale refactoring with fallback options
- Performance testing across different implementations
Basic Operations
Creating Worktrees
Create new worktrees
# Create worktree for existing branch
git worktree add ../feature-auth feature/authentication
# Create worktree and new branch simultaneously
git worktree add ../hotfix-123 -b hotfix/issue-123
# Create worktree for specific commit
git worktree add ../release-prep v2.1.0
# Create worktree in subdirectory
git worktree add worktrees/feature-payments feature/payments
Expected Output:
Preparing worktree (new branch 'hotfix/issue-123')
HEAD is now at a1b2c3d Fix critical security vulnerability
Listing Worktrees
# List all worktrees
git worktree list
# List with more details
git worktree list --porcelain
# Show only paths
git worktree list | awk '{print $1}'
Worktree List Output:
/home/user/project a1b2c3d [main]
/home/user/feature-auth b2c3d4e [feature/authentication]
/home/user/hotfix-123 c3d4e5f [hotfix/issue-123]
/home/user/release-prep d4e5f6g (detached HEAD)
- Path - Directory location of the worktree
- Commit Hash - Current commit in that worktree
- Branch - Current branch or detached HEAD state
Working with Worktrees
Navigate and work in different worktrees
# Switch to different worktree
cd ../feature-auth
# Check current branch and status
git branch --show-current
git status
# Make changes and commit
echo "new feature code" >> auth.js
git add auth.js
git commit -m "Implement authentication feature"
# Switch to another worktree
cd ../hotfix-123
# Work on hotfix
echo "security fix" >> security.js
git add security.js
git commit -m "Fix security vulnerability"
Removing Worktrees
# Remove worktree (safe - checks for uncommitted changes)
git worktree remove ../feature-auth
# Force remove (ignores uncommitted changes)
git worktree remove --force ../hotfix-123
# Remove worktree and delete branch
git worktree remove ../feature-payments
git branch -d feature/payments
โ ๏ธ Warning: Removing a worktree only removes the working directory. The branch remains unless explicitly deleted with
git branch -d
.
Advanced Workflows
Parallel Development Workflow
Step 1: Set Up Multiple Worktrees
# Main development branch
git worktree add ../main-dev main
# Feature branches
git worktree add ../feature-ui -b feature/ui-redesign
git worktree add ../feature-api -b feature/api-upgrade
# Testing environment
git worktree add ../testing develop
Step 2: Parallel Development
# Terminal 1: Work on UI
cd ../feature-ui
# ... make UI changes ...
git add . && git commit -m "Update user interface"
# Terminal 2: Work on API (simultaneously)
cd ../feature-api
# ... make API changes ...
git add . && git commit -m "Upgrade API endpoints"
# Terminal 3: Test changes
cd ../testing
git merge feature/ui-redesign
npm test
Step 3: Integration and Cleanup
# Merge completed features
cd ../main-dev
git merge feature/ui-redesign
git merge feature/api-upgrade
# Clean up worktrees
git worktree remove ../feature-ui
git worktree remove ../feature-api
git branch -d feature/ui-redesign feature/api-upgrade
Release Management Workflow
Managing multiple release versions
# Set up release worktrees
git worktree add ../release-v2.0 release/v2.0
git worktree add ../release-v2.1 release/v2.1
git worktree add ../release-v3.0 -b release/v3.0
# Hotfix for multiple versions
git worktree add ../hotfix-security -b hotfix/security-patch
# Apply hotfix to each release
cd ../hotfix-security
# ... implement security fix ...
git add . && git commit -m "Security patch"
# Cherry-pick to each release
cd ../release-v2.0
git cherry-pick hotfix/security-patch
cd ../release-v2.1
git cherry-pick hotfix/security-patch
Worktree with Hooks and Automation
# Create worktree with custom setup
git worktree add ../staging staging
# Set up environment-specific configuration
cd ../staging
cp .env.staging .env
npm install --production
# Create automation script
cat > setup-worktree.sh << 'EOF'
#!/bin/bash
BRANCH=$1
WORKTREE_DIR="../${BRANCH}"
git worktree add "$WORKTREE_DIR" "$BRANCH"
cd "$WORKTREE_DIR"
# Environment setup
if [[ "$BRANCH" == "staging" ]]; then
cp .env.staging .env
npm install --production
elif [[ "$BRANCH" == "development" ]]; then
cp .env.development .env
npm install
fi
echo "Worktree $BRANCH ready at $WORKTREE_DIR"
EOF
chmod +x setup-worktree.sh
Practical Examples
Scenario 1: Bug Fix During Feature Development
Situation: You're working on a new feature when a critical bug is reported that needs immediate attention.
# Currently working on feature branch
pwd # /home/user/project (on feature/new-dashboard)
git status # shows uncommitted changes
# Create hotfix worktree without disturbing current work
git worktree add ../hotfix-critical -b hotfix/critical-bug main
# Switch to hotfix
cd ../hotfix-critical
# Fix the bug
vim src/utils.js
git add src/utils.js
git commit -m "Fix critical calculation bug"
# Push and create PR
git push origin hotfix/critical-bug
# Return to feature development
cd /home/user/project # back to feature work
# Continue where you left off - no stashing needed!
Scenario 2: Code Comparison and Refactoring
Situation: You want to refactor a module but keep the old implementation for comparison and potential rollback.
# Create worktree for refactoring
git worktree add ../refactor-auth -b refactor/authentication-module
# Keep original in separate worktree for comparison
git worktree add ../original-auth main
# Work on refactoring
cd ../refactor-auth
# ... refactor authentication module ...
# Compare implementations
cd ../original-auth
ls -la src/auth/ # original structure
cd ../refactor-auth
ls -la src/auth/ # new structure
# Run tests in both environments
cd ../original-auth && npm test
cd ../refactor-auth && npm test
# Use diff tools to compare
diff -r ../original-auth/src/auth/ ../refactor-auth/src/auth/
Scenario 3: Documentation and Code Sync
Situation: You need to update documentation while developing features, ensuring they stay in sync.
# Set up parallel documentation workflow
git worktree add ../docs-update docs/main
git worktree add ../feature-docs -b feature/api-documentation
# Terminal 1: Develop feature
cd /home/user/project # main development
# ... implement API changes ...
# Terminal 2: Update docs simultaneously
cd ../feature-docs
# ... update API documentation ...
# Terminal 3: Preview documentation
cd ../docs-update
git merge feature/api-documentation
npm run docs:serve # preview changes
# Coordinate commits
cd /home/user/project
git add . && git commit -m "Implement new API endpoints"
cd ../feature-docs
git add . && git commit -m "Document new API endpoints"
Maintenance and Cleanup
Worktree Health Check
Check and repair worktrees
# List all worktrees and their status
git worktree list
# Prune stale worktree references
git worktree prune
# Repair corrupted worktrees
git worktree repair
# Check for worktree issues
git worktree prune --dry-run
Automated Cleanup Script
#!/bin/bash
# cleanup-worktrees.sh
echo "๐งน Cleaning up Git worktrees..."
# List current worktrees
echo "Current worktrees:"
git worktree list
# Remove merged feature branches
for worktree in $(git worktree list --porcelain | grep "^worktree" | cut -d' ' -f2); do
if [[ "$worktree" != "$(pwd)" ]]; then
cd "$worktree"
branch=$(git branch --show-current)
# Check if branch is merged into main
if git merge-base --is-ancestor HEAD origin/main 2>/dev/null; then
echo "๐๏ธ Removing merged worktree: $worktree ($branch)"
cd - > /dev/null
git worktree remove "$worktree"
git branch -d "$branch" 2>/dev/null
else
cd - > /dev/null
echo "โณ Keeping active worktree: $worktree ($branch)"
fi
fi
done
# Prune stale references
git worktree prune
echo "โ
Cleanup complete!"
Worktree Status Dashboard
Create a status overview script
#!/bin/bash
# worktree-status.sh
echo "๐ Worktree Status Dashboard"
echo "============================"
git worktree list --porcelain | while read -r line; do
if [[ $line == worktree* ]]; then
path=$(echo "$line" | cut -d' ' -f2)
echo "๐ $path"
elif [[ $line == HEAD* ]]; then
commit=$(echo "$line" | cut -d' ' -f2)
echo " ๐ Commit: ${commit:0:8}"
elif [[ $line == branch* ]]; then
branch=$(echo "$line" | cut -d' ' -f2)
echo " ๐ฟ Branch: $branch"
elif [[ $line == "" ]]; then
# Check for uncommitted changes
if [[ -n "$path" ]]; then
cd "$path" 2>/dev/null && {
if [[ -n "$(git status --porcelain)" ]]; then
echo " โ ๏ธ Uncommitted changes detected"
else
echo " โ
Clean working directory"
fi
# Check for unpushed commits
if [[ -n "$(git log @{u}..HEAD 2>/dev/null)" ]]; then
echo " ๐ค Unpushed commits available"
fi
}
cd - > /dev/null
fi
echo ""
fi
done
Best Practices
๐๏ธ Organization
- Use consistent naming conventions for worktree directories
- Keep worktrees in a dedicated parent directory
- Document active worktrees and their purposes
- Clean up completed worktrees promptly
๐ Workflow Integration
- Create aliases for common worktree operations
- Use scripts to automate worktree setup
- Integrate worktree status into your prompt
- Consider worktrees in CI/CD pipeline design
โก Performance
- Limit the number of concurrent worktrees
- Use worktrees for short-lived parallel work
- Monitor disk usage with multiple worktrees
- Consider worktree overhead for large repositories
๐ก๏ธ Safety
- Always commit or stash before removing worktrees
- Use descriptive branch names for worktree clarity
- Regularly run
git worktree prune
- Backup important work before worktree operations
Recommended Git Configuration
# Add useful aliases
git config --global alias.wt 'worktree'
git config --global alias.wtls 'worktree list'
git config --global alias.wtadd 'worktree add'
git config --global alias.wtrm 'worktree remove'
# Configure worktree behavior
git config --global worktree.guessRemote true
๐ก Pro Tips:
- Use worktrees for A/B testing different implementations
- Combine with
git bisect
for parallel debugging - Create worktree templates for consistent environments
- Use symbolic links for shared configuration files
- Consider worktrees for documentation that needs code sync