Git Worktree: The Feature That Eliminated My Context-Switching Overhead¶
Why I stopped stashing, stopped branch-juggling, and started working on multiple branches simultaneously.
The Context-Switching Tax¶
I was deep in a complex refactoring on a feature branch — files changed across a dozen modules, a delicate state I'd spent hours building. Then Slack: "Critical bug in production, can you look?" My options were terrible: stash everything (hoping the stash would apply cleanly later), commit half-done work (polluting history), or clone the repo again (waiting for a fresh build). Every option cost me 15-30 minutes of context rebuilding.
Then I discovered git worktree. It changed how I think about branches entirely.
What Is a Worktree?¶
A git worktree is an additional working directory linked to the same repository. Each worktree has its own checked-out branch, its own index, and its own working files — but they share the same .git object database. No duplication of history, no separate clone, no extra fetch.
# Create a new worktree for a hotfix, checked out from main
git worktree add ../project-hotfix main
# Or create a worktree with a new branch
git worktree add ../project-experiment -b experiment/new-cache
Now I have two directories:
- project/ — my feature branch, untouched
- project-hotfix/ — clean main branch, ready for the fix
I switch directories instead of switching branches. My feature work stays exactly as I left it.
My Worktree Layout¶
Over time, I settled on a consistent directory structure:
~/dev/
laas-main/ # Always on main, for quick lookups
laas-feature/ # Current feature work
laas-hotfix/ # Emergency fixes (created on demand)
laas-review/ # Checking out PRs for code review
# My setup script for a new project
git clone git@github.com:org/project.git project-main
cd project-main
git worktree add ../project-feature -b feature/current-work
git worktree add ../project-review main
Daily Workflow With Worktrees¶
Morning: Start feature work
I cd into my feature worktree and pick up where I left off. No stash-pop, no checkout, no waiting. The files are exactly as I left them, IDE state preserved.
Interruption: Production issue
# Create a hotfix worktree from latest main
cd ~/dev/project-main
git pull
git worktree add ../project-hotfix -b hotfix/fix-timeout
# Work on the fix in the hotfix directory
cd ../project-hotfix
# ... fix, test, push ...
# When done, remove the worktree
cd ../project-main
git worktree remove ../project-hotfix
Code review: Check out a PR
cd ~/dev/project-review
git fetch origin pull/123/head:pr-123
git checkout pr-123
# Run tests, inspect code, leave comments
My feature work was never touched. Zero context loss.
Worktrees and Build Systems¶
One subtlety: each worktree has its own working directory, so build artifacts are independent. This is actually a feature — I can have the main branch compiled and running while building a feature branch separately. No artifact contamination.
For projects with expensive builds, I keep a main worktree always built, so I can instantly compare behavior:
# In main worktree: always up-to-date, always built
cd ~/dev/project-main
git pull && make build
# In feature worktree: my current work
cd ~/dev/project-feature
make build && make test
# Quick comparison if something seems wrong
diff <(cd ~/dev/project-main && ./cli --version) \
<(cd ~/dev/project-feature && ./cli --version)
Managing Worktrees¶
Keeping track of worktrees is simple:
# List all worktrees
git worktree list
# /home/user/dev/project-main a1b2c3d [main]
# /home/user/dev/project-feature d4e5f6g [feature/auth]
# /home/user/dev/project-review h7i8j9k [pr-123]
# Remove a worktree (when you're done with it)
git worktree remove ../project-hotfix
# Prune stale worktree references (if directory was deleted manually)
git worktree prune
Important constraint: each branch can only be checked out in one worktree at a time. If main is checked out in project-main/, you can't also check it out in project-review/. This prevents conflicting modifications to the same branch.
Worktrees vs. Multiple Clones¶
Before worktrees, I sometimes used multiple clones. Here's why worktrees are better:
| Aspect | Multiple Clones | Worktrees |
|---|---|---|
| Disk space | Full copy of objects per clone | Shared objects |
| Fetch | Fetch in each clone separately | Fetch once, all worktrees see it |
| Branch sync | Manually pull in each | Shared refs |
| Setup time | Clone + configure each | One command |
| Independence | Complete isolation | Share same .git |
The only case where I still use a separate clone is when I need a different git configuration (different user identity for a fork, for example).
Key Takeaway¶
Worktrees eliminate the false choice between "switch context now" and "lose my current state." They make branch-based workflows truly parallel instead of sequential. Once I started using them, stashing and work-in-progress commits became rare. Each task gets its own directory, its own branch, and my attention — without destroying what came before.
Tags: git, worktree, productivity, context-switching, workflow