An independent audit of the ADR-0020 retrofit (issue #99) found that git-submodules, git-worktrees, and gitea-files each collapsed their description length correctly during retrofit but left the capability clause as a verb enumeration (e.g. "Create, list, lock, move, remove, prune, or repair") instead of ADR-0020's required single clause. The deterministic char-count gate can't catch this — it's a qualitative rubric violation the retrofit commits' own messages never claimed to address, only measurable length/word-count fixes. Validated clean via skill-audit and skill-size-check after the fix; boundary clauses and routing targets left untouched. Refs #99
66 lines
3.5 KiB
Markdown
66 lines
3.5 KiB
Markdown
---
|
|
name: git-worktrees
|
|
|
|
description: >
|
|
Use when working on several branches at once without stashing —
|
|
manages the full lifecycle of a git worktree.
|
|
Not ordinary branch switching or checkout -> `git-branches`.
|
|
Not interactive multi-step git guidance -> `git-workflow`.
|
|
|
|
metadata:
|
|
category: git
|
|
source_keys:
|
|
- git-scm-worktree-docs
|
|
---
|
|
|
|
## Gotchas
|
|
|
|
- **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.
|
|
|
|
## Step 1 — Dispatch
|
|
|
|
| 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 |
|
|
|
|
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`.
|
|
|
|
Gates:
|
|
|
|
- **`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.
|
|
|
|
## Step 2 — Report
|
|
|
|
```yaml
|
|
worktrees:
|
|
- path: <directory-path>
|
|
branch: <branch-name>
|
|
commit: <short-hash>
|
|
locked: <true/false>
|
|
lock_reason: <reason or empty>
|
|
```
|
|
|
|
Derive those fields from `git worktree list --porcelain -z`. For a single
|
|
operation, report its outcome instead — `created: true`, `moved: true`,
|
|
`removed: true`.
|