Git Worktrees Changed How I Handle Branches
The worst part of working on multiple branches is the context switching. You are deep in a feature branch, someone asks you to review a hotfix, and now you have to stash your changes, switch branches, wait for your build tools to catch up, do the review, switch back, pop the stash, and hope nothing got lost.
Git worktrees fix this entirely.
What Is a Worktree?
A worktree is a separate working directory that shares the same .git data. Each worktree can have a different branch checked out simultaneously:
# You are on main in /home/user/project
git worktree add ../project-hotfix hotfix/urgent-fix
Now you have two directories:
/home/user/project → main branch
/home/user/project-hotfix → hotfix/urgent-fix branch
Both share the same git history. Commits in one are visible in the other. But they have completely independent working directories.
The Workflow
My typical day looks like this:
# Main work
cd ~/projects/app
# Someone needs a review - create a worktree
git worktree add ~/reviews/pr-142 origin/feature/new-api
# Review in a completely separate directory
cd ~/reviews/pr-142
npm install # only needed first time
npm test
# Done reviewing, remove it
cd ~/projects/app
git worktree remove ~/reviews/pr-142
The key advantage: my main working directory is completely untouched. No stashing, no branch switching, no reinstalling dependencies.
Practical Patterns
Parallel testing
Run tests on two branches at the same time:
git worktree add /tmp/test-main main
git worktree add /tmp/test-feature feature/new-thing
# In two terminals
cd /tmp/test-main && npm test
cd /tmp/test-feature && npm test
Long-running branches
If you maintain a staging branch alongside main:
git worktree add ~/staging staging
Keep it around permanently. Push to staging by working in that directory. No branch switching ever.
CI simulation
Test your CI pipeline locally against a clean checkout:
git worktree add /tmp/ci-test HEAD
cd /tmp/ci-test
npm ci
npm run lint
npm test
npm run build
This catches the classic “works on my machine” issues where you have uncommitted files or stale build artifacts that mask problems.
Managing Worktrees
# List all worktrees
git worktree list
# Output:
# /home/user/project abc1234 [main]
# /home/user/project-hotfix def5678 [hotfix/urgent-fix]
# /tmp/ci-test abc1234 (detached HEAD)
# Remove a worktree
git worktree remove /home/user/project-hotfix
# Clean up stale worktree references
git worktree prune
Gotchas
You cannot check out the same branch in two worktrees. Git prevents this because having the same branch in two places would make it ambiguous which working directory a commit applies to.
If you need to work on the same branch in two places, create a local tracking branch:
git worktree add ../experiment experiment-copy
cd ../experiment
git checkout -b experiment-local origin/experiment
The other thing to watch out for is node_modules. Each worktree needs its own node_modules because paths are different. The first npm install in a new worktree takes time. After that, it is fast because the npm cache is shared.
vs. git stash
Stash is fine for quick interruptions. If someone asks you a question and you need to check something on another branch for thirty seconds, stash works.
But for anything that takes more than a minute, worktrees are better. They do not mess with your working directory, they let you have multiple contexts open in different editor windows, and they do not have the failure mode where you forget to pop the stash and lose track of what you were doing.
I keep a ~/worktrees/ directory for temporary ones and let them accumulate during the week. Friday afternoon I run git worktree list and clean up anything I am done with.