Repository navigation
shape_materialize.py: the docstring of gives_a_branch_another_name says a full name that is no pattern takes the one ref git completes it to, which may be a branch, where it said any other source names no branch (#1238) - #1244
Conversation
…says a full name that is no pattern takes the one ref git completes it to, which may be a branch, where it said any other source names no branch (#1238) The docstring ended "ANY OTHER SOURCE NAMES NO BRANCH, though a refspec from one can still put a ref on a branch's name". That is true of a source in another namespace, such as `refs/pull/7/head`, and untrue of a full name that is no pattern, which git completes: the source `refs/h` is the exact ref, the branch `refs/heads/refs/h`, the tag `refs/tags/refs/h`, `refs/refs/h` or `refs/remotes/refs/h`. Where the remote has a branch of that name the source is a branch, and beside a branch `hy` the carried refspec `+refs/h:refs/remotes/origin/hy` exits 128 ("Cannot fetch both refs/heads/hy and refs/heads/refs/h to refs/remotes/origin/hy"). The same source onto `origin/refs/h`, the branch's own name, or onto a name no branch has, exits 0 (measured on git 2.43.0 and 2.47.1, local bare remotes: rv1235's probes, run again here with the same answers). The sentence now says that any other source takes no branch by a pattern; that a full name that is no pattern takes the one ref git completes it to on the remote, `refs/h` itself or one such as the branch `refs/heads/refs/h` or the tag `refs/tags/refs/h`; that such a name can stand for a branch its spelling does not show, so it is not left out here; and that a refspec from any such source can still put a ref on a branch's name if the ref is not that branch itself, the clash `origin_fetch_refspecs` describes (WHAT CAN STILL CLASH). Wording only, in one docstring. `gives_a_branch_another_name("refs/h", ...)` is False and the refspec is carried, as on main. The file's syntax tree with every docstring dropped is as on main (`ast.dump`). The two sentences that say "whose source names no branch" (`shape_materialize.py` WHAT CAN STILL CLASH, `bump-leg.py` `_leg_fetch_refspecs`) are left: they define the clashing shape by its examples, the pull requests, and make no claim about what git completes a name to. Closes #1238 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reviewer's GuideImplementationUpdate the function’s docstring to clarify how Git completes full non-pattern ref names and when a carried refspec can clash with a branch name.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
(lane openRepoShape-5, 2026-11-08T15:21:27Z) Independent review of #1244 (#1238) for lane openRepoShape-5, by rv1244 and rv1244b (sonnet), at 36ec589: READY I found no MUST and no SHOULD. There are four optional NITs. None of them blocks landing, and I would not hold the PR for them. rv1244 ran the first gates and rv1244b did the rest. I changed nothing on GitHub or in the PR. My folder is What the PR isThe PR is one commit on base What I measuredMain moved (the point of R4b).
Gates on the merged tree.
Syntax tree, docstrings dropped (
Width and ASCII of the added lines.
Git probes (
I did not rerun the push claims from the issue; they are not in the docstring. A plain Merge-trees.
Judgement on leaving
|
|
|
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 5 days and 22 hours by commenting |



Goal
#1238 is a wording NIT that the review of #1235 (#1230) found in the code: NIT 4 of rv1235's first review, and NIT 2 of its re-check. The docstring of
gives_a_branch_another_nameinscripts/shape_materialize.pyended "ANY OTHER SOURCE NAMES NO BRANCH", but git completes a source that is a full name and no pattern, and completesrefs/hto the branchrefs/heads/refs/hwhere the remote has one. The sentence now says what git does with such a source, as an open list ("such as"), and where the clash is. A reader of the docstring is no longer told that a source outsiderefs/heads/is never a branch.Wording only, in one docstring of one file: 9 lines added, 3 removed. No code, no row, no other file. The file's syntax tree with every docstring dropped is the same as main's.
What held on main (
50869f384)The sentence is at
scripts/shape_materialize.py:1720-1723, the end of the docstring ofgives_a_branch_another_name(line 1671):It is true of a source in another namespace such as
refs/pull/7/head. It is not true of every other source. A source that is a full name and no pattern takes the one ref git completes the name to on the remote: forrefs/h,refs/hitself, the branchrefs/heads/refs/h, the tagrefs/tags/refs/h,refs/refs/horrefs/remotes/refs/h, and where several exist git takes the exact ref over a tag over a branch. Where the remote has the branch, the source is a branch. The code is right:gives_a_branch_another_name("refs/h", ...)is False, because the source has no*and does not start withrefs/heads/, so the refspec is carried. What fails afterwards is the clash the docstring's own next clause names. Only the words were untrue.Measured on this branch's base, with git 2.43.0 (
/usr/bin/git) and git 2.47.1, which gave the same answers on every row. Local bare remotes,GIT_CONFIG_GLOBAL=/dev/null,GIT_CONFIG_NOSYSTEM=1,GIT_SSH_COMMAND=false. rv1235's probe scripts were run again here (copied unchanged, new output folders), and their logs are identical to rv1235's. The fetch was+refs/heads/*:refs/remotes/origin/*plus the refspec of the row, and the remote hadmainandhy:So a name with no
*can be a branch that its spelling does not show, and the clash is a ref that is not that branch put on a branch's name, which is what the second half of the sentence has to say. "ANY OTHER" was wrong in a second way: a carried refspec from a source that IS the branch does not clash onto that branch's own name.What changed
The docstring's last sentence, now lines 1721-1729:
refs/heads/starts with the part before the*only where that part is a start ofrefs/heads/or is under it, the two cases the function reads before this sentence.refs/refs/h,refs/remotes/refs/h), so no reader takes the three as all.gives_a_branch_another_nameis False forrefs/hontoorigin/hy, ontoorigin/refs/h, forrefs/pull/7/headontoorigin/main, and for the patternrefs/pull/*/head, andorigin_fetch_refspecs(["+refs/h:refs/remotes/origin/hy"])returns it carried. It is True forrefs/heads/mainontoorigin/hy, as before.The checks the issue's Verify lists:
50869f384) and at this head underpython3 -I,ast.dump: 380120 characters of dump on both sides. A control that renamesgives_a_branch_another_nameon the head side gives 380121 and DIFFERENT, and the same trees with the docstrings kept differ (520956 against 521366), so the check can fail. Python 3.12.3. The check compares two dumps made by one interpreter and asserts no text that depends on the version.git grep -n 'ANY OTHER SOURCE NAMES NO$' -- scripts/finds nothing at this head. On main it findsshape_materialize.py:1721. With any case and no line end,git grep -n -i 'other source names no'also finds nothing here, and nothing but that line on main.README.md,docs/page orAGENTS.mdline pins the sentence. The issue's grep holds at this head.The two sentences left alone
The issue asks whether
shape_materialize.py:1874(now 1880, in the docstring oforigin_fetch_refspecs) andbump-leg.py:1165(in_leg_fetch_refspecs) want the same change. Both paragraphs were read, and both are left as they are:origin/pr/where a branchpr/7is, and+refs/pull/7/head:refs/remotes/origin/mainbeside a branchmain), and neither namesrefs/h. They were not the sentence that told a reader a source is never a branch.refs/heads/NAMES BRANCHES" is true by spelling too:can_name_a_tag's docstring measures that+refs/heads/zztook the tagrefs/tags/refs/heads/zzwhere the remote had no branchzz. The sentence changed here now says outright that the spelling of a name with no*does not show what it stands for, so the docstring that defines the class carries the caveat the two borrowers need.refs/h: "wherever a name it writes is a branch's". Theorigin_fetch_refspecsparagraph ends with why such a refspec is carried at all: "Which names the remote's branches have is not known from its refspecs, and left out, what such a refspec keeps would be pruned on every run". That holds forrefs/hword for word.refs/hbeside a remote branchrefs/heads/refs/h. If the review wants a word there, it is a few words in each place, and no open PR touches either paragraph (merge-trees below), so it can be a fix round.Rows failing on main, and mutants
None of either. No row is added or changed and no behaviour moved: the syntax tree outside the docstring is main's, so there is nothing for main to fail and nothing to mutate.
gives_a_branch_another_namereturns what it returned for every case in the table above (called in process at this head; the syntax tree outside the docstrings is main's).Runs
All through the lane's runner
run9.sh(stubghfirst on PATH,GIT_SSH_COMMAND=false,GIT_CONFIG_GLOBAL=/dev/null), on the committed head36ec589a6with the tree clean (dirty=0), as one run of seven files at a time:tests/test_pinned_copy_text.py,tests/test_path_guard_hygiene.py,tests/test_repo_hygiene.py,tests/test_agents_md_codes.py,tests/test_cli_reference.py(the hygiene five),tests/test_family_bump_fetch_refspecs.pyandtests/test_bump_leg_fetch_refspecs.py./usr/bin/git): 504 passed in 469.44s (47test_agents_md_codes.py, 68test_bump_leg_fetch_refspecs.py, 23test_cli_reference.py, 57test_family_bump_fetch_refspecs.py, 121test_path_guard_hygiene.py, 87test_pinned_copy_text.py, 101test_repo_hygiene.py; the counts are from--collect-only -qon the same head and add up to 504). Logv131/n1238/gate-g243.log.git --versionprinted into the log): 504 passed in 714.00s. Logv131/n1238/gate-g247.log.-k carried-refs-h-not-a-patternovertests/test_family_bump_fetch_refspecs.pyandtests/test_bump_leg_fetch_refspecs.py: 2 passed, 123 deselected, on 2.43.0 and on 2.47.1 (run-k-g243.log,run-k-g247.log).dirty=0. Python 3.12.3 (CI runs 3.14); nothing asserts text that depends on the version.The measured git behaviour above comes from the probe scripts, not the test files.
-k carried-refs-h-not-a-patternover the two fetch-refspec files is part of those runs.Merge-trees
git merge-tree --write-tree origin/main HEADexits 0, with tree9d874bcf2caf, equal to this head's tree, against main50869f384(the merge base). Against the head of each open PR that touchesscripts/shape_materialize.pyorscripts/bump-leg.py(read fromgh pr list --state open --limit 100 --json number,headRefName,headRefOid,files, 52 open PRs at the last read, 7 of them touch one of the two files),git merge-tree --write-tree HEAD <head>exits 0 and the merged tree still holds the new sentence and not the old one:Main moved once while this was gated, to
4829418f0(adopt-project.py,docs/cli.mdand a new test file: none of the files this change or its runs touch), andgit merge-tree --write-tree origin/main HEADagainst it also exits 0.None of their hunks is within 100 lines of the sentence changed here.
Closes #1238
Lane: openreposhape-5 (openRepoShape-5)
🤖 Generated with Claude Code
Summary by Sourcery
Enhancements:
gives_a_branch_another_namedocstring to accurately describe how Git resolves full, non-pattern ref names and when carried refspecs can clash with branch names.