From 6582c3237e20ad5dc2279491c6349b5a713d26d5 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 5 Sep 2026 01:31:10 +0200 Subject: [PATCH] fix: name the stale pin when the file is only shorter The diagnostic caught a ref whose file was missing at the pin. nestopia showed the other shape: the file is there and the line is not yet. Its palette and database loads were cited at 2041 and 2063, which is where HEAD carries them, against a pin four hundred lines shorter, and that reported as a plain GONE with nothing to act on. A cited line past the end of the pinned file that fits HEAD is the same finding as before and now says so. nestopia's pin moved to the revision its refs describe: 8 refs, all anchored. --- emulators/nestopia.yml | 2 +- scripts/profile_sync.py | 21 ++++++++++++++++++++- tests/test_profile_sync.py | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/emulators/nestopia.yml b/emulators/nestopia.yml index 317c2528..89dd0ae0 100644 --- a/emulators/nestopia.yml +++ b/emulators/nestopia.yml @@ -5,7 +5,7 @@ source: "https://github.com/libretro/nestopia" upstream: "https://gitlab.com/jgemu/nestopia" logo: "https://raw.githubusercontent.com/0ldsk00l/nestopia/master/icons/svg/nestopia.svg" profiled_date: "2026-03-24" -source_commit: "d0f461cee801c509748606e91c8ff0563ef62cd6" +source_commit: "5a1cd378cb46ca9ccc2dd6f8b2b6a79ab986052e" core_version: "1.53.1" display_name: "Nintendo - NES / Famicom (Nestopia)" cores: [nestopia] diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index 76949537..2b029f00 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -740,6 +740,15 @@ def locate_by_declared_value( return None +def _written_against_head(part, head_lines) -> bool: + """Whether the cited line exists at HEAD, which is where it was written.""" + return ( + head_lines is not None + and part.start is not None + and part.start <= len(head_lines) + ) + + def anchor_part( part: RefPart, fetch, rename_getter, describe=None, tokens=() ) -> PartResult: @@ -820,10 +829,20 @@ def anchor_part( # 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): + if _written_against_head(part, head_lines): reason = "written against HEAD, pin names an older revision" return PartResult(part, "GONE", None, None, None, [], reason, slug, url) + if part.start > len(pin_lines) and _written_against_head(part, head_lines): + # The file is there and the line is not yet: the pinned revision is + # shorter than the one the ref was written against. nestopia cited + # the palette and database loads at 2041 and 2063, which is where + # HEAD carries them, over a pin four hundred lines shorter. + return PartResult( + part, "GONE", None, None, None, [], + "written against HEAD, pin names an older revision", slug, url, + ) + end = part.end or part.start anchored = anchor_block(pin_lines, head_lines, part.start, end) note = anchored.reason diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index 364697c7..659af9e3 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -1499,6 +1499,21 @@ class TestRefsAheadOfTheirPin(TestBuildReport): part.reason, "written against HEAD, pin names an older revision" ) + def test_a_range_past_the_pin_file_but_inside_head_names_the_pin(self): + """nestopia's shape: the file is there, the line is not yet. + + Palette and database loads sat at 2041 and 2063, which is where HEAD + carries them; the pinned revision was four hundred lines shorter. + """ + self.files[("pinsha", "a.c")] = ["x"] * 10 + self.files[("headsha", "a.c")] = ["x"] * 40 + ["the cited line"] + ["y"] + report = build_report("test", self._profile(["a.c:41"]), 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"]