SeriesPart 2 of 8 // Git Quick Hits
gitWriting
Aug 17, 2026
3 min read
git-quick-hits

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.

Two identical open doorways leading off the same hallway, each showing a different room, representing two working directories from one repository.

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
# * main

Add 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.2
Preparing worktree (checking out 'release-3.2')
HEAD is now at e9eccbb initial commit

git 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.txt
git -C myapp status --short
#  M app.txt
git -C myapp-release-3.2 status --short
#  M app.txt

Two 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_modules or vendor directory, 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.2

If 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.

Series contents

01
Automating Regression Hunts with `git bisect run`
Read
02
Parallel Branches Without Stashing: `git worktree`
Current
03
The Undo Button Nobody Uses: `git reflog`
Coming soon // Aug 24, 2026
04
`git rerere`: Stop Resolving the Same Conflict Twice
Coming soon // Aug 31, 2026
05
`.gitignore` vs `.git/info/exclude` vs Global Excludes
Coming soon // Sep 7, 2026
06
Shipping a Repo as One File with `git bundle`
Coming soon // Sep 14, 2026
07
Attaching Build Metadata with `git notes`
Coming soon // Sep 21, 2026
08
Why Shallow Clones Break Your Changelog
Coming soon // Sep 28, 2026