From 1a8833eb9a07d2ae9aa13882ff2a87c1ab16a095 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Fri, 18 Sep 2026 12:27:18 +0200 Subject: [PATCH] check_no_binaries: one git call and no grep fork per file 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) Claude-Session: https://claude.ai/code/session_016P4KZw1E2sXJjYqfcZWf1x --- scripts/check_no_binaries.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/check_no_binaries.sh b/scripts/check_no_binaries.sh index befb273..c0abe2d 100755 --- a/scripts/check_no_binaries.sh +++ b/scripts/check_no_binaries.sh @@ -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