chore(plugins): sync generated content mirrors

Regenerate plugins/*/skills/ from plugins/*/.apm/ after the previous
four commits, via scripts/sync-plugin-content.sh --all. The mirror is
generated output (ADR-0017) that check-plugin-content-sync's pre-push
hook diffs against .apm/; nothing here is hand-edited.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeH8SCbcrCAQrtymkNuhKP
This commit is contained in:
2026-09-07 20:43:51 +00:00
parent 09eea5e7ab
commit af8b46cd57
45 changed files with 467 additions and 201 deletions

View File

@@ -9,6 +9,7 @@ description: >
Not a Gitea remote's branches -> `gitea-branches`.
metadata:
version: "1.0.0"
category: git
source_keys:
- context7-git-htmldocs
@@ -20,7 +21,7 @@ metadata:
## Gotchas
- **Uncommitted changes abort a switch.** `git switch` refuses rather than clobbering conflicting local edits. Offer to stash and retry — forcing the checkout past it is how work disappears.
- **A branch and a tag can carry the same name.** Detect it before acting — `git branch --list <name>` and `git tag --list <name>`; output from both means the name is ambiguous. Prefer `git switch` over `git checkout`, and where a command accepts either ref, disambiguate with `refs/heads/<name>` or `refs/tags/<name>`.
- **A branch and a tag can carry the same name.** Detect it before acting — `rtk git branch --list <name>` and `rtk git tag --list <name>`; output from both means the name is ambiguous. Prefer `git switch` over `git checkout`, and where a command accepts either ref, disambiguate with `refs/heads/<name>` or `refs/tags/<name>`.
- **`main` and `master` are a refusal, not a gate.** Force-pushing, force-deleting, or renaming them is rejected even when the caller passes `confirm: true` — no flag makes the remote's history recoverable. Offer a new branch instead.
## Step 1 — Determine the branching pattern
@@ -51,7 +52,7 @@ These gates are passable. The `main`/`master` refusal in Gotchas is not.
## Step 4 — Set tracking
A new branch's first push must be `git push -u origin <branch>`. The push itself is `git-remotes`' — every remote-side gate lives there, which is why Step 2's remote-delete row hands off the same way — but the upstream requirement originates here, so carry it in the handoff. Without an upstream, later pushes and pulls either fail or silently target the wrong remote branch, and the caller has no way to tell which happened.
A new branch's first push must be `rtk git push -u origin <branch>`. The push itself is `git-remotes`' — every remote-side gate lives there, which is why Step 2's remote-delete row hands off the same way — but the upstream requirement originates here, so carry it in the handoff. Without an upstream, later pushes and pulls either fail or silently target the wrong remote branch, and the caller has no way to tell which happened.
## Step 5 — Return a structured result

View File

@@ -8,21 +8,21 @@ source_keys:
One command per action. Where two forms exist, the first is the default and the second the escape
hatch.
- **create** — `git switch -c <branch> <base>`. Base comes from the config's `base_branch`
- **create** — `rtk git switch -c <branch> <base>`. Base comes from the config's `base_branch`
(`main` under GitHub Flow, usually `develop` under Gitflow).
- **switch** — `git switch <branch>` moves to an existing local branch; it aborts rather than
clobbering conflicting local changes. `git switch -` returns to the previous branch.
- **delete (local)** — `git branch -d <branch>` refuses when the branch holds unmerged commits,
which is why it is the default. `git branch -D <branch>` forces the deletion and discards that
- **switch** — `rtk git switch <branch>` moves to an existing local branch; it aborts rather than
clobbering conflicting local changes. `rtk git switch -` returns to the previous branch.
- **delete (local)** — `rtk git branch -d <branch>` refuses when the branch holds unmerged commits,
which is why it is the default. `rtk git branch -D <branch>` forces the deletion and discards that
work — only after the destructive-operation gates pass and `confirm: true` is set.
- **delete (remote)** — not this skill's. Deleting a remote branch is a push, and every remote-side
gate lives in `git-remotes`; hand it there rather than running the push from here. Its
`references/push.md` carries the command and the refspec form.
- **rename** — `git branch -m <old> <new>`.
- **list** — `git branch` (local), `-a` (local plus remote-tracking), `-r` (remote-tracking only),
- **rename** — `rtk git branch -m <old> <new>`.
- **list** — `rtk git branch` (local), `-a` (local plus remote-tracking), `-r` (remote-tracking only),
`--merged` / `--no-merged` (filter by merge status into the current branch).
- **track** — `git branch --set-upstream-to=origin/<branch>` sets an upstream without pushing.
`git branch -vv` shows the tracking state of every local branch.
- **track** — `rtk git branch --set-upstream-to=origin/<branch>` sets an upstream without pushing.
`rtk git branch -vv` shows the tracking state of every local branch.
## get-intent
@@ -40,17 +40,17 @@ intent is worse than one built on none.
A switch aborts rather than clobbering conflicting local changes (see Gotchas). Stash is the way
past it: it shelves the working tree and index so the branch pointer can move.
- **save** — `git stash push -m "<message>"`. Add `-u` to include untracked files; verified on Git
- **save** — `rtk git stash push -m "<message>"`. Add `-u` to include untracked files; verified on Git
2.39.5, a plain `push` leaves them in place, and a plain `push` with *only* untracked changes
reports `No local changes to save` and stashes nothing. Bare `git stash` is `push` with no message.
- **restore** — `git stash pop` applies the newest entry and deletes it. `git stash apply stash@{n}`
- **restore** — `rtk git stash pop` applies the newest entry and deletes it. `rtk git stash apply stash@{n}`
applies without deleting, for replaying one shelf onto more than one branch.
- **list** — `git stash list`; `git stash show -p stash@{n}` prints that entry's diff.
- **drop** — `git stash drop stash@{n}` deletes one entry. `git stash clear` deletes all of them
- **list** — `rtk git stash list`; `rtk git stash show -p stash@{n}` prints that entry's diff.
- **drop** — `rtk git stash drop stash@{n}` deletes one entry. `rtk git stash clear` deletes all of them
and nothing recovers them — confirm before running it.
- **branch from a stash** — `git stash branch <branch> stash@{n}` creates a branch at the commit the
- **branch from a stash** — `rtk git stash branch <branch> stash@{n}` creates a branch at the commit the
stash was taken from and pops it there. Use it when the stash no longer applies to the current tip.
**A conflicting `pop` keeps the entry.** Verified on 2.39.5: it exits 1, writes conflict markers,
prints "The stash entry is kept in case you need it again", and `git stash list` still shows it.
Resolve, `git add`, then `git stash drop` the entry by hand — otherwise it silently accumulates.
Resolve, `rtk git add`, then `rtk git stash drop` the entry by hand — otherwise it silently accumulates.

