fix: bios_integrity stops when git fails

modified_for_git read the stdout of git status without its exit code:
a corrupt index printed nothing, the working change read as unmodified,
and --apply wrote HEAD's blob over it. Every git call now raises on a
non-zero status, and the command exits 2 naming the git error.
This commit is contained in:
Abdessamad Derraz committed 2026-11-06 08:14:17 +01:00
1 parent 57ccca640a
commit afceabaf3c
2 files changed
+27 -2

No files matched your search

+17 -2
View File
@@ -91,8 +91,19 @@ def sha1_of(path: Path) -> str:
return digest.hexdigest()
class GitFailed(RuntimeError):
"""A git command failed: its empty output says nothing about the file."""
def git(root: Path, *args: str) -> subprocess.CompletedProcess:
return subprocess.run(["git", "-C", str(root), *args], capture_output=True, check=False)
"""Run git in root. A failure raises: an unreadable index read as an empty
status made a session's working change look unmodified, and --apply wrote
HEAD's bytes over it."""
done = subprocess.run(["git", "-C", str(root), *args], capture_output=True, check=False)
if done.returncode:
message = done.stderr.decode(errors="replace").strip()
raise GitFailed(f"git {' '.join(args)} exited {done.returncode}: {message}")
return done
def head_blob(root: Path, path: str) -> str:
@@ -197,7 +208,11 @@ def main() -> int:
from common import load_database
root = Path.cwd()
report = check(root, load_database(args.db), args.apply)
try:
report = check(root, load_database(args.db), args.apply)
except GitFailed as exc:
print(f"ERROR: {exc}. Nothing was restored past this point.", file=sys.stderr)
return 2
if args.json:
print(json.dumps(report.as_dict(), indent=2))
else:
+10
View File
@@ -891,6 +891,16 @@ class BiosIntegrity(Scratch):
self.assertEqual([(f.path, f.verdict) for f in report.findings], [(rel, bib.SKIPPED)])
self.assertEqual((self.repo / rel).read_bytes(), b"\x02" * 80)
def test_an_unreadable_index_stops_before_any_restore(self):
"""git status failed on a corrupt index, its empty stdout read as
"unmodified", and --apply wrote HEAD's bytes over the session's."""
rel = "bios/Sony/edited.bin"
(self.repo / rel).write_bytes(b"\x02" * 80)
(self.repo / ".git" / "index").write_bytes(b"garbage\n")
with self.assertRaises(bib.GitFailed):
bib.check(self.repo, self.db, apply=True)
self.assertEqual((self.repo / rel).read_bytes(), b"\x02" * 80)
def test_a_mismatch_the_second_read_does_not_confirm_is_a_misread(self):
reads = {}
expected = {e["path"]: e["sha1"] for e in self.db["files"].values()}