Git Worktrees: Working on Multiple Branches Without the Headache
Learn how Git worktrees let you check out multiple branches simultaneously, keeping your context intact while handling production emergencies, code reviews, and parallel feature development.
I was neck-deep in refactoring our authentication system when Slack started going crazy. A bunch of notifications start popping off. Production was down.
A payment bug was blocking invoices from processing, and every minute meant lost revenue (not really, just a few annoyed customers). My working directory looked like a bomb went off with half-written code across a dozen files, experimental changes I wasn't ready to commit, a bunch of migrations and that one function where I'd been testing something risky or over engineering a simple feature.
Before I discovered worktrees, this scenario meant a frantic scramble with git stash, hoping nothing would conflict when I popped it later. Now? I just open a new terminal tab and fix the problem while my feature work sits untouched.
Understanding Git Worktrees
Git worktrees let you check out multiple branches of the same repository into different folders. Instead of constantly switching branches in one directory, you maintain several directories, each on its own branch, all sharing the same Git data.
/projects/myapp # Feature branch work
/projects/myapp-hotfix # Emergency fixes
/projects/myapp-review # Code review
Each directory has its own working files, staged changes, and local state, but they all point to the same .git repository.
Why Worktrees Matter
Traditional Git workflows force you to abandon your current context whenever you need to switch branches. You stash changes, switch branches, do the work, switch back, pop the stash, and hope for the best. It's disruptive and error-prone.
With worktrees, you keep everything exactly where it is. Your uncommitted changes, your running dev server, your mental context, all stay intact while you handle other tasks in a separate directory.
Here's a real example from last week:
# From my feature directory
git worktree add ../myapp-hotfix main
cd ../myapp-hotfix
git checkout -b hotfix/payment-validation
# Fixed the bug, tested it properly
git commit -m "Fix payment validation edge case"
git push origin hotfix/payment-validation
# Back to feature work, nothing to restore
cd ../myapp No having to compile assets or rebuild the project entirely and then losing your previous context. You can just switch back to your previous work without this annoying step.
Practical Use Cases
Production Emergencies
When bugs hit production, create a worktree from main and fix it there. Your feature branch stays exactly as you left it, uncommitted changes and all.
Code Reviews
Stop contaminating your working directory with other people's code. Check out pull requests in a dedicated worktree, run their tests, start their dev server, all without touching your current work.
git worktree add ../myapp-review
cd ../myapp-review
git fetch origin pull/234/head:pr-234
git checkout pr-234
npm install && npm test Experiments
Want to try a radically different approach? Create a worktree from your current branch and go wild. If it doesn't work out, just delete the directory.
Parallel Features
Working on features that need different configurations or long-running processes? Keep them in separate worktrees with their own dependencies and servers.
Setting Up Worktrees
The commands are simple:
# Add a worktree
git worktree add <path> <branch>
# See what you have
git worktree list
# Remove when done
git worktree remove <path>
# Clean up references
git worktree prune I organize mine like this:
myproject/
├── main/ # Primary working directory
├── feature/ # Current feature work
├── hotfix/ # Emergency fixes
└── review/ # PR reviews Things to Consider
Disk Space
Each worktree is a full working directory. Projects with massive dependencies will eat disk space quickly. Monitor usage if you create many worktrees.
Branch Limitations
You can't check out the same branch in multiple worktrees. Git prevents this to avoid conflicts. Plan accordingly.
Shared State
All worktrees share the same repository data. Branches, remotes, tags, and stashes are visible everywhere. Keep this in mind when managing your repository.
Tool Compatibility
Modern development tools handle multiple directories well. VS Code workspaces work great with worktrees. Some older tools might need tweaking. I've found GitKraken (and Gitlens) a useful paid tool for handling worktrees.
Ignored Files
You'll need to create a method for handling your ignored files as these will be reset for each worktree. A good strategy for this is to create a script to symlink these files to your worktree when required. When I am working on a project with a .env file, I'll often set this up in the core folder, and have a script that does something like:
ln -s ../<base>/.env .env When to Skip Worktrees
Quick fixes like typos don't need worktrees. Regular branch switching works fine for small changes. Worktrees excel when you need to preserve state or work on multiple things simultaneously.
Projects with unusual build systems or hardcoded paths might struggle with worktrees. Test first before committing to this workflow.
Daily Workflow Example
My typical day with worktrees looks like this:
Morning standup reveals an urgent bug. Instead of postponing it until after my feature work, I create a hotfix worktree and address it immediately.
Colleague needs a PR review. I pull it into my review worktree, run it locally, test thoroughly, and provide feedback while my feature tests continue running.
I want to compare two implementation approaches. Temporary worktree, alternative implementation, benchmark both solutions side by side.
End of day cleanup: remove temporary worktrees, run git worktree prune to clean up any dangling references.
Getting Started
Try worktrees on your next multitasking challenge:
git worktree add ../project-fix main
cd ../project-fix
# Handle the urgent task
cd -
git worktree remove ../project-fix Start small. Get comfortable with the basics before developing complex workflows.
Wrapping Up
Git worktrees solve a specific problem elegantly: managing multiple branches without losing context. They reduce the mental overhead of task switching and make handling interruptions less painful.
The best part? There's no need for complex third party tooling or setup. It's all a part of git. If worktrees don't fit your workflow, you simply don't use them. But if you regularly juggle multiple branches, they're worth exploring.
One last tip: git worktree prune is your friend. Run it occasionally to clean up references to deleted worktree directories. Git doesn't do this automatically.