View File

@@ -8,9 +8,9 @@ source_keys:
The two-dot and three-dot forms mean different things and are easy to swap by accident — check the
direction before reporting a result.
- `git log main..feature` — commits on `feature` that are not on `main`.
- `git log feature..main` — the reverse direction: commits on `main` not on `feature`.
- `git log --left-right main...feature` — both diverging sets at once (symmetric difference).
- `git diff main...feature` — the diff from the common ancestor to `feature`'s tip, which is what
- `rtk git log main..feature` — commits on `feature` that are not on `main`.
- `rtk git log feature..main` — the reverse direction: commits on `main` not on `feature`.
- `rtk git log --left-right main...feature` — both diverging sets at once (symmetric difference).
- `rtk git diff main...feature` — the diff from the common ancestor to `feature`'s tip, which is what
a reviewer sees, rather than the diff between the two tips.
- `git merge-base main feature` — print the common ancestor commit.
- `rtk git merge-base main feature` — print the common ancestor commit.

View File

@@ -9,22 +9,22 @@ source_keys:
Scope is fast-forward and merge-commit mechanics plus conflict resolution. Rebase and cherry-pick
belong to `git-commits`; revert to `git-history`.
- **Fast-forward** — `git merge <branch>` advances the pointer with no merge commit when the
- **Fast-forward** — `rtk git merge <branch>` advances the pointer with no merge commit when the
target has not diverged.
- **True merge** — `git merge --no-ff <branch>` forces a merge commit even when a fast-forward is
- **True merge** — `rtk git merge --no-ff <branch>` forces a merge commit even when a fast-forward is
possible. Gitflow requires it on every supporting-branch merge.
- **Squash merge** — `git merge --squash <branch>` stages the combined diff without committing.
Follow it with a `git commit`.
- **Octopus merge** — `git merge branch-a branch-b branch-c` merges more than two branches at
- **Squash merge** — `rtk git merge --squash <branch>` stages the combined diff without committing.
Follow it with a `rtk git commit`.
- **Octopus merge** — `rtk git merge branch-a branch-b branch-c` merges more than two branches at
once, but fails outright on any conflict. Use sequential two-way merges when conflicts are
likely.
## Conflict resolution
When Git cannot auto-merge it writes conflict markers and stops mid-merge. Run `git status` to
list the conflicted files, edit each to resolve its markers, then `git add <file>` and
`git merge --continue`.
When Git cannot auto-merge it writes conflict markers and stops mid-merge. Run `rtk git status` to
list the conflicted files, edit each to resolve its markers, then `rtk git add <file>` and
`rtk git merge --continue`.
- `git merge --abort` restores the pre-merge state.
- `git mergetool` opens the configured merge tool.
- `git diff --diff-filter=U` shows only the still-conflicted files.
- `rtk git merge --abort` restores the pre-merge state.
- `rtk git mergetool` opens the configured merge tool.
- `rtk git diff --diff-filter=U` shows only the still-conflicted files.

View File

