Repository navigation
fix(ci): isolate git from the ambient environment so -C is authoritative (#13948) - #13949
Merged
Merged
Conversation
…ive (#13948) python-suite shard 2/12 is red on Dev_new_gui, failing on every PR that runs it — seen on #13902, a dependabot bump touching nothing related. Git treats GIT_INDEX_FILE as higher precedence than -C, so with one exported into the job every xdist worker stages into the SAME index while committing in its OWN tmpdir repo. A worker then writes a tree whose blobs live in another worker's object store and git reports: error: invalid object 100644 dae199ae... for 'solo_12.py' error: Error building trees which reads as repository corruption in a test about co-change coupling. The popen-gw1 in the path is the tell: it only happens with parallel workers, which is why it looked intermittent. Reproduced exactly before fixing: GIT_INDEX_FILE=/tmp/shared-index pytest co_change_test.py -n 4 Without -n 4, or without the variable, it passes — which is why the failure message alone never reproduced it. GitHistoryCrawler._run_git had the same exposure and a worse failure mode: with GIT_DIR exported it reads THAT repository instead of the one passed to -C and returns a plausible history for the wrong tree — no error, no empty result, just an answer about something else. Confirmed by the suite switching from failing to HANGING when GIT_DIR pointed at the main checkout. Variables are named explicitly rather than stripping GIT_* wholesale, because GIT_AUTHOR_* and GIT_SSH_COMMAND are legitimate and removing them would break unrelated callers. Verified against the reproduction and against the case that must keep passing: reproduction now green, plain run green, GIT_DIR case 9s instead of a timeout. 3 mutations killed — production env isolation removed, GIT_DIR dropped from the strip list, and the test-side isolation removed (which reproduces the original CI failure: 4 failed, 13 errors).
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
Applied Black, isort, and autoflake to match code-quality checks. Triggered by workflow auto-fix-formatting.yml.
4 tasks
This was referenced Aug 11, 2026
mrveiss
added a commit
that referenced
this pull request
Aug 11, 2026
…3983) (#13987) * chore: claim worktree for #13983 * docs(code-intelligence): correct stale issue references to #13983 (#13983) #13949 was written against issue number #13948, which belongs to an unrelated open issue (a distillation-cursor DST bug). The filing command was malformed — 'gh issue create --json number' is not a valid flag combination, so it errored before creating anything and the '||' fallback returned the newest EXISTING issue number instead. That wrong number then reached the PR body, five source comments, and a test fixture directory name. #13948 has been reopened and is untouched; the real issue is #13983, filed after the fact with the full diagnosis. Comments and identifiers only — no behaviour change. The suite still passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Correction: this PR originally said
Closes #13948. That number belongs to an unrelated open issue — the filing command was malformed so the intended issue was never created. The correct issue is #13983; #13948 has been reopened and is untouched.Closes #13983
Thinking Path
python-suite shard 2/12is red onDev_new_gui— failing on every PR that runs it, including #13902, a dependabot bump touching nothing related.The message pointed at the wrong thing:
That reads as repository corruption inside a test about co-change coupling. The
popen-gw1in the tmpdir path is the actual tell — it only happens with parallel workers, which is why it looked intermittent.Git treats
GIT_INDEX_FILEas higher precedence than-C. With one exported into the job, every xdist worker stages into the same index while committing in its own tmpdir repo, so a worker writes a tree whose blobs live in another worker's object store.Reproduced exactly before writing any fix:
Without
-n 4, or without the variable, it passes — which is why the failure message alone never reproduced it.What Changed
co_change_test.py—_gitand_git_initrun under_hermetic_git_env(): the ambient environment minus the variables that outrank-C, plusGIT_CONFIG_GLOBAL/SYSTEM=/dev/nulland an explicit identity, so the fixture no longer depends on the runner having git configured.code_evolution_miner._run_git— the same isolation, for a quieter and worse problem. WithGIT_DIRexported, the crawler reads that repository instead of the one passed to-Cand returns a perfectly plausible history for the wrong tree: no error, no empty result, just an answer about something else. Confirmed by the suite switching from failing to hanging onceGIT_DIRpointed at the main checkout — it was walking the real repo's history.Variables are named explicitly rather than stripping
GIT_*wholesale:GIT_AUTHOR_*andGIT_SSH_COMMANDare legitimate and removing them would break unrelated callers.Verification
Against the reproduction and the case that must keep passing — not just a re-run:
GIT_INDEX_FILE+-n 4(the CI failure)GIT_DIRat the main checkout3 mutations applied, 3 killed:
env=_git_env()removed from_run_gitGIT_DIRdropped from the strip listThe new
test_the_crawler_reads_the_repo_it_was_given_not_the_ambient_onebuilds a second repo containingdecoy.py, pointsGIT_DIRat it, and asserts the crawler still reportsschema.pyand neverdecoy.py— a not-crashing assertion would have passed against the bug.Note
Per #13162 the Python suite is not a required check, so this was red on the base without blocking any merge. That is the reason it survived.
Model Used
claude-opus-5[1m]