From 3dd5387671837a55a837b7fdcf2e702fe9a50587 Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Sun, 30 Aug 2026 13:10:53 +0000 Subject: [PATCH] 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. --- .../git/.apm/skills/git-worktrees/README.md | 6 +- .../git/.apm/skills/git-worktrees/SKILL.md | 132 +++++------------- .../skills/git-worktrees/references/README.md | 2 +- .../git-worktrees/references/sources.md | 4 +- .../git-worktrees/references/worktrees.md | 53 +++++++ plugins/git/skills/git-worktrees/README.md | 6 +- plugins/git/skills/git-worktrees/SKILL.md | 132 +++++------------- .../skills/git-worktrees/references/README.md | 2 +- .../git-worktrees/references/sources.md | 4 +- .../git-worktrees/references/worktrees.md | 53 +++++++ 10 files changed, 190 insertions(+), 204 deletions(-) diff --git a/plugins/git/.apm/skills/git-worktrees/README.md b/plugins/git/.apm/skills/git-worktrees/README.md index 14bb54b..2042f80 100644 --- a/plugins/git/.apm/skills/git-worktrees/README.md +++ b/plugins/git/.apm/skills/git-worktrees/README.md @@ -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 | diff --git a/plugins/git/.apm/skills/git-worktrees/SKILL.md b/plugins/git/.apm/skills/git-worktrees/SKILL.md index 5d735a5..51a1980 100644 --- a/plugins/git/.apm/skills/git-worktrees/SKILL.md +++ b/plugins/git/.apm/skills/git-worktrees/SKILL.md @@ -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//`. 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 -cd -``` -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 ` | +| Create on a new branch | `git worktree add -b ` | +| Create on the branch named after the path basename | `git worktree add ` — 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 ` | +| Create tracking a remote branch | `git worktree add /` | +| Throwaway experiment, no branch | `git worktree add -d ` | +| List | `git worktree list -v`, or `--porcelain -z` to parse | +| Lock or unlock | `git worktree lock [--reason ] ` / `git worktree unlock ` | +| Move | `git worktree move ` | +| Remove | `git worktree remove ` | +| Prune stale metadata | `git worktree prune --dry-run`, then without the flag | +| Repair after a manual move | `git worktree repair []` — from the main worktree to fix all links, or from the moved worktree itself | -**Create-or-reset a branch**: `git worktree add -B ` — 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 / -``` -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 -# Cannot move: main worktree, worktrees with submodules -# To override safeguards: -f; to override locked state too: -ff -``` - -**Remove a worktree**: -```bash -git worktree remove # only if clean -git worktree remove -f # force-remove unclean -git worktree remove -ff # 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 # 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: @@ -116,10 +58,8 @@ worktrees: commit: locked: lock_reason: - - ... ``` -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`. diff --git a/plugins/git/.apm/skills/git-worktrees/references/README.md b/plugins/git/.apm/skills/git-worktrees/references/README.md index c8a0777..f5f6037 100644 --- a/plugins/git/.apm/skills/git-worktrees/references/README.md +++ b/plugins/git/.apm/skills/git-worktrees/references/README.md @@ -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 diff --git a/plugins/git/.apm/skills/git-worktrees/references/sources.md b/plugins/git/.apm/skills/git-worktrees/references/sources.md index b92c420..54fecc3 100644 --- a/plugins/git/.apm/skills/git-worktrees/references/sources.md +++ b/plugins/git/.apm/skills/git-worktrees/references/sources.md @@ -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) diff --git a/plugins/git/.apm/skills/git-worktrees/references/worktrees.md b/plugins/git/.apm/skills/git-worktrees/references/worktrees.md index b938211..ebade88 100644 --- a/plugins/git/.apm/skills/git-worktrees/references/worktrees.md +++ b/plugins/git/.apm/skills/git-worktrees/references/worktrees.md @@ -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//`. 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 | @@ -52,6 +73,16 @@ 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 | @@ -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 +``` diff --git a/plugins/git/skills/git-worktrees/README.md b/plugins/git/skills/git-worktrees/README.md index 14bb54b..2042f80 100644 --- a/plugins/git/skills/git-worktrees/README.md +++ b/plugins/git/skills/git-worktrees/README.md @@ -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 | diff --git a/plugins/git/skills/git-worktrees/SKILL.md b/plugins/git/skills/git-worktrees/SKILL.md index 5d735a5..51a1980 100644 --- a/plugins/git/skills/git-worktrees/SKILL.md +++ b/plugins/git/skills/git-worktrees/SKILL.md @@ -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//`. 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 -cd -``` -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 ` | +| Create on a new branch | `git worktree add -b ` | +| Create on the branch named after the path basename | `git worktree add ` — 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 ` | +| Create tracking a remote branch | `git worktree add /` | +| Throwaway experiment, no branch | `git worktree add -d ` | +| List | `git worktree list -v`, or `--porcelain -z` to parse | +| Lock or unlock | `git worktree lock [--reason ] ` / `git worktree unlock ` | +| Move | `git worktree move ` | +| Remove | `git worktree remove ` | +| Prune stale metadata | `git worktree prune --dry-run`, then without the flag | +| Repair after a manual move | `git worktree repair []` — from the main worktree to fix all links, or from the moved worktree itself | -**Create-or-reset a branch**: `git worktree add -B ` — 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 / -``` -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 -# Cannot move: main worktree, worktrees with submodules -# To override safeguards: -f; to override locked state too: -ff -``` - -**Remove a worktree**: -```bash -git worktree remove # only if clean -git worktree remove -f # force-remove unclean -git worktree remove -ff # 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 # 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: @@ -116,10 +58,8 @@ worktrees: commit: locked: lock_reason: - - ... ``` -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`. diff --git a/plugins/git/skills/git-worktrees/references/README.md b/plugins/git/skills/git-worktrees/references/README.md index c8a0777..f5f6037 100644 --- a/plugins/git/skills/git-worktrees/references/README.md +++ b/plugins/git/skills/git-worktrees/references/README.md @@ -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 diff --git a/plugins/git/skills/git-worktrees/references/sources.md b/plugins/git/skills/git-worktrees/references/sources.md index b92c420..54fecc3 100644 --- a/plugins/git/skills/git-worktrees/references/sources.md +++ b/plugins/git/skills/git-worktrees/references/sources.md @@ -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) diff --git a/plugins/git/skills/git-worktrees/references/worktrees.md b/plugins/git/skills/git-worktrees/references/worktrees.md index b938211..ebade88 100644 --- a/plugins/git/skills/git-worktrees/references/worktrees.md +++ b/plugins/git/skills/git-worktrees/references/worktrees.md @@ -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//`. 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 | @@ -52,6 +73,16 @@ 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 | @@ -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 +```