
How I use Git worktrees to work on 4 things at once without losing my mind
I had a production hotfix, two feature branches, and a code review all due by end of day. Stashing was not going to cut it.
The Problem With Branches
Every developer knows the dance. You are deep in a feature branch, files changed everywhere, tests half-written, when Slack lights up: "Production is down, we need a hotfix NOW." So you stash your changes, switch branches, pray nothing conflicts, fix the bug, push, switch back, pop the stash, and spend ten minutes figuring out where you were.
Now multiply that by four parallel streams of work. That was my Tuesday.
I was working on a large Laravel application with a team of five. My plate that day: a feature for invoice generation, a refactor of the notification system, a code review for a colleague's PR, and the inevitable production hotfix. Traditional branch switching would have destroyed my flow state four times over.
Then I discovered Git worktrees, and everything changed.
What Worktrees Actually Are
A Git worktree is a separate working directory linked to the same repository. Same .git folder, same history, same remotes - but a completely independent checkout. You can have branch A open in one directory and branch B in another, simultaneously, with no stashing, no switching, no context loss.
The command is deceptively simple:
git worktree add ../hotfix-payment main
git worktree add ../feature-invoices feature/invoices
git worktree add ../review-pr-47 origin/pr/47
Three commands, three directories, three branches, zero conflicts. Each one is a full working copy with its own node_modules, its own running dev server, its own terminal tab.
The Setup That Changed My Workflow
Here is how I organize a typical workday with worktrees:
Main checkout: ~/projects/app - always on the main branch. I never develop here. This is my reference copy, my "what does production look like right now" directory.
Feature work: ~/projects/app-feature-invoices - my current feature branch. IDE open here, tests running, dev server on port 3000.
Hotfix: ~/projects/app-hotfix - created on demand when something breaks. Dev server on port 3001. I can fix, test, and push without touching my feature work.
Review: ~/projects/app-review - colleague's PR checked out. I can run their code, test it, compare it side by side with main. Dev server on port 3002.
Four directories. Four contexts. Zero mental overhead switching between them. I just click a different terminal tab.
The Hotfix That Proved the Point
The production issue was a payment processing bug. A race condition in the webhook handler was causing duplicate charges for about 2% of customers. Not catastrophic, but every minute it stayed live was money - literally.
In the old workflow, I would have stashed my invoice feature changes (47 modified files), switched to main, created a hotfix branch, fixed the bug, tested it, pushed it, switched back, and unstashed. Minimum 15 minutes of context switching, plus the cognitive overhead of remembering where I was.
With worktrees, I opened a new terminal tab, ran git worktree add ../app-hotfix main, had a clean checkout in seconds, fixed the race condition, pushed, and switched back to my invoice tab. My feature code was exactly where I left it. My dev server was still running. My test output was still on screen. Total context switch time: about 30 seconds.
Where It Gets Really Powerful
Worktrees are useful for any developer, but they become transformative when you combine them with AI coding agents. This is where my workflow gets interesting.
I run multiple AI agents in parallel, each in its own worktree. Agent one works on the invoice feature. Agent two refactors the notification system. Agent three runs the test suite against a proposed change. They never interfere with each other because they are in completely isolated directories with their own file state.
My dev orchestrator - a tool I built specifically for this workflow - manages port allocation, Docker services, and environment variables per worktree. Each one gets its own database, its own Redis instance, its own set of ports. True isolation without the overhead of separate repositories.
The orchestrator also handles the lifecycle: create worktree, install dependencies, start services, run agent, collect results, clean up. What used to be a manual juggling act is now a single command.
The Gotchas
Worktrees are not without pain points. Here are the ones that bit me:
Dependencies. Each worktree needs its own node_modules (or vendor directory, for PHP). That means running npm install or composer install in each one. Disk space adds up. I mitigate this with symlinks for heavy directories that rarely change, but it is not perfect.
Ports. If two worktrees try to start a dev server on the same port, one fails silently or crashes. You need a port allocation strategy. I use a simple convention: main gets 3000, feature gets 3001, hotfix gets 3002, review gets 3003.
IDE confusion. Some IDEs get confused when the same repository has multiple working directories. VS Code handles it well with multi-root workspaces. PhpStorm needs a separate project for each worktree. Neovim does not care at all - it just opens whatever directory you point it at.
Branch locks. You cannot have the same branch checked out in two worktrees simultaneously. Git prevents this to avoid conflicts. If you need to work on the same branch from two angles, you need to create a temporary branch.
My Daily Routine Now
Morning: I check what is on my plate. If it is more than one stream of work - and it usually is - I set up worktrees for each. Takes about two minutes.
During the day: I switch between tasks by switching terminal tabs. No stashing, no branch switching, no rebuilding. Each context is exactly where I left it.
End of day: I clean up finished worktrees with git worktree remove. The branches stay; only the working directories disappear.
The result: I estimate I save 30-45 minutes per day on context switching alone. Over a week, that is nearly four hours. Over a month, almost two full working days. And that does not account for the cognitive benefit of never losing your place.
When Not to Use Worktrees
If you work on one thing at a time, you do not need worktrees. If your project is small enough that switching branches takes seconds and you have no state to lose, stick with the simple workflow.
Worktrees shine when you have multiple parallel streams, when context switching is expensive (large projects with slow builds or heavy dependencies), or when you are orchestrating multiple agents or processes that need isolated environments.
The Commands You Need
# Create a worktree
git worktree add ../my-feature feature/my-branch
# Create from a new branch off main
git worktree add -b hotfix/payment ../hotfix main
# List all worktrees
git worktree list
# Remove a worktree (after merging)
git worktree remove ../my-feature
# Prune stale worktree references
git worktree prune
Five commands. That is the entire API. Simple enough to memorize in an afternoon, powerful enough to change how you work.
The best productivity tool is not a faster computer or a better IDE. It is eliminating the transitions between tasks. Worktrees do not make you code faster - they make you lose less time between coding sessions.
