Files
tty7/crates
l0ng-ai 209ebe6ca5 fix(gitignore): obey core.ignorecase, as git does
Differential-tested the ignore chain against `git check-ignore` on ~50
patterns — anchored, directory-only, `**` at either end and in the middle,
whitelists under ordinary and excluded directories, character classes,
escaped spaces, comments, CRLF, the `*` / `!*/` / `!*.c` recipe — and it
agreed with git everywhere except case.

`git init` probes the filesystem and sets `core.ignorecase = true` on a
case-insensitive one, which is every stock macOS and Windows install, and
git's ignore matching then folds case. The chain matched case-sensitively no
matter what. So a `.gitignore` whose pattern differs in case from the name on
disk diverged: `Build/` against a `build/`, `*.LOG` against an `a.log`. git
calls those ignored. The tree drew them as tracked, and — worse than a
styling difference — expanded and watched a directory git never descends.
The capitalised build directory is not a corner case; the .gitignore
templates and the tools that create the directory routinely disagree about
it.

Read from `core.ignorecase` rather than probed, because config is what git
obeys and someone who set it false on a case-insensitive disk means it. Once
per root, kept across `clear()`: editing a `.gitignore` cannot change the
setting, and a git spawn per keystroke in the ignore file would buy nothing.
The matcher cache is now keyed by the fold flag too, since a repository
nested inside another can answer differently.

The guard sets `core.ignorecase` explicitly in both directions rather than
leaving it to the probe, so it asserts the same thing on a case-sensitive
disk; its answers are `git check-ignore`'s under each setting. Checked
against both injected regressions — never folding and always folding.
2026-08-23 02:53:02 +08:00
..