comparison 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
comparison
equal deleted inserted replaced
48220:e7b5e8ba7cab 48221:a32a96079e2d
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from __future__ import absolute_import 8 from __future__ import absolute_import
9 9
10 import stat
10 import struct 11 import struct
11 import zlib 12 import zlib
12 13
13 from ..node import ( 14 from ..node import (
14 nullrev, 15 nullrev,
40 # a special value used internally for `size` if the file is modified/merged/added 41 # a special value used internally for `size` if the file is modified/merged/added
41 NONNORMAL = -1 42 NONNORMAL = -1
42 43
43 # a special value used internally for `time` if the time is ambigeous 44 # a special value used internally for `time` if the time is ambigeous
44 AMBIGUOUS_TIME = -1 45 AMBIGUOUS_TIME = -1
46
47 # Bits of the `flags` byte inside a node in the file format
48 DIRSTATE_V2_WDIR_TRACKED = 1 << 0
49 DIRSTATE_V2_P1_TRACKED = 1 << 1
50 DIRSTATE_V2_P2_INFO = 1 << 2
51 DIRSTATE_V2_HAS_MODE_AND_SIZE = 1 << 3
52 DIRSTATE_V2_HAS_MTIME = 1 << 4
53 DIRSTATE_V2_MODE_EXEC_PERM = 1 << 5
54 DIRSTATE_V2_MODE_IS_SYMLINK = 1 << 6
45 55
46 56
47 @attr.s(slots=True, init=False) 57 @attr.s(slots=True, init=False)
48 class DirstateItem(object): 58 class DirstateItem(object):
49 """represent a dirstate entry 59 """represent a dirstate entry
105 if has_meaningful_data: 115 if has_meaningful_data:
106 self._mode = parentfiledata[0] 116 self._mode = parentfiledata[0]
107 self._size = parentfiledata[1] 117 self._size = parentfiledata[1]
108 if has_meaningful_mtime: 118 if has_meaningful_mtime:
109 self._mtime = parentfiledata[2] 119 self._mtime = parentfiledata[2]
120
121 @classmethod
122 def from_v2_data(cls, flags, size, mtime):
123 """Build a new DirstateItem object from V2 data"""
124 has_mode_size = bool(flags & DIRSTATE_V2_HAS_MODE_AND_SIZE)
125 mode = None
126 if has_mode_size:
127 assert stat.S_IXUSR == 0o100
128 if flags & DIRSTATE_V2_MODE_EXEC_PERM:
129 mode = 0o755
130 else:
131 mode = 0o644
132 if flags & DIRSTATE_V2_MODE_IS_SYMLINK:
133 mode |= stat.S_IFLNK
134 else:
135 mode |= stat.S_IFREG
136 return cls(
137 wc_tracked=bool(flags & DIRSTATE_V2_WDIR_TRACKED),
138 p1_tracked=bool(flags & DIRSTATE_V2_P1_TRACKED),
139 p2_info=bool(flags & DIRSTATE_V2_P2_INFO),
140 has_meaningful_data=has_mode_size,
141 has_meaningful_mtime=bool(flags & DIRSTATE_V2_HAS_MTIME),
142 parentfiledata=(mode, size, mtime),
143 )
110 144
111 @classmethod 145 @classmethod
112 def from_v1_data(cls, state, mode, size, mtime): 146 def from_v1_data(cls, state, mode, size, mtime):
113 """Build a new DirstateItem object from V1 data 147 """Build a new DirstateItem object from V1 data
114 148