Worktrees — Multiple Checkouts of One Repo
git worktree lets you have multiple branches checked out at the same time, in different directories, sharing one .git directory. No need to clone twice.
The problem worktrees solve
You’re deep in a feature branch with uncommitted changes. A urgent bug arrives on main. Without worktrees:
- Stash → switch → fix → commit → switch back → unstash → context lost.
- Or: clone the repo a second time, fix in the clone.
With worktrees:
git worktree add ../hotfix main
# now ../hotfix is a checkout of main
cd ../hotfix
# ... fix and commit ...
cd -
git worktree remove ../hotfix
Your original directory stays exactly as it was.
Basic commands
git worktree add <path> <branch> # check out <branch> at <path>
git worktree add <path> # create branch named after the path
git worktree add -b new-feature <path> # create a new branch and check it out at path
git worktree list # show all worktrees
git worktree remove <path> # remove a worktree (must be clean)
git worktree prune # clean up administrative records of removed dirs
What gets shared, what doesn’t
All worktrees share the same .git/ directory:
| Shared | Per-worktree |
|---|---|
| object store (commits, blobs, packfiles) | working tree files |
| refs (branches, tags) | HEAD pointer |
| reflog | index (staging area) |
| config (mostly) | submodules state |
| hooks |
This means:
- A commit in worktree A is immediately visible from worktree B’s
git log. - A new branch in A is visible in B’s
git branch. - But each worktree has its own checked-out state.
Constraint: a branch is checked out in only one place
git worktree add ../second main
# fatal: 'main' is already checked out at '/path/to/original'
Two worktrees can’t have the same branch checked out at once. Use a different branch or a detached HEAD:
git worktree add --detach ../inspect main # checkout main as detached HEAD
Common workflows
Hotfix without disturbing your feature
git worktree add ../hotfix -b hotfix/critical main
cd ../hotfix
# fix, commit, push, PR
cd - # back to your feature work, untouched
git worktree remove ../hotfix
Code review someone else’s PR
git fetch origin pull/123/head:pr-123
git worktree add ../pr-123 pr-123
cd ../pr-123
# poke around, run tests, leave it
When done: git worktree remove ../pr-123 && git branch -D pr-123.
Run two versions side by side
git worktree add ../app-v1 v1.4.0
git worktree add ../app-v2 v2.0.0
# start both, compare behavior
Long-running CI / build in one worktree, develop in another
The build worktree never has uncommitted changes; you commit and push from your dev worktree, the build worktree pulls and runs.
Bare repo + worktrees pattern
For “I always want to work this way”:
git clone --bare git@github.com:org/repo.git repo.git
cd repo.git
git worktree add ../main main
git worktree add ../feature -b feature
Now you have a bare repo.git/ (no working tree, just .git content) and two sibling directories with checkouts. Some teams prefer this over the conventional clone-with-default-checkout layout.
Pitfalls
git worktree removerefuses on dirty worktrees. Clean up first or--force.- Stashing is global per worktree? No — stash is repo-wide, accessible from any worktree. Easy to confuse “where did my stash go.”
- Submodules and worktrees mix awkwardly. Modern git handles it but check
.gitmodulesconfiguration if things misbehave. pruneis needed when yourm -rfa worktree directory directly. Git keeps administrative metadata;git worktree prunecleans up.
git worktree list
git worktree list
/home/me/myrepo a1b2c3d [main]
/home/me/myrepo-hotfix e4f5g6h [hotfix/critical]
/home/me/myrepo-pr-123 h7i8j9k (detached HEAD)
git worktree list --porcelain for a stable, parseable form.
Worktrees vs alternatives
| Approach | Pro | Con |
|---|---|---|
| Stash + switch | one directory | loses context, slow with large stashes |
| Worktree | parallel checkouts share .git | extra disk for files (not history), one branch per dir |
| Second clone | totally independent | duplicates .git history (large), separate fetches |
For occasional context switches: stash. For frequent multi-context work (hotfixes during feature work, reviewing many PRs): worktrees. Avoid second clones unless you need true isolation.
Common interview confusions
- “Each worktree has its own history.” — they share the .git history. Only the working tree files differ.
- “Worktrees are like git submodules.” — unrelated. Submodules are external repos pinned to a SHA. Worktrees are extra checkouts of the same repo.
- “You can have main checked out in two worktrees.” — no, branch is exclusive. Use
--detachif you need to.
Interview angle
- “What’s
git worktreefor?” — multiple branches checked out simultaneously in separate directories, sharing one.git. Lets you context-switch (hotfix during a feature) without stash/branch dance. - “What’s shared between worktrees?” — object store, refs, reflog, hooks, config. Each worktree has its own working tree, index, HEAD.
- “Can two worktrees have the same branch checked out?” — no. Use
--detachfor read-only inspection. - “How does worktree compare to cloning twice?” — worktree shares history (smaller, faster fetch); two clones are fully independent (more disk, separate fetches).
- “When would you prefer stashing over a worktree?” — short context switches where setting up a directory is overkill. Worktrees pay off when you switch contexts often.
- “How do you get rid of a worktree?” —
git worktree remove <path>. If yourm -rf’d it directly,git worktree prunecleans up the metadata.