Repository navigation
tests: PASTE_ENV in tests/test_doctor_legs_members_next.py is an import-time snapshot that overwrites GIT_CONFIG_COUNT, seven tests hand-build the same append beside appended_to_command_scope, and six git clone --no-local calls build clone_just_pushed's options by hand #758
Description
Goal: every test that gives git a setting through GIT_CONFIG_COUNT appends to the entries the environment holds, built at the call by one helper, so a setting set by the session fixture, the Windows job or another fixture reaches every git the test starts.
Filed by lane openRepoShape-5, from rv662's review of #662's PR (#748, "PASTE_ENV ... is a snapshot of os.environ taken at import") and from that PR's own "Left out" (five tests that build the same arithmetic by hand; six git clone --no-local calls, "not read closely"). Tests only.
Lands after: lane 5's #645 (PR #713, fix/645-fixture-copy-maintenance-race, head 979bb394), which adds appended_to_command_scope and the autouse no_auto_maintenance fixture, and #662 (PR #748, fix/662-insteadof-helper, head deb029c9), which adds insteadof_entries, insteadof_args and submodule_update_through_git and makes read_through_git append. Neither is on main.
Lines (path:line at main 66b230ed; the helpers are at deb029c9:tests/conftest.py: appended_to_command_scope :279, insteadof_entries :107, submodule_update_through_git :192, read_through_git :1595)
-
PASTE_ENVis built once at import and setsGIT_CONFIG_COUNTto 1 (tests/test_doctor_legs_members_next.py:63-68; used at:101,:442,:514,:609,:785and:1018). Read from source, not measured. It copiesos.environwhen the module is imported, which pytest does at collection; tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713's session fixtureno_auto_maintenancesetsGIT_CONFIG_COUNT, its two keys andGIT_CONFIG_GLOBALlater, at session start. So the copy holds neither scope, and its own"GIT_CONFIG_COUNT": "1"would overwrite a count the environment did hold (the Windows job holds two). A line pasted throughpaste()(sh -c row["next"]) that clones a local remote, such as thegit submodule update --init --recursive --checkoutthe rows hand over, therefore runs with git's automatic maintenance on, which is the race tests: theholderfixtures copy the family fixture withshutil.copytreewhile git's background gc or maintenance can still be packing it, so a test errors at setup when a loose object vanishes mid-copy (#440's race, through a file copy) #645 closes for every other clone the suite makes. tests/conftest.py: one helper builds theurl.<file URI>.insteadOfrewrite thatclone_just_pushed,read_through_gitand the adopt tests'pastedeach built, and the empty-mountsubmodule update --initsites use it (#662) #748 fixed the same overwrite inread_through_git(its body: "it used to overwrite the count, which dropped tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713's two settings") and moved threesubmodule updatecalls of this file onto its wrapper, and leftPASTE_ENV. Direction: build the environment per call:{**os.environ minus PYTHONPATH, **GIT_IDENTITY, PYTHONDONTWRITEBYTECODE, **appended_to_command_scope(os.environ, [("protocol.file.allow", "always")])}, in a function the six uses call, as rv662 asks ("Build it per test fromread_through_git"). - Seven tests build
held = int(os.environ.get("GIT_CONFIG_COUNT") or 0)and append by hand. Read from source:tests/test_adopt_git_reads.py:114,tests/test_adopt_nested_attributes.py:386,tests/test_adopt_reencoded_files.py:105,tests/test_adopt_root_symlinks.py:226,tests/test_adopt_ignored_shape_files.py:585,tests/test_bootstrap_after_bump.py:151andtests/test_family_bump_remove_rollback.py:680. tests/conftest.py: one helper builds theurl.<file URI>.insteadOfrewrite thatclone_just_pushed,read_through_gitand the adopt tests'pastedeach built, and the empty-mountsubmodule update --initsites use it (#662) #748's body counts five, from its base; main holds seven bygrep.tests/test_clone_just_pushed.py:84is the helper's own test and stays. Direction: one call toappended_to_command_scopeeach, with the entries it adds. The otherGIT_CONFIG_COUNTliterals in tests (tests/test_adopt_empty_symlinks.py:73,tests/test_non_utf8_git_reads.py:81and:423,tests/test_family.py:77,tests/test_family_dry_run.py:81and others) set the count to a fixed number and ride in the same sweep only where the environment they replace can hold entries; read each before changing it. - Six
git clone --no-localcalls build the optionsclone_just_pushedbuilds. Read from source, not read closely (tests/conftest.py: one helper builds theurl.<file URI>.insteadOfrewrite thatclone_just_pushed,read_through_gitand the adopt tests'pastedeach built, and the empty-mountsubmodule update --initsites use it (#662) #748's own words):tests/test_bump_leg_dry_run_truth.py:98and:110,tests/test_doctor_legs_members_next.py:1890and:1991,tests/test_doctor_pin_restore_merges.py:714andtests/test_family_bump_to_checks.py:235. Each passesprotocol.file.allowand--no-localby hand; the helper adds theurl.<file URI>.insteadOfrewrite that makes the clone read the remote through git. Whether a given call clones one of the session's remotes (and so wants the helper) or a repository the test made itself (and needs nothing) is the question tests/conftest.py: one helper builds theurl.<file URI>.insteadOfrewrite thatclone_just_pushed,read_through_gitand the adopt tests'pastedeach built, and the empty-mountsubmodule update --initsites use it (#662) #748 left open; answer it per call, as tests/conftest.py: one helper builds theurl.<file URI>.insteadOfrewrite thatclone_just_pushed,read_through_gitand the adopt tests'pastedeach built, and the empty-mountsubmodule update --initsites use it (#662) #748 did for the 55clonesites.
Verify: tests/test_doctor_legs_members_next.py, the seven files above, tests/test_clone_just_pushed.py and tests/test_no_auto_maintenance.py pass on Linux. A test beside tests/test_no_auto_maintenance.py that starts paste()'s shell with GIT_CONFIG_COUNT=2 in os.environ and asserts git config --show-origin through it lists the two maintenance keys and protocol.file.allow. A hygiene test that fails a new "GIT_CONFIG_COUNT": "<digit>" literal in tests/ outside conftest.
Overlaps. #748 (fix/662-insteadof-helper) edits tests/conftest.py, tests/test_doctor_legs_members_next.py (the submodule update sites, :631, :987 and :1054 at its base), tests/test_family_bump_remove_rollback.py and tests/test_clone_just_pushed.py, so this lands after it. fix/648-bootstrap-and-gate-order (#682), fix/681-validate-family-remedies (#747) and fix/704-bootstrap-leg-moves (#745) edit tests/test_doctor_legs_members_next.py too (one hunk each, at :1587, far from :63). fix/704-bootstrap-leg-moves edits tests/test_bootstrap_after_bump.py. l3-687-pin-restore-other-side edits tests/test_doctor_pin_restore_merges.py. No pinned file changes.
Parent: #461.
Milestone: v1.1.1. Tests only, and no test fails today.
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 17, 2026
(lane openRepoShape-5, 2026-10-17T01:17:51Z) One more line for this issue, from lane 5's investigation i645 of the
objects changedfailure intests/test_family_bump_remove_rollback.py(lane 3's report on #645 of #736's Linux run 38981191418,test_two_sections_neither_named_after_the_path_are_both_printedat:639; i645 found #713 needs no change before it lands). It is two comments about git's automatic maintenance, in the files this issue's sweep reads. It changes no behaviour. Line numbers are at maine3137010fortests/test_family_dry_run.py(the same at #713's head979bb394) and at979bb394fortests/conftest.py.tests/test_family_dry_run.py:74-80: "OFF for every git this module starts, through git'sGIT_CONFIG_COUNTprotocol and never a global file".NO_MAINTENANCE(:81-86) reaches only the gits that are givenisolated()'s environment (:89-92):family.py's children and the snapshot's gits. The module's own setup commits go throughconftest.git, which passes noenv=, so they inheritos.environ(i645'sGIT_TRACE2_CONFIG_PARAMStrace: on mainGIT_CONFIG_COUNT=2, run9's identity only, and no maintenance key, so each startsgit maintenance run --auto --quiet; on tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713's head the same commits readmaintenance.auto=falsefrom the session fixture, in both its scopes). So once tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713 lands the sentence is not moot but wrong in two places: "every git this module starts" is true by the session's doing and not this constant's, and "never a global file" is false of the suite, whose fixture writes one. The constant also fixesGIT_CONFIG_COUNTat 3, which is the overwrite this issue's first line is about, and is right only because it puts the same keys back. Direction: say whatNO_MAINTENANCEis for (the gitsisolated()hands an environment to, whose count and global fileexcluding()and the identity overwrite) and that the session fixture covers the rest.tests/conftest.py:152-156at979bb394: "since 2.54 its default strategy (geometric) repacks a repository of a few hundred loose objects and deletes the ones it packed". i645 read git v2.55.0's source (a read-only web fetch ofbuiltin/gc.c,builtin/commit.candrun-command.c; no git 2.55 was run, only 2.43.0 is installed):geometric_repack_auto_conditionfires when its estimate is above 256, the estimate countsobjects/17alone and multiplies by 256, so two loose objects there are enough, about 0.8 to 0.9% per commit at 34 to 37 objects. The case of record istests/test_family_bump_remove_rollback.py:626-639: the firstgit commit(commit_gitmodules,:540) starts a detached repack, the second commit's three objects land during it, andbeforelists 37 loose objects whereafterlists two packs (a main pack and a cruft pack holding the second commit's objects). The CI runner image i645 read lists Git 2.55.0. i645 reproduced it on 2.43 twice by forcing it (gc.auto=1with two planted17objects; and 2.55's own repack command started detached after the first commit): 3 of 3 failed on main, and the same runs passed on tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713's head and on its merge with main (2 plain, 3 forced). Direction: i645's two replacements, in tests/conftest.py: the session turns git's automatic maintenance off, in command scope and in a global config that includes the person's own, so acopytreeof a fixture no longer meets a detached repack deleting its loose objects (#645) #713's comment and the matching sentence of its body: "repacks once its estimate, taken fromobjects/17alone, is above 256 loose objects, so two loose objects there are enough", and, after the copy sentence, "and a listing of.git/objectstaken before and after it differs:test_family_bump_remove_rollback.py'sobjects changed, 37 loose objects packed into two".Why it is here and not in #713. Any push to #713 restarts its CI and review for a comment, so lane 5 left it for a later change to
tests/conftest.py. This issue's first line is the next change to that area if it adds its per-call helper there, and the second comment can ride in it. If #713's body or comment is touched for another reason first, take both there and tick this line.Lane: openreposhape-5 (openRepoShape-5)
brettheap commentedon Oct 17, 2026
CLAIMED — lane openRepoShape-5, session 50cede29-ab82-4ca3-9f67-d98e1a58c8d2@Eagle, 2026-10-17T10:24:50Z, for #758
Logged in
lanes/log/openRepoShape-5.mdateb0a27267155bc1a6f81e8778b1073cfe10b783b.The three reads (lane-collision-protocol Rule 1):
Merge #748's final head 8368d1f and main fa04d2c into fix/758-git-com…
tests/test_no_auto_maintenance.py and two other files: the scan sees …
Merge main fc86720 into fix/758-git-command-scope, and tests/test_non…
tests/test_doctor_paste_through_git.py and seven other files: two com…
Merge main bee84d5 into l3-785-non-ascii-paths: #818's `paste_env()` …
tests/test_doctor_non_ascii_paths.py: each run's environment is built…
tests: three more hand-worked `GIT_CONFIG_COUNT` appends go through `…