refactor(skills): retrofit the corpus to the ADR-0020 context contract #129
@@ -24,18 +24,19 @@ metadata:
|
||||
|
||||
| Operation | Run |
|
||||
|---|---|
|
||||
| Create on an existing branch | `git worktree add <path> <branch>` |
|
||||
| Create on a branch that already exists locally | `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>` |
|
||||
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** when `<branch>` has no local copy (gate below) |
|
||||
| Throwaway experiment, no branch | `git worktree add -d <path>` — detached HEAD |
|
||||
| **Never** `git worktree add <path> <remote>/<branch>` | That ref resolves, so the shortcut never fires and you get **a detached HEAD, no branch, no upstream**. Commits there go unreachable once HEAD moves, and `git push` needs an explicit refspec. Use the tracking row above |
|
||||
| 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 |
|
||||
| Repair after a manual move | `git worktree repair` — in the main worktree if *it* moved, or inside a linked worktree that moved. `git worktree repair <path>...` — from any worktree, naming each moved linked worktree's new path |
|
||||
|
||||
If the operation needs anything the table does not carry — the full `add` flag
|
||||
table, orphan branches, sparse-checkout, locking for removable media, remote
|
||||
@@ -47,6 +48,7 @@ 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` — the bare-name tracking shortcut needs exactly one remote.** `git worktree add <path> <branch>` sets up tracking only when `<branch>` is absent locally, no `-b`/`-B`/`-d` is given, and exactly one remote carries the name. With several, it fires only if `checkout.defaultRemote` names one. When the remote is ambiguous or unknown, use `--track -b`.
|
||||
- **`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
|
||||
|
||||
@@ -15,16 +15,29 @@ or moved. Every other worktree is a **linked worktree** created by `git worktree
|
||||
## `add` forms
|
||||
|
||||
```bash
|
||||
git worktree add <path> <branch> # check out an existing branch — non-destructive
|
||||
git worktree add <path> <branch> # <branch> exists locally: check it out — 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 --track -b <branch> <path> <remote>/<branch>
|
||||
# new local branch tracking the remote — always works
|
||||
git worktree add <path> <branch> # <branch> absent locally and in exactly one remote:
|
||||
# Git expands this to the --track -b form above
|
||||
git worktree add -d <path> # detached HEAD, no branch
|
||||
```
|
||||
|
||||
The same `git worktree add <path> <branch>` spelling appears twice above and does two
|
||||
different things: it checks out a local branch when one exists, and only otherwise falls
|
||||
through to the remote-tracking shortcut. Read the local branch list before relying on either.
|
||||
|
||||
**Do not write `git worktree add <path> <remote>/<branch>`.** A remote-tracking ref resolves as a
|
||||
commit-ish, so the tracking shortcut never fires and the worktree lands on a **detached HEAD with
|
||||
no local branch and no upstream** — commits there go unreachable once HEAD moves or the worktree is
|
||||
removed, and `git push` fails without an explicit refspec. That spelling is correct only as the
|
||||
final argument of the `--track -b` form.
|
||||
|
||||
## Full `add` flag table
|
||||
|
||||
| Flag | Meaning |
|
||||
@@ -69,19 +82,40 @@ git worktree unlock <path> # when reconnected
|
||||
## Remote-branch disambiguation
|
||||
|
||||
```bash
|
||||
git worktree add <path> <remote>/<branch>
|
||||
git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
|
||||
git worktree add <path> <branch> # shortcut: needs one clear remote
|
||||
```
|
||||
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.
|
||||
The shortcut fires only when `<branch>` is not found locally, none of `-b`/`-B`/`--detach` were
|
||||
given, and a tracking branch of that name exists in exactly one remote. When several remotes carry
|
||||
the name, `checkout.defaultRemote` picks one for disambiguation purposes; with no such setting the
|
||||
shortcut has no single remote to resolve against and does not apply.
|
||||
|
||||
`--guess-remote` covers the *other* spelling — `git worktree add <path>` with no `<commit-ish>` at
|
||||
all. It bases the new branch on the remote-tracking branch matching `$(basename <path>)` when
|
||||
exactly one remote has it, and marks that branch as upstream. Its default comes from the
|
||||
`worktree.guessRemote` config.
|
||||
|
||||
## 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
|
||||
git worktree repair # the MAIN worktree moved: run it there to reconnect every linked
|
||||
# worktree back to the main worktree
|
||||
git worktree repair # a LINKED worktree moved: run it inside that recently-moved worktree
|
||||
git worktree repair <path>... # reconnect a specific linked worktree — runnable from any worktree,
|
||||
# naming each moved tree's new path
|
||||
```
|
||||
|
||||
`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.
|
||||
Which form applies depends on what moved:
|
||||
|
||||
| What moved | Remedy |
|
||||
|---|---|
|
||||
| The main worktree (or bare repo) | `git worktree repair` in the main worktree |
|
||||
| One linked worktree | `git worktree repair` inside that worktree |
|
||||
| Several linked worktrees | `git worktree repair <path>...` from any worktree, listing each new path |
|
||||
| Both main and linked worktrees | `git worktree repair <path>...` in the main worktree, naming each linked worktree's new path — this restores the connections in both directions |
|
||||
|
||||
Only the no-argument form is tied to the current directory. The `<path>...` form is not — it
|
||||
reestablishes the connection to every path you name, run from any worktree.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -111,6 +145,10 @@ git worktree remove ../temp
|
||||
context switch:
|
||||
|
||||
```bash
|
||||
git worktree add ../review-pr-123 origin/feature-xyz
|
||||
git worktree add ../review-pr-123 origin/feature-xyz # detached HEAD — read-only review
|
||||
git worktree add --track -b feature-xyz ../review-pr-123 origin/feature-xyz # if you will commit
|
||||
# open ../review-pr-123 in a second editor window or terminal
|
||||
```
|
||||
|
||||
Pick the second form the moment you intend to push anything back: the first leaves no branch to
|
||||
push and no upstream to push to.
|
||||
|
||||
@@ -24,18 +24,19 @@ metadata:
|
||||
|
||||
| Operation | Run |
|
||||
|---|---|
|
||||
| Create on an existing branch | `git worktree add <path> <branch>` |
|
||||
| Create on a branch that already exists locally | `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>` |
|
||||
| Create a local branch tracking a remote one | `git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** when `<branch>` has no local copy (gate below) |
|
||||
| Throwaway experiment, no branch | `git worktree add -d <path>` — detached HEAD |
|
||||
| **Never** `git worktree add <path> <remote>/<branch>` | That ref resolves, so the shortcut never fires and you get **a detached HEAD, no branch, no upstream**. Commits there go unreachable once HEAD moves, and `git push` needs an explicit refspec. Use the tracking row above |
|
||||
| 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 |
|
||||
| Repair after a manual move | `git worktree repair` — in the main worktree if *it* moved, or inside a linked worktree that moved. `git worktree repair <path>...` — from any worktree, naming each moved linked worktree's new path |
|
||||
|
||||
If the operation needs anything the table does not carry — the full `add` flag
|
||||
table, orphan branches, sparse-checkout, locking for removable media, remote
|
||||
@@ -47,6 +48,7 @@ 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` — the bare-name tracking shortcut needs exactly one remote.** `git worktree add <path> <branch>` sets up tracking only when `<branch>` is absent locally, no `-b`/`-B`/`-d` is given, and exactly one remote carries the name. With several, it fires only if `checkout.defaultRemote` names one. When the remote is ambiguous or unknown, use `--track -b`.
|
||||
- **`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
|
||||
|
||||
@@ -15,16 +15,29 @@ or moved. Every other worktree is a **linked worktree** created by `git worktree
|
||||
## `add` forms
|
||||
|
||||
```bash
|
||||
git worktree add <path> <branch> # check out an existing branch — non-destructive
|
||||
git worktree add <path> <branch> # <branch> exists locally: check it out — 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 --track -b <branch> <path> <remote>/<branch>
|
||||
# new local branch tracking the remote — always works
|
||||
git worktree add <path> <branch> # <branch> absent locally and in exactly one remote:
|
||||
# Git expands this to the --track -b form above
|
||||
git worktree add -d <path> # detached HEAD, no branch
|
||||
```
|
||||
|
||||
The same `git worktree add <path> <branch>` spelling appears twice above and does two
|
||||
different things: it checks out a local branch when one exists, and only otherwise falls
|
||||
through to the remote-tracking shortcut. Read the local branch list before relying on either.
|
||||
|
||||
**Do not write `git worktree add <path> <remote>/<branch>`.** A remote-tracking ref resolves as a
|
||||
commit-ish, so the tracking shortcut never fires and the worktree lands on a **detached HEAD with
|
||||
no local branch and no upstream** — commits there go unreachable once HEAD moves or the worktree is
|
||||
removed, and `git push` fails without an explicit refspec. That spelling is correct only as the
|
||||
final argument of the `--track -b` form.
|
||||
|
||||
## Full `add` flag table
|
||||
|
||||
| Flag | Meaning |
|
||||
@@ -69,19 +82,40 @@ git worktree unlock <path> # when reconnected
|
||||
## Remote-branch disambiguation
|
||||
|
||||
```bash
|
||||
git worktree add <path> <remote>/<branch>
|
||||
git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
|
||||
git worktree add <path> <branch> # shortcut: needs one clear remote
|
||||
```
|
||||
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.
|
||||
The shortcut fires only when `<branch>` is not found locally, none of `-b`/`-B`/`--detach` were
|
||||
given, and a tracking branch of that name exists in exactly one remote. When several remotes carry
|
||||
the name, `checkout.defaultRemote` picks one for disambiguation purposes; with no such setting the
|
||||
shortcut has no single remote to resolve against and does not apply.
|
||||
|
||||
`--guess-remote` covers the *other* spelling — `git worktree add <path>` with no `<commit-ish>` at
|
||||
all. It bases the new branch on the remote-tracking branch matching `$(basename <path>)` when
|
||||
exactly one remote has it, and marks that branch as upstream. Its default comes from the
|
||||
`worktree.guessRemote` config.
|
||||
|
||||
## 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
|
||||
git worktree repair # the MAIN worktree moved: run it there to reconnect every linked
|
||||
# worktree back to the main worktree
|
||||
git worktree repair # a LINKED worktree moved: run it inside that recently-moved worktree
|
||||
git worktree repair <path>... # reconnect a specific linked worktree — runnable from any worktree,
|
||||
# naming each moved tree's new path
|
||||
```
|
||||
|
||||
`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.
|
||||
Which form applies depends on what moved:
|
||||
|
||||
| What moved | Remedy |
|
||||
|---|---|
|
||||
| The main worktree (or bare repo) | `git worktree repair` in the main worktree |
|
||||
| One linked worktree | `git worktree repair` inside that worktree |
|
||||
| Several linked worktrees | `git worktree repair <path>...` from any worktree, listing each new path |
|
||||
| Both main and linked worktrees | `git worktree repair <path>...` in the main worktree, naming each linked worktree's new path — this restores the connections in both directions |
|
||||
|
||||
Only the no-argument form is tied to the current directory. The `<path>...` form is not — it
|
||||
reestablishes the connection to every path you name, run from any worktree.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -111,6 +145,10 @@ git worktree remove ../temp
|
||||
context switch:
|
||||
|
||||
```bash
|
||||
git worktree add ../review-pr-123 origin/feature-xyz
|
||||
git worktree add ../review-pr-123 origin/feature-xyz # detached HEAD — read-only review
|
||||
git worktree add --track -b feature-xyz ../review-pr-123 origin/feature-xyz # if you will commit
|
||||
# open ../review-pr-123 in a second editor window or terminal
|
||||
```
|
||||
|
||||
Pick the second form the moment you intend to push anything back: the first leaves no branch to
|
||||
push and no upstream to push to.
|
||||
|
||||
Reference in New Issue
Block a user