Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/dirstateutils/v2.py @ 48262:dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Right now, we don't record ignored or unknown files in the dirstate. However
the structure would allow it. So we introduce two flags that can be used to
clarify whether all unknown/ignored children are recorded or not. This will
allow for more information to be stored in the future if this end up being
relevant.
Differential Revision: https://phab.mercurial-scm.org/D11682
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 15 Oct 2021 16:33:19 +0200 |
parents | 0524c1359bfc |
children | 269ff8978086 |
rev | line source |
---|---|
48233
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 |
48234
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
12 from ..thirdparty import attr |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
13 from .. import error, policy |
48233
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 |
48243
0524c1359bfc
dirstate-v2: Extend node flags to 16 bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48240
diff
changeset
|
21 NODE_SIZE = 44 |
48233
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 |
48243
0524c1359bfc
dirstate-v2: Extend node flags to 16 bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48240
diff
changeset
|
53 NODE = struct.Struct('>LHHLHLLLLHlll') |
48233
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 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
59 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
60 def parse_dirstate(map, copy_map, data, tree_metadata): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
61 """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
|
62 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
63 - map: a {path: entry} mapping that will be filled |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
64 - 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
|
65 - data: a binary blob contains v2 nodes data |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 - 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
|
67 """ |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
68 ( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
69 root_nodes_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
70 root_nodes_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
71 _nodes_with_entry_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
72 _nodes_with_copy_source_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
73 _unreachable_bytes, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
74 _unused, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
75 _ignore_patterns_hash, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 ) = TREE_METADATA.unpack(tree_metadata) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
77 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
|
78 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 def parse_nodes(map, copy_map, data, start, len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
81 """parse <len> nodes from <data> starting at offset <start> |
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 This is used by parse_dirstate to recursively fill `map` and `copy_map`. |
48262
dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48243
diff
changeset
|
84 |
dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48243
diff
changeset
|
85 All directory specific information is ignored and do not need any |
dfc5a505ddc5
dirstate-v2: adds two flag to track the presence of some unrecorded files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48243
diff
changeset
|
86 processing (HAS_DIRECTORY_MTIME, ALL_UNKNOWN_RECORDED, ALL_IGNORED_RECORDED) |
48233
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 """ |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
88 for i in range(len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
89 node_start = start + NODE_SIZE * i |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 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
|
91 ( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 path_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 path_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 _basename_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 copy_source_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 copy_source_len, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 children_start, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 children_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
99 _descendants_with_entry_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
100 _tracked_descendants_count, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 flags, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 size, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
103 mtime_s, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
104 _mtime_ns, |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
105 ) = NODE.unpack(node_bytes) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
106 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
107 # Parse child nodes of this node recursively |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
108 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
|
109 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
110 item = parsers.DirstateItem.from_v2_data(flags, size, mtime_s) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
111 if not item.any_tracked: |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
112 continue |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
113 path = slice_with_len(data, path_start, path_len) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
114 map[path] = item |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
115 if copy_source_start: |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
116 copy_map[path] = slice_with_len( |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
117 data, copy_source_start, copy_source_len |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
118 ) |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
119 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
120 |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
121 def slice_with_len(data, start, len): |
a32a96079e2d
dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
122 return data[start : start + len] |
48234
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
123 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
124 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
125 @attr.s |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
126 class Node(object): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
127 path = attr.ib() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
128 entry = attr.ib() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
129 parent = attr.ib(default=None) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
130 children_count = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
131 children_offset = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
132 descendants_with_entry = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
133 tracked_descendants = attr.ib(default=0) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
134 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
135 def pack(self, copy_map, paths_offset): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
136 path = self.path |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
137 copy = copy_map.get(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
138 entry = self.entry |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
139 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
140 path_start = paths_offset |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
141 path_len = len(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
142 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:
48233
diff
changeset
|
143 if copy is not None: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
144 copy_source_start = paths_offset + len(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
145 copy_source_len = len(copy) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
146 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
147 copy_source_start = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
148 copy_source_len = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
149 if entry is not None: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
150 flags, size, mtime_s = entry.v2_data() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
151 mtime_ns = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
152 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
153 # There are no mtime-cached directories in the Python implementation |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
154 flags = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
155 size = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
156 mtime_s = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
157 mtime_ns = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
158 return NODE.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
159 path_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
160 path_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
161 basename_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
162 copy_source_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
163 copy_source_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
164 self.children_offset, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
165 self.children_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
166 self.descendants_with_entry, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
167 self.tracked_descendants, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
168 flags, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
169 size, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
170 mtime_s, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
171 mtime_ns, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
172 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
173 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
174 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
175 def pack_dirstate(map, copy_map, now): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
176 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
177 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:
48233
diff
changeset
|
178 the bytearray. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
179 `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:
48233
diff
changeset
|
180 conditions in writing the dirstate to disk, see inline comment. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
181 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
182 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:
48233
diff
changeset
|
183 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:
48233
diff
changeset
|
184 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:
48233
diff
changeset
|
185 format in `mercurial/helptext/internals/dirstate-v2`. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
186 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
187 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:
48233
diff
changeset
|
188 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:
48233
diff
changeset
|
189 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:
48233
diff
changeset
|
190 format. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
191 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
192 # Algorithm explanation |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
193 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
194 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:
48233
diff
changeset
|
195 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:
48233
diff
changeset
|
196 algorithm is in place. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
197 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
198 ## Building a subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
199 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
200 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:
48233
diff
changeset
|
201 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:
48233
diff
changeset
|
202 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:
48233
diff
changeset
|
203 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:
48233
diff
changeset
|
204 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:
48233
diff
changeset
|
205 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:
48233
diff
changeset
|
206 of the tree lazily. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
207 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:
48233
diff
changeset
|
208 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:
48233
diff
changeset
|
209 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:
48233
diff
changeset
|
210 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:
48233
diff
changeset
|
211 `Node["a"]`. These nodes are kept around in a stack. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
212 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:
48233
diff
changeset
|
213 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:
48233
diff
changeset
|
214 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:
48233
diff
changeset
|
215 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:
48233
diff
changeset
|
216 the subtree we're in is complete. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
217 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
218 ## Writing the subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
219 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
220 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:
48233
diff
changeset
|
221 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:
48233
diff
changeset
|
222 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:
48233
diff
changeset
|
223 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:
48233
diff
changeset
|
224 we hit the "other" subtree. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
225 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
226 An example: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
227 a |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
228 dir1/b |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
229 dir1/c |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
230 dir2/dir3/d |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
231 dir2/dir3/e |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
232 dir2/f |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
233 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
234 Would have us: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
235 - add to the stack until "dir2/dir3/e" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
236 - realize that "dir2/f" is in a different subtree |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
237 - 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:
48233
diff
changeset
|
238 pack them since the next entry is "dir2/dir3" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
239 - go back up to "dir2" |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
240 - add "dir2/f" to the stack |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
241 - realize we're done with the map |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
242 - 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:
48233
diff
changeset
|
243 - 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:
48233
diff
changeset
|
244 that order |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
245 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
246 ## Special case for the root node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
247 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
248 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:
48233
diff
changeset
|
249 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:
48233
diff
changeset
|
250 `mercurial/helptext/internals/dirstate-v2`. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
251 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
252 now = int(now) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
253 data = bytearray() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
254 root_nodes_start = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
255 root_nodes_len = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
256 nodes_with_entry_count = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
257 nodes_with_copy_source_count = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
258 # 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:
48233
diff
changeset
|
259 # to disk |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
260 unreachable_bytes = 0 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
261 unused = b'\x00' * 4 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
262 # 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:
48233
diff
changeset
|
263 ignore_patterns_hash = b'\x00' * 20 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
264 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
265 if len(map) == 0: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
266 tree_metadata = TREE_METADATA.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
267 root_nodes_start, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
268 root_nodes_len, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
269 nodes_with_entry_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
270 nodes_with_copy_source_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
271 unreachable_bytes, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
272 unused, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
273 ignore_patterns_hash, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
274 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
275 return data, tree_metadata |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
276 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
277 sorted_map = sorted(map.items(), key=lambda x: x[0]) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
278 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
279 # 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:
48233
diff
changeset
|
280 # instead of building the entire tree in memory |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
281 stack = [] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
282 current_node = Node(b"", None) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
283 stack.append(current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
284 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
285 for index, (path, entry) in enumerate(sorted_map, 1): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
286 if entry.need_delay(now): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
287 # The file was last modified "simultaneously" with the current |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
288 # 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:
48233
diff
changeset
|
289 # systems with a granularity of 1 sec). This commonly happens |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
290 # for at least a couple of files on 'update'. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
291 # The user could change the file without changing its size |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
292 # within the same second. Invalidate the file's mtime in |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
293 # dirstate, forcing future 'status' calls to compare the |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
294 # 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:
48233
diff
changeset
|
295 # mistakenly treating such files as clean. |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
296 entry.set_possibly_dirty() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
297 nodes_with_entry_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
298 if path in copy_map: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
299 nodes_with_copy_source_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
300 current_folder = get_folder(path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
301 current_node = move_to_correct_node_in_tree( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
302 current_folder, current_node, stack |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
303 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
304 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
305 current_node.children_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
306 # Entries from `map` are never `None` |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
307 if entry.tracked: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
308 current_node.tracked_descendants += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
309 current_node.descendants_with_entry += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
310 stack.append(Node(path, entry, current_node)) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
311 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
312 should_pack = True |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
313 next_path = None |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
314 if index < len(sorted_map): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
315 # 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:
48233
diff
changeset
|
316 # pack yet |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
317 next_path = sorted_map[index][0] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
318 should_pack = not get_folder(next_path).startswith(current_folder) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
319 if should_pack: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
320 pack_directory_children(current_node, copy_map, data, stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
321 while stack and current_node.path != b"": |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
322 # 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:
48233
diff
changeset
|
323 # entry (if any, otherwise the root) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
324 parent = current_node.parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
325 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:
48233
diff
changeset
|
326 get_folder(next_path).startswith(get_folder(stack[-1].path)) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
327 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
328 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:
48233
diff
changeset
|
329 break |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
330 pack_directory_children(parent, copy_map, data, stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
331 current_node = parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
332 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
333 # 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:
48233
diff
changeset
|
334 # children to the docket |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
335 current_node = stack.pop() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
336 assert current_node.path == b"", current_node.path |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
337 assert len(stack) == 0, len(stack) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
338 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
339 tree_metadata = TREE_METADATA.pack( |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
340 current_node.children_offset, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
341 current_node.children_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
342 nodes_with_entry_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
343 nodes_with_copy_source_count, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
344 unreachable_bytes, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
345 unused, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
346 ignore_patterns_hash, |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
347 ) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
348 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
349 return data, tree_metadata |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
350 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
351 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
352 def get_folder(path): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
353 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
354 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:
48233
diff
changeset
|
355 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
356 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:
48233
diff
changeset
|
357 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
358 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
359 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:
48233
diff
changeset
|
360 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
361 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:
48233
diff
changeset
|
362 `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:
48233
diff
changeset
|
363 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
364 while target_folder != current_node.path: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
365 if target_folder.startswith(current_node.path): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
366 # We need to go down a folder |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
367 prefix = target_folder[len(current_node.path) :].lstrip(b'/') |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
368 subfolder_name = prefix.split(b'/', 1)[0] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
369 if current_node.path: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
370 subfolder_path = current_node.path + b'/' + subfolder_name |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
371 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
372 subfolder_path = subfolder_name |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
373 next_node = stack[-1] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
374 if next_node.path == target_folder: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
375 # 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:
48233
diff
changeset
|
376 # merge with the last node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
377 current_node = next_node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
378 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
379 current_node.children_count += 1 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
380 current_node = Node(subfolder_path, None, current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
381 stack.append(current_node) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
382 else: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
383 # We need to go up a folder |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
384 current_node = current_node.parent |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
385 return current_node |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
386 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
387 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
388 def pack_directory_children(node, copy_map, data, stack): |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
389 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
390 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:
48233
diff
changeset
|
391 `data` |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
392 """ |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
393 direct_children = [] |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
394 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
395 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:
48233
diff
changeset
|
396 direct_children.append(stack.pop()) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
397 if not direct_children: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
398 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:
48233
diff
changeset
|
399 |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
400 # Reverse the stack to get the correct sorted order |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
401 direct_children.reverse() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
402 packed_children = bytearray() |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
403 # 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:
48233
diff
changeset
|
404 for child in direct_children: |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
405 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:
48233
diff
changeset
|
406 packed_children.extend(packed) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
407 data.extend(child.path) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
408 data.extend(copy_map.get(child.path, b"")) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
409 node.tracked_descendants += child.tracked_descendants |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
410 node.descendants_with_entry += child.descendants_with_entry |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
411 # Write the fixed-size child nodes all together |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
412 node.children_offset = len(data) |
7e78c72ee3ea
dirstate-v2: Initial Python serializer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48233
diff
changeset
|
413 data.extend(packed_children) |