From 01fcb25972f1853824112365b7a9cb8fd60de8ee Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Wed, 21 Oct 2026 12:29:40 +0000 Subject: [PATCH 1/2] bump-leg.py and family.py: rows tag a descendant of the commit `--to` names, so a tag above it is told as one that reaches it and a tag below it keeps the plain words, and `--points-at` in place of `--contains` no longer survives (#1019) `_remote_tag_reaches` (bump-leg.py) and `_origin_tag_reaches` (family.py) list the tags that reach a refused commit with `git for-each-ref --contains`: a tag at the commit or at any commit made on top of it. Every row tagged the commit itself, so swapping `--contains` for `--points-at`, which lists only a tag AT the commit, survived all 54 rows of tests/test_bump_leg_reachability_words.py and tests/test_family_bump_reachability_words.py (mutant M9 of #988's review). Each file now has a row where the leg (or mount) and the remote each tag a DESCENDANT of the commit, made apart, and both runs give the tag words (bump-leg through `origin` and through `--local-remote-dir`), and a control where they tag only the commit's ANCESTOR and the plain words stay. No production code changes. Closes #1019 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 --- tests/test_bump_leg_reachability_words.py | 98 +++++++++++++++++- tests/test_family_bump_reachability_words.py | 101 +++++++++++++++++++ 2 files changed, 195 insertions(+), 4 deletions(-) diff --git a/tests/test_bump_leg_reachability_words.py b/tests/test_bump_leg_reachability_words.py index 4ef92881..7d4bbadb 100644 --- a/tests/test_bump_leg_reachability_words.py +++ b/tests/test_bump_leg_reachability_words.py @@ -81,12 +81,13 @@ def runner(project: Path, remotes: Path, via: str): *extra) -def made_in_the_leg(project: Path, name: str) -> str: - """A commit made inside the leg's mount, adding `.md`, with the leg - put back where it stood, detached at the pin. Returns the commit.""" +def made_in_the_leg(project: Path, name: str, on: str = "HEAD") -> str: + """A commit made inside the leg's mount, adding `.md`, on top of + `on` (the pin unless a commit is named), with the leg put back where it + stood, detached at the pin. Returns the commit.""" leg = project / "spec" pinned = git("rev-parse", "HEAD", cwd=leg).stdout.strip() - git("checkout", "-q", "--detach", cwd=leg) + git("checkout", "-q", "--detach", on, cwd=leg) (leg / f"{name}.md").write_text(f"{name}\n", encoding="utf-8") git("add", "--", f"{name}.md", cwd=leg) git("commit", "-qm", name, cwd=leg) @@ -333,6 +334,95 @@ def test_a_tag_of_a_tag_the_two_share_reaches_it(project, scaffolded, via): assert refusal(stderr) == tag_reaches(made) +@pytest.mark.parametrize("kinds", [ + ("annotated", "annotated"), ("lightweight", "annotated"), + ("annotated", "lightweight")], + ids=["both-annotated-made-apart", "leg-lightweight-remote-annotated", + "leg-annotated-remote-lightweight"]) +@pytest.mark.parametrize("via", VIA) +def test_a_tag_at_a_descendant_of_the_commit_reaches_it( + project, scaffolded, via, kinds): + """#1019. A TAG AT A DESCENDANT OF THE COMMIT REACHES IT, as a tag at the + commit does: the leg's tags are listed with `for-each-ref --contains`, a + tag at the commit or at any commit made on top of it, where `--points-at` + lists only a tag AT the commit. A commit on no branch of the leg's remote + and a commit made on top of it, on none either; the leg and the remote + each tag the DESCENDANT `v1`, made apart (the reviewer's case J of #988). + Both runs refuse the commit `bump-leg-commit-local-only` in the tag + words, through the leg's `origin` and through `--local-remote-dir`, with + nothing moved and the leg's own `v1` as it was. Every row before this one + tagged the commit itself, so `--points-at` in place of `--contains`, the + mutant M9 of #988's review, survived all 54 of them.""" + leg_kind, remote_kind = kinds + remotes = private_remote(project, scaffolded) + bare = bare_of(remotes) + leg = project / "spec" + made = made_in_the_leg(project, "BELOW") + above = made_in_the_leg(project, "ABOVE", on=made) + remote_tag = tag_as(leg, remote_kind, "v1-w1019", above, "the remote's") + pushed(project, "refs/tags/v1-w1019", "refs/tags/v1-w1019") + git("tag", "-d", "v1-w1019", cwd=leg) + leg_tag = tag_as(leg, leg_kind, "v1-w1019", above, "the leg's") + assert git("rev-parse", f"{above}^", cwd=leg).stdout.strip() == made, ( + "premise: the commit is the parent of the one the tags name") + assert leg_tag != remote_tag, "premise: the two tags are two objects" + for work in (leg, bare): + assert git("rev-parse", "refs/tags/v1-w1019^{}", cwd=work + ).stdout.strip() == above, ( + "premise: both tags name the descendant") + assert git("for-each-ref", "--points-at", made, "refs/tags/", + cwd=work).stdout == "", ( + "premise: no tag is AT the commit") + run, before = only_a_tag_reaches(project, remotes, via, made) + + stderr = assert_one_refusal(project, run, made, + "bump-leg-commit-local-only", before) + + assert refusal(stderr) == tag_reaches(made) + assert "cannot fetch" not in stderr + assert git("rev-parse", "v1-w1019", cwd=leg).stdout.strip() == leg_tag, ( + "the leg's own tag is as it was") + + +@pytest.mark.parametrize("via", VIA) +def test_a_tag_at_an_ancestor_of_the_commit_alone_keeps_the_plain_words( + project, scaffolded, via): + """#1019's CONTROL, the row above turned over. The commit the run names is + the CHILD here, which the leg's remote does not hold, and the leg and the + remote both tag its PARENT, which only a tag reaches. A tag at an + ancestor does not reach a commit made on top of it: `for-each-ref + --contains` lists the tags at the commit and above it, never below it. So + both runs keep the plain words, "a pin the rest of the world cannot + fetch" included, which are true of the child, through `origin` and + through `--local-remote-dir`. A check that read the tags the other way + round (`--merged`) would tell the tag words here.""" + remotes = private_remote(project, scaffolded) + bare = bare_of(remotes) + leg = project / "spec" + parent = made_in_the_leg(project, "PARENT") + child = made_in_the_leg(project, "CHILD", on=parent) + tag_as(leg, "annotated", "v-below-w1019", parent, "the parent's") + pushed(project, "refs/tags/v-below-w1019", "refs/tags/v-below-w1019") + assert git("rev-parse", f"{child}^", cwd=leg).stdout.strip() == parent, ( + "premise: the commit named is the child of the one tagged") + assert contains(bare, parent, "refs/tags/"), ( + "premise: a tag of the leg's remote reaches the parent") + assert git("cat-file", "-e", child, cwd=bare, check=False + ).returncode != 0, "premise: the remote does not hold the child" + assert not contains(leg, child, "refs/tags/"), ( + "premise: no tag of the leg reaches the child") + assert not contains(leg, child, "refs/remotes/"), ( + "premise: no remote-tracking ref of the leg does") + branched(project) + run = runner(project, remotes, via) + before = snapshot(project) + + stderr = assert_one_refusal(project, run, child, + "bump-leg-commit-local-only", before) + + assert refusal(stderr) == local_only(child) + + # --- R613 p10: a leg with no remote named `origin` -------------------------- #: The note both runs print first when the leg has no remote named `origin`. diff --git a/tests/test_family_bump_reachability_words.py b/tests/test_family_bump_reachability_words.py index bd814a65..2c5f69a1 100644 --- a/tests/test_family_bump_reachability_words.py +++ b/tests/test_family_bump_reachability_words.py @@ -444,6 +444,107 @@ def test_a_tag_of_a_tag_the_two_share_reaches_it(holder, offline, tmp_path): offline.assert_left_nothing() +def made_on(holder: Path, env: dict, parent: str, name: str) -> str: + """A commit made in the holder's own mount on top of `parent`, a commit + only the mount holds, and NEVER PUSHED, adding the file `name`, with the + mount put back at the pin: `commit_in_mount`, which checks `parent` out + first. Returns its sha.""" + def change(mount: Path) -> None: + raw(mount, env, "checkout", "-q", parent) + (mount / name).write_bytes(b"made in the mount, on top of another\n") + + return commit_in_mount(holder, env, change, push=False) + + +@pytest.mark.parametrize("kinds", [ + ("annotated", "annotated"), ("lightweight", "annotated"), + ("annotated", "lightweight")], + ids=["both-annotated-made-apart", "mount-lightweight-origin-annotated", + "mount-annotated-origin-lightweight"]) +def test_a_tag_at_a_descendant_of_the_commit_reaches_it( + holder, offline, tmp_path, kinds): + """#1019. A TAG AT A DESCENDANT OF THE COMMIT REACHES IT, as a tag at the + commit does: the mount's tags are listed with `for-each-ref --contains`, + a tag at the commit or at any commit made on top of it, where + `--points-at` lists only a tag AT the commit. A commit on no branch of + the member's remote and a commit made on top of it, on none either; the + mount and the remote each tag the DESCENDANT `v1`, made apart (the + reviewer's case J of #988). Both runs refuse the commit + `member-to-local-only` in the tag words, with nothing moved and the + mount's own `v1` as it was. Every row before this one tagged the commit + itself, so `--points-at` in place of `--contains`, the mutant M9 of + #988's review, survived all 54 of them.""" + mount_kind, remote_kind = kinds + env = isolated(offline, tmp_path) + mount = holder / PATH + made = made_in_the_mount(holder, env, "BELOW.md") + above = made_on(holder, env, made, "ABOVE.md") + remote_tag = tag_as(mount, env, remote_kind, "v1", above, "the remote's") + remote = private_origin(holder, env) + raw(mount, env, "push", "-q", "origin", "refs/tags/v1") + raw(mount, env, "tag", "-d", "v1") + mount_tag = tag_as(mount, env, mount_kind, "v1", above, "the mount's") + assert raw(mount, env, "rev-parse", f"{above}^").stdout.decode().strip( + ) == made, "premise: the commit is the parent of the one the tags name" + assert mount_tag != remote_tag, "premise: the two tags are two objects" + for repository in (mount, remote): + assert raw(repository, env, "rev-parse", "refs/tags/v1^{}" + ).stdout.decode().strip() == above, ( + "premise: both tags name the descendant") + assert raw(repository, env, "for-each-ref", "--points-at", made, + "refs/tags/").stdout == b"", ( + "premise: no tag is AT the commit") + assert contains(remote, env, made, "refs/tags/"), ( + "premise: a tag of the member's remote reaches it, from above") + assert not contains(remote, env, made, "refs/heads/"), ( + "premise: no branch of the member's remote reaches it") + assert not contains(mount, env, made, "refs/remotes/"), ( + "premise: no remote-tracking ref of the mount does") + + stderr = both_runs(holder, env, made) + + assert refusal(stderr) == local_only(made, made, tagged=True) + assert "cannot fetch" not in stderr + assert raw(mount, env, "rev-parse", "v1").stdout.decode().strip() \ + == mount_tag, "the mount's own tag is as it was" + offline.assert_left_nothing() + + +def test_a_tag_at_an_ancestor_of_the_commit_alone_keeps_the_plain_words( + holder, offline, tmp_path): + """#1019's CONTROL, the row above turned over. The commit the runs name is + the CHILD here, which the member's remote does not hold, and the mount + and the remote both tag its PARENT, which only a tag reaches. A tag at an + ancestor does not reach a commit made on top of it: `for-each-ref + --contains` lists the tags at the commit and above it, never below it. + So both runs keep #613's words, "a pin the rest of the world cannot + fetch" included, which are true of the child. A check that read the tags + the other way round (`--merged`) would tell the tag words here.""" + env = isolated(offline, tmp_path) + mount = holder / PATH + parent = made_in_the_mount(holder, env, "PARENT.md") + child = made_on(holder, env, parent, "CHILD.md") + tag_as(mount, env, "annotated", "v-below", parent, "the parent's") + remote = private_origin(holder, env) + raw(mount, env, "push", "-q", "origin", "refs/tags/v-below") + assert raw(mount, env, "rev-parse", f"{child}^").stdout.decode().strip( + ) == parent, "premise: the commit named is the child of the one tagged" + assert contains(remote, env, parent, "refs/tags/"), ( + "premise: a tag of the member's remote reaches the parent") + assert raw(remote, env, "cat-file", "-e", child, + check=False).returncode != 0, ( + "premise: the member's remote does not hold the child") + assert not contains(mount, env, child, "refs/tags/"), ( + "premise: no tag of the mount reaches the child") + assert not contains(mount, env, child, "refs/remotes/"), ( + "premise: no remote-tracking ref of the mount does") + + stderr = both_runs(holder, env, child) + + assert refusal(stderr) == local_only(child) + offline.assert_left_nothing() + + def no_origin(to: str) -> tuple[str, str]: """The two lines `bump --to `, a commit the mount holds, is refused with when the mount has no remote named `origin`.""" From ee48b5fe9693ebda099d1c0aadaca7bdc16b91c1 Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Wed, 21 Oct 2026 14:00:14 +0000 Subject: [PATCH 2/2] test_bump_leg_reachability_words.py and test_family_bump_reachability_words.py: the descendant rows' docstrings say no earlier row of their file tags a descendant, and no longer count "all 54" rows of both files (#1019) rv1107's NIT 2: "survived all 54 of them" counted the rows of the two files together (34 + 20), several of those rows tag nothing (the no-`origin` and prune rows), and the number goes stale with the next row. Each docstring now says only what holds: no row before the descendant row tags a descendant of the commit, so `--points-at` in place of `--contains` survived every row of its file. Docstrings only. Refs #1019 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 --- tests/test_bump_leg_reachability_words.py | 7 ++++--- tests/test_family_bump_reachability_words.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_bump_leg_reachability_words.py b/tests/test_bump_leg_reachability_words.py index 7d4bbadb..eb361d8b 100644 --- a/tests/test_bump_leg_reachability_words.py +++ b/tests/test_bump_leg_reachability_words.py @@ -350,9 +350,10 @@ def test_a_tag_at_a_descendant_of_the_commit_reaches_it( each tag the DESCENDANT `v1`, made apart (the reviewer's case J of #988). Both runs refuse the commit `bump-leg-commit-local-only` in the tag words, through the leg's `origin` and through `--local-remote-dir`, with - nothing moved and the leg's own `v1` as it was. Every row before this one - tagged the commit itself, so `--points-at` in place of `--contains`, the - mutant M9 of #988's review, survived all 54 of them.""" + nothing moved and the leg's own `v1` as it was. No row before this one + tags a descendant of the commit: the tags in them are at the commit itself + or below it, so `--points-at` in place of `--contains`, the mutant M9 of + #988's review, survived every row of this file.""" leg_kind, remote_kind = kinds remotes = private_remote(project, scaffolded) bare = bare_of(remotes) diff --git a/tests/test_family_bump_reachability_words.py b/tests/test_family_bump_reachability_words.py index 2c5f69a1..a2063856 100644 --- a/tests/test_family_bump_reachability_words.py +++ b/tests/test_family_bump_reachability_words.py @@ -471,9 +471,10 @@ def test_a_tag_at_a_descendant_of_the_commit_reaches_it( mount and the remote each tag the DESCENDANT `v1`, made apart (the reviewer's case J of #988). Both runs refuse the commit `member-to-local-only` in the tag words, with nothing moved and the - mount's own `v1` as it was. Every row before this one tagged the commit - itself, so `--points-at` in place of `--contains`, the mutant M9 of - #988's review, survived all 54 of them.""" + mount's own `v1` as it was. No row before this one tags a descendant of + the commit: the tags in them are at the commit itself or below it, so + `--points-at` in place of `--contains`, the mutant M9 of #988's review, + survived every row of this file.""" mount_kind, remote_kind = kinds env = isolated(offline, tmp_path) mount = holder / PATH