Summary
.claude/hooks/guard-git.sh's block for reverting files via git checkout -- <file> uses a regex that matches checkout followed by whitespace then --.
This matches any git checkout --flag, not just the file-reverting form it's meant to catch. Legitimate flags like --detach, --track, --orphan, --ours/--theirs also start with -- and get denied even though they don't revert working-tree changes.
Worse, the hook greps the raw command string passed to Bash, not the code path that will actually execute. A multi-line script with a conditional branch containing git checkout --detach origin/main gets blocked even when that branch's condition is false and the line never runs — the hook has no way to know that, since it's a static text scan over the whole script (in fact, this very issue body triggered the same false positive on first attempt, since it quoted the offending git command literally).
Repro
Encountered while running /fixer (issue #1923 branch-cut step, per the skill's own boilerplate): a script containing a conditional git checkout --detach origin/main fallback (only reached if a stale local branch already exists) was blocked outright, even though the branch didn't exist yet and that line never executed.
Suggested fix
Narrow the regex to require a path-like token after -- (not another flag) — e.g. require -- to be followed by whitespace then a non---prefixed token, or a bare -- immediately before end-of-segment/end-of-string. At minimum, exclude common non-destructive flags (--detach, --track, --orphan, --no-track, --guess).
Summary
.claude/hooks/guard-git.sh's block for reverting files viagit checkout -- <file>uses a regex that matchescheckoutfollowed by whitespace then--.This matches any
git checkout --flag, not just the file-reverting form it's meant to catch. Legitimate flags like--detach,--track,--orphan,--ours/--theirsalso start with--and get denied even though they don't revert working-tree changes.Worse, the hook greps the raw command string passed to Bash, not the code path that will actually execute. A multi-line script with a conditional branch containing
git checkout --detach origin/maingets blocked even when that branch's condition is false and the line never runs — the hook has no way to know that, since it's a static text scan over the whole script (in fact, this very issue body triggered the same false positive on first attempt, since it quoted the offending git command literally).Repro
Encountered while running
/fixer(issue #1923 branch-cut step, per the skill's own boilerplate): a script containing a conditionalgit checkout --detach origin/mainfallback (only reached if a stale local branch already exists) was blocked outright, even though the branch didn't exist yet and that line never executed.Suggested fix
Narrow the regex to require a path-like token after
--(not another flag) — e.g. require--to be followed by whitespace then a non---prefixed token, or a bare--immediately before end-of-segment/end-of-string. At minimum, exclude common non-destructive flags (--detach,--track,--orphan,--no-track,--guess).