diff mercurial/pure/parsers.py @ 48221:a32a96079e2d

dirstate-v2: initial Python parser The dirstate-v2 file format should be supported even if Rust extensions are not enabled. This changeset adds parsing code that is not used yet. Differential Revision: https://phab.mercurial-scm.org/D11518
author Simon Sapin <simon.sapin@octobus.net>
date Sun, 03 Oct 2021 13:18:03 +0200
parents 77fc340acad7
children 7e78c72ee3ea
line wrap: on
line diff
--- a/mercurial/pure/parsers.py	Fri Oct 08 13:15:22 2021 +0200
+++ b/mercurial/pure/parsers.py	Sun Oct 03 13:18:03 2021 +0200
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import stat
 import struct
 import zlib
 
@@ -43,6 +44,15 @@
 # a special value used internally for `time` if the time is ambigeous
 AMBIGUOUS_TIME = -1
 
+# Bits of the `flags` byte inside a node in the file format
+DIRSTATE_V2_WDIR_TRACKED = 1 << 0
+DIRSTATE_V2_P1_TRACKED = 1 << 1
+DIRSTATE_V2_P2_INFO = 1 << 2
+DIRSTATE_V2_HAS_MODE_AND_SIZE = 1 << 3
+DIRSTATE_V2_HAS_MTIME = 1 << 4
+DIRSTATE_V2_MODE_EXEC_PERM = 1 << 5
+DIRSTATE_V2_MODE_IS_SYMLINK = 1 << 6
+
 
 @attr.s(slots=True, init=False)
 class DirstateItem(object):
@@ -109,6 +119,30 @@
             self._mtime = parentfiledata[2]
 
     @classmethod
+    def from_v2_data(cls, flags, size, mtime):
+        """Build a new DirstateItem object from V2 data"""
+        has_mode_size = bool(flags & DIRSTATE_V2_HAS_MODE_AND_SIZE)
+        mode = None
+        if has_mode_size:
+            assert stat.S_IXUSR == 0o100
+            if flags & DIRSTATE_V2_MODE_EXEC_PERM:
+                mode = 0o755
+            else:
+                mode = 0o644
+            if flags & DIRSTATE_V2_MODE_IS_SYMLINK:
+                mode |= stat.S_IFLNK
+            else:
+                mode |= stat.S_IFREG
+        return cls(
+            wc_tracked=bool(flags & DIRSTATE_V2_WDIR_TRACKED),
+            p1_tracked=bool(flags & DIRSTATE_V2_P1_TRACKED),
+            p2_info=bool(flags & DIRSTATE_V2_P2_INFO),
+            has_meaningful_data=has_mode_size,
+            has_meaningful_mtime=bool(flags & DIRSTATE_V2_HAS_MTIME),
+            parentfiledata=(mode, size, mtime),
+        )
+
+    @classmethod
     def from_v1_data(cls, state, mode, size, mtime):
         """Build a new DirstateItem object from V1 data