fix: a citation in an unmoved repo needs no move

This commit is contained in:
Abdessamad Derraz committed 2026-10-10 07:51:09 +02:00
1 parent a213898c6d
commit 884c43c109
2 files changed
+53 -4

No files matched your search

+26 -4
View File
@@ -2654,9 +2654,15 @@ def _resolve_at(
def _realign_part(
part: RefPart, pairs, cache_dir: str, offline: bool
part: RefPart, pairs, cache_dir: str, offline: bool, pinned=()
) -> tuple[str, object] | None:
"""One range, anchored from its writing revision to the current pin."""
"""One range, anchored from its writing revision to the current pin.
`pinned` lists every declared (repository, current pin). A path no moved
repository carries but an unmoved one does lives where nothing moved:
it needs no move, and calling it absent made two readings of the same
history disagree on every run (nethersx2's AetherSX2 citations).
"""
if is_external_citation(part.path):
return None
unclear = None
@@ -2683,6 +2689,13 @@ def _realign_part(
return "skip", f"{part.path}:{part.start} {anchored.status.lower()}"
if unclear:
return "skip", f"{part.path}: {unclear}"
moved = {repo for repo, _written, _current in pairs}
if any(
upstream.fetch_file(repo, pin, part.path, cache_dir, offline) is not None
for repo, pin in pinned
if repo not in moved
):
return None
return "skip", f"{part.path} absent at the writing revision"
@@ -2722,6 +2735,7 @@ def _realign_citation(
ambiguous: list[str],
cache_dir: str,
offline: bool,
pinned=(),
) -> tuple[dict[int, tuple[int, int, str | None]], list[str]]:
"""The moves one prose run needs, and what blocks them.
@@ -2737,7 +2751,7 @@ def _realign_citation(
outcomes = {
repr(result): result
for result in (
_realign_part(part, pairs, cache_dir, offline) if pairs else None
_realign_part(part, pairs, cache_dir, offline, pinned) if pairs else None
for pairs in readings
)
}
@@ -2784,6 +2798,12 @@ def realign_prose(
repos = [(field, repo) for field, repo in repos if repo is not None]
if not repos:
return []
pinned = [
(repo, document[f"{field}_commit"])
for field, repo in repos
if isinstance(document.get(f"{field}_commit"), str)
and document[f"{field}_commit"]
]
history = _git_history(path)
if not history:
return []
@@ -2819,7 +2839,9 @@ def realign_prose(
readings, ambiguous = _writing_pairs(document, repos, revisions, intro_sha)
if not any(readings):
continue
moves, blocked = _realign_citation(citation, readings, ambiguous, cache_dir, offline)
moves, blocked = _realign_citation(
citation, readings, ambiguous, cache_dir, offline, pinned
)
if blocked:
# Half a run must not move: the untouched ranges would read as
# already realigned when they were never even located.
+27
View File
@@ -3372,6 +3372,33 @@ class TestRealignProse(unittest.TestCase):
)
self.assertEqual(self.path.read_text(), before)
def test_a_citation_in_an_unmoved_upstream_needs_no_reading(self):
"""nethersx2 cites AetherSX2 files that only its upstream carries,
at an upstream pin that never moved. The port's pin did move under
the text, and the reading through the port called each file absent
while the other said nothing: thirteen disagreements on every run."""
sample = (
'emulator: Test\n'
'source: "https://github.com/o/port"\n'
'upstream: "https://github.com/o/up"\n'
'source_commit: "oldpin"\n'
'upstream_commit: "uppin"\n'
'notes: |\n'
' The BIOS check lives upstream (up.c:5).\n'
)
self._git("init", "-q")
self._git("config", "user.email", "t@t")
self._git("config", "user.name", "t")
self._commit(sample, "profile")
self._commit(sample.replace('"oldpin"', '"pin"'), "advance the port")
self.files[("uppin", "up.c")] = ["a", "b", "c", "d", "check bios"]
before = self.path.read_text()
messages = profile_sync.realign_prose(self.path, self.tmp.name, dry_run=True)
self.assertFalse(
any("readings disagree" in m for m in messages), messages
)
self.assertEqual(self.path.read_text(), before)
def test_dry_run_writes_nothing(self):
self._repo_with_advanced_pin()
self.files[("oldpin", "a.c")] = ["x"] * 9 + ["subject"]