Mercurial > public > mercurial-scm > hg
annotate mercurial/dirstateutils/v2.py @ 48264:bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Tracking directory "explicitly" give use the opportunity to distinct between
entry that are untracked because they are part of the directory structure and
entry that are ignored/unknown files on the files system.
The help is adjusted to the new semantic and the code now comply to it for both
read and write.
Differential Revision: https://phab.mercurial-scm.org/D11694
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 19 Oct 2021 18:18:05 +0200 |
parents | 83d0bd45b662 |
children | 434de12918fd 46d12f7762e4 |
rev | line source |
---|---|
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
1 # v2.py - Pure-Python implementation of the dirstate-v2 file format |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
2 # |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
3 # Copyright Mercurial Contributors |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 # |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 from __future__ import absolute_import |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 import struct |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 |
48222
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
12 from ..thirdparty import attr |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
13 from .. import error, policy |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
14 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 parsers = policy.importmod('parsers') |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 # Must match the constant of the same name in |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 # `rust/hg-core/src/dirstate_tree/on_disk.rs` |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 TREE_METADATA_SIZE = 44 |
48231
0524c1359bfc
dirstate-v2: Extend node flags to 16 bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48228
diff
changeset
|
21 NODE_SIZE = 44 |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 # Must match the `TreeMetadata` Rust struct in |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there. |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 # |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 # * 4 bytes: start offset of root nodes |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
28 # * 4 bytes: number of root nodes |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
29 # * 4 bytes: total number of nodes in the tree that have an entry |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
30 # * 4 bytes: total number of nodes in the tree that have a copy source |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
31 # * 4 bytes: number of bytes in the data file that are not used anymore |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
32 # * 4 bytes: unused |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
33 # * 20 bytes: SHA-1 hash of ignore patterns |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
34 TREE_METADATA = struct.Struct('>LLLLL4s20s') |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
35 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
36 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 # Must match the `Node` Rust struct in |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there. |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
39 # |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
40 # * 4 bytes: start offset of full path |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
41 # * 2 bytes: length of the full path |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 # * 2 bytes: length within the full path before its "base name" |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
43 # * 4 bytes: start offset of the copy source if any, or zero for no copy source |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
44 # * 2 bytes: length of the copy source if any, or unused |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 # * 4 bytes: start offset of child nodes |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
46 # * 4 bytes: number of child nodes |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
47 # * 4 bytes: number of descendant nodes that have an entry |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
48 # * 4 bytes: number of descendant nodes that have a "tracked" state |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
49 # * 1 byte: flags |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
50 # * 4 bytes: expected size |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
51 # * 4 bytes: mtime seconds |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 # * 4 bytes: mtime nanoseconds |
48231
0524c1359bfc
dirstate-v2: Extend node flags to 16 bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48228
diff
changeset
|
53 NODE = struct.Struct('>LHHLHLLLLHlll') |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
54 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
55 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 assert TREE_METADATA_SIZE == TREE_METADATA.size |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 assert NODE_SIZE == NODE.size |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
58 |
48264
bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48263
diff
changeset
|
59 # match constant in mercurial/pure/parsers.py |
bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48263
diff
changeset
|
60 DIRSTATE_V2_DIRECTORY = 1 << 5 |
bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48263
diff
changeset
|
61 |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
62 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
63 def parse_dirstate(map, copy_map, data, tree_metadata): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
64 """parse a full v2-dirstate from a binary data into dictionnaries: |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
65 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 - map: a {path: entry} mapping that will be filled |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
67 - copy_map: a {path: copy-source} mapping that will be filled |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
68 - data: a binary blob contains v2 nodes data |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
69 - tree_metadata:: a binary blob of the top level node (from the docket) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
70 """ |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
71 ( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
72 root_nodes_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
73 root_nodes_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
74 _nodes_with_entry_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
75 _nodes_with_copy_source_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 _unreachable_bytes, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
77 _unused, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
78 _ignore_patterns_hash, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 ) = TREE_METADATA.unpack(tree_metadata) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 parse_nodes(map, copy_map, data, root_nodes_start, root_nodes_len) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
81 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
82 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
83 def parse_nodes(map, copy_map, data, start, len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
84 """parse <len> nodes from <data> starting at offset <start> |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
85 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
86 This is used by parse_dirstate to recursively fill `map` and `copy_map`. |
48251
dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48231
diff
changeset
|
87 |
dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48231
diff
changeset
|
88 All directory specific information is ignored and do not need any |
48264
bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48263
diff
changeset
|
89 processing (DIRECTORY, ALL_UNKNOWN_RECORDED, ALL_IGNORED_RECORDED) |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 """ |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
91 for i in range(len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 node_start = start + NODE_SIZE * i |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 node_bytes = slice_with_len(data, node_start, NODE_SIZE) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 ( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 path_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 path_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 _basename_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 copy_source_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
99 copy_source_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
100 children_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 children_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 _descendants_with_entry_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
103 _tracked_descendants_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
104 flags, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
105 size, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
106 mtime_s, |
48263
83d0bd45b662
dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents:
48260
diff
changeset
|
107 mtime_ns, |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
108 ) = NODE.unpack(node_bytes) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
109 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
110 # Parse child nodes of this node recursively |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
111 parse_nodes(map, copy_map, data, children_start, children_count) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
112 |
48260
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48251
diff
changeset
|
113 item = parsers.DirstateItem.from_v2_data(flags, size, mtime_s, mtime_ns) |
48221
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
114 if not item.any_tracked: |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
115 continue |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
116 path = slice_with_len(data, path_start, path_len) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
117 map[path] = item |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
118 if copy_source_start: |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
119 copy_map[path] = slice_with_len( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
120 data, copy_source_start, copy_source_len |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
121 ) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
122 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
123 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
124 def slice_with_len(data, start, len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
125 return data[start : start + len] |
48222
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
126 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
127 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
128 @attr.s |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
129 class Node(object): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
130 path = attr.ib() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
131 entry = attr.ib() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
132 parent = attr.ib(default=None) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
133 children_count = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
134 children_offset = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
135 descendants_with_entry = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
136 tracked_descendants = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
137 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
138 def pack(self, copy_map, paths_offset): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
139 path = self.path |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
140 copy = copy_map.get(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
141 entry = self.entry |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
142 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
143 path_start = paths_offset |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
144 path_len = len(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
145 basename_start = path.rfind(b'/') + 1 # 0 if rfind returns -1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
146 if copy is not None: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
147 copy_source_start = paths_offset + len(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
148 copy_source_len = len(copy) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
149 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
150 copy_source_start = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
151 copy_source_len = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
152 if entry is not None: |
48260
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48251
diff
changeset
|
153 flags, size, mtime_s, mtime_ns = entry.v2_data() |
48222
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
154 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
155 # There are no mtime-cached directories in the Python implementation |
48264
bb240915f69f
dirstate-v2: adjust the meaning of directory flags
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48263
diff
changeset
|
156 flags = DIRSTATE_V2_DIRECTORY |
48222
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
157 size = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
158 mtime_s = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
159 mtime_ns = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
160 return NODE.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
161 path_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
162 path_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
163 basename_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
164 copy_source_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
165 copy_source_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
166 self.children_offset, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
167 self.children_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
168 self.descendants_with_entry, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
169 self.tracked_descendants, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
170 flags, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
171 size, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
172 mtime_s, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
173 mtime_ns, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
174 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
175 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
176 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
177 def pack_dirstate(map, copy_map, now): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
178 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
179 Pack `map` and `copy_map` into the dirstate v2 binary format and return |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
180 the bytearray. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
181 `now` is a timestamp of the current filesystem time used to detect race |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
182 conditions in writing the dirstate to disk, see inline comment. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
183 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
184 The on-disk format expects a tree-like structure where the leaves are |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
185 written first (and sorted per-directory), going up levels until the root |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
186 node and writing that one to the docket. See more details on the on-disk |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
187 format in `mercurial/helptext/internals/dirstate-v2`. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
188 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
189 Since both `map` and `copy_map` are flat dicts we need to figure out the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
190 hierarchy. This algorithm does so without having to build the entire tree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
191 in-memory: it only keeps the minimum number of nodes around to satisfy the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
192 format. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
193 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
194 # Algorithm explanation |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
195 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
196 This explanation does not talk about the different counters for tracked |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
197 descendents and storing the copies, but that work is pretty simple once this |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
198 algorithm is in place. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
199 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
200 ## Building a subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
201 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
202 First, sort `map`: this makes it so the leaves of the tree are contiguous |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
203 per directory (i.e. a/b/c and a/b/d will be next to each other in the list), |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
204 and enables us to use the ordering of folders to have a "cursor" of the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
205 current folder we're in without ever going twice in the same branch of the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
206 tree. The cursor is a node that remembers its parent and any information |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
207 relevant to the format (see the `Node` class), building the relevant part |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
208 of the tree lazily. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
209 Then, for each file in `map`, move the cursor into the tree to the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
210 corresponding folder of the file: for example, if the very first file |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
211 is "a/b/c", we start from `Node[""]`, create `Node["a"]` which points to |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
212 its parent `Node[""]`, then create `Node["a/b"]`, which points to its parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
213 `Node["a"]`. These nodes are kept around in a stack. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
214 If the next file in `map` is in the same subtree ("a/b/d" or "a/b/e/f"), we |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
215 add it to the stack and keep looping with the same logic of creating the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
216 tree nodes as needed. If however the next file in `map` is *not* in the same |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
217 subtree ("a/other", if we're still in the "a/b" folder), then we know that |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
218 the subtree we're in is complete. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
219 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
220 ## Writing the subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
221 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
222 We have the entire subtree in the stack, so we start writing it to disk |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
223 folder by folder. The way we write a folder is to pop the stack into a list |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
224 until the folder changes, revert this list of direct children (to satisfy |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
225 the format requirement that children be sorted). This process repeats until |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
226 we hit the "other" subtree. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
227 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
228 An example: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
229 a |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
230 dir1/b |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
231 dir1/c |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
232 dir2/dir3/d |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
233 dir2/dir3/e |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
234 dir2/f |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
235 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
236 Would have us: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
237 - add to the stack until "dir2/dir3/e" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
238 - realize that "dir2/f" is in a different subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
239 - pop "dir2/dir3/e", "dir2/dir3/d", reverse them so they're sorted and |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
240 pack them since the next entry is "dir2/dir3" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
241 - go back up to "dir2" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
242 - add "dir2/f" to the stack |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
243 - realize we're done with the map |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
244 - pop "dir2/f", "dir2/dir3" from the stack, reverse and pack them |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
245 - go up to the root node, do the same to write "a", "dir1" and "dir2" in |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
246 that order |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
247 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
248 ## Special case for the root node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
249 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
250 The root node is not serialized in the format, but its information is |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
251 written to the docket. Again, see more details on the on-disk format in |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
252 `mercurial/helptext/internals/dirstate-v2`. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
253 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
254 data = bytearray() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
255 root_nodes_start = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
256 root_nodes_len = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
257 nodes_with_entry_count = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
258 nodes_with_copy_source_count = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
259 # Will always be 0 since this implementation always re-writes everything |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
260 # to disk |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
261 unreachable_bytes = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
262 unused = b'\x00' * 4 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
263 # This is an optimization that's only useful for the Rust implementation |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
264 ignore_patterns_hash = b'\x00' * 20 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
265 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
266 if len(map) == 0: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
267 tree_metadata = TREE_METADATA.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
268 root_nodes_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
269 root_nodes_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
270 nodes_with_entry_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
271 nodes_with_copy_source_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
272 unreachable_bytes, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
273 unused, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
274 ignore_patterns_hash, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
275 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
276 return data, tree_metadata |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
277 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
278 sorted_map = sorted(map.items(), key=lambda x: x[0]) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
279 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
280 # Use a stack to not have to only remember the nodes we currently need |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
281 # instead of building the entire tree in memory |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
282 stack = [] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
283 current_node = Node(b"", None) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
284 stack.append(current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
285 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
286 for index, (path, entry) in enumerate(sorted_map, 1): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
287 if entry.need_delay(now): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
288 # The file was last modified "simultaneously" with the current |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
289 # write to dirstate (i.e. within the same second for file- |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
290 # systems with a granularity of 1 sec). This commonly happens |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
291 # for at least a couple of files on 'update'. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
292 # The user could change the file without changing its size |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
293 # within the same second. Invalidate the file's mtime in |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
294 # dirstate, forcing future 'status' calls to compare the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
295 # contents of the file if the size is the same. This prevents |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
296 # mistakenly treating such files as clean. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
297 entry.set_possibly_dirty() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
298 nodes_with_entry_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
299 if path in copy_map: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
300 nodes_with_copy_source_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
301 current_folder = get_folder(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
302 current_node = move_to_correct_node_in_tree( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
303 current_folder, current_node, stack |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
304 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
305 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
306 current_node.children_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
307 # Entries from `map` are never `None` |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
308 if entry.tracked: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
309 current_node.tracked_descendants += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
310 current_node.descendants_with_entry += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
311 stack.append(Node(path, entry, current_node)) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
312 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
313 should_pack = True |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
314 next_path = None |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
315 if index < len(sorted_map): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
316 # Determine if the next entry is in the same sub-tree, if so don't |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
317 # pack yet |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
318 next_path = sorted_map[index][0] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
319 should_pack = not get_folder(next_path).startswith(current_folder) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
320 if should_pack: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
321 pack_directory_children(current_node, copy_map, data, stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
322 while stack and current_node.path != b"": |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
323 # Go up the tree and write until we reach the folder of the next |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
324 # entry (if any, otherwise the root) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
325 parent = current_node.parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
326 in_parent_folder_of_next_entry = next_path is not None and ( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
327 get_folder(next_path).startswith(get_folder(stack[-1].path)) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
328 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
329 if parent is None or in_parent_folder_of_next_entry: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
330 break |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
331 pack_directory_children(parent, copy_map, data, stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
332 current_node = parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
333 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
334 # Special case for the root node since we don't write it to disk, only its |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
335 # children to the docket |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
336 current_node = stack.pop() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
337 assert current_node.path == b"", current_node.path |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
338 assert len(stack) == 0, len(stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
339 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
340 tree_metadata = TREE_METADATA.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
341 current_node.children_offset, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
342 current_node.children_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
343 nodes_with_entry_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
344 nodes_with_copy_source_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
345 unreachable_bytes, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
346 unused, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
347 ignore_patterns_hash, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
348 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
349 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
350 return data, tree_metadata |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
351 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
352 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
353 def get_folder(path): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
354 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
355 Return the folder of the path that's given, an empty string for root paths. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
356 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
357 return path.rsplit(b'/', 1)[0] if b'/' in path else b'' |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
358 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
359 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
360 def move_to_correct_node_in_tree(target_folder, current_node, stack): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
361 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
362 Move inside the dirstate node tree to the node corresponding to |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
363 `target_folder`, creating the missing nodes along the way if needed. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
364 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
365 while target_folder != current_node.path: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
366 if target_folder.startswith(current_node.path): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
367 # We need to go down a folder |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
368 prefix = target_folder[len(current_node.path) :].lstrip(b'/') |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
369 subfolder_name = prefix.split(b'/', 1)[0] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
370 if current_node.path: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
371 subfolder_path = current_node.path + b'/' + subfolder_name |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
372 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
373 subfolder_path = subfolder_name |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
374 next_node = stack[-1] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
375 if next_node.path == target_folder: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
376 # This folder is now a file and only contains removed entries |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
377 # merge with the last node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
378 current_node = next_node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
379 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
380 current_node.children_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
381 current_node = Node(subfolder_path, None, current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
382 stack.append(current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
383 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
384 # We need to go up a folder |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
385 current_node = current_node.parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
386 return current_node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
387 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
388 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
389 def pack_directory_children(node, copy_map, data, stack): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
390 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
391 Write the binary representation of the direct sorted children of `node` to |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
392 `data` |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
393 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
394 direct_children = [] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
395 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
396 while stack[-1].path != b"" and get_folder(stack[-1].path) == node.path: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
397 direct_children.append(stack.pop()) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
398 if not direct_children: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
399 raise error.ProgrammingError(b"no direct children for %r" % node.path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
400 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
401 # Reverse the stack to get the correct sorted order |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
402 direct_children.reverse() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
403 packed_children = bytearray() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
404 # Write the paths to `data`. Pack child nodes but don't write them yet |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
405 for child in direct_children: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
406 packed = child.pack(copy_map=copy_map, paths_offset=len(data)) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
407 packed_children.extend(packed) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
408 data.extend(child.path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
409 data.extend(copy_map.get(child.path, b"")) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
410 node.tracked_descendants += child.tracked_descendants |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
411 node.descendants_with_entry += child.descendants_with_entry |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
412 # Write the fixed-size child nodes all together |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
413 node.children_offset = len(data) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48221
diff
changeset
|
414 data.extend(packed_children) |