You are mid-change, nothing compiles, and someone drops a pull request that needs eyes now. The reflex is git stash, a branch switch, and a prayer that you remember what you were doing. There is a better mechanic built into Git, and most teams never turn it on.
A stash is a bet that you will come back to the same mental state within the hour. In practice you don’t. The review takes longer than expected, the stash stack grows, and half-finished work sits in a place that is invisible in your editor and easy to clobber. git worktree removes the bet entirely: it lets one repository check out several branches at once, each in its own directory, sharing a single object store. No stashing, no re-cloning, no context lost. This is a working recipe for using it around code review, plus the two places it will bite you.
What a worktree actually is
A normal clone has one working directory bound to one branch. A worktree is an additional working directory attached to the same repository. The primary clone keeps its full .git directory; each linked worktree gets a lightweight .git file that points back into .git/worktrees/<name> in the main repo. Crucially, all of them share one object database. Your commits, blobs, tags and fetched refs live once on disk and are visible from every worktree the moment they land.
Free · 4 minutes
Is your engineering team shipping safely, or quietly accumulating risk?
Fourteen questions on how work gets from idea to production — cadence, testing, rollback, and the key-person risk in your delivery. Banded finding on screen, full sheet by email.
That shared store is the whole point. A second clone re-downloads history, duplicates gigabytes of packed objects, and needs its own remotes configured. A worktree costs only the checked-out files. Fetch a colleague’s branch once in any worktree and it is immediately checkoutable in all of them. On a large monorepo the difference is minutes and gigabytes versus seconds and a few megabytes.
A hotfix and a feature, side by side
Start from your normal clone on main. Keep a long-lived feature branch in a worktree of its own, and spin up a hotfix worktree when production catches fire — both live at once, in separate folders, with independent working states.
# from inside your main clone (on 'main')
# a worktree for an existing feature branch
git worktree add ../app-feature feature/new-billing
# a worktree that also CREATES the hotfix branch, cut from main
git worktree add -b hotfix/payment-timeout ../app-hotfix main
# see what you have
git worktree list
# /srv/app 9c1f2a1 [main]
# /srv/app-feature 4b7e0d3 [feature/new-billing]
# /srv/app-hotfix 9c1f2a1 [hotfix/payment-timeout]
Now cd ../app-hotfix, fix the bug, commit and push, while your billing work sits untouched in ../app-feature and your editor windows stay exactly where you left them. Each directory has its own index and its own dirty state. There is no stash, because nothing was ever interrupted.
A throwaway worktree for reviewing a PR
Review is the case worktrees were made for. You want the author’s code checked out, built and running, without disturbing your own branch, and you want it gone the moment you are done. The helper below fetches a GitHub pull request into a temporary worktree with a detached HEAD, drops you into it, and cleans up on exit. It uses a detached checkout deliberately so it never creates a local branch you have to remember to delete.
#!/usr/bin/env bash
# pr-review: check out a GitHub PR in a throwaway worktree, then prune it.
# Usage: pr-review 1234 (run from anywhere inside the repo)
set -euo pipefail
pr="${1:?usage: pr-review <pr-number>}"
remote="${PR_REMOTE:-origin}"
root="$(git rev-parse --show-toplevel)"
dir="$(mktemp -d "${TMPDIR:-/tmp}/pr-${pr}.XXXX")"
# Fetch the PR head; --detach avoids leaving a stray local branch behind.
git -C "$root" fetch --quiet "$remote" "pull/${pr}/head"
git -C "$root" worktree add --quiet --detach "$dir" FETCH_HEAD
cleanup() {
git -C "$root" worktree remove --force "$dir"
git -C "$root" worktree prune
}
trap cleanup EXIT
echo "Reviewing PR #${pr} in ${dir} (exit the shell to tear it down)"
( cd "$dir" && "${SHELL:-bash}" )
Run pr-review 1234, poke at the branch, run the tests, and type exit. The trap removes the worktree and prunes the administrative entry so nothing lingers. Note the pull/<n>/head refspec is GitHub’s convention; GitLab exposes merge requests at merge-requests/<n>/head, so parameterise it if you work across both. If you prefer, gh pr checkout 1234 does the fetch for you and you point worktree add at the resulting ref instead.
The two things that will bite you
The same branch cannot be checked out in two worktrees. Try it and Git stops you with fatal: 'feature/new-billing' is already checked out at .... This is a guardrail, not a bug: two working directories editing one branch’s index would corrupt your sense of what is committed. If you genuinely need it — usually to build the same ref two ways — use --detach for the second checkout, or --force if you fully understand the consequences. Reach for detached HEAD by default; it is the honest choice for a read-only look at someone else’s code.
Deleting the folder is not removing the worktree. If you rm -rf a worktree directory, Git still holds a stale administrative record in .git/worktrees, and that record can keep the branch “checked out” so you cannot reuse it. Always tear down with git worktree remove <path>, which refuses if the tree is dirty unless you pass --force. If a directory has already gone — deleted, or on an unmounted drive — run git worktree prune to clear the orphaned entries. The helper above does both, which is why it never leaves debris.
Making it a habit
Two operational notes make this stick. First, hooks are per-worktree checkouts of tracked files but share the repo’s config, so a pre-commit baseline that actually runs will run identically in every worktree once installed — you are not weakening your guardrails by spreading out. Second, review latency is a real delivery metric, not a nicety: the friction of stashing quietly inflates the time a pull request sits waiting, which is exactly the kind of drag that shows up when you start instrumenting lead time and change-failure rate. Cheaper context switching is not a developer indulgence; it is throughput.
Keep worktrees outside the primary checkout so your editor and file watchers do not index them twice, name them for what they hold, and prune on the way out. Do that and the stash stack you have been carrying since 2019 simply stops accumulating.
Free interactive tool
Website compliance checklist
What your site has to do, based on what it actually does
Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.
Everything that applies
Ordered by what to do first: legal requirements you can close quickly, then larger pieces of work, then what is expected rather than required. Not exhaustive, and not a legal audit.
Dated PDF, yours to keep or circulate.
Most technology problems are not technology problems. They are control problems.
The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.