mercurial/dirstateutils/docket.py
changeset 47682 78f7f0d490ee
parent 47674 ff97e793ed36
child 47684 852262e2e7d9
--- a/mercurial/dirstateutils/docket.py	Thu Jul 08 19:23:44 2021 +0200
+++ b/mercurial/dirstateutils/docket.py	Thu Jul 15 23:02:17 2021 +0200
@@ -14,47 +14,60 @@
 
 V2_FORMAT_MARKER = b"dirstate-v2\n"
 
+# Must match the constant of the same name in
+# `rust/hg-core/src/dirstate_tree/on_disk.rs`
+TREE_METADATA_SIZE = 40
+
 # * 12 bytes: format marker
 # * 32 bytes: node ID of the working directory's first parent
 # * 32 bytes: node ID of the working directory's second parent
 # * 4 bytes: big-endian used size of the data file
+# * {TREE_METADATA_SIZE} bytes: tree metadata, parsed separately
 # * 1 byte: length of the data file's UUID
 # * variable: data file's UUID
 #
 # Node IDs are null-padded if shorter than 32 bytes.
 # A data file shorter than the specified used size is corrupted (truncated)
-HEADER = struct.Struct(">{}s32s32sLB".format(len(V2_FORMAT_MARKER)))
+HEADER = struct.Struct(
+    ">{}s32s32sL{}sB".format(len(V2_FORMAT_MARKER), TREE_METADATA_SIZE)
+)
 
 
 class DirstateDocket(object):
     data_filename_pattern = b'dirstate.%s.d'
 
-    def __init__(self, parents, data_size, uuid):
+    def __init__(self, parents, data_size, tree_metadata, uuid):
         self.parents = parents
         self.data_size = data_size
+        self.tree_metadata = tree_metadata
         self.uuid = uuid
 
     @classmethod
-    def with_new_uuid(cls, parents, data):
-        return cls(parents, data, docket_mod.make_uid())
+    def with_new_uuid(cls, parents, data_size, tree_metadata):
+        return cls(parents, data_size, tree_metadata, docket_mod.make_uid())
 
     @classmethod
     def parse(cls, data, nodeconstants):
         if not data:
             parents = (nodeconstants.nullid, nodeconstants.nullid)
-            return cls(parents, 0, None)
-        marker, p1, p2, data_size, uuid_size = HEADER.unpack_from(data)
+            return cls(parents, 0, b'', None)
+        marker, p1, p2, data_size, meta, uuid_size = HEADER.unpack_from(data)
         if marker != V2_FORMAT_MARKER:
             raise ValueError("expected dirstate-v2 marker")
         uuid = data[HEADER.size : HEADER.size + uuid_size]
         p1 = p1[: nodeconstants.nodelen]
         p2 = p2[: nodeconstants.nodelen]
-        return cls((p1, p2), data_size, uuid)
+        return cls((p1, p2), data_size, meta, uuid)
 
     def serialize(self):
         p1, p2 = self.parents
         header = HEADER.pack(
-            V2_FORMAT_MARKER, p1, p2, self.data_size, len(self.uuid)
+            V2_FORMAT_MARKER,
+            p1,
+            p2,
+            self.data_size,
+            self.tree_metadata,
+            len(self.uuid),
         )
         return header + self.uuid