Parallel Branches Without Stashing: `git worktree`
Reviewing a PR while you're mid-feature usually means stash, checkout, review, checkout, stash pop, and hope nothing got left behind. git worktree checks out a second branch into its own folder instead.

You're halfway through a feature — half-written code, nothing committed — when someone asks you to check out their branch to reproduce a bug. The normal path is git stash, git checkout their-branch, poke around, git checkout back, git stash pop, and hope the stash pop doesn't collide with anything. It usually works. Occasionally it doesn't, and now you're untangling a merge conflict in your own half-finished work.
git worktree skips all of it. It checks out a second branch into its own directory, backed by the same .git folder, so both branches exist on disk at once. No stashing, no switching.
One repository, two folders
Start with a normal repo on main:
git branch
# * mainAdd a worktree for another branch — say a release branch you need to poke at without leaving main:
git worktree add ../myapp-release-3.2 release-3.2Preparing worktree (checking out 'release-3.2')
HEAD is now at e9eccbb initial commitgit worktree list now shows both:
/path/to/myapp e9eccbb [main]
/path/to/myapp-release-3.2 e9eccbb [release-3.2]../myapp-release-3.2 is a full working directory — same tracked files, same .git history, its own HEAD. Editing one doesn't touch the other:
# in myapp/
echo "main-work" >> app.txt
# in myapp-release-3.2/
echo "release-work" >> app.txtgit -C myapp status --short
# M app.txt
git -C myapp-release-3.2 status --short
# M app.txtTwo separate uncommitted changes, two separate directories, one repository underneath. Open both in two terminal tabs — or two editor windows — and work on them like they're unrelated checkouts.
Same commit, same repo, but git tracks a separate HEAD and index for each worktree — so status, staging, and checkouts in one don't leak into the other.
A main checkout and a linked worktree aren't quite symmetric, though. The directory you originally cloned into is the main worktree; everything added with git worktree add is a linked worktree, and a linked one shows up as a .git file rather than a .git folder — a single line pointing back at the real .git directory, plus a per-worktree admin area under .git/worktrees/. You'll never need to touch either by hand, but it explains why removing a worktree's directory without telling git first leaves debris behind.
Why this beats stashing
Stashing is fine for a five-minute interruption. It falls apart in a few specific ways worktrees don't:
- Long builds. If your build takes two minutes and you need to switch branches to check something, a worktree lets the first branch's build keep running in its own directory while you work in the second.
- Dependencies that differ per branch. Switching a normal checkout between branches with different lockfiles usually means reinstalling. Separate worktrees can each keep their own
node_modulesorvendordirectory, installed once, never touched by the other branch. - Reviewing a PR mid-feature. You get a second, disposable directory to build and run someone else's branch in, without your in-progress changes ever leaving your primary checkout.
- CI matrix jobs on one checkout. A pipeline that needs to build two versions of the same commit range side by side — say, comparing a benchmark before and after a change — can set up both as worktrees instead of paying for two full clones.
Cleaning up
A worktree you're done with comes off with one command, run from any of the linked worktrees:
git worktree remove ../myapp-release-3.2If it has uncommitted changes git refuses, same as a normal checkout would — add --force if you're sure you want to discard them. Deleting the directory by hand also works, but leaves a stale entry behind; git worktree prune clears those out.
One rule to keep in mind: a branch can only be checked out in one worktree at a time. Git will stop you from adding a second worktree for a branch that's already checked out somewhere else — including your primary directory. That's a feature, not a bug: it's the same guarantee that stops you from having two conflicting versions of the same branch on disk without git noticing.
Next time you catch yourself reaching for git stash just to peek at another branch, reach for git worktree add instead. Your half-finished feature stays exactly where you left it.