You’re halfway through building a new API endpoint. The code compiles, the tests are green so far, and Claude Code has full context of what you’re doing. Then Slack lights up: a production bug needs fixing now.
So you stash your changes. Switch branches. Try to remember what the codebase looked like before your feature work. Fix the bug. Switch back. Pop the stash. Re-explain to Claude Code what you were doing.
Sound familiar? There’s a better way.
What are git worktrees?
A git worktree lets you check out multiple branches of the same repository in separate directories — without cloning the repo again. Each directory has its own working tree, its own checked-out branch, and its own files. But they all share the same .git history.
# Create a worktree for a hotfix
git worktree add ../my-project-hotfix fix/payment-timeout
That’s it. You now have two directories:
my-project/— your main working copy, still on your feature branchmy-project-hotfix/— a separate directory, checked out onfix/payment-timeout
No cloning. No downloading. It takes seconds because the files are already local. The new directory is a full working copy — you can build, test, and run it independently.
Why worktrees and Claude Code are a natural fit
Claude Code runs in your terminal, in a specific directory. It reads the files around it, builds context from what it sees, and works within that scope. One directory, one session, one focus.
That maps perfectly to worktrees. Each worktree is a separate directory with a separate branch. Start a Claude Code session in each one, and you have independent AI sessions — each with their own context, their own conversation, their own focus.
No file conflicts. No stash juggling. No re-explaining what you were working on. Each session picks up exactly where it is.
Setting it up for a .NET solution
Let’s say you’re working on an ASP.NET Core solution called OrderSystem. Your main working copy is in ~/projects/OrderSystem/, and you’re on a feature branch.
A hotfix comes in. Here’s what you do:
# From your main project directory
cd ~/projects/OrderSystem
# Create a worktree for the hotfix
git worktree add ../OrderSystem-hotfix fix/order-total-rounding
# Open a new terminal tab and navigate to it
cd ~/projects/OrderSystem-hotfix
The worktree contains your full solution — .sln file, all projects, all configuration. You can immediately run:
dotnet build
dotnet test
Everything works. It’s a complete copy of your repo, just on a different branch.
Now start Claude Code:
claude
Claude Code reads the solution structure, finds the .csproj files, sees the CLAUDE.md — and it’s ready to work. Completely independent from your other session.
Scenario: feature + hotfix in parallel
Here’s how this plays out in practice.
Terminal 1 — your feature work, in ~/projects/OrderSystem/:
You’re building a customer dashboard endpoint. Claude Code has been helping you for the last hour. It knows the controller patterns, the service layer, the DTOs you’ve been creating. You’re mid-conversation:
“Add pagination to the GetOrderHistory endpoint. Use the same PagedResult pattern from the ProductsController.”
Claude Code is working on this. Don’t touch it.
Terminal 2 — the hotfix, in ~/projects/OrderSystem-hotfix/:
You open a fresh Claude Code session:
“There’s a rounding bug in OrderTotalCalculator.cs. When applying a percentage discount, the total sometimes ends up with three decimal places instead of two. Fix it and add a unit test that covers this edge case.”
This session has no idea about your feature work. It doesn’t need to. It focuses purely on the rounding bug, finds the issue, writes the fix, adds the test.
Fifteen minutes later, the hotfix is done. You commit, push, create a PR. Meanwhile, Terminal 1 has finished the pagination work — completely undisturbed.
CLAUDE.md works automatically
If you have a CLAUDE.md file in your repository root — and you should — it travels with every worktree. When Claude Code starts in a worktree directory, it finds and reads CLAUDE.md just like it would in your main copy.
Your project conventions, architecture notes, coding standards — all of it applies automatically. You don’t need to copy files or set anything up. The worktree is a real checkout of your repository, so everything that’s tracked in git is there.
Cleaning up
When you’re done with a worktree, remove it:
# First, make sure you've committed and pushed your changes
cd ~/projects/OrderSystem-hotfix
git push origin fix/order-total-rounding
# Then remove the worktree
cd ~/projects/OrderSystem
git worktree remove ../OrderSystem-hotfix
The directory disappears, the branch stays. Your git history is clean, and you’re back to a single working directory.
If you want to see all active worktrees:
git worktree list
I make it a habit to clean up worktrees as soon as the branch is merged. It keeps your disk tidy and avoids confusion about which directories are still active.
When worktrees are overkill
Let’s be honest — you don’t always need this.
Quick fixes on the same branch. If you just need to edit one file and commit, git stash is fine. Don’t create a worktree for a two-minute change.
Tightly coupled changes. If both tasks need to modify the same files, worktrees won’t help. You’ll end up with merge conflicts anyway. Work on them sequentially instead.
Small repositories. If your project is a single API with five files, the overhead of managing multiple directories adds more complexity than it removes.
Worktrees shine when your solution is large enough that different tasks touch different parts of the codebase. A typical .NET solution with multiple projects — API, services, shared libraries, tests — is exactly where this approach pays off.
Try it yourself
Next time an interruption hits while you’re mid-feature, resist the urge to stash. Instead:
# Create a worktree for the interruption
git worktree add ../my-project-fix fix/the-urgent-thing
# Open a new terminal
cd ../my-project-fix
claude
Give Claude Code a clear, focused instruction. Let it work while your other session stays exactly where you left it.
The first time you switch back to your feature terminal and find everything exactly as you left it — context intact, conversation preserved, files untouched — you’ll wonder why you ever used git stash.