@@ -8,6 +8,7 @@ description: >
`git-commits`. Not a Gitea server's history -> `gitea-branches`.
metadata:
version: "1.0.0"
category: git
source_keys:
- git-scm-bisect-docs
@@ -34,13 +35,13 @@ allowed-tools: Bash
## Step 2 — Query the log
Default to `git log --oneline`, then narrow by whatever is known:
Default to `rtk git log --oneline`, then narrow by whatever is known:
- **Content**: `git log -S"string"`, or `-G"regex"` to match any diff line. `--pickaxe-regex` makes the `-S` argument a POSIX ERE; `--pickaxe-all` shows every file in a matching changeset.
- **A line or function**: `git log -L <start>,<end>:<file>` or `git log -L :<function>:<file>`. Confirm the range resolves before reporting on it — an off-by-one silently omits the target.
- **A file across renames**: `git log --follow -- <file>`. Without `--follow` the history stops at the rename boundary.
- **Content**: `rtk git log -S"string"`, or `-G"regex"` to match any diff line. `--pickaxe-regex` makes the `-S` argument a POSIX ERE; `--pickaxe-all` shows every file in a matching changeset.
- **A line or function**: `rtk git log -L <start>,<end>:<file>` or `rtk git log -L :<function>:<file>`. Confirm the range resolves before reporting on it — an off-by-one silently omits the target.
- **A file across renames**: `rtk git log --follow -- <file>`. Without `--follow` the history stops at the rename boundary.
- **Mainline only**: `--first-parent` follows the integration branch and skips commits merged in from side branches.
- **Structured output**: `git log --format="%h | %s | %an (%ar)"`.
- **Structured output**: `rtk git log --format="%h | %s | %an (%ar)"`.
If you need the placeholder catalogue, format presets, `--diff-filter` letters, full `-L` syntax, ancestry filters, pickaxe binary-file behaviour, or `git diff` output-control flags such as `--stat`, `--word-diff` and the whitespace options, read `references/git-log-format.md`.
@@ -49,8 +50,8 @@ If you need the placeholder catalogue, format presets, `--diff-filter` letters,
Offer the operation and its consequence; run it only once the user has chosen.
- Backporting the commit to another branch is a cherry-pick, and cherry-pick is `git-commits`' — it owns the destination-branch check, the `rtk git` wrapper and the `--abort` path. Hand it the SHA; do not run `git cherry-pick` from here.
- `git revert <commit>` adds a new commit undoing it — for un-applying merged work without rewriting history.
- `git blame <file>` attributes each line to the commit that last touched it, when the question is which commit introduced one specific line.
- `rtk git revert <commit>` adds a new commit undoing it — for un-applying merged work without rewriting history.
- `rtk git blame <file>` attributes each line to the commit that last touched it, when the question is which commit introduced one specific line.
For diff output control on the located commit, read `references/git-log-format.md`.

View File

@@ -12,43 +12,43 @@ or line range to search the log for. Binary search reduces the trials from O(N)
## Manual flow
```bash
git bisect start
git bisect bad [HEAD] # mark current (or specified) as broken
git bisect good <commit> # mark known-good baseline
rtk git bisect start
rtk git bisect bad [HEAD] # mark current (or specified) as broken
rtk git bisect good <commit> # mark known-good baseline
# Git checks out the midpoint; test it
git bisect good # test passes
git bisect bad # test fails
rtk git bisect good # test passes
rtk git bisect bad # test fails
# Repeat until git reports "X is the first bad commit"
git bisect reset # return to the original HEAD
rtk git bisect reset # return to the original HEAD
```
## Automated
With a test command available, use `git bisect run <cmd>`. Git reads the exit code: `0` good,
With a test command available, use `rtk git bisect run <cmd>`. Git reads the exit code: `0` good,
`1`–`124` bad, `125` skip (build broken), `126`–`127` POSIX shell errors, treated as bad, and
`128` or above aborts the session outright rather than marking the commit bad.
## Untestable commits
`git bisect skip` excludes a commit that cannot be built or tested without deciding good or bad
`rtk git bisect skip` excludes a commit that cannot be built or tested without deciding good or bad
for it. When the first bad commit is adjacent to a skipped range, bisect reports that it cannot
pinpoint the culprit and lists the candidates — that is the precise answer the skip range allows,
not a failure.
## Undoing a wrong good/bad call
`git bisect log` prints the session's decision history. Save it, edit out the mistaken entry, and
`rtk git bisect log` prints the session's decision history. Save it, edit out the mistaken entry, and
resume from the corrected log rather than restarting the search:
```bash
git bisect log > bisect.log
rtk git bisect log > bisect.log
# edit bisect.log, removing the wrong decision
git bisect reset && git bisect replay bisect.log
rtk git bisect reset && rtk git bisect replay bisect.log
```
## Narrowing and speeding up
- `git bisect start HEAD v1.2 -- src/` restricts bisection to a path, cutting the trial count.
- `rtk git bisect start HEAD v1.2 -- src/` restricts bisection to a path, cutting the trial count.
- `--no-checkout` updates the `BISECT_HEAD` ref instead of checking out a working tree — useful
for tests that do not need one, and automatic in bare repos.
- `--first-parent` follows only first parents at merges, finding the integration commit that
@@ -56,12 +56,12 @@ git bisect reset && git bisect replay bisect.log
## Inspecting the remaining candidates
`git bisect visualize` (alias `view`) opens the suspects in gitk, falling back to `git log` when
`rtk git bisect visualize` (alias `view`) opens the suspects in gitk, falling back to `git log` when
no graphical display is detected. Add `--stat` or `-p` for a diffstat or full patches.
## Hunting a non-bug property change
`git bisect start --term-new <new> --term-old <old>` searches for any property change — a
`rtk git bisect start --term-new <new> --term-old <old>` searches for any property change — a
performance regression, say — instead of a bug. Use the custom terms in place of `good` and `bad`
for the rest of the session.

View File

