--- topic: worktrees source_keys: - git-scm-worktree-docs --- ## 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//`. 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 ```bash git worktree add # check out an existing branch — non-destructive git worktree add -b # create a new branch; fails if it exists git worktree add # branch named after $(basename ): checked out # if it exists, else created from HEAD git worktree add -B # create the branch, or reset an existing one to HEAD, # discarding the commits it carried git worktree add / # track a remote branch git worktree add -d # detached HEAD, no branch ``` ## Full `add` flag table | Flag | Meaning | |---|---| | `-b ` | Create and check out a new branch; fails if it exists | | `-B ` | 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 ]` | 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 `` is shorthand for `@{-1}` (the branch checked out before the current one), e.g. `git worktree add -`. ## New unborn branch ```bash git worktree add --orphan -b ``` Creates an empty branch with no commits. ## Sparse-checkout worktree Suppress the initial checkout to configure sparse-checkout first: ```bash 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 ```bash git worktree add --lock --reason "external SSD" git worktree unlock # when reconnected ``` ## Remote-branch disambiguation ```bash git worktree add / ``` 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 ```bash git worktree repair # run from the main worktree: fixes the links to every linked worktree git worktree repair # 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: ```bash 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: ```bash git worktree add ../review-pr-123 origin/feature-xyz # open ../review-pr-123 in a second editor window or terminal ```