- Dec 26, 2025
Git Worktrees Explained: Work on Multiple Branches Simultaneously
- Teddy Kim
- 0 comments
Every developer knows the pain of context switching. You're deep in a feature branch, someone asks you to review a hotfix, and suddenly you're stashing changes, switching branches, and trying to remember where you left off twenty minutes later.
Git worktrees solve this. They let you have multiple branches checked out simultaneously, each in its own directory. No stashing. No switching. You literally cd to a different folder and you're on a different branch.
I started using worktrees for the Referee Pattern, where I run three AI agents in parallel, each implementing the same spec with different optimization goals. Worktrees are the only sane way to do this. But once I understood them, I started using them everywhere.
What Worktrees Actually Are
A git repository has a .git folder that stores everything: history, branches, objects, the whole kitchen sink. When you clone a repo, you get one working tree (the actual files) pointing to one branch at a time.
Worktrees let you create additional working directories that share the same .git folder. Each worktree has its own set of files, its own branch, and its own state. But they're all part of the same repository.
# Your normal repo structure
my-project/
├── .git/ # The actual repository
├── src/
├── package.json
└── README.md
# With worktrees, you get sibling directories
my-project/ # Main worktree (usually main branch)
my-project-feature-a/ # Worktree on feature-a branch
my-project-feature-b/ # Worktree on feature-b branchThe key insight: these are not separate clones. They share history. If you commit in one worktree, the commit exists in all of them. If you push from one, the others see it. They're views into the same repository.
Worktrees vs. Branches
Branches are pointers. A branch points to a specific commit, and you can only have one branch checked out in a working directory at a time.
Worktrees are directories. Each directory can have its own branch checked out. This means you can have three terminals open, each in a different worktree, each on a different branch, all at the same time.
Why does this matter? Because switching branches has costs:
Stashing. If you have uncommitted changes, you need to stash them before switching. Stash conflicts are annoying. Forgetting to stash is worse.
Rebuilding. Many build systems cache based on file modification times. Switching branches changes files, which invalidates caches. Ever waited five minutes for TypeScript to recompile because you switched branches?
Mental overhead. When you switch branches, you lose your place. The file you had open might not exist on the new branch. The terminal history suddenly references a different context.
Worktrees eliminate all of this. Each worktree maintains its own state. Your IDE stays open with the right files. Your terminal history makes sense. Your build cache is intact.
The Referee Pattern Use Case
The Referee Pattern runs three AI agents in parallel, each optimizing for a different quality attribute: maintainability, performance, and robustness. Each agent needs its own isolated environment to work in.
Without worktrees, you'd have two bad options:
Option 1: Sequential execution. Run one agent, commit its work, switch branches, run the next agent, repeat. This serializes what should be parallel work, and you can't compare implementations side-by-side until they're all done.
Option 2: Multiple clones. Clone the repo three times. Now you have three copies of .git, three copies of node_modules, and no shared history. When you want to merge, you're pulling between repositories instead of branches.
Worktrees give you a third option: parallel branches in separate directories, all sharing the same repository.
# Create three worktrees for parallel agent work
git worktree add -b maintainability-impl ../my-project-maintainability
git worktree add -b performance-impl ../my-project-performance
git worktree add -b robustness-impl ../my-project-robustnessNow you have three directories:
my-project/ # Main branch
my-project-maintainability/ # Maintainability agent's workspace
my-project-performance/ # Performance agent's workspace
my-project-robustness/ # Robustness agent's workspaceEach agent works in isolation. No conflicts. No context switching. When they're done, you can open all three in separate IDE windows and compare implementations line by line.
Common Worktree Commands
Here's the practical stuff.
Creating a Worktree
# Create a worktree with a new branch
git worktree add -b my-branch ../my-project-feature
# Create a worktree with an existing branch
git worktree add ../my-project-feature existing-branch
# Create a worktree in detached HEAD state (for exploring commits)
git worktree add ../my-project-experiment abc123The path can be anywhere on your filesystem. I usually put worktrees next to the main repo as sibling directories, but you can organize however you like.
Listing Worktrees
git worktree listOutput looks like:
/Users/me/projects/my-project abc1234 [main]
/Users/me/projects/my-project-maintainability def5678 [maintainability-impl]
/Users/me/projects/my-project-performance ghi9012 [performance-impl]Removing a Worktree
When you're done with a worktree:
# Remove the worktree (from the main repo directory)
git worktree remove ../my-project-feature
# If there are uncommitted changes, force removal
git worktree remove --force ../my-project-featureYou can also just delete the directory and then run:
git worktree pruneThis cleans up the worktree references for directories that no longer exist.
Moving a Worktree
git worktree move ../my-project-feature ../new-locationLocking a Worktree
If a worktree is on a network drive or removable media and might disappear temporarily:
git worktree lock ../my-project-feature
git worktree unlock ../my-project-featureLocking prevents git from pruning the worktree reference.
Troubleshooting
"fatal: 'branch-name' is already checked out"
You can't have the same branch checked out in multiple worktrees. This is by design—it prevents you from making conflicting changes to the same branch in different places.
Solutions:
- Check out a different branch in one of the worktrees
- Create a new branch for the worktree
"fatal: is a missing linked working tree"
This happens when you delete a worktree directory without telling git. Run:
git worktree pruneWorktree shows wrong branch
Make sure you're actually in the worktree directory. It's easy to accidentally be in the main repo. Check with:
pwd
git branchIDE doesn't recognize the worktree
Most IDEs handle worktrees fine, but some get confused. The worktree directory doesn't have a .git folder—it has a .git file that points to the main repository's .git folder.
cat .git
# Output: gitdir: /path/to/main/repo/.git/worktrees/my-worktreeIf your IDE doesn't recognize this, try opening the folder as a new workspace rather than adding it to an existing workspace.
Dependencies aren't installed
Each worktree has its own node_modules (or equivalent). If you create a worktree, you need to run npm install in that directory. The dependencies are not shared.
This is actually a feature for some workflows—you can test different dependency versions in different worktrees—but it does mean more disk space.
When Worktrees Shine
Worktrees are overkill for simple branch switches. If you're checking a hotfix that takes five minutes, just switch branches.
But worktrees excel when:
You need parallel isolated environments. The Referee Pattern. Long-running experiments. Comparing approaches.
Context switching is expensive. If your build takes forever, or your IDE takes forever, worktrees pay for themselves quickly.
You're juggling multiple reviews. Have three PRs to review? Create three worktrees, run each, and compare without rebuilding between them.
You're debugging across versions. Bisecting a bug often requires jumping between commits. A worktree on each end of the bisect lets you compare behavior side-by-side.
The mental model shift is this: instead of thinking about branches as things you switch between, think about them as things you can look at simultaneously. Once that clicks, worktrees feel less like an advanced feature and more like something that should have been obvious all along.
---
If you want to go deeper on AI development patterns like the Referee Pattern and how to structure your workflow around them, I put together a free study guide covering the fundamentals. Grab the AI Study Guide here.