From 15f34d3043a06b8fa541cc7d37ce9c563215fd32 Mon Sep 17 00:00:00 2001 From: GalaxyGamingFR <153150716+GalaxyGamingFR@users.noreply.github.com> Date: Sun, 11 Oct 2026 02:38:52 -0700 Subject: [PATCH] fix(tools): decode pr_overlap git output with errors=replace One PR diff containing a byte that is not valid UTF-8 made git() and merge() raise, which aborted the hourly run and dropped the overlap comment on every PR. Both subprocess calls now pass errors="replace", matching check_conventions.py. A test commits a Latin-1 byte and checks the export is still found. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01V9UU71SP1UKGR51Sowbgmq --- tools/pr_overlap.py | 4 ++-- tools/tests/test_pr_overlap_encoding.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tools/pr_overlap.py b/tools/pr_overlap.py index 40a5efb9d..d42e24592 100644 --- a/tools/pr_overlap.py +++ b/tools/pr_overlap.py @@ -16,7 +16,7 @@ MARKER = "" def git(*args): - return subprocess.run(["git", *args], capture_output=True, text=True, encoding="utf-8", check=True).stdout + return subprocess.run(["git", *args], capture_output=True, text=True, encoding="utf-8", errors="replace", check=True).stdout def gh(*args): @@ -49,7 +49,7 @@ def fetch(base, prs): def merge(*args): result = subprocess.run(["git", "merge-tree", "--write-tree", "--name-only", "--no-messages", *args], - capture_output=True, text=True, encoding="utf-8") + capture_output=True, text=True, encoding="utf-8", errors="replace") lines = result.stdout.splitlines() if result.returncode not in (0, 1) or not lines: raise RuntimeError(f"git merge-tree {' '.join(args)} failed: {result.stderr.strip()}") diff --git a/tools/tests/test_pr_overlap_encoding.py b/tools/tests/test_pr_overlap_encoding.py index 9a4c3f449..2d2b92c42 100644 --- a/tools/tests/test_pr_overlap_encoding.py +++ b/tools/tests/test_pr_overlap_encoding.py @@ -1,5 +1,6 @@ from contextlib import contextmanager import json +import os from pathlib import Path import subprocess import sys @@ -74,6 +75,25 @@ class EncodingTests(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, UNICODE): pr_overlap.merge("main", "topic") + def test_git_diff_survives_invalid_utf8(self): + with TemporaryDirectory() as directory: + repo = Path(directory) + source = repo / "core" / "libs" / "prx" / "x" / "a.cpp" + source.parent.mkdir(parents=True) + ident = ["-c", "user.name=t", "-c", "user.email=t@example.test"] + for args in (["init", "-q"], ["commit", "-q", "--allow-empty", "-m", "base"]): + subprocess.run(["git", *ident, *args], cwd=repo, check=True, capture_output=True) + source.write_bytes(b"int APS5_VABI f() {} // caf\xe9\n") + for args in (["add", "."], ["commit", "-q", "-m", "add"]): + subprocess.run(["git", *ident, *args], cwd=repo, check=True, capture_output=True) + old = os.getcwd() + os.chdir(repo) + try: + diff = pr_overlap.git("diff", "-U0", "--no-color", "HEAD~1", "HEAD", "--", "core/libs/prx/*.cpp") + finally: + os.chdir(old) + self.assertEqual(pr_overlap.exports(diff), {"f"}) + def test_report_is_written_as_utf8(self): with TemporaryDirectory() as directory: path = Path(directory) / "1.md"