Description 592 -> 248 chars, body 756 -> 515 words, Gotchas 8 -> 4. The audit found the dispatch table had no row for a worktree on an existing local branch, so that request fell to the adjacent -B row, which resets the branch to HEAD and discards its commits. Non-destructive create is now the first row and -B names its own destructiveness. Adds the missing lock/unlock row and repair's run-from constraint.
4.6 KiB
topic, source_keys
| topic | source_keys | |
|---|---|---|
| worktrees |
|
Shared vs. per-worktree state
All worktrees share one object store, one config, and most refs under refs/. Each worktree keeps
its own HEAD, index, and per-worktree metadata (ORIG_HEAD, MERGE_HEAD, refs/bisect/,
refs/worktree/, refs/rewritten/) under $GIT_DIR/worktrees/<name>/. Exactly one main
worktree exists per repo — the one git init or git clone produced — and it cannot be removed
or moved. Every other worktree is a linked worktree created by git worktree add.
add forms
git worktree add <path> <branch> # check out an existing branch — non-destructive
git worktree add -b <branch> <path> # create a new branch; fails if it exists
git worktree add <path> # branch named after $(basename <path>): checked out
# if it exists, else created from HEAD
git worktree add -B <branch> <path> # create the branch, or reset an existing one to HEAD,
# discarding the commits it carried
git worktree add <path> <remote>/<branch> # track a remote branch
git worktree add -d <path> # detached HEAD, no branch
Full add flag table
| Flag | Meaning |
|---|---|
-b <branch> |
Create and check out a new branch; fails if it exists |
-B <branch> |
Like -b but resets the branch if it already exists |
-d / --detach |
Detach HEAD; useful for throwaway experiments |
--orphan |
Create empty unborn branch |
--no-checkout |
Suppress initial checkout (for sparse-checkout setup) |
--guess-remote |
Look for a matching remote-tracking branch by path basename |
--lock [--reason <str>] |
Lock immediately on creation (atomic; avoids race vs. add-then-lock) |
-f / --force |
Allow when branch is already checked out elsewhere |
--relative-paths |
Link via relative paths (portable across moves) |
Using - as <commit-ish> is shorthand for @{-1} (the branch checked out before the current one), e.g. git worktree add <path> -.
New unborn branch
git worktree add --orphan -b <branch> <path>
Creates an empty branch with no commits.
Sparse-checkout worktree
Suppress the initial checkout to configure sparse-checkout first:
git worktree add --no-checkout ../sparse main
cd ../sparse
git sparse-checkout init --cone
git sparse-checkout set src/
git checkout main
Worktree on removable media
git worktree add --lock --reason "external SSD" <path> <branch>
git worktree unlock <path> # when reconnected
Remote-branch disambiguation
git worktree add <path> <remote>/<branch>
For ambiguous names across remotes, checkout.defaultRemote config disambiguates explicitly, or --guess-remote auto-matches by path basename (default controlled by worktree.guessRemote config). If a branch name matches multiple remotes during worktree add and neither is set, Git refuses rather than guessing.
Repair after a manual move
git worktree repair # run from the main worktree: fixes the links to every linked worktree
git worktree repair <path> # run from a moved linked worktree: fixes its own pointer back to main
repair reestablishes the bidirectional pointers a manual move breaks, but only for the side it is
run from. Run it from the wrong directory and it reports nothing and fixes nothing.
Configuration
| Key | Effect |
|---|---|
worktree.guessRemote |
Default for --guess-remote on git worktree add |
worktree.useRelativePaths |
Default for --relative-paths on git worktree add (link via relative paths — portable across moves) |
gc.worktreePruneExpire |
How long before stale worktree metadata is pruned by git gc |
extensions.worktreeConfig |
Enable per-worktree config scope (config.worktree file) — see Gotchas in SKILL.md |
checkout.defaultRemote |
Disambiguates which remote to use when a branch name matches multiple remotes during worktree add |
Workflow patterns
Emergency fix without disrupting current work — nothing is stashed, and the main worktree is untouched throughout:
git worktree add -b emergency-fix ../temp main
cd ../temp
# fix, then commit
git commit -a -m "fix: critical production bug"
cd -
git worktree remove ../temp
Review a PR branch alongside your own work — both branches stay checked out, so there is no context switch:
git worktree add ../review-pr-123 origin/feature-xyz
# open ../review-pr-123 in a second editor window or terminal