Skip to content

Git worktrees for parallel branch work

How and when to use git worktree to keep multiple branches checked out at once, sharing one object store, without the disk cost or coordination headaches of multiple clones.

Updated May 26, 2026

A clone gets expensive once you need three branches open at the same time. git worktree is the underused alternative: one repository, many working directories, one object store. Reach for it the moment you find yourself either stashing work to switch branches or running git clone against the same remote a second time.

Concept

Git worktree

A linked working directory attached to an existing repository — shares objects and most refs, owns its own HEAD and index.

The repository created by git clone or git init is the main worktree. Every additional directory created by git worktree add is a linked worktree. Linked worktrees share the object database and refs/* with the main, but each has its own HEAD, index, and pseudorefs. The headline rule that falls out of that design: one branch cannot be checked out in two worktrees at the same time — Git refuses by default.

What is shared, what is per-worktree

The shared object store is why a worktree is cheap. Disk usage is roughly “the checked-out files plus a tiny .git gitfile that points back to the main.” A second git clone would re-download every object the main already has.

When a worktree pays for itself

  1. Interrupt-driven hotfix without stashing

    A teammate pages you with a P1 while you have a half-finished refactor staged. git worktree add -b hotfix-123 ../hotfix-123 origin/main gives you a clean branch off main in a sibling directory. Your refactor stays exactly as you left it.

  2. Parallel feature branches

    Three branches you actually need to switch between today (auth, billing, perf profiling) become three worktrees side by side. No stash juggling, no “did I commit before checking out?” anxiety.

  3. Long-running build or test in isolation

    git worktree add --detach ../test-run HEAD gives you a throwaway checkout to run a 20-minute integration suite while you keep coding in the main worktree.

  4. Reproducing a bug on a clean checkout

    Spinning up a worktree at a tag (git worktree add ../repro v1.4.2) is faster than git stash, git checkout, then untangling everything later.

The commands you actually use

Add a worktree
# New branch off current HEAD, in a sibling directory
git worktree add ../feature-x

# Existing branch
git worktree add ../release release

# New branch from an explicit start point
git worktree add -b hotfix-login ../hotfix origin/main

# Detached HEAD, for throwaway builds/tests
git worktree add --detach ../test-run HEAD
Inspect and clean up
git worktree list -v           # what exists, where, and on what HEAD
git worktree remove ../feature-x   # safe: refuses if dirty
git worktree prune -v          # drop stale admin records after manual deletes
git worktree repair            # fix links after manual moves/copies

If <commit-ish> is omitted, Git names the branch after basename(<path>). The shorthand - resolves to @{-1} (the previously checked-out ref) — handy when scripting.

Worktree vs second clone

Axis Worktree Second clone
Disk Shares object store; only the checked-out files cost space. Full duplicate — every object, every ref, every pack.
Creation time Near-instant; no network fetch. Full clone — re-downloads everything from the remote.
Branch safety Built-in: refuses duplicate checkout by default. No coordination — easy to make divergent commits on the same branch in two places.
Fetch propagation Fetch once; every worktree sees the new refs. Each clone fetches independently.
Mental cost Requires knowing what's shared vs per-worktree. Familiar — it's just another repo.

Sharp edges

Conventions worth adopting

  • Pick a naming scheme and stick to it: ../wt-<branch> keeps siblings sortable and obvious in shell completion.
  • Treat git worktree list -v as the source of truth — never poke at .git/worktrees/ files directly.
  • Lock worktrees on removable drives with a reason: git worktree lock --reason "external disk" ../portable. Otherwise Git’s auto-prune will quietly drop the admin record after the configured expiry.
  • For scripting, prefer the porcelain output: git worktree list --porcelain -z.

Recovery playbook

SymptomAction
worktree list shows a prunable entrygit worktree prune -v
Linked worktree was moved or copied manuallygit worktree repair from the main worktree
“branch already checked out elsewhere”git worktree list to find the holder; remove or switch
Config differs by worktree unexpectedlyInspect via git rev-parse --git-path config.worktree

When in doubt, git rev-parse --git-path <name> is the safe way to resolve any path Git uses — it picks the per-worktree or shared file as appropriate without you having to know which.

The official git-worktree(1) man page is the authoritative reference and worth reading in full once you start relying on this command.

Related