Repository navigation
validate-family.py: in a sparse checkout that leaves .gitmodules out, the put-back line git checkout -- .gitmodules matches no file and every git add -- .gitmodules the findings print exits 1, so no printed line set cures a finding there #1242
Description
Problem
templates/family-root/scripts/validate-family.py prints remedies for .gitmodules as lines to type: a put-back of the file git reads where the work tree holds none (GITMODULES_SOURCES, _gitmodules_put_back: git checkout -- .gitmodules for the index's), git config -f .gitmodules ... edits, and git add -- .gitmodules (STAGE_LINE, about ten call sites: the value check, gitmodules-path-unnamed, the hand mount and stray lines, the staged removal's _keys_back, the wrong-case move, and the gitmodules-unreadable refusal for the index's file that #1227 adds).
In a sparse checkout whose patterns leave .gitmodules out (non-cone /* and !/.gitmodules; its index entry is skip-worktree, git ls-files -t says S), none of these works:
git checkout -- .gitmodulesexits 1:error: pathspec '.gitmodules' did not match any file(s) known to git.- So the
git config -f .gitmodules --unset-all ...after it has no file and exits 5. git add -- .gitmodulesexits 1 even once the file is on disk:The following paths and/or pathspecs matched paths that exist outside of your sparse-checkout definition, so will not be updated in the index(hint:Use the --sparse option).- A plain
git commitafter the lines then records what the index held, the value git dies on and all.
The family bootstrap already prints its index put-back with --ignore-skip-worktree-bits (gitmodules_cures, RV877's NIT-3), and tests/test_family_gitmodules_values.py's put_back_mended_and_committed adds with --sparse there; the gate's own lines do neither.
Measured
Git 2.43.0, offline (run9.sh: stub gh, GIT_SSH_COMMAND=false, GIT_CONFIG_GLOBAL=/dev/null), on #1227's branch merged with main e04826db4 (d95308e95). The probe is lane 5's scratch v124/n1150/d/probes/test_n1150d_probe.py (test_s2_*), logs in v124/n1150/d/probes-out/merged-d95308e/s2-*.log; rv1227's probes e3a and e3b (v129/rv1227/out/head/e3a-*.log, e3b-*.log) gave the same on #1227's head b031f4938.
update = !truestaged in MEMBER's section of the index's file, thengit sparse-checkout set --no-cone '/*' '!/.gitmodules'(lose_by_a_sparse_checkout). The gate (--no-members) givesgitmodules-value-refused, exit 1, withgit checkout -- .gitmodules, the--unset-allline andgit add -- .gitmodules.- As printed:
git checkout -- .gitmodulesexits 1, the--unset-allexits 5,git add -- .gitmodulesexits 1, and a plaingit commitrecords!truein HEAD (rv1227's e3a). - In their place:
git checkout --ignore-skip-worktree-bits -- .gitmodulesexits 0 and clears the bit (ls-files -tsaysH); the--unset-allexits 0;git add -- .gitmodulesstill exits 1 (outside the sparse-checkout definition);git add --sparse -- .gitmodulesexits 0; a plaingit committhen has nothing to commit, HEAD holds no value, and the gate passes.
- As printed:
- HEAD's file and then a line git cannot parse, staged, and the same sparse checkout. The gate refuses
gitmodules-unreadablefor the index's file, exit 2. Its remediation'sgit checkout -- .gitmodulesexits 1 and itsgit add -- .gitmodulesexits 1 (rv1227's e3b). With--ignore-skip-worktree-bits, the line mended by hand, andgit add --sparse, the gate passes.
Suggested fix
Where the index's .gitmodules entry is skip-worktree (git ls-files -t -- .gitmodules starts S, or -v gives a lower-case letter), print the index's put-back as git checkout --ignore-skip-worktree-bits -- .gitmodules (in _gitmodules_put_back, as bootstrap prints it) and every stage line as git add --sparse -- .gitmodules: a _stage_line(root) in place of the constant STAGE_LINE at each call site, and the same in the words that quote it (STAGE_SAID, the refusal's remediation). HEAD's put-back, git checkout HEAD -- .gitmodules, needs no flag: it is printed only where the index holds no entry. Elsewhere every line stays as it is, so no text outside that state changes. git add --sparse needs git 2.34 or later.
Verify
- A row for each finding that prints a put-back or a stage line, in the sparse checkout above: the lines typed as printed, in order, then a plain
git commit, leave HEAD right and the gate passing in every mode (ends_well), on git 2.43.0 and 2.47.1. - Every existing row of
tests/test_family_gitmodules_values.py,tests/test_validate_family_index_gitmodules.py,tests/test_validate_family_index_value_unmerged.py,tests/test_family_hand_mount_git_rm_lines.pyandtests/test_family_holder_remedies_compose.pypasses unchanged: no line changes outside a sparse checkout. tests/test_path_guard_hygiene.py,tests/test_agents_md_codes.py,tests/test_cli_reference.pyandtests/test_pinned_copy_text.pypass.
Found by rv1227's S2 on #1227 (issuecomment-6374575208); kept out of #1227's fix round because the fix changes every stage line the gate prints, not only #1227's.
Lane: openreposhape-5 (openRepoShape-5)
Activity