Git Worktrees: Working on Multiple Branches Simultaneously
In this tutorial, you'll learn Git worktrees for working on multiple branches at once including creating and managing worktrees, use cases for parallel development, and comparison to stashing and cloning.
Why Git Worktrees Matter
Every developer has faced this scenario: you are working on a feature branch when a critical bug is reported on main. You need to switch branches, but you have uncommitted changes. You could stash, but stashing is fragile. You could clone the repo again, but that wastes disk space and setup time. Git worktrees let you check out multiple branches simultaneously in separate directories, all sharing a single Repository.
By the end of this guide, you will create and manage worktrees, understand their use cases, and integrate them into your workflow.
What is a Git Worktree?
A Git worktree is an additional working directory linked to the same Repository. Each worktree has its own working directory, index, and HEAD. Changes in one worktree do not affect others. All worktrees share the same Git object database, so they use minimal additional disk space.
flowchart TD A[Main Repository] --> B[.git directory] A --> C[Primary Worktree: ~/project/main] B --> D[Worktree 1: ~/project/feature-auth] B --> E[Worktree 2: ~/project/hotfix-bug] B --> F[Worktree 3: ~/project/experiment] D --> G[HEAD: feature/auth] E --> H[HEAD: hotfix/bug-123] F --> I[HEAD: experiment/new-ui]
Basic Commands
Creating a Worktree
# Create a worktree for a new branch
git worktree add ../project-feature feature/new-feature
# Create a worktree for an existing branch
git worktree add ../project-main main
# Create a worktree with a new branch (detached)
git worktree add ../project-experiment
# Create a worktree based on a tag
git worktree add ../project-v1 v1.0.0
Expected Output
$ git worktree add ../project-feature feature/new-feature
Preparing worktree (new branch 'feature/new-feature')
HEAD is now at a1b2c3d Add new feature implementation
Listing Worktrees
git worktree list
Expected Output
~/project a1b2c3d [main]
~/project-feature d4e5f6g [feature/new-feature]
~/project-hotfix h7i8j9k [hotfix/bug-123]
~/project-experiment l0m1n2o (detached HEAD)
Removing a Worktree
# Remove a worktree
git worktree remove ../project-feature
# Force remove (even with uncommitted changes)
git worktree remove --force ../project-feature
Pruning Worktrees
When worktrees are deleted manually (using rm -rf), Git still tracks them. Use prune to clean up:
git worktree prune
Use Cases
Hotfix While Developing
# In current feature branch
git worktree add ../project-hotfix main
cd ../project-hotfix
# Make the hotfix, commit, push
git checkout -b hotfix/critical-bug
# Fix the bug...
git commit -am "Fix critical bug"
git push origin hotfix/critical-bug
# Switch back to feature work
cd ../project
# Continue feature work without interruption
Code Review
# Check out a pull request for review
git worktree add ../project-review origin/pr/42
cd ../project-review
# Review code, run tests, check behavior
git log --oneline -5
npm test
# Remove when done
cd ..
git worktree remove ../project-review
Running Tests on Multiple Branches
#!/bin/bash
# test-all-branches.sh
BRANCHES="main develop feature/new-ui"
for BRANCH in $BRANCHES; do
echo "Testing $BRANCH..."
git worktree add "../project-$BRANCH" "$BRANCH" 2>/dev/null
cd "../project-$BRANCH"
npm test
cd ..
git worktree remove "../project-$BRANCH"
done
Advanced Worktree Operations
Moving a Worktree
# Move a worktree to a new location
git worktree move ../project-feature ../project-feature-v2
Locking a Worktree
Prevent accidental pruning:
git worktree lock ../project-feature --reason "Active review session"
git worktree unlock ../project-feature
Worktree with Custom Options
# Create worktree at specific commit
git worktree add --detach ../project-fix f7e8d9c
# Create worktree with no checkout (bare worktree)
git worktree add --no-checkout ../project-empty feature/branch
git -C ../project-empty checkout feature/branch
Worktree and Git Hooks
Worktrees respect the hooks from the main Repository's .git/hooks/. If you need per-worktree hooks, they are stored in the worktree's own .git/worktrees/<name>/hooks/ directory.
Comparison with Alternatives
| Approach | Pros | Cons |
|---|---|---|
| Git Stash | Fast, no extra directories | Only works for uncommitted changes; stashes can be lost |
| Multiple clones | Full isolation | Wastes disk space; each clone needs its own remote setup |
| Git Worktrees | Shared objects, low overhead; separate working trees | Must remember to prune; limited workflows need care |
Disk Space Comparison
# Single clone
~/.project (342 MB) # .git = 340 MB + working tree = 2 MB
# Two worktrees
~/.project (342 MB) # Same .git (340 MB), working tree = 2 MB
~/feature (2 MB) # Only working tree, no additional .git
# Two clones
~/.project (342 MB) # Full clone
~/project2 (342 MB) # Second full clone (wasteful)
Common Pitfalls
# Cannot checkout branch that is checked out in another worktree
git checkout feature/new-feature # Fails!
# fatal: 'feature/new-feature' is already checked out at '.../project-feature'
# Solution: work on the branch in the worktree's directory
cd ../project-feature
# Or force checkout (creates detached HEAD)
git checkout --ignore-other-worktrees feature/new-feature
Common Errors
| Problem | Cause | Fix |
|---|---|---|
fatal: 'branch' is already checked out |
Branch in another worktree | Work on that branch in its own worktree directory |
fatal: 'path' already exists |
Directory already exists | Remove the directory or choose a different path |
warning: deleting branch that has been merged |
Auto-checkout creates branch | Use --no-track or manage branches manually |
worktree remove: not empty |
Uncommitted changes | Commit or stash changes, then remove |
fatal: unable to create 'path/index.lock' |
Another Git Process running | Check for hung Git processes |
Practice Questions
1. What does git worktree add ../path branch do?
Creates a new working directory at ../path with branch checked out.
2. How do Git worktrees save disk space compared to multiple clones?
All worktrees share the same .git object database instead of duplicating it.
3. When would you use git worktree prune?
After manually deleting worktree directories to clean up stale references.
4. What happens if you try to checkout a branch that is already checked out in another worktree?
Git shows fatal: 'branch' is already checked out at '...'.
5. How do you remove a worktree?
git worktree remove <path>.
Challenge
Create a script called review-pr.sh that: accepts a PR number, creates a worktree for that PR branch, opens the directory in Neovim, runs the test suite, and removes the worktree when done. Include error handling and status messages.
Real-World Task
Set up a workflow on a project using Git worktrees. Create one worktree for the main branch (for quick hotfixes) and one for your current feature branch. Practice switching between them throughout the day: make a hotfix commit in the main worktree, push it, then continue feature development without ever stashing or losing context. Measure how much time this saves compared to your previous workflow.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro