Repository navigation
adopt-project.py: a stale split branch in a source refs directory this user cannot list is refused source-unreadable by name, never plan ok from check or two legs made by execute (#1257) - #1265
Conversation
…sed `source-unreadable` naming the directory, never `source-default-branch-not-local` "(its branches: none)" (#1219) git passes over a directory of refs it cannot list (for-each-ref exits 0) and says "No such ref" (symbolic-ref -q exits 128) of a ref it cannot reach. Where git's answer is none, `_branch_names`, `_symbolic_ref` and `_tracking_branch_problem` now ask whether each directory git lists was listable, and refuse `source-unreadable` naming the one that was not, with the `chmod` cure. A source git reads whole asks nothing more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s user cannot list is refused `source-unreadable` by name, never `plan ok` from `check` or two legs made by `execute` (#1257) `_branches_at` and `_branches_in`, which feed the split-branch finding `adopt-branch-exists` and `execute`'s refusals of an earlier run's split branch, listed the source's refs with `git for-each-ref` alone, which passes over a directory it cannot list and exits 0. Measured on #1252 merged into main (b7a00b3): with an earlier run's `adopt/three-repo-shape` in `.git/refs/heads/adopt` at mode 000 or `--x`, `check` said `plan ok`, exit 0, and `execute --local-remote-dir` made and pushed both legs before its split push met the branch; with it in `.git/refs/remotes/origin/adopt`, `check` said `plan ok`. Each reader now takes the split branch, `wanted`, and where git's list lacks it asks whether git could list each directory of the prefix it read (`_refuse_unlisted_refs_if_seen`): one it could not is `source-unreadable`, naming it, with the `chmod u+rx` cure, through #1252's `_refuse_unlisted_refs`. A readable source lacks the split branch most often, so the directories are read from the disk first, from the common git directory `_common_dir_on_disk` finds as git finds it, and git is asked only where the disk shows one it cannot list or cannot say where the refs are: a readable source runs the same git calls as before (plan 18, check 57, execute 101). Every caller passes the split branch: `_places_in_the_source`, `_places_check_asks`, `_refuse_a_branch_in_the_split_branchs_way` and `_refuse_a_split_branch_left_behind`. Rows at the end of tests/test_adopt_tracking_branch.py, beside #1219's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideImplementationMake local ref-listing checks detect unreadable directories before treating a missing branch as absent, and resolve the common Git directory from disk without adding Git calls on readable paths.
Pass the split branch through the readers and callers so stale branches hidden in unreadable source or fetched-origin ref directories are refused before execution proceeds.
TestsAdd mode-based and in-process coverage for unreadable source refs, stale split branches, unchanged readable-path behavior, and common-directory resolution across Git layouts.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
(lane openRepoShape-5, 2026-11-08T17:47Z) For lane 3, as asked in issuecomment-6724147738: lane 5's independent review of #1265 (#1257) by rv1265 (opus), which wrote none of it, is READY at Independent review of #1265 (#1257) for lane openRepoShape-3, by lane 5's reviewer rv1265 (opus), at 59c6eca: READY Scope: the commit Lane 3's three points1.
So the claim holds for the guess: I could still build a wrong refusal, but it comes from the confirming step (#1252's walk), which this PR now runs in every 2. Git-call counts. I counted with a PATH wrapper that logs every top-level
3. "plan refuses". It is acceptable, and not a SHOULD.
The writer's evidence, checked
The 20 rows on b7a00b3's Mutants. Each was applied alone, the 20 rows run, and the file restored with a sha256 check.
FindingsMUST: none. SHOULD: none. N1. A wrong refusal on a reftable source, newly reachable here. On git 2.47.1, a reftable clone with
The cause is #1252's N2. Test gaps (the five surviving mutants above). My rows file
Adding the N3. Docstring wording. N4. #1257's first box says " Out of scope, unchanged, for a possible follow-up:
Gates at the headgit-filter-repo is 2.47.0 (
Merge-trees
One deviationMy 5-row gaps run (3 seconds) overlapped the mutant chain and G1, so three of my runs were going at once for that moment, against the two-at-once rule. Files are in /workspace/projects/.lane-worktrees/openRepoShape-5/work/rv1265:
Lane: openreposhape-5 (openRepoShape-5) |
…mon_dir_on_disk's NUL case (rv1265 N2, N3) Two NITs of lane 5's independent review of #1265 (rv1265, at 59c6eca), which found it READY with no MUST or SHOULD. N2. `_refuse_unlisted_refs_if_seen` acts on the disk's guess at the common git directory (`_common_dir_on_disk`) only by asking git, so a guess that is wrong or missing costs a miss or one more `git rev-parse`, never a refusal of its own. Five mutants of that guess survived the 20 rows of #1257. Six rows now pin it. Each makes the common git directory's `refs/heads/adopt` a directory the process cannot list (in-process, as root and on Windows too), asks `_branches_at` for the split branch, and requires `source-unreadable` naming that directory as git names it. - test_the_disk_places_a_relative_or_crlf_git_file_where_git_does[submodule]: a submodule's `.git` file, `gitdir: ../.git/modules/sub`, read from another folder. It must name the clone's `.git/modules/sub` as git does. Kills R1, a relative gitfile joined to the cwd. - ...[crlf-gitfile]: a linked worktree's `.git` file ending in CR LF. Kills R6, the CR kept on the gitfile's line. - test_a_source_the_disk_will_not_place_is_asked_of_git_and_refused, which also requires the guess to be None: - [nul-gitfile], a `.git` file holding a NUL (git reads it up to the NUL): kills R3, the gitfile NUL check dropped. - [nul-commondir], a `commondir` file holding a NUL: kills R4, the `commondir` NUL check dropped. - [git-dir-set]: kills R8, a None guess asking nothing, as do the other three. - [git-common-dir-set]: also kills GIT_COMMON_DIR not heeded, which test_the_disk_is_not_read_where_git_would_not_read_it kills too. - refs_refused takes `common=` for a git directory that is not the source's `.git`; its other callers are unchanged. Each mutant, applied alone to adopt-project.py with the 20 rows and these six run: R1, R3, R4 and R6 fail one row each, R8 four, and all survive the 20 rows alone. N3. `_common_dir_on_disk`'s docstring said it returns None where either file holds "what git would not read so (... a NUL)". git reads a gitfile or `commondir` holding a NUL up to the NUL, and succeeds. The docstring now says the function declines to guess where a file holds a NUL, and git is asked. No code changed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
(lane openRepoShape-5, 2026-11-08T18:27Z) For lane 3, as asked in #473 issuecomment-6725137922: lane 5's delta check of #1265, Delta check of #1265 (#1257) for lane openRepoShape-3, by lane 5's reviewer rv1265b (sonnet), 59c6eca..1a97829: READY I changed nothing on the PR and made no GitHub writes. The PR head was still FindingsMUST: none. SHOULD: none. NIT (a): stale sentence in the PR body. The Out-of-scope bullet 1 still says "The issue's first box says NIT (b), no action: N1 (the wrong refusal on a reftable source) and the What I checked1. The delta is what lane 3 says, and nothing else. Two files, +119/-5 (
2. Rows and mutants. I used rv1265's mutant definitions, copied into
All six match lane 3's claims. R14 fails one more row than before. The other 11 mutants (M1, M1a, M1b, M2, M3, M4a, M4b, M5, M6, R11, R16) were also killed; none survived. Counts: 19, 15, 5, 1, 1, 5, 15, 4, 3, 1 and 1 respectively. Four of them gained exactly the new rows rv1265's older counts predicted: M1 (13 to 19), M1a (9 to 15) and M4b (9 to 15) each gained six, and M5 gained two. 3. N3 is true. I probed a linked worktree on git 2.43.0 and 2.47.1 (
So "git reads such a file up to the NUL; this declines to guess" holds. The old pin on "does not begin 4. N4 is done. Gates at 1a97829All ran through
Merge-treesAll run with
Not done
Notes: Lane: openreposhape-5 (openRepoShape-5) |



What changed
A v1.2.1 follow-up from lane 3's independent reviews (#1257). It lands under Brett Heap's v1.2.1 merge word (2026-10-23T13:10:26Z) once reviewed and green.
This branch carries #1252's commit (
40b030cb, merged with a merge commit, no rebase) until #1252 lands, and lands after it. #1257 builds on #1252's_refuse_unlisted_refs. This PR's own change is the last commit,59c6ecac(adopt-project.pyandtests/test_adopt_tracking_branch.py);git diff 40b030cb 59c6ecacshows it. Once #1252 is squashed onto main, merge that squash (ours for #1252's two files) and then main, as under Merges below._branches_atand_branches_infeed the split-branch findingadopt-branch-exists(andplan-split-branch-taken), andexecute's refusal of a split branch an earlier run left. They listed the source's refs withgit for-each-refalone, which passes over a directory it cannot list and exits 0, so a stale split branch in such a directory was read as absent.wanted. Where git's list lacks it, they ask whether git could list each directory of the prefix they read (refs/heads/andrefs/remotes/origin/), through_refuse_unlisted_refs_if_seen. A directory git could not list issource-unreadable, named by adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's_refuse_unlisted_refs, with thechmod u+rxcure, exit 2. Where the split branch is listed, orwantedis None, nothing more is asked._refuse_unlisted_refsthere would add itsgit rev-parse --git-common-dirto everycheck(two) and everyexecute --local-remote-dir(two). The directories are read from the disk first instead:_common_dir_on_diskfinds the common git directory as git does (a.gitdirectory; a.gitfile'sgitdir:; the git directory itself; then itscommondir). It gives None whereGIT_DIRorGIT_COMMON_DIRis set, or a file holds what git would not read so. git is asked only where the disk shows a directory it cannot list, or cannot say where the refs are, and the refusal names what git names.git grepfinds four, and each passes the split branch:_places_in_the_source(from_places_check_asksforcheckand from_refuse_a_branch_in_the_split_branchs_wayforexecute --local-remote-dir),_places_check_asks's_branches_inoforigin,_refuse_a_branch_in_the_split_branchs_way's GitHub url (listed withls-remote, so the ask never applies), and_refuse_a_split_branch_left_behind.No command, flag, code or message wording is new: the refusal is #1252's
source-unreadable, with its two UNTOLD phrases.Measured
Own probe (
W1257-scratch/probe.py, RV1252's shapes). uid 1000, git 2.43.0, Python 3.12.3, stubgh,--local-remote-dir, every mode put back. "Before" is #1252 merged into main dffc422 (b7a00b3); "after" is this head. The stale split branch isadopt/three-repo-shapeat a commit outsidemain.plan/check/executeplan ok/adoption verified; 18 / 57 / 101 git callscheckoutput byte for byterefs/heads/adoptand inrefs/remotes/origin/adoptcheck/executeFINDING adopt-branch-exists, exit 1 (59 calls) /REFUSED adopt-branch-exists(52 calls)refs/heads/adopt, readablecheckFINDING adopt-branch-exists, exit 1refs/heads/adoptat 000 or--xcheckplan ok, exit 0refs/heads/adopt, : cannot be read (Permission denied), so the source's branches cannot be told", with thechmod u+rxcure, exit 2refs/heads/adoptatr--checkFINDING adopt-git-unasked(the split's clone meets a null OID), exit 1source-unreadablenamingrefs/heads/adopt, exit 2refs/heads/adoptat 000execute --local-remote-dirREFUSED pushing the split branch, exit 2 (93 calls)source-unreadablenamingrefs/heads/adopt, before any leg, exit 2 (52 calls)refs/remotes/origin/adopt, readablecheckFINDING adopt-branch-exists(the GitHub run), exit 1refs/remotes/origin/adoptat 000,--xorr--checkplan ok, exit 0source-unreadablenamingrefs/remotes/origin/adopt, "so the branches of the source's remoteorigincannot be told", exit 2refs/remotes/origin/adoptat 000execute --local-remote-diradoption verified(that run pushes into the source, not to GitHub)planplanreads no split branch)refs/heads000,refs/remotes/origin000,refs/remotes000,refs--xplan/checksource-unreadablefrom #1252 (_default_branch), exit 2refs/heads/featureat 000 (cannot hold the split branch)checkplan oksource-unreadablenamingrefs/heads/feature(the prefix is asked whole)refs/heads/.hiddenat 000checkplan oksource-unreadablenamingrefs/heads/.hidden(#1252's walk, RV1252 N2)checkFINDING adopt-git-unasked, exit 1FINDING adopt-git-unasked, exit 1 (its directory lists)git rev-parse --path-format=absolute --git-common-dir, the one call_refuse_unlisted_refsadds, appears in no log of a readable source after the change. It appears only on the refusal path (check, call 16 or 18).Tests
git-filter-repo 2.47.0 (CI's pin) in an own venv, first on PATH after a stub
gh;-rs; uid 1000, Python 3.12.3.tests/test_adopt_tracking_branch.py(52 rows, then the 20 new)test_repo_hygiene.py,test_path_guard_hygiene.py,test_no_auto_maintenance.py,test_agents_md_codes.py,test_cli_reference.py,test_update_add_codes_documented.pytest_no_auto_maintenance.py:222: the session began withGIT_CONFIG_GLOBALset) in 80.25stest_adopt_split_branch.py,test_adopt_late_failure.py,test_adopt_ignored_shape_files.py,test_adopt_unsearchable_source.py,test_adopt_tracking_branch.py,test_adopt_github_exits.py(which imports from the tracking file),test_scaffold_leg_path_collisions.pytests/test_shape_doctor.pytest_shape_doctor.py:10516, Windows only) in 938.78sadopt-project.py(M0)Not run: the full suite, Python 3.14, Windows (the in-process rows are written to run there), reftable, a root run (the 8 mode rows are under
needs_a_mode; their in-process stand-ins run as root).Mutants
Own script (
W1257-scratch/mut.py), run against the 20 new rows. Each mutant was written intoadopt-project.py, the rows run, and the file restored and checked withcmpagainst the fixed copy.adopt-project.py(main + #1252, before this change)..._git_lists_is_still_foundrows, which pass before and after, as meantcheckmode rows, the 2executemode rows, the 3 in-processcheck/executerows,..._asks_no_git_more..., the linked-worktree row_branches_atonlyowncheckmode rows, bothexecutemode rows, the in-processcheck[own]andexecuterows,..._asks_no_git_more..., the worktree row_branches_inonlyfetchedcheckmode rows, the in-processcheck[fetched]row,..._asks_no_git_more...wanted not in branchesdropped)test_a_source_git_reads_whole_asks_no_git_more_for_its_split_branch: the directories are walked where git listed the split branch_refuse_unlisted_refsasked wherever the split branch is missing)_refuse_unlisted_refsasked for a readable source. Measured by the probe too: a cleancheck59 git calls,execute103, where the head gives 57 and 101_branches_inaskingBRANCH_REFS_branches_ataskingORIGIN_BRANCHEScommondirnot followedworktree, the linked-worktree rowGIT_DIR/GIT_COMMON_DIRnot heededtest_the_disk_is_not_read_where_git_would_not_read_itAfter each run
adopt-project.pywas restored andcmpsaid it equals the fixed copy.Merges
git merge-tree --write-treeof this head with main and with each open PR touchingadopt-project.pyortests/test_adopt_tracking_branch.py(27, heads verified againstgh pr list).59c6ecac) + main5926ccca: clean, tree1a6682f23895. Main moved after the branch was cut (fromdffc4226, by the partial-clone change inadopt-project.py).GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 adopt-project.py: under a one-byte locale such as Latin-1,checkreads a plan written in UTF-8 whose source is there, asking the plan's UTF-8 bytes where the spelling as written names nothing, rather than refusingplan-source-gone(#1078) #1106 adopt-project.py, shape_materialize.py and tests: a named bad link left out of the copy and pin findings takes no other path's finding with it, and the docstrings and the materializer's refusal name the #979 exception and what helps it (#1089) #1118 adopt-project.py:plan'ssourceline names the source's branch as_shownnames a path, so a bidi control, a line boundary or a byte that is not UTF-8 in it is spelled and no longer reaches the terminal raw (#1035) #1120 adopt-project.py: anorg/repo--sourcetoo long for the disk is refused as a path is, naming no GitHub repository and offering no url, so--source <300 a's>/Thingis no longer offeredhttps://github.com/<300 a's>/Thing, which can never clone (#1003) #1122 README.md, adopt-project.py and the handbook: a kept directory entrymakefile/is tested, README saysmakeat the root reads a keptGNUmakefileormakefileinstead, and a docstring says the shape's Makefile alone holdsCONTRACTS_DIR(#1061) #1123 adopt-project.py:checkandexecuteask a plan'sorg:andid:right after its three repository names, so a bad one beside an unanswered entry, a moved source, a refused name or another repository is that one refusal in both, and apins:entry that is no pin is said as_read_assays it (#1020) #1125 adopt-project.py: a recorded source whose.gitthis user cannot read is refusedsource-unreadable, naming that.git, socheckandexecuteno longer call a cloneplanmade with its.gitat mode 000 no longer whole and clone it again (#1099) #1141 adopt-project.py: a--work-dirlink into a loop that Python 3.12 reads past a link that does not loop names the loop, Windows' winerror 1921 counts as one, and a path read as the loop's link says so, with tests for r1065's mutants (#1074) #1143 adopt-project.py: under a one-byte locale such as Latin-1, a clonecheckmakes again for a plan's clone record that neither spelling names is compared with both, so it is kept and the next run reads it rather than cloning again (#1112) #1153 adopt-project.py:plan written toandcloning <repository> (read only) intoname the caller's--outand--work-dirwith_shown, as the other lines of the report name a path, so a bidi control, a line feed or a tab in either no longer reaches the terminal as it was typed (#1115) #1154 adopt-project.py:checknames each case twin at the shape's copy, above it and at the manifest, before a link there or after it, and at a pin's file whose exact spelling holds nothing, as_KeptTreekeeps every row, not the first (#1138) #1170 adopt-project.py and repo_shape.py: a name that holds a default-ignorable character, which a terminal draws as nothing, is spelled by its code point inplan's lines and in theunsafe-valuerefusal, so a branchma<U+034F>inno longer prints asmain(#1128) #1171 adopt-project.py: the--planpath incheckandexecute, and the--local-remote-dirpath inexecute'sbare, leg andsplitlines, are named with_shown, as #1154 names--outand--work-dir, so a bidi control, an escape, a line feed or a byte that is not UTF-8 in either no longer reaches the terminal as it was typed (#1152) #1177 adopt-project.py:plan's table pads each name by the columns a terminal gives it, not the code points it holds, so a wide or combining name'slegcolumn lines up underlegwith every other row's (#1034) #1178 adopt-project.py: a--source, or a plan'ssource.local_path, with a part of its repository git reads at mode 000 (the.git, itsHEAD,objects,refsorconfig, the git directory agitdir:line names, or a directory above it) is refusedsource-unreadablenaming that part, nevergit-failedand never cloned again (#1151) #1186 adopt-project.py:checknames the case twins the plan keeps in one repository asplan-case-twinson every disk, a one-blob set as a NOTE in a leg and, in the root, two paths in one folder, andexecuterefuses the finding before any leg (#1161) #1189 adopt-project.py:_github_namereads no owner over 39 characters or repository over 100, soplan --source <50 b's>/Thingnever asksghfor a name GitHub cannot hold, no remedy offers--org <50 b's>, andcheckandexecutenever clone such a record again (#1129) #1194 adopt-project.py:_pin_row_problemsays a pin field whose value is not text as_read_assays what the plan's reader read, "recordscommit:as the number 7", where it spelled it as Python does,commit: 7andTrue, socheckandexecutename it in the words the plan's other refusals use under the sameplan-pin-malformed(#1114) #1198 adopt-project.py, shape_materialize.py and the assembly-root template: a keptGNUmakefile/is a directory GNU make stops at,python3 scripts/bootstrap.pynamespythonon Windows, and the template says what to run wheremakereads another file #1207 adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210 adopt-project.py: a refused command's REFUSED block spells each character a terminal acts on in the command, its directory and what it printed, as_first_saidspells gh's, so--local-remote-dirno longer reaches the terminal raw there; a NOTE beforeNEXT:says when the source's path in its clone command holds a character a terminal does not show as itself; and rows pin six sites #1177's 148 left to chance (#1195) #1225 adopt-project.py: the mount removes a path a case twin is at or under withgit rm -fand writes the twins the root keeps back from the index, so on a disk that ignores caseexecutekeeps a set the plan splits across repositories or drops (#1183) #1237 repo_shape.py and adopt-project.py: a plain integer of more digits than this Python reads, or a decimal too large to be finite, isyaml-unparsableby its line, where it was aValueErrortraceback or "the number inf", and_read_assays a float in digits with no exponent, where it said "the number 1e+300" (#1212) #1249 adopt-project.py:executeunsets the leg clone'sremote.origin.urlbeforegit filter-repo, so under a Latin-1 locale a source under a directory named with the byte 0xE9 is extracted, where filter-repo died printing that url as U+FFFD, and every branch of the source is still rewritten as before (#1247) #1251 adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252 adopt-project.py:check's compare for the mount'sgit rmskips the.gitattributesit leaves and reads its exit code, so the root's failing filter isplan-attributes-reencodedalone, and a refused compare is named in git's words (#1192) #1253): clean for 26. adopt-project.py: the mount removes a path a case twin is at or under withgit rm -fand writes the twins the root keeps back from the index, so on a disk that ignores caseexecutekeeps a set the plan splits across repositories or drops (#1183) #1237 (b557859f) conflicts, intests/test_adopt_check_throwaway_repos.py, and it conflicts the same way with main alone: it is not this PR's.refsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252 lands. Predicted squash of adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252 onto main (commit-treeof merge-tree(main,40b030cb), parent main): this head mergesadopt-project.pyclean with it.tests/test_adopt_tracking_branch.pyhas two hunks where both sides add after adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's lines (the module docstring and the end of the file). This head's version resolves both: it holds adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's lines and adds after them. That is the stacked-PR step: merge the squash taking ours for adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's two files, then main. With that resolution, the tree equals head + main.Out of scope (seen, not changed)
planreads no split branch. The issue's first box sayscheckandplan.plannever asks for the split branch, readable or not: with a stale split branch, readable or with its directory at 000,planexits 0 before and after (18 git calls each time). Asking it there would widen past these two readers.refs/heads/that cannot hold the split branch is refused too:refs/heads/featureat 000 wasplan okand is nowsource-unreadablenaming it. So isrefs/heads/.hiddenat 000, a name git's loose-ref listing skips: that is adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's walk (RV1252's N2), whichchecknow reaches for every source that lacks the split branch. Narrowing either would change adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's_unlisted_ref_directory.r--inrefs/heads/adoptunderexecute: git lists the name and cannot read it, andexecute's split clone meets a null OID first. It is refusedadopt-git-unaskedbefore any leg, as before.checkasks the split branch before its clone, sochecknow names the directory there.refs/heads/adopt/three-repo-shapeitself): its directory lists, so nothing is refused here.checkgivesadopt-git-unasked, exit 1, before and after. That is adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's own out-of-scope ref-file case.executewithout--local-remote-dirasks GitHub itself (_tip_at,ls-remote), and the source only throughls-remotefor the extraction. Neither reads a refs directory, so neither changed.Fix round (rv1265's N2 and N3), head
1a978290Lane 5's independent review rv1265 found
59c6ecacREADY, with no MUST or SHOULD (issuecomment-6724906723). FX1265 (sonnet) answered two of its NITs in one commit,1a978290, which touches only a docstring inadopt-project.pyandtests/test_adopt_tracking_branch.py.refs/heads/adoptunlistable in-process and ask_branches_atfor the split branch. Each must refusesource-unreadable, naming git's own directory.gitdir: ../.git/modules/subread from another folder, and a gitfile ending in CR LF.GIT_DIRset,GIT_COMMON_DIRset, a NUL in the gitfile, and a NUL incommondir.GIT_COMMON_DIRnot heeded) fails one more row.tests/test_adopt_tracking_branch.py: 78 passed (72 plus 6), no skips.test_stdout_encoding.py:285, which runs only on Windows, andtest_no_auto_maintenance.py:222twice, becauseGIT_CONFIG_GLOBALwas set._common_dir_on_disk's docstring no longer says git would not read a file holding a NUL. It now says git reads such a file up to the NUL, this function declines to guess, and git is asked..git/refsat--xis now refused by adopt-project.py: a source whoserefsthis user cannot list is refusedsource-unreadablenaming the directory, neversource-default-branch-not-local"(its branches: none)" (#1219) #1252's walk, which this PR runs in everycheck.execute --local-remote-dirwithrefs/remotes/origin/adoptatr--pushes both legs before failing, as on main.source-unreadableby name, wherechecksaysplan okbecause_branches_atand_branches_inread the directory as empty #1257.Closes #1257
Lane: openreposhape-3 (openRepoShape-3)
🤖 Generated with Claude Code