Add opt-in raw-git nudge hook, independent of anti-chaining hook
Forces a normal confirmation prompt (never a silent block, never a silent allow) when Bash runs raw git instead of git_cmd.sh, worded more insistently when the subcommand is one the wrapper already supports. Raw git stays a valid fallback for unsupported subcommands and unregistered repos - a hard deny would remove that fallback entirely. Also documents in SKILL.md that repo ambiguity (which registered repo is meant, or none at all) must be resolved by asking the user rather than guessing - a hook only sees the literal command string, not the conversation, so that judgment can't live in the hook itself.
This commit is contained in:
+34
-5
@@ -28,11 +28,12 @@ git_cmd.sh <subcommand> [--repo <name>] [-- <git-args...>]
|
||||
one chained command — which is exactly what keeps every single one of
|
||||
them covered by the whitelist.
|
||||
- **A fixed set of allowed subcommands:** `status`, `log`, `diff`, `show`,
|
||||
`fetch`, `remote`, `branch`, `checkout`, `add`, `commit`, `push`, `pull`.
|
||||
Anything else (`reset`, `rebase`, `filter-branch`, arbitrary `git config`,
|
||||
...) is rejected by the script itself, before git ever runs — not because
|
||||
those operations are inherently dangerous, but because they're
|
||||
consequential enough that they should go through a normal confirmation
|
||||
`fetch`, `remote`, `branch`, `checkout`, `add`, `commit`, `push`, `pull`,
|
||||
`tag`. Anything else (`reset`, `rebase`, `stash`, `merge`, `filter-branch`,
|
||||
arbitrary `git config`, ...) is rejected by the script itself, before git
|
||||
ever runs — not because those operations are inherently dangerous, but
|
||||
because they can rewrite or discard history/working-tree state in ways
|
||||
that are hard to reverse, so they should go through a normal confirmation
|
||||
prompt rather than being auto-approved.
|
||||
|
||||
## Setup
|
||||
@@ -56,6 +57,10 @@ This will:
|
||||
silent pass-through) any time a Bash command contains shell chaining or
|
||||
substitution characters (`&&`, `;`, `|`, `` ` ``, `$(...)`) — see
|
||||
"The anti-chaining hook" below.
|
||||
4. Ask whether you also want a second, independent hook installed: one that
|
||||
forces the same kind of normal confirmation prompt any time a Bash
|
||||
command runs raw `git` instead of `git_cmd.sh` — see "The raw-git nudge
|
||||
hook" below.
|
||||
|
||||
## Usage examples
|
||||
|
||||
@@ -110,6 +115,30 @@ up in the first place — this hook is a backstop for the rare cases they do
|
||||
anyway (or for other tools/skills in your setup that aren't as careful
|
||||
about it).
|
||||
|
||||
## The raw-git nudge hook
|
||||
|
||||
Optional, offered during `/git-manager:setup`, independent of the
|
||||
anti-chaining hook above (you can install neither, either, or both). If
|
||||
installed, it watches every Bash command and, when it sees raw `git` used
|
||||
instead of `git_cmd.sh`, forces the normal confirmation prompt instead of
|
||||
letting whitelist matching decide — the same "never silently block, never
|
||||
silently allow" behavior as the anti-chaining hook.
|
||||
|
||||
This is deliberately **not** a hard block. Raw git stays a legitimate
|
||||
fallback for subcommands `git_cmd.sh` doesn't support (`stash`, `merge`,
|
||||
`rebase`, `reset`, ...) and for repos that aren't registered yet — a full
|
||||
block would remove that fallback entirely. What the hook does instead is
|
||||
make sure raw git is never invisible: every time it's used, it's a
|
||||
confirmed, visible choice, worded more insistently when the subcommand is
|
||||
one `git_cmd.sh` already supports (in which case there's rarely a good
|
||||
reason to have bypassed it) and more permissively otherwise.
|
||||
|
||||
What this hook can't do — and isn't trying to do — is figure out from the
|
||||
surrounding conversation whether raw git was actually the right call here.
|
||||
It only ever sees the literal Bash command text, not the request that led
|
||||
to it; that kind of judgment is the skill's own job (see `SKILL.md`), and
|
||||
this hook is just the backstop for when that judgment gets skipped.
|
||||
|
||||
## What's deliberately *not* included
|
||||
|
||||
- No `Bash(git:*)` — that would also permit `git reset --hard`, `git clean
|
||||
|
||||
Reference in New Issue
Block a user