Repository navigation
bootstrap.py: the name the rename line gives a twin skips one with a branch stored under it, Main-kept over Main-kept/x, which git refuses, so the pasted line works and the next run makes the tracking branch (#1000) - #1006
Conversation
…branch stored under it, `Main-kept` over `Main-kept/x`, which git refuses, so the pasted line works and the next run makes the tracking branch (#1000) Follow-up of #962 (landed as #984, 2a78ae1): rv984b's two NITs. `_kept_name` chose `<twin>-kept` when no branch of the leg FOLDED to it, and did not look for a branch stored UNDER it. With the leg detached at the pin, `Main` packed with a commit and a branch `Main-kept/x`, the refusal printed `git -C spec branch -m Main Main-kept`, which git refuses with exit 128 (`'refs/heads/Main-kept/x' exists; cannot create 'refs/heads/Main-kept'`; a loose ref or a packed one, at any depth; git 2.43.0 and 2.47.1, the reftable backend too), and the next run printed the same line, so the person had to choose a name. `_taken(held, name)` is now the question `_kept_name` asks: one of the branches, folded, is the name, or starts with the name and a slash. `Main-kept-2` is printed, the pasted line works, and the next run makes the tracking branch. A disk that folds case reads `main-kept/` as `Main-kept` too, so the fold applies as it does for a name that is there. What git does not refuse is left alone: a branch that only starts with the name (`Main-kept-x`), a tag, a remote-tracking ref or the stash of that name, and an unborn HEAD twin, whose rename only rewrites HEAD. A branch that is a directory prefix of the name cannot be held beside a twin below it, and would stop the tracking branch itself. A reflog directory left under the name by hand, and a name at the file-name limit, are refused by git and cannot be seen from the refs; `_kept_name`'s docstring says so. A test row for a twin whose name has a slash (`--branch team/main`, a packed `Team/main`, detached over it and on it): rv984b's mutant O3, `_folded_spelling` returning the last path part, survived 63 of 63 tests, and is killed, as is the same cut at the HEAD-twin site. tests/test_bootstrap_create_twins.py: 13 tests added, 9 of which fail at 2a78ae1; the other 4 pass there by design (a name that only starts with the name, or holds it in the middle, is no bar; the two slash rows pin code that was right). bootstrap.py is a pinned copy: every project's `bootstrap.py` takes an `upstream-changed` row, and re-pins it. Closes #1000 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
(lane openRepoShape-5, 2026-10-19T20:38Z) @codex review |
Reviewer's GuideThe PR makes bootstrap-generated twin rename commands reliably pasteable by skipping candidate names blocked by folded branch descendants, then validates the behavior across ref storage formats, case and Unicode variants, slash-containing names, and subsequent bootstrap runs. Sequence diagram for pasteable twin branch renamesequenceDiagram
participant Bootstrap
participant Git
participant User
Bootstrap->>Bootstrap: _heads(sub)
Bootstrap->>Bootstrap: _kept_name(sub, spelling)
Bootstrap->>Bootstrap: _taken(held, name)
alt candidate is occupied or has a held descendant
Bootstrap->>Bootstrap: Try next -kept candidate
else candidate is available
Bootstrap-->>User: Print git -C <leg> branch -m <twin> <name>
User->>Git: Paste branch rename command
Git-->>User: Rename succeeds
User->>Bootstrap: Run bootstrap again
Bootstrap->>Git: Create tracking branch at pin
end
Flow diagram for selecting a safe kept branch nameflowchart TD
A[Candidate: spelling-kept] --> B["_taken(held, name)"]
B -->|folded name exists| C[Try spelling-kept-2]
B -->|held branch starts with folded name plus slash| C
B -->|available| D[Return candidate]
C --> B
D --> E[Print pasteable git branch -m command]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Independent review of #1006 (#1000) at The fix does what #1000 asks. In a real repository, the line printed over a branch stored under MUSTNone. SHOULDNone. NIT
Checked and found true
Could not verifyNothing on a real APFS or NTFS disk. What a folding disk does with a directory Reviewer: rv984b, lane 5's independent reviewer, not the writer (w1000). Lane: openreposhape-5 (openRepoShape-5) |
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 1 hour and 34 minutes by commenting |



Lane: openreposhape-5 (openRepoShape-5)
Claim: #1000 (comment)
Follow-up of #962 (landed as #984,
2a78ae1a): the two NITs of rv984b's READY re-check (#984 issuecomment-6266764236), filed as #1000. One commit,9b8c643f, on2a78ae1a. Two files change:templates/assembly-root/scripts/bootstrap.pyandtests/test_bootstrap_create_twins.py(+177, -10).A pinned copy: every project's
bootstrap.pytakes anupstream-changedrow, and re-pins it. No digest of the template is kept anywhere, and #984 handled it the same way.The Goal
The line step (a) prints to rename a twin,
git -C <leg> branch -m <twin> <name>, can be pasted as it is._kept_name's docstring says so (#962), and #984 chose the concrete<twin>-keptname to keep that promise. It broke when a branch is stored UNDER the chosen name.What was wrong (#1000 item 1)
_kept_nameskipped<twin>-keptonly when a branch of the leg FOLDED to it. With the leg detached at the pin,Mainpacked and holding a commit, and a branchMain-kept/x, the line wasgit -C spec branch -m Main Main-kept, which git refuses: exit 128,error: 'refs/heads/Main-kept/x' exists; cannot create 'refs/heads/Main-kept',fatal: branch rename failed. The next run printed the same line again, so the person had to find a name alone. On a disk that folds case,main-kept/xblocksMain-keptthe same way.What changed
_taken(held, name)(new,bootstrap.py): the name is taken when a held branch, folded, is_fold(name)or starts with_fold(name) + "/"._kept_nameloopswhile _taken(held, name):<twin>-kept, then-kept-2and on.Main-kept-2is printed, the pasted line works, and the next run makes the tracking branch._takenand_kept_namestate the rule, why a branch that is a directory PREFIX of the name needs no check, and what the helper cannot see (below)._kept_nameskips a-keptname with a branch stored under it, and a test row for a twin with a slash (follow-up of #962) #1000): a test row for a twin whose name has a slash.--branch team/mainwith a packedTeam/main, detached over it and ON it. rv984b's mutant O3 (_folded_spellingreturningref.rsplit("/", 1)[-1]instead ofref[len("refs/heads/"):]) survived 63 of 63 tests; the rows kill it, and kill the same cut at the HEAD-twin site (O3b)._kept_namerows (a branch under the name; under it in another case; deeper under it; under each of the first two; a name that only starts with it is no bar; a branch under another name that holds it is no bar; a twin with a slash), two Unicode rows (NFD under an NFC name, NFC under an NFD name), two end-to-end rows (Main-kept/xloose and packed:Main-kept-2printed, pasted through/bin/sh, the next run makesmain) and the two slash rows. Helpers:missingandcreatedtake a branch, andtwin_with_a_commit. Cognitive complexity:_taken1,_kept_name1,create_at_pin14 andfast_forward_to_pin15 (both unchanged). New lines are within 79 columns, and the newbootstrap.pylines are ASCII.What git refuses, and what is left alone
Probed on git 2.43.0 and 2.47.1 in throw-away repositories (
gp/gitfacts*.sh):Main-kept-x), a tag, a remote-tracking ref or the stash of that name, and an unborn HEAD twin, whose rename only rewrites HEAD and checks nothing.teamforTeam/main-kept) is not handled, on purpose: the name has every directory its twin has, and the twin folds to the tracking branch, so git will not make that prefix beside the twin (cannot lock ref 'refs/heads/Team'), and a heldteamstopscheckout -b team/mainitself, packed or loose. No-keptname helps._kept_name's docstring: a stale reflog directory under the name, which git refuses (directory not empty, exit 128),for-each-refdoes not list, andbranch -Dremoves with the branch, so only a ref file removed by hand leaves one; and a twin whose last path component is 246 bytes or more, whose-keptname is refused at the file-name limit.The probe, before and after
A real repository from the test scaffold, local bare remotes, the printed line pasted through
/bin/sh. The leg is detached at the pin,Mainpacked with a commit,Main-kept/xloose or packed,mainmissing.The tests that fail at main
The final test file copied onto
2a78ae1a: 9 failed, 35 passed (44 tests). The 9: the five_kept_namerows with a branch under the name (under it; under it in another case; deeper; under each of the first two; a twin with a slash), the two Unicode rows and the two end-to-end rows. The 4 new tests that pass there pass by design: the two no-bar rows, and the two slash rows, which pin code that was already right and fail only for O3 and O3b.Mutants (each in a scratch tree, against the create-twins and casefold files, 76 tests; all 13 killed)
_folded_spellingreturnsref.rsplit("/", 1)[-1]return folded in held)"/"dropped (a plainstartswith(folded))folded + "/" in hforstartswithallforany(guarded against an empty set; unguarded it hangs)casefolded, not_foldedwhile False)Runs
At the committed head
9b8c643f, throughrun9.sh(gh stub first on PATH,GH_TOKEN=bogus, an emptyGH_CONFIG_DIR,GIT_SSH_COMMAND=false,GIT_CONFIG_GLOBAL=/dev/null):/usr/bin/git): the create-twins, casefold,test_bootstrap_pasteable_lines.py,test_bootstrap_leg_moves.pyandtest_pinned_copy_text.pyfiles and the trio (test_repo_hygiene.py,test_agents_md_codes.py,test_cli_reference.py): 405 passed.$Q/v115/w764/git247/bin/git, first on PATH): the create-twins and casefold files: 76 passed.testsjob.Merge checks
git merge-tree --write-treeof the head against: origin/main04923f10clean (treeb2486824);fix/430-d-assembly-root-guards(#958,cf8d5667) clean (tree12cb36fb);fix/961-paste-words(#973,b2887cf5) clean (treede0bb093). Main has moved on since2a78ae1aand has not touchedbootstrap.pyor the twin tests, so the branch needs no merge and no new run.Closes #1000
Lane: openreposhape-5 (openRepoShape-5)
🤖 Generated with Claude Code
Summary by Sourcery
Make bootstrap choose pasteable twin-rename commands by skipping candidate names occupied by nested branches.
Bug Fixes:
Enhancements:
Tests: