mercurial/dirstateutils/docket.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 19 Nov 2021 16:21:00 -0800
changeset 48417 35f1ecd84bd0
parent 48233 a32a96079e2d
child 48966 6000f5b25c9b
permissions -rw-r--r--
errors: use detailed exit code in pathauditor Differential Revision: https://phab.mercurial-scm.org/D11830
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     1
# dirstatedocket.py - docket file for dirstate-v2
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     2
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
# Copyright Mercurial Contributors
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     4
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     7
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     8
from __future__ import absolute_import
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     9
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    10
import struct
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    11
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    12
from ..revlogutils import docket as docket_mod
48233
a32a96079e2d dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48177
diff changeset
    13
from . import v2
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    14
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    15
V2_FORMAT_MARKER = b"dirstate-v2\n"
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    16
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    17
# * 12 bytes: format marker
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    18
# * 32 bytes: node ID of the working directory's first parent
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    19
# * 32 bytes: node ID of the working directory's second parent
48177
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47994
diff changeset
    20
# * {TREE_METADATA_SIZE} bytes: tree metadata, parsed separately
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    21
# * 4 bytes: big-endian used size of the data file
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    22
# * 1 byte: length of the data file's UUID
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    23
# * variable: data file's UUID
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    24
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    25
# Node IDs are null-padded if shorter than 32 bytes.
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    26
# A data file shorter than the specified used size is corrupted (truncated)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    27
HEADER = struct.Struct(
48233
a32a96079e2d dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48177
diff changeset
    28
    ">{}s32s32s{}sLB".format(len(V2_FORMAT_MARKER), v2.TREE_METADATA_SIZE)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    29
)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    30
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    31
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    32
class DirstateDocket(object):
47994
681851d6409b dirstate-v2: Remove the `.d` suffix in data file names
Simon Sapin <simon.sapin@octobus.net>
parents: 47684
diff changeset
    33
    data_filename_pattern = b'dirstate.%s'
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    34
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    35
    def __init__(self, parents, data_size, tree_metadata, uuid):
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    36
        self.parents = parents
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    37
        self.data_size = data_size
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    38
        self.tree_metadata = tree_metadata
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    39
        self.uuid = uuid
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    40
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    41
    @classmethod
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    42
    def with_new_uuid(cls, parents, data_size, tree_metadata):
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    43
        return cls(parents, data_size, tree_metadata, docket_mod.make_uid())
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    44
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    45
    @classmethod
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    46
    def parse(cls, data, nodeconstants):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    47
        if not data:
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    48
            parents = (nodeconstants.nullid, nodeconstants.nullid)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    49
            return cls(parents, 0, b'', None)
48177
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47994
diff changeset
    50
        marker, p1, p2, meta, data_size, uuid_size = HEADER.unpack_from(data)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    51
        if marker != V2_FORMAT_MARKER:
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    52
            raise ValueError("expected dirstate-v2 marker")
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    53
        uuid = data[HEADER.size : HEADER.size + uuid_size]
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    54
        p1 = p1[: nodeconstants.nodelen]
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    55
        p2 = p2[: nodeconstants.nodelen]
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    56
        return cls((p1, p2), data_size, meta, uuid)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    57
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    58
    def serialize(self):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    59
        p1, p2 = self.parents
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    60
        header = HEADER.pack(
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    61
            V2_FORMAT_MARKER,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    62
            p1,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    63
            p2,
48177
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47994
diff changeset
    64
            self.tree_metadata,
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    65
            self.data_size,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    66
            len(self.uuid),
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    67
        )
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    68
        return header + self.uuid
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    69
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    70
    def data_filename(self):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    71
        return self.data_filename_pattern % self.uuid