check_no_binaries: one git call and no grep fork per file
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
file length / file-length (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
palette drift / palette (push) Has been cancelled
shared gate tests / gate unit tests (push) Has been cancelled

Two forks per path (`git ls-files --error-unmatch`, `grep -qiE <<<`) made
the gate a 5 s step on a 2053-file repo. The tracked set now comes from a
single `git ls-files -z -- "$@"` and the extension match is bash's own
`=~` on the lower-cased path (same case-insensitive semantics as `grep -i`).
0.2 s on the same tree; verdicts unchanged (blocked / allowlisted /
untracked-ignored checked on a throwaway repo).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016P4KZw1E2sXJjYqfcZWf1x
This commit is contained in:
Krzysztof Rudnicki 2026-09-18 12:27:18 +02:00
parent 3acf913b32
commit 1a8833eb9a

View File

@ -74,10 +74,18 @@ main() {
pattern="$(build_pattern)"
load_allowlist
# Untracked or deleted paths are not this gate's business. One git call
# for the whole list, not one per file: a CI run hands this every
# tracked path (2000+), and two forks per file made it a 5 s gate.
local -A tracked=()
while IFS= read -r -d '' file; do
tracked["$file"]=1
done < <(git ls-files -z -- "$@" 2>/dev/null)
for file in "$@"; do
# Untracked or deleted paths are not this gate's business.
git ls-files --error-unmatch "$file" >/dev/null 2>&1 || continue
grep -qiE "$pattern" <<<"$file" || continue
[[ -v "tracked[$file]" ]] || continue
# Extensions are matched case-insensitively (grep -i, before).
[[ "${file,,}" =~ $pattern ]] || continue
is_allowed "$file" && continue
echo "BLOCKED: $file"
found=1