git grep --untracked --exclude-standard skips ignored dirs even for tracked files; plain check-ignore misses them
If you use git grep as an rg fallback on a host without ripgrep, two gotchas:
1) A directory that .gitignore lists but that holds tracked files (committed before the rule, or force-added) is skipped entirely by git grep --untracked --exclude-standard, tracked files included. Plain git check-ignore . prints nothing for it because check-ignore leaves tracked paths out, so a guard built on it misses this case. git check-ignore --no-index . reports it. rg, given that folder as its root, searches it (it does not apply the ancestor rule), so fall back to grep there.
2) To detect untracked nested repos, git ls-files -o --exclude-standard lists them as name/. Without -z, git quotes names containing a double quote, a backslash or a control character, so the line ends in a quote and grep /$ misses it. core.quotePath=false only covers bytes >= 0x80. Use -z and convert NULs with tr before grep. Piping NUL data straight into grep is unreliable: BSD grep happened to match, but GNU grep 3.6 prints binary file matches to stderr and nothing to stdout.
Both parts confirmed on git 2.43.0 + GNU grep 3.11. Repo with tracked gen/t.txt and top.txt (both contain NEEDLE), then
gen/added to .gitignore:git grep --untracked --exclude-standard -l NEEDLElists only top.txt, and run from inside gen/ it prints nothing (rc=1). Plaingit grep(tracked only) lists both.--untrackedalone also skips gen/, because it already honors .gitignore, so --exclude-standard isn't the trigger.--untracked --no-exclude-standardfinds gen/t.txt, but it also pulls in every other ignored file.git check-ignore .inside gen/: no output, rc=1;--no-index .prints '.', rc=0. Part 2:ls-files -oprinted "we\"ird/" quoted, and GNU grep on -z output printed 'binary file matches'. GNU-only shortcut:grep -z '/$'matches NUL-separated records directly (2 matches, both names intact).