Git Worktrees: Work on Multiple Branches Simultaneously
Learn to use git worktrees to check out multiple branches at once without stashing or switching. Covers setup, workflows, and practical use cases.
What you'll learn
- ✓What git worktrees are and why they are useful
- ✓How to create, list, and remove worktrees
- ✓Workflows for code review, hotfixes, and parallel work
- ✓Organizing worktrees on disk
- ✓Common pitfalls and tips
Prerequisites
- •Git basics (branches, checkout, commit)
- •Understanding of the Git working directory
- •Familiarity with branching workflows
You are deep into a feature branch, files are modified, tests are half-written. Then someone asks you to review a pull request on a different branch, or a production bug needs an urgent fix. The usual options: stash everything, switch branches, do the other work, switch back, and pop the stash. Git worktrees eliminate this friction by letting you check out multiple branches in separate directories simultaneously.
What is a worktree?
A worktree is an additional working directory linked to the same repository. Each worktree has its own checked-out branch, its own index (staging area), and its own HEAD. But they all share the same .git data: the same objects, the same refs, the same history.
Think of it as having multiple clones without duplicating the repository data.
Creating a worktree
# Basic syntax
git worktree add <path> <branch>
# Example: check out the 'main' branch in a sibling directory
git worktree add ../main main
# Check out a new branch
git worktree add ../feature/login -b feature/login
# Check out a remote branch
git worktree add ../review/pr-42 origin/fix/memory-leak
After running git worktree add ../main main, you have:
~/projects/
myapp/ # Your original worktree (feature branch)
main/ # New worktree (main branch)
Both directories share the same Git repository data. Changes committed in either directory are immediately visible to the other.
Listing worktrees
git worktree list
Output:
/Users/you/projects/myapp abc1234 [feature/user-auth]
/Users/you/projects/main def5678 [main]
/Users/you/projects/review/pr-42 ghi9012 [fix/memory-leak]
Removing a worktree
# Remove a worktree (the directory must be clean -- no uncommitted changes)
git worktree remove ../main
# Force remove (discards uncommitted changes)
git worktree remove --force ../main
# If you already deleted the directory manually, clean up the reference
git worktree prune
Workflow 1: code review
You are working on a feature. A teammate asks you to review their PR:
# Create a worktree for the PR branch
git fetch origin
git worktree add ../review/pr-42 origin/feature/new-dashboard
# Open it in your editor
code ../review/pr-42
# Review, test, leave comments
cd ../review/pr-42
npm install
npm test
# When done, remove the worktree
cd ../myapp
git worktree remove ../review/pr-42
Your feature branch is completely undisturbed. No stashing, no context switching.
Workflow 2: hotfix
Production is broken. You need to fix it immediately:
# Create a worktree for the hotfix
git worktree add ../hotfix -b hotfix/fix-login main
# Fix the bug in the hotfix worktree
cd ../hotfix
# ... make changes ...
git add .
git commit -m "fix: resolve login redirect loop"
git push origin hotfix/fix-login
# Go back to your feature work
cd ../myapp
# Clean up after the hotfix is merged
git worktree remove ../hotfix
Workflow 3: comparing branches side by side
Open two branches in two editor windows to compare implementations:
git worktree add ../v2-refactor feature/v2-refactor
# Open both directories in your editor
# Compare files side by side
Workflow 4: running tests on a different branch
You want to run the test suite on main while continuing to code on your feature branch:
git worktree add ../test-main main
cd ../test-main
npm test & # Run tests in background
cd ../myapp
# Continue working while tests run
Organizing worktrees
A clean directory structure helps when using multiple worktrees:
~/projects/myapp/
.bare/ # Bare repository (shared Git data)
main/ # Worktree for main
develop/ # Worktree for develop
feature/
user-auth/ # Worktree for feature/user-auth
dashboard/ # Worktree for feature/dashboard
review/
pr-42/ # Temporary worktree for code review
Setting up a bare repository with worktrees
For a worktree-centric workflow, start with a bare clone:
# Clone as bare (no working directory)
git clone --bare git@github.com:user/myapp.git myapp/.bare
cd myapp
# Configure the bare repo to fetch all remote branches
git -C .bare config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git -C .bare fetch origin
# Create worktrees for the branches you need
git -C .bare worktree add ../main main
git -C .bare worktree add ../develop develop
Now you have a clean structure where each branch is a separate directory, all sharing the same Git data in .bare/.
Important rules
One branch per worktree
You cannot have the same branch checked out in two worktrees:
# This fails if 'main' is already checked out somewhere
git worktree add ../another-main main
# fatal: 'main' is already checked out at '/Users/you/projects/main'
This prevents conflicting changes to the same branch. If you need to work on the same branch in two places, create a new branch from it.
Worktrees share refs
All worktrees share the same branches, tags, and remote refs. A commit made in any worktree is immediately visible in all others:
# In worktree A (on main)
git commit -m "update readme"
# In worktree B
git log main # Shows the new commit immediately
Each worktree has its own staged changes
The index (staging area) is per-worktree. Staging a file in one worktree does not affect another.
Worktrees with submodules
If your project uses submodules, each worktree needs its own submodule checkout:
git worktree add ../review/pr-42 origin/feature-x
cd ../review/pr-42
git submodule update --init
Cleaning up
Periodically clean up stale worktree references (e.g., if you deleted a worktree directory manually):
git worktree prune
List and remove worktrees you no longer need:
git worktree list
git worktree remove ../review/pr-42
git worktree remove ../old-feature
Worktrees vs multiple clones
| Aspect | Worktrees | Multiple Clones |
|---|---|---|
| Disk space | Shared Git data | Duplicated Git data |
| Branch sharing | Immediate | Requires fetch/push |
| Setup time | Instant | Full clone time |
| Isolation | Shared refs, separate working dir | Fully independent |
| Submodules | Need separate init per worktree | Independent |
Worktrees are better for temporary parallel work (reviews, hotfixes). Multiple clones are better when you need full isolation (e.g., testing different Git configurations).
Tips
- Name worktree directories after their purpose, not just the branch name.
../hotfix/is clearer than../fix-login-redirect/. - Remove worktrees when done. Leftover worktrees clutter the output of
git worktree listand prevent reusing those branches. - Use
git worktree pruneif you delete a worktree directory manually without usinggit worktree remove. - Worktrees work with any Git hosting: GitHub, GitLab, Bitbucket, self-hosted — they are a local Git feature.
Summary
Git worktrees let you check out multiple branches simultaneously in separate directories, all sharing the same repository data. They eliminate the need for stashing and branch switching when you need to do parallel work. Create a worktree with git worktree add, use it for its purpose (review, hotfix, testing), and remove it with git worktree remove when done. For teams that frequently context-switch between branches, worktrees are a significant productivity improvement.
Related articles
- Git Debugging with Git Bisect
Learn to use git bisect to find the exact commit that introduced a bug. Covers manual bisect, automated bisect with scripts, and practical strategies.
- Git Advanced Git Stash Techniques
Go beyond basic git stash. Learn partial stashing, stash branches, managing multiple stashes, and recovering dropped stashes.
- Git Git Rebase Explained: When to Rebase and When to Merge
A deeper look at git rebase — the mechanics, interactive rebase with squash/fixup/edit/drop, the golden rule of published branches, conflict resolution, and rerere for repeated conflicts.
- Git Git Remotes and Pull Requests Explained
Understand Git remotes, the difference between origin and upstream, fetch vs pull, the forking workflow, and how to open a pull request that is easy to review.