Repository navigation
Description
Goal: in the family holder's two pinned scripts, no printed remedy undoes another's write or refuses when typed as printed, the checkout a git mv moved is named, and bootstrap never says ok after git's update has stopped.
Filed by lane openRepoShape-5, from the five candidates (C1-C5) of rv876's independent review of #876 (#839), #876 issuecomment-6246717354. rv876 measured each one on git 2.43.0 and 2.47.1. Each is the same at #876's base 233a334e, so none is a regression of #876. path:line is at #876's head 77f8a6c8.
Lands after: #876 (fix/839-holder-bootstrap-texts), which changes these functions. Stack on it, or wait for its squash.
Lines
- C1. The wrong-case move's
git config -f .gitmodules submodule.<variant>.path <row path>line (_move_context,templates/family-root/scripts/validate-family.py:689-704) commits a one-key file where the work tree's.gitmodulesis gone.- Measured: OTHER recorded only at
Members/IRSS, with HEAD's section giving that path; the work tree's.gitmodulesdeleted.- In members mode the move is a refusal printed alone. Typed as printed, HEAD's file keeps one key, and every other section is lost (P5e).
- In
--no-membersmode, with MEMBER's url also gone, the move prints first. Itsgit add -- .gitmodulesstages the one-key file.member-gitmodules-url-absentthen printsgit checkout -- .gitmodules, which restores that staged one-key file. Typed and committed, the gate reportsmember-gitmodules-absentandmember-gitmodules-url-absentin every mode (P5b).
- Direction: put the file back first, from where git reads it, as the family root's bootstrap.py and validate-family.py: the credential advice and a member's exit code say what happened, and the gate's
git rm --cached, guardedmvand section lines type as printed where they failed (#839) #876's url-absent and absent findings do. And order the move's write with theirs, so that one put-back serves all.
- Measured: OTHER recorded only at
- C2.
member-gitlink-removal-stagedprintsgit checkout HEAD -- .gitmoduleswhere the work tree's file is gone (_put_back_lines,:2434-2435), and that undoes an earlier finding's write.- Measured:
git rm --cached members/IRRS, the file gone, and OTHER's section gone from HEAD. The absent finding puts the file back and writes OTHER's section. The removal-staged line then puts HEAD's file back over it. The commit fails with nothing to commit, andmember-gitmodules-absentreturns (P5d). - Direction: read "section taken" from the file as git reads it, not from the empty work tree. Print no second put-back after a finding that already put the file back.
- Measured:
- C3. A committed value git refuses, plus a stray gitlink: the stray's
git rm --cachedexits 128.- Measured: the value finding's
--unset-alllines leave.gitmodulesunstaged. The stray'sgit rm --cachedthen refuses withplease stage your changes to .gitmodules or stash them to proceed, and-fdoes not help (P5g). - Direction: print
git add -- .gitmodulesafter the value finding's lines, before anygit rm. Or order the stray's line first.
- Measured: the value finding's
- C4. After the
git mvstate's lines are typed as printed, the checkoutgit mvmoved stays atMembers/<P>, untracked and never named.- Measured in all three
git mvstates: clean, a commit in the checkout, and an untracked file in it.- After typing, the gate passes in every mode and
git statusreads?? Members/. family.py add --dry-runthen refuses withfamily-members-dir-variantandmv -- Members/IRRS <new name>.- After the update,
git -C Members/<P> statusreads the row's path, so the checkout's untracked file goes unseen. - Neither the STRAY finding nor
member-gitlink-removal-stagedsays what that directory is, or that its commits are in the member's store. The wrong-case move's closing sentences say both.
- After typing, the gate passes in every mode and
- Direction: name the checkout, with its
git -C <path> status, before the update, asfamily.py add's closing sentences do after family.py add: the move back of a member's gitlink points its section of.gitmodulesback, sets aside first what the index holds in its way and puts back a member whose removal is staged, its closingmvis guarded and leaves a checkout to delete by hand, and--sparsefollows the sparse rules, so no printed line leaves a section naming another spelling or un-registers a member (#761) #828 and family.py add: a section astray beside its gitlink, a variant of a row's path undermembers/, a link or checkout in a move's way, an unmerged entry and a staged or unmerged.gitmodulesare named first, so each remedy types clean (#840) #865.
- Measured in all three
- C5. Bootstrap says
family bootstrap ok, with the credential advice, while git's update has exited 128 (lane 4's RV877, O1 on bootstrap.py: a.gitmodulesblob with a line git cannot parse is read up to that line, as git reads it, and a parity test holds the value rules both family scripts write to one answer (#856) #877, issuecomment-6246457284).- The state: every member checked out, the work tree's
.gitmodulesgone, and a bad line such asbranch = "unterminatedcommitted in HEAD's file after the first section. - Measured: git's update exits 128 with
No url found for submodule path 'members/B'. Bootstrap prints the advice, thenfamily bootstrap ok, at77f8a6c8and at233a334ealike. - Why:
unfetchablereturns beforeinit_stopwhen no row is left (templates/family-root/scripts/bootstrap.py:758-759).git config --blobrefuses the whole blob, while git's own reader takes the first section, so the sections come back empty and are not markedunreadable.- The
okfollows bootstrap.py and validate-family.py:family bootstrap okwith no member checked out, an earlier row'smember-uninitializedhiding a case-variant refusal, andmember-gitlink-unnamedwith no command under--no-members#648's rule that a run with every member checked out passes.
- Direction: ask
init_stopeven when no row is left, and fail on a stop there. - Overlap: lane 3's bootstrap.py: a
.gitmodulesblob with a line git cannot parse is read up to that line, as git reads it, and a parity test holds the value rules both family scripts write to one answer (#856) #877 (bootstrap.py and validate-family.py (family root): a.gitmodulesin the index or HEAD with one bad line is read as no sections where git reads those before it, so a no-credential run fails wrongly, and the value rules are written twice #856) changes the blob read. Settle the order with it.
- The state: every member checked out, the work tree's
Verify:
- Each state above, typed as printed, then the gate in every mode.
- A plain clone plus
git submodule update --init --recursiveexits 0 with every member checked out. - For C5, bootstrap exits non-zero and names the stop.
- One mutant per line, each caught.
- Both scripts are pinned in every holder (
FAMILY_COPIED_VERBATIM), so each holder takes oneupstream-changedrow per file. - No Windows or macOS run, since CI is Linux only (ci: run the test suite on Linux only #597).
Overlaps: #876 (#839), lane 3's #877 (#856, stacked on #876), lane 4's #878 (stacked on #876) and lane 4's #870 all edit validate-family.py; #877 also edits bootstrap.py.
Parent: #459.
Milestone: v1.1.1. Each line needs the work tree's .gitmodules gone, a hand git mv, or a hand-committed bad line, and then the printed remedies typed in order. None is a regression, and the gate's verdicts in the plain states are unchanged.
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 18, 2026
CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-18T06:53:04Z, for #879
Logged in
lanes/log/openRepoShape-4.mdat3649c90d2ad83016fa1450a374e1c2d2b2212699.The three reads (lane-collision-protocol Rule 1):
the family root's bootstrap.py and validate-family.py: the credential…
docs/release-notes/v1.1.1.md: the v1.1.1 notes take RV883's NIT list …
validate-family.py: `gitmodules-path-unnamed` takes the gitlink at a …
docs/release-notes/v1.1.1.md: the v1.1.1 notes take RV883's round 3 a…
docs/release-notes/v1.1.1.md: the v1.1.1 notes run to main a249910, w…
docs/release-notes/v1.1.1.md: the v1.1.1 notes run to main 0d5d2b1, w…
docs/release-notes/v1.1.1.md: the v1.1.1 notes run to main e7039b7, w…
validate-family.py and bootstrap.py: a staged removal's section writt…
docs/release-notes/v1.1.1.md holds the v1.1.1 release notes, and rele…
validate-family.py: a staged removal writes no section into a `.gitmo…
docs/release-notes/v1.1.1.md: #778's leg-clone sentence says which le…
validate-family.py: a hand mount's text quotes both of git's refusals…
docs/release-notes/v1.1.1.md: the points RV883 round 5 held for after…
validate-family.py and bootstrap.py: the holder's remedies, typed as …
Merge #889's final head b41f722 into fix/430-f-siblings-bootstrap-unr…
the family root's bootstrap.py: a gitlink a member's own index gives …