Picture this: you’re deep in a half-baked feature branch — files open everywhere, mental context fully loaded — and you got an alert about production being down, need a patch immediately. You have two choices. You either stash your entire working state, switch branches, fix the bug, switch back, pop the stash, and pray nothing breaks. Or… you use Git Worktree and just walk over to a different folder like it’s nothing.
Or what about working with the ai coding agents themselves? Wish you could run multiple coding agents on the same project repo, working in parallel on independent features/issues? Git Worktree to rescue here as well.
I spent years doing the stash-switch dance before I discovered Git Worktree. Once I started using it, I genuinely don’t know how I worked without it.
What is Git Worktree?
Git Worktree lets you check out multiple branches of the same repository into separate directories on your filesystem — simultaneously — without cloning the repo again.
It ships built into Git (no plugins needed) and works by linking additional “working trees” to a single .git directory. Each worktree has its own working directory and index, but shares the full commit history and objects.
Why Git Worktree Matters
Most developers think the only way to work on two branches at once is to clone the repo twice. That works, but it’s wasteful — you duplicate the entire object store. Git Worktree solves this cleanly. Here’s where it actually earns its keep:
1. Hotfixes while keeping your feature context intact No stashing. No context switching. Your feature branch stays exactly where you left it in ~/projects/my-app. You pop open ~/projects/my-app-hotfix, apply the patch, push, and walk away.
2. Running two versions of the app side-by-side Comparing how main renders vs. a UI overhaul branch? Spin up both worktrees, run npm start in each directory on different ports, and compare live.
3. Long-running background processes If a branch runs a test suite that takes 20 minutes, you don’t have to wait. Switch to another worktree and keep coding. 🚀
Reflective question: How many hours have you lost this year to stash-switch-unstash cycles? That’s Git Worktree’s entire value proposition.
Step-by-Step Tutorial
Prerequisites
- Git 2.5+ (check with
git --version; worktrees landed in Git 2.5, released July 2015) - An existing local repository
Step 1 — Understand Your Repo’s Starting Structure
Before adding a worktree, let’s see what a normal repo looks like on disk:
my-app/
├── .git/ ← the one true Git database
│ ├── HEAD
│ ├── objects/
│ └── worktrees/ ← Git will manage linked worktrees here
├── src/
└── package.jsonCode language: JavaScript (javascript)
When you add a worktree, Git creates a sibling directory (or wherever you specify) that acts as a fully functional working copy — but shares .git/objects with the original. No duplication.
Step 2 — Add a New Worktree
The core command is git worktree add. The simplest form:
# Syntax: git worktree add <path> <branch>
git worktree add ../my-app-hotfix hotfix/login-crashBashWhat just happened?
~/projects/
├── my-app/ ← your original worktree (feature branch active)
│ └── .git/
│ └── worktrees/
│ └── my-app-hotfix/ ← Git's internal tracking files
└── my-app-hotfix/ ← NEW linked worktree (hotfix branch active)
├── src/
└── package.json
../my-app-hotfix— path where the new working directory landshotfix/login-crash— the branch to check out there
Pro Tip: If the branch doesn’t exist yet, add
-bto create it in one shot:Bashgit worktree add -b hotfix/login-crash ../my-app-hotfix mainThis creates
hotfix/login-crashbranching offmainand immediately checks it out in the new directory.
Step 3 — Verify Your Worktrees
git worktree listBashExpected output:
/home/user/projects/my-app abc1234 [feature/dashboard]
/home/user/projects/my-app-hotfix def5678 [hotfix/login-crash]BashEach line shows: path, HEAD commit, and active branch. Clean and auditable.
Step 4 — Work in the New Worktree
Just cd into it. It’s a normal directory:
cd ../my-app-hotfix
# Make your fix
vim src/auth/login.js
# Stage and commit exactly as you would anywhere else
git add src/auth/login.js
git commit -m "fix: resolve null user crash on login"
git push origin hotfix/login-crashBashNo ceremony. No stash. Your original my-app/ directory is completely untouched and still on your feature branch.
Step 5 — Remove the Worktree When You’re Done
Once you’ve merged the hotfix, clean up:
# From the original repo directory (NOT from inside the worktree)
cd ~/projects/my-app
git worktree remove ../my-app-hotfixBashOr, if the worktree has uncommitted changes Git won’t let you remove it without --force:
git worktree remove --force ../my-app-hotfixBashAfter removal, Git cleans up .git/worktrees/my-app-hotfix automatically. Verify:
git worktree list
# Should now show only the main worktreeBashFull Workflow in One Go (Reference Cheatsheet)
# 1. Add worktree for hotfix, branching off main
git worktree add -b hotfix/login-crash ../my-app-hotfix main
# 2. Go fix the bug
cd ../my-app-hotfix
git commit -am "fix: null crash on login"
git push origin hotfix/login-crash
# 3. Return and clean up
cd ~/projects/my-app
git worktree remove ../my-app-hotfix
# 4. Verify state
git worktree listBashTroubleshooting & Gotchas
❌ Error: “fatal: branch already checked out”
fatal: 'feature/dashboard' is already checked out at '/home/user/projects/my-app'BashWhy it happens: Git prevents the same branch from being live in two worktrees at once. This avoids index conflicts.
Fix: Use a different branch (or create a new one with -b) for each worktree. If you need the same base, create a new branch from it:
git worktree add -b feature/dashboard-review ../my-app-review feature/dashboardBash❌ Stale Worktree Entries After Manual Deletion
If you deleted the worktree directory with rm -rf instead of git worktree remove, Git’s tracking files become orphaned. git worktree list will show a path that no longer exists.
Fix:
git worktree pruneBashThis scans .git/worktrees/ and removes references to directories that no longer exist. Run it after any manual cleanup.
❌ IDE Opens the Wrong Root
Some IDEs (VS Code, IntelliJ) don’t automatically understand that a linked worktree belongs to the same project. You open my-app-hotfix/ and it starts a fresh workspace with no extensions configured.
Fix: Open it as a folder (not a workspace) in VS Code — extensions tied to the repo root still apply. Alternatively, use the VS Code multi-root workspace feature to add both directories under one window.
Reflective question: Have you ever accidentally committed to the wrong branch because you lost track of which terminal was in which directory? Worktrees don’t fix human error, but keeping distinct directory names (
my-app-hotfixvsmy-app) helps a lot.
Limitations / Caveats
Git Worktree is powerful, but it’s not always the right tool:
1. Submodule complexity If your repo uses Git submodules, worktrees and submodules interact awkwardly. Each worktree needs its own submodule initialization. Expect friction.
2. Some Git GUIs don’t support it well Tools like GitKraken and Sourcetree have limited or no worktree UI. You’ll fall back to the CLI for worktree management, which isn’t a dealbreaker, but worth knowing before you evangelize this to teammates who live in GUIs.
3. Not a replacement for proper Git hygiene Worktrees make context switching easier, but they don’t replace good branching strategy. If you’re relying on worktrees to avoid dealing with a chaotic branch structure, fix the structure.
4. Disk space isn’t free The object store is shared, but each worktree has its own copy of your working files. For repos with large build artifacts or node_modules, those accumulate fast. Add worktree paths to a top-level .gitignore if they live inside the repo root (rare, but possible).
Pro Tip: Keep a naming convention for worktree directories — I use
<repo-name>-<branch-purpose>(e.g.,my-app-hotfix,my-app-review). It makesls ~/projectsimmediately readable.
Next Steps
Once you’re comfortable with the basics, here’s where to go next:
- Official Git Worktree docs — The
--lockflag lets you protect a worktree from being pruned (useful for worktrees on external drives). - Bare repository + worktrees pattern — Some developers (especially those following the ThePrimeagen workflow) clone repos as bare (
git clone --bare) and use worktrees exclusively, never having a “main” working directory. Extreme, but elegant. - Combine with
git bisect— Run a bisect in one worktree while staying productive in another. Time saver. - CI/CD parallel testing — Provision multiple worktrees in a pipeline to test different branches against the same environment simultaneously.
Conclusion
Git Worktree is one of those features that’s been sitting in Git for nearly a decade, quietly waiting for developers to notice it. Once you internalize the mental model — one repo, many working directories — it changes how you structure your entire development day.
Stop stashing or cloning repos twice. Stop losing your mental context every time production breaks. Add a worktree, fix the bug, delete the worktree. That’s it.
Try it on your next real hotfix and see if you ever go back. I’d bet you won’t.
Found this useful? Share it with a teammate who’s still doing the stash-switch dance. They’ll thank you. 🙌
Sources & Further Reading:
- git-worktree — Official Git Documentation
- Atlassian Git WorkTree Tutorial
- VS Code Multi-root Workspaces
Discover more from CodeSamplez.com
Subscribe to get the latest posts sent to your email.

Leave a Reply