Skip to content
All essays
CraftMarch 26, 202511 min

Git Worktrees: Work on Multiple Branches Simultaneously

Master Git worktrees for working on multiple branches simultaneously. Boost productivity by eliminating branch switching.

Ü
Ümit Uz
Mobile & Full Stack Developer

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 branches

Basic 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-bug

Worktree 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 directory

Managing 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 --verbose

Removing 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 --verbose

Moving 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-renamed

Advanced 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 feature

Code 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-review

Parallel 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 API

Worktree 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 origin

Checking 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-ui

Worktree 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/2

2. 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
done

3. Worktree Aliases

bash
# .gitconfig
[alias]
  wt = worktree
  wt-add = worktree add
  wt-list = worktree list
  wt-remove = worktree remove
  wt-prune = worktree prune

IDE 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-workspace

JetBrains IDEs

bash
# Open worktree as new project
idea ../my-project-feature

# Or attach to existing project
File → Open → Select worktree directory

Troubleshooting 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-feature

Detached 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-feature

Corrupted 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-name

Worktrees 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 cost

CI/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 test

Performance 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!

Enjoyed this essay? Share it.

Related essays

Next essay
Git Submodules: Managing Nested Repositories