From 0be753d567db61e45d7e3c691cc159ecdb085487 Mon Sep 17 00:00:00 2001
From: Valentin Lorentz <vlorentz@softwareheritage.org>
Date: Fri, 5 Aug 2022 14:20:38 +0200
Subject: [PATCH] Add parameter 'ignore_unresolved' to snapshot_git_object

It allows building a snapshot manifest despite some branches being
unresolved (instead of raising an error).

This feature was removed in 57ae405d312879bec19107d29a20c2c290d7861d
but in the end, Snapshot.compute_hash() will need to use it so that
swh-scrubber does not crash when checksum such snapshots.
---
 swh/model/git_objects.py            | 10 ++++++++--
 swh/model/tests/test_identifiers.py |  5 +++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/swh/model/git_objects.py b/swh/model/git_objects.py
index 41be6f2e..2eb48d8d 100644
--- a/swh/model/git_objects.py
+++ b/swh/model/git_objects.py
@@ -412,7 +412,9 @@ def release_git_object(release: Union[Dict, model.Release]) -> bytes:
     return format_git_object_from_headers("tag", headers, release.message)
 
 
-def snapshot_git_object(snapshot: Union[Dict, model.Snapshot]) -> bytes:
+def snapshot_git_object(
+    snapshot: Union[Dict, model.Snapshot], *, ignore_unresolved: bool = False
+) -> bytes:
     """Formats a snapshot as a git-like object.
 
     Snapshots are a set of named branches, which are pointers to objects at any
@@ -456,6 +458,10 @@ def snapshot_git_object(snapshot: Union[Dict, model.Snapshot]) -> bytes:
       Note that, akin to directory manifests, there is no separator between
       entries. Because of symbolic branches, identifiers are of arbitrary
       length but are length-encoded to avoid ambiguity.
+
+    Args:
+      ignore_unresolved: if False (the default), raises an exception when
+        alias branches point to non-existing branches cause
     """
     if isinstance(snapshot, dict):
         # For backward compatibility
@@ -495,7 +501,7 @@ def snapshot_git_object(snapshot: Union[Dict, model.Snapshot]) -> bytes:
             ]
         )
 
-    if unresolved:
+    if unresolved and not ignore_unresolved:
         raise ValueError(
             "Branch aliases unresolved: %s"
             % ", ".join("%r -> %r" % x for x in unresolved),
diff --git a/swh/model/tests/test_identifiers.py b/swh/model/tests/test_identifiers.py
index 793e6d5b..bbbdc8c4 100644
--- a/swh/model/tests/test_identifiers.py
+++ b/swh/model/tests/test_identifiers.py
@@ -758,6 +758,11 @@ class SnapshotIdentifier(unittest.TestCase):
         with self.assertRaisesRegex(ValueError, "b'foo' -> b'bar'"):
             Snapshot.from_dict(remove_id(self.unresolved))
 
+    def test_git_object_unresolved(self):
+        with self.assertRaisesRegex(ValueError, "b'foo' -> b'bar'"):
+            git_objects.snapshot_git_object(self.unresolved)
+        git_objects.snapshot_git_object(self.unresolved, ignore_unresolved=True)
+
     def test_all_types(self):
         self.assertEqual(
             Snapshot.from_dict(remove_id(self.all_types)).id,
-- 
GitLab