@@ -116,15 +116,15 @@ source_keys:
**`-S<string>`** — finds commits where the **count** of `<string>` changed (i.e. the string was added or removed net). Does not match commits where the string merely appears in a diff hunk without a count change.
```bash
git log -S"my_function"
git log -S"my_function" --pickaxe-regex # treat as POSIX ERE
git log -S"my_function" --pickaxe-all # show all files in matching changesets
rtk git log -S"my_function"
rtk git log -S"my_function" --pickaxe-regex # treat as POSIX ERE
rtk git log -S"my_function" --pickaxe-all # show all files in matching changesets
```
**`-G<regex>`** — finds commits where any added or removed **line** in the patch matches `<regex>`. Broader than `-S`: matches whenever the pattern appears in diff text regardless of count.
```bash
git log -G"frotz\(nitfol"
rtk git log -G"frotz\(nitfol"
```
**Critical distinction:** given a diff that removes one occurrence of `foo` and adds one occurrence of `foo` (net change = 0):
@@ -151,8 +151,8 @@ Selects commits (in `git log`) or files (in `git diff`) by change type:
Lowercase letters **exclude** that type:
```bash
git log --diff-filter=ad # exclude added and deleted files
git log --diff-filter=M # only show commits with modified files
rtk git log --diff-filter=ad # exclude added and deleted files
rtk git log --diff-filter=M # only show commits with modified files
```
`C` and `R` only appear when copy/rename detection is enabled (`-C`, `-M` flags or `diff.renames` config).
@@ -162,10 +162,10 @@ git log --diff-filter=M # only show commits with modified files
Traces the evolution of a specific range of lines or a named function through commits. Implies `--patch`.
```bash
git log -L 10,20:file.txt
git log -L /start_pattern/,/end_pattern/:file.txt
git log -L :myfunction:src/app.c
git log -L /init/,+15:config.py # 15 lines after first match of /init/
rtk git log -L 10,20:file.txt
rtk git log -L /start_pattern/,/end_pattern/:file.txt
rtk git log -L :myfunction:src/app.c
rtk git log -L /init/,+15:config.py # 15 lines after first match of /init/
```
Range formats:
@@ -182,12 +182,12 @@ Limitations: incompatible with `--raw`, `--numstat`, `--shortstat`, `--name-only
## Graph and Ancestry Filters
```bash
git log --first-parent # at merges, follow only first parent (mainline evolution)
git log --merges # only merge commits (≥2 parents); equivalent to --min-parents=2
git log --no-merges # only non-merge commits; equivalent to --max-parents=1
git log --ancestry-path D..M # only commits actually on the path from D to M
git log --min-parents=<n> # include only commits with ≥ n parents
git log --max-parents=<n> # include only commits with ≤ n parents
rtk git log --first-parent # at merges, follow only first parent (mainline evolution)
rtk git log --merges # only merge commits (≥2 parents); equivalent to --min-parents=2
rtk git log --no-merges # only non-merge commits; equivalent to --max-parents=1
rtk git log --ancestry-path D..M # only commits actually on the path from D to M
rtk git log --min-parents=<n> # include only commits with ≥ n parents
rtk git log --max-parents=<n> # include only commits with ≤ n parents
```
`--ancestry-path` is significant: without it, `D..M` includes all commits reachable from M but not D — including side branches that merged into the path. With it, only commits directly between D and M are shown.
@@ -197,17 +197,17 @@ git log --max-parents=<n> # include only commits with ≤ n parents
### --stat
```bash
git diff --stat # diffstat: file names + ± bar
git diff --stat=<width>,<name-width>,<count>
git diff --compact-summary # alongside --stat: shows new/gone, +x/-x (executable), +l (symlink)
git diff --numstat # machine-readable: <added>\t<deleted>\t<path>; - for binary
rtk git diff --stat # diffstat: file names + ± bar
rtk git diff --stat=<width>,<name-width>,<count>
rtk git diff --compact-summary # alongside --stat: shows new/gone, +x/-x (executable), +l (symlink)
rtk git diff --numstat # machine-readable: <added>\t<deleted>\t<path>; - for binary
```
### --name-only / --name-status
```bash
git diff --name-only # only filenames, one per line
git diff --name-status # status letter + filename per line
rtk git diff --name-only # only filenames, one per line
rtk git diff --name-status # status letter + filename per line
```
`--name-status` uses the same status letters as `--diff-filter`.
@@ -215,10 +215,10 @@ git diff --name-status # status letter + filename per line
### --word-diff
```bash
git diff --word-diff # inline word-level diff with [-removed-] {+added+} markers
git diff --word-diff=color # color only, no markers
git diff --word-diff=porcelain # machine-readable: +/- prefixed lines, ~ for newlines
git diff --word-diff-regex=<re> # define what counts as a "word"
rtk git diff --word-diff # inline word-level diff with [-removed-] {+added+} markers
rtk git diff --word-diff=color # color only, no markers
rtk git diff --word-diff=porcelain # machine-readable: +/- prefixed lines, ~ for newlines
rtk git diff --word-diff-regex=<re> # define what counts as a "word"
```
### Whitespace Flags

View File

@@ -10,6 +10,7 @@ description: >
Not submodule pointers -> `git-submodules`.
metadata:
version: "1.0.0"
category: git
source_keys:
- git-scm-remote-docs
@@ -27,7 +28,7 @@ metadata:
## Step 1 — Clear the force-push gate
`main` and `master` are a hard refusal: decline a force-push targeting either, whatever confirmation accompanies it, because no local approval can restore what the remote loses. On any other branch, `git push --force` and `-f` run only after the caller passes `confirm: true` for that specific push — for a human caller, prompt instead of failing.
`main` and `master` are a hard refusal: decline a force-push targeting either, whatever confirmation accompanies it, because no local approval can restore what the remote loses. On any other branch, `rtk git push --force` and `-f` run only after the caller passes `confirm: true` for that specific push — for a human caller, prompt instead of failing.
## Step 2 — Dispatch

View File

@@ -11,19 +11,19 @@ Fetch **with no refspec** updates remote-tracking branches (`refs/remotes/<name>
That safety comes from the default refspec, not from `fetch` itself. Give it an explicit one and it writes to local branches: verified on Git 2.39.5, `git fetch origin main:probe` fast-forwarded the local `probe` branch, and a `+` prefix force-updates the destination, discarding whatever commits it held. Treat any `fetch` carrying a `<src>:<dst>` refspec as a branch update, not a read.
- **One remote**: `git fetch <remote>` — all branches
- **One branch**: `git fetch <remote> <branch>` — the result lands in `FETCH_HEAD`, not a tracking ref
- **All remotes**: `git fetch --all`
- **Prune properly**: `git fetch --all --prune --prune-tags` cleans stale branches *and* tags
- **Auto-prune**: `git config --global fetch.prune true` (or `remote.<name>.prune` to scope it to one remote), and `fetch.pruneTags true` for tags
- **One remote**: `rtk git fetch <remote>` — all branches
- **One branch**: `rtk git fetch <remote> <branch>` — the result lands in `FETCH_HEAD`, not a tracking ref
- **All remotes**: `rtk git fetch --all`
- **Prune properly**: `rtk git fetch --all --prune --prune-tags` cleans stale branches *and* tags
- **Auto-prune**: `rtk git config --global fetch.prune true` (or `remote.<name>.prune` to scope it to one remote), and `fetch.pruneTags true` for tags
## Shallow and partial fetch
```bash
git fetch --depth=<n> # deepen history, or create a shallow clone
git fetch --unshallow # convert a shallow clone to full history
git fetch --update-shallow # allow the fetch to update the shallow boundary
git fetch --refmap='' <remote> <branch> # fetch without updating any tracking ref (FETCH_HEAD only)
rtk git fetch --depth=<n> # deepen history, or create a shallow clone
rtk git fetch --unshallow # convert a shallow clone to full history
rtk git fetch --update-shallow # allow the fetch to update the shallow boundary
rtk git fetch --refmap='' <remote> <branch> # fetch without updating any tracking ref (FETCH_HEAD only)
```
## Default fetch refspec

