refactor(git-worktrees): retrofit to the ADR-0020 context contract
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.
This commit is contained in:
@@ -4,7 +4,7 @@ Manage git worktrees to enable multi-branch parallel development across isolated
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles worktree operations within the git workflow suite. It creates, lists, locks/unlocks, moves, removes, prunes, and repairs worktrees — letting an agent work on multiple branches simultaneously without stashing. It returns structured results (paths, branches, lock status) suitable for agent composition.
|
||||
This skill handles worktree operations within the git workflow suite. It creates, lists, locks/unlocks, moves, removes, prunes, and repairs worktrees — letting an agent work on multiple branches simultaneously without stashing. It returns structured results (paths, branches, lock status) suitable for agent composition. For multi-step flows spanning branch strategy plus worktree setup, `git-workflow` handles the broader orchestration and delegates the worktree mechanics here.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -18,7 +18,7 @@ Describe your worktree task: create a worktree for a branch, list existing workt
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `SKILL.md` | Dispatch table, per-operation gates, and the report format |
|
||||
| `references/README.md` | Describes the references directory contents |
|
||||
| `references/worktrees.md` | Full `add` flag table, sparse-checkout, removable-media locking, remote disambiguation, configuration |
|
||||
| `references/worktrees.md` | Read when an operation needs more than the dispatch table: shared vs. per-worktree state, the `add` command forms, the full `add` flag table, orphan branches, sparse-checkout, removable-media locking, remote disambiguation, where to run `repair` from, config keys, and the emergency-fix and PR-review patterns |
|
||||
| `references/sources.md` | Research sources and provenance |
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
name: git-worktrees
|
||||
|
||||
description: >
|
||||
Manage Git worktrees to enable multi-branch parallel development across isolated directories.
|
||||
Use when the user needs to work on multiple branches simultaneously without stashing, switch between feature/hotfix/experimental work, or coordinate code reviews alongside ongoing development.
|
||||
Handles creation, listing, locking, moving, removal, pruning, and repair of worktrees.
|
||||
Provides structured results (paths, branches, lock status) for agent composition in git orchestration workflows.
|
||||
Do not use when only inspecting a single branch or when the user needs standard checkout/stash workflows.
|
||||
Use when working on several branches at once without stashing.
|
||||
Create, list, lock, move, remove, prune, or repair git worktrees.
|
||||
Not ordinary branch switching or checkout -> `git-branches`.
|
||||
Not interactive multi-step git guidance -> `git-workflow`.
|
||||
|
||||
metadata:
|
||||
category: git
|
||||
@@ -14,101 +13,44 @@ metadata:
|
||||
- git-scm-worktree-docs
|
||||
---
|
||||
|
||||
## Concept
|
||||
|
||||
A worktree lets you check out multiple branches simultaneously from one repository, each in its own directory. All worktrees share the same objects, config, and most refs (`refs/`). Each worktree has its own `HEAD`, index, and per-worktree metadata (`ORIG_HEAD`, `MERGE_HEAD`, `refs/bisect/`, `refs/worktree/`, `refs/rewritten/`) stored at `$GIT_DIR/worktrees/<name>/`. The **main worktree** (from `git init`/`git clone`) is exactly one per repo and cannot be removed; **linked worktrees** are the additional ones created via `git worktree add`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **A branch can only be checked out in one worktree at a time.** Attempting `git worktree add` for an already-checked-out branch fails unless you pass `--force`. Use `--force` only when intentional.
|
||||
- **Submodules are unsupported and block operations.** Repos with submodules have incomplete worktree support. Worktrees containing submodules cannot be moved and require `--force` to remove.
|
||||
- **Never manually `rm -rf` a worktree directory.** This leaves stale metadata in `$GIT_DIR/worktrees/`. Always use `git worktree remove`. If already deleted, run `git worktree prune` to clean up.
|
||||
- **Manual moves break bidirectional pointers.** If a worktree directory is moved outside of `git worktree move`, run `git worktree repair` to fix connections.
|
||||
- **Force-flag escalation with locks.** Removing or moving a locked worktree requires `-ff` (two flags), not just `-f`.
|
||||
- **Worktree identification is by full path, unique basename, or unique partial path.** Ambiguous names error. Use `git worktree list` to see available identifiers.
|
||||
- **`--lock` on `add` is atomic; create-then-lock has a race window.** Use `--lock` directly on `git worktree add` when consistency matters.
|
||||
- **`extensions.worktreeConfig = true` is a one-way door.** It enables per-worktree config (`git config --worktree ...`) but makes the repo refuse to open in older Git versions. Once set, `core.bare`/`core.worktree` must live in `config.worktree`, not `config`. Don't enable it unless per-worktree config is actually needed.
|
||||
- **A branch can be checked out in only one worktree at a time.** `git worktree add` on an already-checked-out branch fails; `--force` is the only override, so use it only deliberately.
|
||||
- **Never `rm -rf` a worktree directory.** That strands metadata in `$GIT_DIR/worktrees/`. Use `git worktree remove`, or `git worktree prune` afterwards.
|
||||
- **Submodules break worktree support.** A worktree containing submodules cannot be moved at all, and needs `--force` to remove.
|
||||
- **`extensions.worktreeConfig = true` is a one-way door.** It costs compatibility with older Git and forces `core.bare`/`core.worktree` into `config.worktree`. Leave it off unless per-worktree config is needed.
|
||||
|
||||
## Common Operations
|
||||
## Step 1 — Dispatch
|
||||
|
||||
**Create and switch to a new worktree** — default approach:
|
||||
```bash
|
||||
git worktree add -b <new-branch> <path>
|
||||
cd <path>
|
||||
```
|
||||
This creates a new branch and checks it out in a new directory. Other branches cannot be checked out elsewhere simultaneously.
|
||||
| Operation | Run |
|
||||
|---|---|
|
||||
| Create on an existing branch | `git worktree add <path> <branch>` |
|
||||
| Create on a new branch | `git worktree add -b <branch> <path>` |
|
||||
| Create on the branch named after the path basename | `git worktree add <path>` — checks that branch out if it exists, else creates it from HEAD |
|
||||
| Create and reset an existing branch to HEAD — discards its commits | `git worktree add -B <branch> <path>` |
|
||||
| Create tracking a remote branch | `git worktree add <path> <remote>/<branch>` |
|
||||
| Throwaway experiment, no branch | `git worktree add -d <path>` |
|
||||
| List | `git worktree list -v`, or `--porcelain -z` to parse |
|
||||
| Lock or unlock | `git worktree lock [--reason <str>] <path>` / `git worktree unlock <path>` |
|
||||
| Move | `git worktree move <from> <to>` |
|
||||
| Remove | `git worktree remove <path>` |
|
||||
| Prune stale metadata | `git worktree prune --dry-run`, then without the flag |
|
||||
| Repair after a manual move | `git worktree repair [<path>]` — from the main worktree to fix all links, or from the moved worktree itself |
|
||||
|
||||
**Create-or-reset a branch**: `git worktree add -B <branch> <path>` — like `-b` but resets the branch to HEAD if it already exists.
|
||||
If the operation needs anything the table does not carry — the full `add` flag
|
||||
table, orphan branches, sparse-checkout, locking for removable media, remote
|
||||
disambiguation across several remotes, worktree config keys, or the worked
|
||||
emergency-fix and PR-review patterns — read `references/worktrees.md`.
|
||||
|
||||
**Create a worktree for an existing remote branch**:
|
||||
```bash
|
||||
git worktree add <path> <remote>/<branch>
|
||||
```
|
||||
For ambiguous names across remotes, disambiguate via `checkout.defaultRemote` config or `--guess-remote`. Full flag table and detail: `references/worktrees.md`.
|
||||
Gates:
|
||||
|
||||
**Throwaway experiment in detached HEAD**:
|
||||
```bash
|
||||
git worktree add -d ../experiment # or --detach
|
||||
# experiment freely, no branch created
|
||||
git worktree remove ../experiment
|
||||
```
|
||||
- **`move`, `remove` — the main worktree cannot be moved or removed.** Only linked worktrees, the ones `git worktree add` created, are candidates.
|
||||
- **`add`, `move`, `remove` — escalate force flags one step at a time.** `-f` overrides a safeguard such as an unclean tree; `move` and `remove` need `-ff` on top of that when the worktree is locked. Confirm with the user before either — both discard state.
|
||||
- **`lock`, `move`, `remove`, `repair` — identify a worktree by full path, unique basename, or unique partial path.** An ambiguous name errors rather than picking; `git worktree list` shows the usable identifiers.
|
||||
- **`add` — lock at creation, not after.** `git worktree add --lock` is atomic, where add-then-`lock` leaves a window in which the worktree is unprotected.
|
||||
|
||||
**List all worktrees with state**:
|
||||
```bash
|
||||
git worktree list -v # human-readable with lock/prune reasons
|
||||
git worktree list --porcelain -z # machine-readable, NUL-terminated
|
||||
```
|
||||
## Step 2 — Report
|
||||
|
||||
**Move a worktree to a new path**:
|
||||
```bash
|
||||
git worktree move <current-path> <new-path>
|
||||
# Cannot move: main worktree, worktrees with submodules
|
||||
# To override safeguards: -f; to override locked state too: -ff
|
||||
```
|
||||
|
||||
**Remove a worktree**:
|
||||
```bash
|
||||
git worktree remove <path> # only if clean
|
||||
git worktree remove -f <path> # force-remove unclean
|
||||
git worktree remove -ff <path> # force-remove even if locked
|
||||
```
|
||||
|
||||
**Prune stale metadata**:
|
||||
```bash
|
||||
git worktree prune --dry-run # preview what would be removed
|
||||
git worktree prune # clean up orphaned metadata
|
||||
```
|
||||
Also triggered by `git gc`, controlled by `gc.worktreePruneExpire` config.
|
||||
|
||||
**Repair broken connections** (after a manual move):
|
||||
```bash
|
||||
git worktree repair # from main worktree or after it was moved
|
||||
git worktree repair <path> # reconnect a specific linked worktree
|
||||
```
|
||||
|
||||
Sparse-checkout worktrees, locking for removable media, the full `add` flag table, and the config key reference: `references/worktrees.md`.
|
||||
|
||||
## Worked Examples
|
||||
|
||||
**Emergency fix without disrupting current work** — no stashing needed, ongoing work in the main worktree is untouched:
|
||||
```bash
|
||||
git worktree add -b emergency-fix ../temp main
|
||||
cd ../temp
|
||||
# fix, commit
|
||||
git commit -a -m "fix: critical production bug"
|
||||
cd -
|
||||
git worktree remove ../temp
|
||||
```
|
||||
|
||||
**Review a PR branch alongside your current work** — no context switch, both branches stay checked out:
|
||||
```bash
|
||||
git worktree add ../review-pr-123 origin/feature-xyz
|
||||
# open ../review-pr-123 in a second editor window or terminal
|
||||
```
|
||||
|
||||
## Return Format for Agents
|
||||
|
||||
When invoking worktree operations, return structured results:
|
||||
```yaml
|
||||
worktrees:
|
||||
- path: <directory-path>
|
||||
@@ -116,10 +58,8 @@ worktrees:
|
||||
commit: <short-hash>
|
||||
locked: <true/false>
|
||||
lock_reason: <reason or empty>
|
||||
- ...
|
||||
```
|
||||
Derive these fields from `git worktree list --porcelain -z` — its `worktree`/`branch`/`HEAD`/`locked` lines map directly to `path`/`branch`/`commit`/`locked`+`lock_reason`.
|
||||
|
||||
For single operations, include the operation result (e.g., `created: true`, `removed: true`, `moved: true`).
|
||||
|
||||
For multi-step flows spanning branch strategy plus worktree setup, compose with the `git-workflow` skill — it handles the broader orchestration, this skill handles the worktree mechanics.
|
||||
Derive those fields from `git worktree list --porcelain -z`. For a single
|
||||
operation, report its outcome instead — `created: true`, `moved: true`,
|
||||
`removed: true`.
|
||||
|
||||
@@ -10,4 +10,4 @@ This directory contains provenance metadata and research sources for the `git-wo
|
||||
## Files
|
||||
|
||||
- `sources.md` — Extracted research sources and their contributing documents
|
||||
- `worktrees.md` — Full `add` flag table, sparse-checkout setup, removable-media locking, remote-branch disambiguation, and the config key reference
|
||||
- `worktrees.md` — Shared vs. per-worktree state, the `add` command forms, the full `add` flag table, orphan branches, sparse-checkout setup, removable-media locking, remote-branch disambiguation, where to run `repair` from, the config key reference, and the emergency-fix and PR-review workflow patterns
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
- **Research doc:** plugins/git/docs/research/docs/git/worktrees.md (whole-document reference — covers `## Concept Overview`, `## Key Commands`, `## Workflow Patterns`, `## Common Gotchas`, `## Configuration`)
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Concept, Gotchas, Common Operations, Worked Examples, Return Format)
|
||||
- references/worktrees.md (full `add` flag table, sparse-checkout, removable media, remote disambiguation, configuration)
|
||||
- SKILL.md (Gotchas, Step 1 dispatch table and per-operation gates, Step 2 report format)
|
||||
- references/worktrees.md (shared vs. per-worktree state, `add` command forms, full `add` flag table, orphan branches, sparse-checkout, removable media, remote disambiguation, `repair` invocation directory, configuration, workflow patterns)
|
||||
|
||||
@@ -4,6 +4,27 @@ 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/<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
|
||||
|
||||
```bash
|
||||
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 |
|
||||
@@ -52,6 +73,16 @@ 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
|
||||
|
||||
```bash
|
||||
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 |
|
||||
@@ -61,3 +92,25 @@ For ambiguous names across remotes, `checkout.defaultRemote` config disambiguate
|
||||
| `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
|
||||
```
|
||||
|
||||
@@ -4,7 +4,7 @@ Manage git worktrees to enable multi-branch parallel development across isolated
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles worktree operations within the git workflow suite. It creates, lists, locks/unlocks, moves, removes, prunes, and repairs worktrees — letting an agent work on multiple branches simultaneously without stashing. It returns structured results (paths, branches, lock status) suitable for agent composition.
|
||||
This skill handles worktree operations within the git workflow suite. It creates, lists, locks/unlocks, moves, removes, prunes, and repairs worktrees — letting an agent work on multiple branches simultaneously without stashing. It returns structured results (paths, branches, lock status) suitable for agent composition. For multi-step flows spanning branch strategy plus worktree setup, `git-workflow` handles the broader orchestration and delegates the worktree mechanics here.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -18,7 +18,7 @@ Describe your worktree task: create a worktree for a branch, list existing workt
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `SKILL.md` | Dispatch table, per-operation gates, and the report format |
|
||||
| `references/README.md` | Describes the references directory contents |
|
||||
| `references/worktrees.md` | Full `add` flag table, sparse-checkout, removable-media locking, remote disambiguation, configuration |
|
||||
| `references/worktrees.md` | Read when an operation needs more than the dispatch table: shared vs. per-worktree state, the `add` command forms, the full `add` flag table, orphan branches, sparse-checkout, removable-media locking, remote disambiguation, where to run `repair` from, config keys, and the emergency-fix and PR-review patterns |
|
||||
| `references/sources.md` | Research sources and provenance |
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
name: git-worktrees
|
||||
|
||||
description: >
|
||||
Manage Git worktrees to enable multi-branch parallel development across isolated directories.
|
||||
Use when the user needs to work on multiple branches simultaneously without stashing, switch between feature/hotfix/experimental work, or coordinate code reviews alongside ongoing development.
|
||||
Handles creation, listing, locking, moving, removal, pruning, and repair of worktrees.
|
||||
Provides structured results (paths, branches, lock status) for agent composition in git orchestration workflows.
|
||||
Do not use when only inspecting a single branch or when the user needs standard checkout/stash workflows.
|
||||
Use when working on several branches at once without stashing.
|
||||
Create, list, lock, move, remove, prune, or repair git worktrees.
|
||||
Not ordinary branch switching or checkout -> `git-branches`.
|
||||
Not interactive multi-step git guidance -> `git-workflow`.
|
||||
|
||||
metadata:
|
||||
category: git
|
||||
@@ -14,101 +13,44 @@ metadata:
|
||||
- git-scm-worktree-docs
|
||||
---
|
||||
|
||||
## Concept
|
||||
|
||||
A worktree lets you check out multiple branches simultaneously from one repository, each in its own directory. All worktrees share the same objects, config, and most refs (`refs/`). Each worktree has its own `HEAD`, index, and per-worktree metadata (`ORIG_HEAD`, `MERGE_HEAD`, `refs/bisect/`, `refs/worktree/`, `refs/rewritten/`) stored at `$GIT_DIR/worktrees/<name>/`. The **main worktree** (from `git init`/`git clone`) is exactly one per repo and cannot be removed; **linked worktrees** are the additional ones created via `git worktree add`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **A branch can only be checked out in one worktree at a time.** Attempting `git worktree add` for an already-checked-out branch fails unless you pass `--force`. Use `--force` only when intentional.
|
||||
- **Submodules are unsupported and block operations.** Repos with submodules have incomplete worktree support. Worktrees containing submodules cannot be moved and require `--force` to remove.
|
||||
- **Never manually `rm -rf` a worktree directory.** This leaves stale metadata in `$GIT_DIR/worktrees/`. Always use `git worktree remove`. If already deleted, run `git worktree prune` to clean up.
|
||||
- **Manual moves break bidirectional pointers.** If a worktree directory is moved outside of `git worktree move`, run `git worktree repair` to fix connections.
|
||||
- **Force-flag escalation with locks.** Removing or moving a locked worktree requires `-ff` (two flags), not just `-f`.
|
||||
- **Worktree identification is by full path, unique basename, or unique partial path.** Ambiguous names error. Use `git worktree list` to see available identifiers.
|
||||
- **`--lock` on `add` is atomic; create-then-lock has a race window.** Use `--lock` directly on `git worktree add` when consistency matters.
|
||||
- **`extensions.worktreeConfig = true` is a one-way door.** It enables per-worktree config (`git config --worktree ...`) but makes the repo refuse to open in older Git versions. Once set, `core.bare`/`core.worktree` must live in `config.worktree`, not `config`. Don't enable it unless per-worktree config is actually needed.
|
||||
- **A branch can be checked out in only one worktree at a time.** `git worktree add` on an already-checked-out branch fails; `--force` is the only override, so use it only deliberately.
|
||||
- **Never `rm -rf` a worktree directory.** That strands metadata in `$GIT_DIR/worktrees/`. Use `git worktree remove`, or `git worktree prune` afterwards.
|
||||
- **Submodules break worktree support.** A worktree containing submodules cannot be moved at all, and needs `--force` to remove.
|
||||
- **`extensions.worktreeConfig = true` is a one-way door.** It costs compatibility with older Git and forces `core.bare`/`core.worktree` into `config.worktree`. Leave it off unless per-worktree config is needed.
|
||||
|
||||
## Common Operations
|
||||
## Step 1 — Dispatch
|
||||
|
||||
**Create and switch to a new worktree** — default approach:
|
||||
```bash
|
||||
git worktree add -b <new-branch> <path>
|
||||
cd <path>
|
||||
```
|
||||
This creates a new branch and checks it out in a new directory. Other branches cannot be checked out elsewhere simultaneously.
|
||||
| Operation | Run |
|
||||
|---|---|
|
||||
| Create on an existing branch | `git worktree add <path> <branch>` |
|
||||
| Create on a new branch | `git worktree add -b <branch> <path>` |
|
||||
| Create on the branch named after the path basename | `git worktree add <path>` — checks that branch out if it exists, else creates it from HEAD |
|
||||
| Create and reset an existing branch to HEAD — discards its commits | `git worktree add -B <branch> <path>` |
|
||||
| Create tracking a remote branch | `git worktree add <path> <remote>/<branch>` |
|
||||
| Throwaway experiment, no branch | `git worktree add -d <path>` |
|
||||
| List | `git worktree list -v`, or `--porcelain -z` to parse |
|
||||
| Lock or unlock | `git worktree lock [--reason <str>] <path>` / `git worktree unlock <path>` |
|
||||
| Move | `git worktree move <from> <to>` |
|
||||
| Remove | `git worktree remove <path>` |
|
||||
| Prune stale metadata | `git worktree prune --dry-run`, then without the flag |
|
||||
| Repair after a manual move | `git worktree repair [<path>]` — from the main worktree to fix all links, or from the moved worktree itself |
|
||||
|
||||
**Create-or-reset a branch**: `git worktree add -B <branch> <path>` — like `-b` but resets the branch to HEAD if it already exists.
|
||||
If the operation needs anything the table does not carry — the full `add` flag
|
||||
table, orphan branches, sparse-checkout, locking for removable media, remote
|
||||
disambiguation across several remotes, worktree config keys, or the worked
|
||||
emergency-fix and PR-review patterns — read `references/worktrees.md`.
|
||||
|
||||
**Create a worktree for an existing remote branch**:
|
||||
```bash
|
||||
git worktree add <path> <remote>/<branch>
|
||||
```
|
||||
For ambiguous names across remotes, disambiguate via `checkout.defaultRemote` config or `--guess-remote`. Full flag table and detail: `references/worktrees.md`.
|
||||
Gates:
|
||||
|
||||
**Throwaway experiment in detached HEAD**:
|
||||
```bash
|
||||
git worktree add -d ../experiment # or --detach
|
||||
# experiment freely, no branch created
|
||||
git worktree remove ../experiment
|
||||
```
|
||||
- **`move`, `remove` — the main worktree cannot be moved or removed.** Only linked worktrees, the ones `git worktree add` created, are candidates.
|
||||
- **`add`, `move`, `remove` — escalate force flags one step at a time.** `-f` overrides a safeguard such as an unclean tree; `move` and `remove` need `-ff` on top of that when the worktree is locked. Confirm with the user before either — both discard state.
|
||||
- **`lock`, `move`, `remove`, `repair` — identify a worktree by full path, unique basename, or unique partial path.** An ambiguous name errors rather than picking; `git worktree list` shows the usable identifiers.
|
||||
- **`add` — lock at creation, not after.** `git worktree add --lock` is atomic, where add-then-`lock` leaves a window in which the worktree is unprotected.
|
||||
|
||||
**List all worktrees with state**:
|
||||
```bash
|
||||
git worktree list -v # human-readable with lock/prune reasons
|
||||
git worktree list --porcelain -z # machine-readable, NUL-terminated
|
||||
```
|
||||
## Step 2 — Report
|
||||
|
||||
**Move a worktree to a new path**:
|
||||
```bash
|
||||
git worktree move <current-path> <new-path>
|
||||
# Cannot move: main worktree, worktrees with submodules
|
||||
# To override safeguards: -f; to override locked state too: -ff
|
||||
```
|
||||
|
||||
**Remove a worktree**:
|
||||
```bash
|
||||
git worktree remove <path> # only if clean
|
||||
git worktree remove -f <path> # force-remove unclean
|
||||
git worktree remove -ff <path> # force-remove even if locked
|
||||
```
|
||||
|
||||
**Prune stale metadata**:
|
||||
```bash
|
||||
git worktree prune --dry-run # preview what would be removed
|
||||
git worktree prune # clean up orphaned metadata
|
||||
```
|
||||
Also triggered by `git gc`, controlled by `gc.worktreePruneExpire` config.
|
||||
|
||||
**Repair broken connections** (after a manual move):
|
||||
```bash
|
||||
git worktree repair # from main worktree or after it was moved
|
||||
git worktree repair <path> # reconnect a specific linked worktree
|
||||
```
|
||||
|
||||
Sparse-checkout worktrees, locking for removable media, the full `add` flag table, and the config key reference: `references/worktrees.md`.
|
||||
|
||||
## Worked Examples
|
||||
|
||||
**Emergency fix without disrupting current work** — no stashing needed, ongoing work in the main worktree is untouched:
|
||||
```bash
|
||||
git worktree add -b emergency-fix ../temp main
|
||||
cd ../temp
|
||||
# fix, commit
|
||||
git commit -a -m "fix: critical production bug"
|
||||
cd -
|
||||
git worktree remove ../temp
|
||||
```
|
||||
|
||||
**Review a PR branch alongside your current work** — no context switch, both branches stay checked out:
|
||||
```bash
|
||||
git worktree add ../review-pr-123 origin/feature-xyz
|
||||
# open ../review-pr-123 in a second editor window or terminal
|
||||
```
|
||||
|
||||
## Return Format for Agents
|
||||
|
||||
When invoking worktree operations, return structured results:
|
||||
```yaml
|
||||
worktrees:
|
||||
- path: <directory-path>
|
||||
@@ -116,10 +58,8 @@ worktrees:
|
||||
commit: <short-hash>
|
||||
locked: <true/false>
|
||||
lock_reason: <reason or empty>
|
||||
- ...
|
||||
```
|
||||
Derive these fields from `git worktree list --porcelain -z` — its `worktree`/`branch`/`HEAD`/`locked` lines map directly to `path`/`branch`/`commit`/`locked`+`lock_reason`.
|
||||
|
||||
For single operations, include the operation result (e.g., `created: true`, `removed: true`, `moved: true`).
|
||||
|
||||
For multi-step flows spanning branch strategy plus worktree setup, compose with the `git-workflow` skill — it handles the broader orchestration, this skill handles the worktree mechanics.
|
||||
Derive those fields from `git worktree list --porcelain -z`. For a single
|
||||
operation, report its outcome instead — `created: true`, `moved: true`,
|
||||
`removed: true`.
|
||||
|
||||
@@ -10,4 +10,4 @@ This directory contains provenance metadata and research sources for the `git-wo
|
||||
## Files
|
||||
|
||||
- `sources.md` — Extracted research sources and their contributing documents
|
||||
- `worktrees.md` — Full `add` flag table, sparse-checkout setup, removable-media locking, remote-branch disambiguation, and the config key reference
|
||||
- `worktrees.md` — Shared vs. per-worktree state, the `add` command forms, the full `add` flag table, orphan branches, sparse-checkout setup, removable-media locking, remote-branch disambiguation, where to run `repair` from, the config key reference, and the emergency-fix and PR-review workflow patterns
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
- **Research doc:** plugins/git/docs/research/docs/git/worktrees.md (whole-document reference — covers `## Concept Overview`, `## Key Commands`, `## Workflow Patterns`, `## Common Gotchas`, `## Configuration`)
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Concept, Gotchas, Common Operations, Worked Examples, Return Format)
|
||||
- references/worktrees.md (full `add` flag table, sparse-checkout, removable media, remote disambiguation, configuration)
|
||||
- SKILL.md (Gotchas, Step 1 dispatch table and per-operation gates, Step 2 report format)
|
||||
- references/worktrees.md (shared vs. per-worktree state, `add` command forms, full `add` flag table, orphan branches, sparse-checkout, removable media, remote disambiguation, `repair` invocation directory, configuration, workflow patterns)
|
||||
|
||||
@@ -4,6 +4,27 @@ 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/<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
|
||||
|
||||
```bash
|
||||
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 |
|
||||
@@ -52,6 +73,16 @@ 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
|
||||
|
||||
```bash
|
||||
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 |
|
||||
@@ -61,3 +92,25 @@ For ambiguous names across remotes, `checkout.defaultRemote` config disambiguate
|
||||
| `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
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user