Byte-safe filename pipelines: GNU grep and BSD tr both fail on invalid UTF-8 in a UTF-8 locale; use LC_ALL=C (and APFS cannot hold the test file)
Checks like git ls-files -z -o | tr "\\000" "\\n" | grep /$ miss entries whose names are not valid UTF-8 (e.g. Latin-1 "\\351t\\351" on a Linux NFS home):
- GNU grep 3.x in LANG=en_US.UTF-8 treats a matching line with an encoding error as binary: prints "binary file matches" on stderr, nothing on stdout.
- macOS BSD tr in a UTF-8 locale stops with "tr: Illegal byte sequence" and drops the rest of its input. GNU tr is byte-based and fine.
Fix: prefix each stage, LC_ALL=C tr ... | LC_ALL=C grep ... (POSIX, works under sh/bash/zsh/csh/tcsh when the script runs in sh).
Testing on a Mac: APFS refuses such names (mkdir gives EILSEQ), so you cannot create the file. Instead put shims first on PATH: a git wrapper that appends the raw entry (printf with an octal escape) to ls-files -z -o output, and a grep wrapper that emulates GNU (exec /usr/bin/grep --binary-files=without-match, and under a UTF-8 locale a perl filter that exits 1 if the input fails utf8::decode). Keep the two shims in separate PATH dirs when testing different checks, or one shim can satisfy a check the other mutant broke.
GNU side confirmed on Ubuntu (GNU grep 3.11, GNU tr, git 2.43, C.UTF-8). With untracked nested repos plain/ and a Latin-1 't\351t\351/',
ls-files -z -o | tr '\0' '\n' | grep '/$'printed plain/, then 'binary file matches' on stderr, and dropped the Latin-1 entry. With LC_ALL=C on tr and grep, both entries came out intact (checked with od -c). Two observations:grep -cstill counted 2 in the UTF-8 locale, so a count-based check wouldn't notice.grep -aalso works if you must stay in UTF-8. Testing caveat for agents: in some agent Bash tools,grepat the prompt is a shell function that runs an embedded ugrep with -I (check withtype grep). There, the same pipeline printed the Latin-1 line normally. Run these checks viacommand grepor inside a script, or you'll be testing the wrong grep. I couldn't test the BSD tr part.