View File

@@ -9,11 +9,11 @@ source_keys:
Default strategy: `--ff-only`. It fails on divergence, which forces a conscious choice instead of an accidental merge commit.
- **Fast-forward only**: `git pull --ff-only` — the recommended default
- **Rebase**: `git pull --rebase` replays your commits on top for linear history, but rewrites SHAs. Verify nothing being replayed has been pushed: rebasing published commits breaks everyone downstream.
- **Merge**: `git pull --no-rebase` — three-way merge commit, preserves original commits, non-linear
- **Rebase preserving merges**: `git pull --rebase=merges` keeps intentional local merge commits during the replay
- **Stage without committing**: `git pull --squash` collapses incoming commits into staged changes; you write the message
- **Fast-forward only**: `rtk git pull --ff-only` — the recommended default
- **Rebase**: `rtk git pull --rebase` replays your commits on top for linear history, but rewrites SHAs. Verify nothing being replayed has been pushed: rebasing published commits breaks everyone downstream.
- **Merge**: `rtk git pull --no-rebase` — three-way merge commit, preserves original commits, non-linear
- **Rebase preserving merges**: `rtk git pull --rebase=merges` keeps intentional local merge commits during the replay
- **Stage without committing**: `rtk git pull --squash` collapses incoming commits into staged changes; you write the message
- **Merge strategy**: Git 2.34+ defaults to `ort` (`recursive` is now an alias for it). Strategy options such as `-X ours`, `-X theirs`, `-X ignore-space-change` pass through unchanged.
- **Submodules**: `--recurse-submodules` only fetches submodules already checked out. Newly added ones are not initialized — use the `git-submodules` skill for those.
@@ -37,7 +37,7 @@ Highest wins:
4. `branch.autoSetupRebase` (set automatically when the tracking branch was created)
```bash
git config pull.ff only # deterministic default across Git versions
git config --global pull.rebase true
git config branch.develop.rebase false # develop always merges, regardless of the global default
rtk git config pull.ff only # deterministic default across Git versions
rtk git config --global pull.rebase true
rtk git config branch.develop.rebase false # develop always merges, regardless of the global default
```

View File

