fix: name the stale pin instead of a missing file

A ref whose file is absent at the pinned revision reported "pin revision
missing", which reads as code that vanished. When the same file is at
HEAD and the cited range fits it, nothing vanished: the ref was written
against HEAD while source_commit still names an older revision, and the
profile describes two trees at once. The reason now says so, because the
fix is the pin and not a hunt for a move that never happened.

This is the state three profiles were left in during their own
reprofiling, against a warning the repository already carries. A range
that overruns HEAD stays a plain miss, and a file absent from both
revisions is unchanged.
This commit is contained in:
Abdessamad Derraz committed 2026-09-04 16:45:51 +02:00
1 parent 05b08d6e39
commit 1fb717324b
2 files changed
+41 -3

No files matched your search

+8 -3
View File
@@ -815,9 +815,14 @@ def anchor_part(
# the old path at the pin, which is why that one is tried first.
pin_lines = fetch(PIN, path, part.start, tokens)
if pin_lines is None:
return PartResult(
part, "GONE", None, None, None, [], "pin revision missing", slug, url
)
# Present at HEAD, absent at the pin, and the cited range fits the
# HEAD file: the ref was written against HEAD while source_commit
# still names an older revision. Saying "missing" sends the reader
# hunting for a move that never happened; the fix is the pin.
reason = "pin revision missing"
if head_lines is not None and part.start <= len(head_lines):
reason = "written against HEAD, pin names an older revision"
return PartResult(part, "GONE", None, None, None, [], reason, slug, url)
end = part.end or part.start
anchored = anchor_block(pin_lines, head_lines, part.start, end)
+33
View File
@@ -1435,6 +1435,39 @@ def _sample_report():
)
class TestRefsAheadOfTheirPin(TestBuildReport):
"""Say when a ref describes HEAD and the pin still names an older tree.
Reprofiling against HEAD and forgetting to advance source_commit leaves
the profile describing two revisions at once. The symptom was "pin
revision missing", which reads as code that vanished and sends the
reader hunting for a move that never happened. The cause is the pin.
"""
def test_present_at_head_and_absent_at_the_pin_names_the_pin(self):
self.files[("headsha", "a.c")] = ["x", "the cited line", "y"]
report = build_report("test", self._profile(["a.c:2"]), self.dir)
part = report.entries[0].parts[0]
self.assertEqual(part.status, "GONE")
self.assertEqual(
part.reason, "written against HEAD, pin names an older revision"
)
def test_a_range_beyond_head_is_still_just_missing(self):
"""Not every pin miss is a stale pin; only one that fits HEAD."""
self.files[("headsha", "a.c")] = ["x"]
report = build_report("test", self._profile(["a.c:40"]), self.dir)
part = report.entries[0].parts[0]
self.assertEqual(part.status, "GONE")
self.assertNotEqual(
part.reason, "written against HEAD, pin names an older revision"
)
def test_a_file_missing_from_both_is_unchanged(self):
report = build_report("test", self._profile(["ghost.c:2"]), self.dir)
self.assertEqual(report.entries[0].parts[0].status, "GONE")
class TestBareNameResolvedAtThePin(TestBuildReport):
"""A bare filename belongs to the revision the ref was written against.