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.

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