@@ -9,14 +9,14 @@ source_keys:
Default: safe push to the same-named branch on the remote.
- **Force-push**: never bare `--force`. Use `git push --force-with-lease --force-if-includes <remote> <branch>`, after the SKILL.md Step 1 gate.
- **Basic**: `git push <remote> <branch>`
- **Set upstream**: `git push -u <remote> <branch>` — push and configure tracking
- **Multi-remote**: push sequentially (`git push origin develop`, `git push staging develop`), or add a second push URL with `git remote set-url --add <name> <url>` to reach both in one command
- **Delete a remote branch**: `git push <remote> --delete <branch>` — clearer than the `:<branch>` form
- **Bulk**: `git push --all` (all local branches), `git push --tags` (all tags), `git push origin <tag>` (one tag)
- **Delete remote branches with no local counterpart**: `git push --prune origin 'refs/heads/*:refs/heads/*'`
- **Force only part of a multi-ref push**: prefix the one refspec that needs it with `+` — `git push origin +release develop` forces `release` while safe-pushing `develop`. A `+` prefix is a force-push and passes the SKILL.md Step 1 gate like any other.
- **Force-push**: never bare `--force`. Use `rtk git push --force-with-lease --force-if-includes <remote> <branch>`, after the SKILL.md Step 1 gate.
- **Basic**: `rtk git push <remote> <branch>`
- **Set upstream**: `rtk git push -u <remote> <branch>` — push and configure tracking
- **Multi-remote**: push sequentially (`rtk git push origin develop`, `rtk git push staging develop`), or add a second push URL with `rtk git remote set-url --add <name> <url>` to reach both in one command
- **Delete a remote branch**: `rtk git push <remote> --delete <branch>` — clearer than the `:<branch>` form
- **Bulk**: `rtk git push --all` (all local branches), `rtk git push --tags` (all tags), `rtk git push origin <tag>` (one tag)
- **Delete remote branches with no local counterpart**: `rtk git push --prune origin 'refs/heads/*:refs/heads/*'`
- **Force only part of a multi-ref push**: prefix the one refspec that needs it with `+` — `rtk git push origin +release develop` forces `release` while safe-pushing `develop`. A `+` prefix is a force-push and passes the SKILL.md Step 1 gate like any other.
## Refspec syntax — `[+]<src>[:<dst>]`
@@ -48,19 +48,19 @@ Two mitigations:
# Option 1 — dedicated push-only remote: background tools fetch `origin`, you push
# through a separate remote that nothing else touches, so its tracking ref can't be
# poisoned by an unrelated fetch.
git remote add origin-push $(git config remote.origin.url)
git push --force-with-lease origin-push
rtk git remote add origin-push $(rtk git config remote.origin.url)
rtk git push --force-with-lease origin-push
# Option 2 — explicit SHA via a local tag, unaffected by tracking-branch state
git fetch
git tag base master
git rebase -i master
git push --force-with-lease=master:base master:master
rtk git fetch
rtk git tag base master
rtk git rebase -i master
rtk git push --force-with-lease=master:base master:master
```
`--force-if-includes` adds a second check on top of bare `--force-with-lease`: it verifies the remote-tracking tip actually appears in your local branch's reflog, i.e. you genuinely integrated it before rewriting. It is a no-op without `--force-with-lease`, and has no effect with the `--force-with-lease=<ref>:<sha>` form, which already pins an exact SHA.
Safest combination: `git push --force-with-lease --force-if-includes origin`.
Safest combination: `rtk git push --force-with-lease --force-if-includes origin`.
## Server-side policy

View File

@@ -9,31 +9,31 @@ source_keys:
Which remotes exist, where they point, and what they track.
`git remote show <name>` needs network access — use `-n` for cached data offline, or `git remote -v`, which lists URLs without querying.
`rtk git remote show <name>` needs network access — use `-n` for cached data offline, or `rtk git remote -v`, which lists URLs without querying.
## Add, remove, rename, inspect
- **Add**: `git remote add <name> <url>`, or `-f` to fetch immediately
- **Remove**: `git remote remove <name>` — deletes the remote, all its tracking refs, and its config
- **Rename**: `git remote rename <old> <new>`
- **Inspect**: `git remote -v` (URLs, offline) or `git remote show <name>` (live tracking status)
- **Effective URLs**: `git remote get-url <name>` shows the URL after `insteadOf` rewrites; `git remote get-url --push --all <name>` lists every push URL
- **Add**: `rtk git remote add <name> <url>`, or `-f` to fetch immediately
- **Remove**: `rtk git remote remove <name>` — deletes the remote, all its tracking refs, and its config
- **Rename**: `rtk git remote rename <old> <new>`
- **Inspect**: `rtk git remote -v` (URLs, offline) or `rtk git remote show <name>` (live tracking status)
- **Effective URLs**: `rtk git remote get-url <name>` shows the URL after `insteadOf` rewrites; `rtk git remote get-url --push --all <name>` lists every push URL
## Tracking, mirroring, housekeeping
- **Track one branch**: `git remote add -t <branch> <name> <url>` (repeatable); `--no-tags` suppresses tag import entirely
- **Track one branch**: `rtk git remote add -t <branch> <name> <url>` (repeatable); `--no-tags` suppresses tag import entirely
- **Mirror**: `--mirror=fetch` mirrors all refs locally (bare repos only); `--mirror=push` makes every push behave like `--mirror`
- **Prune stale tracking refs without fetching**: `git remote prune <name>`, with `--dry-run` to preview
- **Default branch pointer**: `git remote set-head <name> -a` (auto-detect, needs a prior fetch), `... <branch>` (explicit), `... -d` (delete `refs/remotes/<name>/HEAD`)
- **Prune stale tracking refs without fetching**: `rtk git remote prune <name>`, with `--dry-run` to preview
- **Default branch pointer**: `rtk git remote set-head <name> -a` (auto-detect, needs a prior fetch), `... <branch>` (explicit), `... -d` (delete `refs/remotes/<name>/HEAD`)
## `set-url` — full form
```bash
git remote set-url <name> <newurl> # replace the first fetch URL
git remote set-url <name> <newurl> <oldurl-regex> # replace only the URL matching regex
git remote set-url --push <name> <url> # change push URL only (must point at same repo)
git remote set-url --add <name> <url> # add an extra push URL (push to multiple remotes)
git remote set-url --delete <name> <regex> # remove URLs matching regex
rtk git remote set-url <name> <newurl> # replace the first fetch URL
rtk git remote set-url <name> <newurl> <oldurl-regex> # replace only the URL matching regex
rtk git remote set-url --push <name> <url> # change push URL only (must point at same repo)
rtk git remote set-url --add <name> <url> # add an extra push URL (push to multiple remotes)
rtk git remote set-url --delete <name> <regex> # remove URLs matching regex
```
`--push` changes only where pushes go — fetch and push URLs must still reference the same repository. For genuine fetch-from-A / push-to-B workflows, use two separate named remotes instead; `--push` cannot do this.

View File

@@ -9,6 +9,7 @@ description: >
Not the superproject's own remotes -> `git-remotes`.
metadata:
version: "1.0.0"
category: git
source_keys:
- git-scm-submodule-docs

View File

@@ -8,6 +8,7 @@ description: >
agent caller -> `git-orchestrate`. Not Gitea -> `gitea-workflow`.
metadata:
version: "1.0.0"
category: git
source_keys:
- nvie-gitflow-post

View File

@@ -8,6 +8,7 @@ description: >
Not interactive multi-step git guidance -> `git-workflow`.
metadata:
version: "1.0.0"
category: git
source_keys:
- git-scm-worktree-docs
@@ -16,7 +17,7 @@ metadata:
## 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.
- **Never `rm -rf` a worktree directory.** That strands metadata in `$GIT_DIR/worktrees/`. Use `rtk git worktree remove`, or `rtk 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.** Without it, `git config --worktree` errors; with it, that flag writes to the worktree's own `config.worktree` file, and `core.bare`/`core.worktree` are forced there too. It also breaks older Git. Leave it off unless per-worktree config is needed.
@@ -24,19 +25,19 @@ metadata:
| Operation | Run |
|---|---|
| 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 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** under the conditions in `references/worktrees.md` |
| Throwaway experiment, no branch | `git worktree add -d <path>` — detached HEAD |
| Create on a branch that already exists locally | `rtk git worktree add <path> <branch>` |
| Create on a new branch | `rtk git worktree add -b <branch> <path>` |
| Create on the branch named after the path basename | `rtk 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 | `rtk git worktree add -B <branch> <path>` |
| Create a local branch tracking a remote one | `rtk git worktree add --track -b <branch> <path> <remote>/<branch>` — always correct. `git worktree add <path> <branch>` expands to exactly this, but **only** under the conditions in `references/worktrees.md` |
| Throwaway experiment, no branch | `rtk 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` — 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 |
| List | `rtk git worktree list -v`, or `--porcelain -z` to parse |
| Lock or unlock | `rtk git worktree lock [--reason <str>] <path>` / `rtk git worktree unlock <path>` |
| Move | `rtk git worktree move <from> <to>` |
| Remove | `rtk git worktree remove <path>` |
| Prune stale metadata | `rtk git worktree prune --dry-run`, then without the flag |
| Repair after a manual move | `rtk git worktree repair` — in the main worktree if *it* moved, or inside a linked worktree that moved. `rtk 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
@@ -48,7 +49,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.
- **`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.
- **`add` — lock at creation, not after.** `rtk git worktree add --lock` is atomic, where add-then-`lock` leaves a window in which the worktree is unprotected.
## Step 2 — Report
@@ -61,6 +62,6 @@ worktrees:
lock_reason: <reason or empty>
```
Derive those fields from `git worktree list --porcelain -z`. For a single
Derive those fields from `rtk git worktree list --porcelain -z`. For a single
operation, report its outcome instead — `created: true`, `moved: true`,
`removed: true`.

