Strip pathspec and attribute-source settings from the walk's git (improvise-a0i3)

GIT_LITERAL/GLOB/NOGLOB/ICASE_PATHSPECS and GIT_ATTR_SOURCE are
process-wide, so --local-env-vars names none of them. Remove them in
git() beside the local-vars loop.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Edward Langley
2026-09-23 17:30:59 -07:00
parent da0eb3d7cb
commit 4cef40c951
2 changed files with 54 additions and 0 deletions
+41
View File
@@ -610,6 +610,47 @@ the `-c` arguments in `run_git` beat relying on the absence of a config file.
Rival: drop `--template=`. Red, as above.
### the_walk_ignores_the_users_pathspec_and_attribute_settings
improvise-a0i3. `git(root)` strips what `git rev-parse --local-env-vars` names,
and that list holds only the variables that point at a repository (`GIT_DIR`,
`GIT_INDEX_FILE` and so on). Pathspec magic and the attribute source are
process-wide settings, so the list names none of them. They still change what
`git ls-files -- '*.improv' '*.improv.gz'` answers:
- `GIT_LITERAL_PATHSPECS=1` reads `*.improv` as a file literally named
`*.improv`, so the walk finds nothing.
- `GIT_GLOB_PATHSPECS=1` stops `*` at `/`, so only a document at the root
matches. `GIT_NOGLOB_PATHSPECS=1` reads `*` literally, like the literal
setting. Every document these tests walk sits below the root, so both
settings made both tests fail.
- `GIT_ATTR_SOURCE=HEAD` makes git read attributes from `HEAD`. The scratch
repository in the gzip shape test has no commit, so `git add` fails with
`bad --attr-source`.
The test reruns `a_gzipped_document_is_walked` and `every_shipped_document_loads`
in a child under each of five settings, which is ten runs, and collects every
failure before it asserts. Red at #260's head `322de370`: 7 of 10 runs failed.
`LITERAL`, `GLOB` and `NOGLOB` each broke both tests. `ATTR_SOURCE` broke only
the gzip shape test, because the real checkout has a `HEAD`. The ticket reported
`ATTR_SOURCE` breaking both tests. Here it broke one, so the difference is in
the checkout the ticket measured, not in the fix.
The fix is to remove the five variables in `git()`, next to the
`--local-env-vars` loop. A `--literal-pathspecs`-style command-line flag would
have to be chosen per variable, and `GIT_ATTR_SOURCE` has no negating flag.
Rivals, each dropping one name from `PATHSPEC_AND_ATTRIBUTE_SETTINGS`:
- Without `GIT_LITERAL_PATHSPECS`, `GIT_GLOB_PATHSPECS` or
`GIT_NOGLOB_PATHSPECS`: red, both tests under that setting.
- Without `GIT_ATTR_SOURCE`: red, the gzip shape test.
- Without `GIT_ICASE_PATHSPECS`: **green.** A case-insensitive match of
`*.improv` still finds every document, so this row of the test cannot fail.
The name stays in the list because it is the fourth of git's pathspec
variables, and a future spelling of the walk that depends on case would be
exposed to it. The test covers it, but that coverage is vacuous today.
---
## `tests/web_demo_model.rs`
+13
View File
@@ -48,6 +48,15 @@ fn every_shipped_document_loads() {
}
}
/// Settings that change how git reads a pathspec or finds attributes.
const PATHSPEC_AND_ATTRIBUTE_SETTINGS: [&str; 5] = [
"GIT_LITERAL_PATHSPECS",
"GIT_GLOB_PATHSPECS",
"GIT_NOGLOB_PATHSPECS",
"GIT_ICASE_PATHSPECS",
"GIT_ATTR_SOURCE",
];
/// `git -C root`, with every repo-local variable a caller exported removed,
/// since `GIT_DIR` and friends override `-C` (improvise-53zz).
fn git(root: &Path) -> std::process::Command {
@@ -59,6 +68,10 @@ fn git(root: &Path) -> std::process::Command {
for name in String::from_utf8(names.stdout).expect("UTF-8").lines() {
git.env_remove(name);
}
// Process-wide, so `--local-env-vars` lists none of them (improvise-a0i3).
for name in PATHSPEC_AND_ATTRIBUTE_SETTINGS {
git.env_remove(name);
}
git.arg("-C").arg(root);
git
}