View File

@@ -23,17 +23,17 @@ that are usable.
## `add` forms
```bash
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
rtk git worktree add <path> <branch> # <branch> exists locally: check it out — non-destructive
rtk git worktree add -b <branch> <path> # create a new branch; fails if it exists
rtk 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,
rtk git worktree add -B <branch> <path> # create the branch, or reset an existing one to HEAD,
# discarding the commits it carried
git worktree add --track -b <branch> <path> <remote>/<branch>
rtk 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:
rtk 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
rtk git worktree add -d <path> # detached HEAD, no branch
```
The same `git worktree add <path> <branch>` spelling appears twice above and does two
@@ -65,19 +65,19 @@ Using `-` as `<commit-ish>` is shorthand for `@{-1}` (the branch checked out bef
## New unborn branch
```bash
git worktree add --orphan -b <branch> <path>
rtk git worktree add --orphan -b <branch> <path>
```
Creates an empty branch with no commits. **`--orphan` needs Git 2.42 or later** — it was added
upstream in 2.42, and on 2.39.5 this fails with `error: unknown option 'orphan'` and exit 129.
Check `git --version` before reaching for it.
Check `rtk git --version` before reaching for it.
Fallback on older Git, verified on 2.39.5 — detach first, then orphan the linked worktree in place,
which leaves the main worktree on its own branch throughout:
```bash
git worktree add -d <path> # linked worktree, detached HEAD
rtk git worktree add -d <path> # linked worktree, detached HEAD
cd <path>
git switch --orphan <branch> # unborn branch: empty index, empty working tree
rtk git switch --orphan <branch> # unborn branch: empty index, empty working tree
```
`git worktree list` then shows the new worktree at `0000000 [<branch>]` until its first commit.
@@ -88,25 +88,25 @@ the disruption worktrees exist to avoid.
Suppress the initial checkout to configure sparse-checkout first:
```bash
git worktree add --no-checkout ../sparse main
rtk git worktree add --no-checkout ../sparse main
cd ../sparse
git sparse-checkout init --cone
git sparse-checkout set src/
git checkout main
rtk git sparse-checkout init --cone
rtk git sparse-checkout set src/
rtk git checkout main
```
## Worktree on removable media
```bash
git worktree add --lock --reason "external SSD" <path> <branch>
git worktree unlock <path> # when reconnected
rtk git worktree add --lock --reason "external SSD" <path> <branch>
rtk git worktree unlock <path> # when reconnected
```
## Remote-branch disambiguation
```bash
git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
git worktree add <path> <branch> # shortcut: needs one clear remote
rtk git worktree add --track -b <branch> <path> <remote>/<branch> # explicit: no guessing at all
rtk git worktree add <path> <branch> # shortcut: needs one clear remote
```
**The bare-name shortcut needs exactly one remote.** It fires only when `<branch>` is not found
locally, none of `-b`/`-B`/`--detach` were given, and a tracking branch of that name exists in
@@ -122,10 +122,10 @@ exactly one remote has it, and marks that branch as upstream. Its default comes
## Repair after a manual move
```bash
git worktree repair # the MAIN worktree moved: run it there to reconnect every linked
rtk 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,
rtk git worktree repair # a LINKED worktree moved: run it inside that recently-moved worktree
rtk git worktree repair <path>... # reconnect a specific linked worktree — runnable from any worktree,
# naming each moved tree's new path
```
@@ -133,10 +133,10 @@ 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 |
| The main worktree (or bare repo) | `rtk git worktree repair` in the main worktree |
| One linked worktree | `rtk git worktree repair` inside that worktree |
| Several linked worktrees | `rtk git worktree repair <path>...` from any worktree, listing each new path |
| Both main and linked worktrees | `rtk 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.
@@ -157,20 +157,20 @@ reestablishes the connection to every path you name, run from any worktree.
untouched throughout:
```bash
git worktree add -b emergency-fix ../temp main
rtk git worktree add -b emergency-fix ../temp main
cd ../temp
# fix, then commit
git commit -a -m "fix: critical production bug"
rtk git commit -a -m "fix: critical production bug"
cd -
git worktree remove ../temp
rtk 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 # detached HEAD — read-only review
git worktree add --track -b feature-xyz ../review-pr-123 origin/feature-xyz # if you will commit
rtk git worktree add ../review-pr-123 origin/feature-xyz # detached HEAD — read-only review
rtk 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
```

View File

@@ -6,6 +6,7 @@ description: >
shellcheck"). Not running, installing, or updating hooks -> `pc-run`.
allowed-tools: Bash Read Write Edit
metadata:
version: "1.0.0"
category: devtools
source_keys:
- context7-pre-commit-com

View File

@@ -15,7 +15,7 @@ flow's file is not needed here. `SKILL.md`'s three common gates still apply.
inferring them from the project's name or README:
```bash
git ls-files | grep -oE '\.[a-z]+$' | sort | uniq -c | sort -rn
rtk git ls-files | grep -oE '\.[a-z]+$' | sort | uniq -c | sort -rn
```
2. Read `references/hooks-by-language.md` and map the detected extensions to recommended hooks.

View File

@@ -17,7 +17,7 @@ Read the existing `.pre-commit-config.yaml` before editing. Note any stale `rev`
1. Run a shallow extension scan, so the addition is judged against the languages actually present:
```bash
git ls-files | grep -oE '\.[a-z]+$' | sort | uniq -c | sort -rn
rtk git ls-files | grep -oE '\.[a-z]+$' | sort | uniq -c | sort -rn
```
2. Read `references/hooks-by-language.md` for the correct repo URL, `rev` and recommended args

View File

@@ -8,6 +8,7 @@ description: >
compatibility: Requires pre-commit installed and available on PATH.
metadata:
version: "1.0.0"
category: devtools
source_keys:
- context7-pre-commit-com
@@ -20,7 +21,7 @@ allowed-tools: Bash Read
- The `SKIP` env var takes exact hook `id` values, comma-separated with no spaces: `SKIP=check-yaml,gitleaks git commit -m "msg"`. A space after a comma silently skips nothing instead of erroring.
- Never bypass a failing hook with `git commit --no-verify` (or `-n`). Hooks are the automated QA gate, so a bypassed commit pushes the failure downstream where it costs more — diagnose it instead.
- `- files were modified by this hook` is not a bug. A fixer hook rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. Re-stage and re-run the same commit: `git add -u && git commit`. Do NOT reach for `pre-commit install -f` here — it overwrites `.git/hooks/` and has nothing to do with re-staging.
- `- files were modified by this hook` is not a bug. A fixer hook rewrote a staged file, so the staged snapshot is stale and the commit is blocked on purpose. Re-stage and re-run the same commit: `rtk git add -u && rtk git commit`. Do NOT reach for `pre-commit install -f` here — it overwrites `.git/hooks/` and has nothing to do with re-staging.
## Gate — `pre-commit clean`

View File

@@ -14,8 +14,8 @@ Cause: A fixer hook (e.g. `trailing-whitespace`, `end-of-file-fixer`, `pretty-fo
Fix: Re-stage and recommit.
```bash
git add -u
git commit -m "same message"
rtk git add -u
rtk git commit -m "same message"
```
Do NOT reach for `pre-commit install -f` here. That flag overwrites existing hook files in `.git/hooks/`; it has nothing to do with re-staging.