##// END OF EJS Templates
cli: fix spelling in `debugnodemap` error messages
Arseniy Alekseyev -
r51403:4fe46f96 default
parent child Browse files
Show More
@@ -1,668 +1,668 b''
1 # nodemap.py - nodemap related code and utilities
1 # nodemap.py - nodemap related code and utilities
2 #
2 #
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net>
4 # Copyright 2019 George Racinet <georges.racinet@octobus.net>
4 # Copyright 2019 George Racinet <georges.racinet@octobus.net>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9
9
10 import re
10 import re
11 import struct
11 import struct
12
12
13 from ..node import hex
13 from ..node import hex
14
14
15 from .. import (
15 from .. import (
16 error,
16 error,
17 requirements,
17 requirements,
18 util,
18 util,
19 )
19 )
20 from . import docket as docket_mod
20 from . import docket as docket_mod
21
21
22
22
23 class NodeMap(dict):
23 class NodeMap(dict):
24 def __missing__(self, x):
24 def __missing__(self, x):
25 raise error.RevlogError(b'unknown node: %s' % x)
25 raise error.RevlogError(b'unknown node: %s' % x)
26
26
27
27
28 def test_race_hook_1():
28 def test_race_hook_1():
29 """hook point for test
29 """hook point for test
30
30
31 This let tests to have things happens between the docket reading and the
31 This let tests to have things happens between the docket reading and the
32 data reading"""
32 data reading"""
33 pass
33 pass
34
34
35
35
36 def post_stream_cleanup(repo):
36 def post_stream_cleanup(repo):
37 """The stream clone might needs to remove some file if persisten nodemap
37 """The stream clone might needs to remove some file if persisten nodemap
38 was dropped while stream cloning
38 was dropped while stream cloning
39 """
39 """
40 if requirements.REVLOGV1_REQUIREMENT not in repo.requirements:
40 if requirements.REVLOGV1_REQUIREMENT not in repo.requirements:
41 return
41 return
42 if requirements.NODEMAP_REQUIREMENT in repo.requirements:
42 if requirements.NODEMAP_REQUIREMENT in repo.requirements:
43 return
43 return
44 unfi = repo.unfiltered()
44 unfi = repo.unfiltered()
45 delete_nodemap(None, unfi, unfi.changelog)
45 delete_nodemap(None, unfi, unfi.changelog)
46 delete_nodemap(None, repo, unfi.manifestlog._rootstore._revlog)
46 delete_nodemap(None, repo, unfi.manifestlog._rootstore._revlog)
47
47
48
48
49 def persisted_data(revlog):
49 def persisted_data(revlog):
50 """read the nodemap for a revlog from disk"""
50 """read the nodemap for a revlog from disk"""
51 if revlog._nodemap_file is None:
51 if revlog._nodemap_file is None:
52 return None
52 return None
53 pdata = revlog.opener.tryread(revlog._nodemap_file)
53 pdata = revlog.opener.tryread(revlog._nodemap_file)
54 if not pdata:
54 if not pdata:
55 return None
55 return None
56 offset = 0
56 offset = 0
57 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size])
57 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size])
58 if version != ONDISK_VERSION:
58 if version != ONDISK_VERSION:
59 return None
59 return None
60 offset += S_VERSION.size
60 offset += S_VERSION.size
61 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
61 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
62 uid_size, tip_rev, data_length, data_unused, tip_node_size = headers
62 uid_size, tip_rev, data_length, data_unused, tip_node_size = headers
63 offset += S_HEADER.size
63 offset += S_HEADER.size
64 docket = NodeMapDocket(pdata[offset : offset + uid_size])
64 docket = NodeMapDocket(pdata[offset : offset + uid_size])
65 offset += uid_size
65 offset += uid_size
66 docket.tip_rev = tip_rev
66 docket.tip_rev = tip_rev
67 docket.tip_node = pdata[offset : offset + tip_node_size]
67 docket.tip_node = pdata[offset : offset + tip_node_size]
68 docket.data_length = data_length
68 docket.data_length = data_length
69 docket.data_unused = data_unused
69 docket.data_unused = data_unused
70
70
71 filename = _rawdata_filepath(revlog, docket)
71 filename = _rawdata_filepath(revlog, docket)
72 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap")
72 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap")
73
73
74 test_race_hook_1()
74 test_race_hook_1()
75 try:
75 try:
76 with revlog.opener(filename) as fd:
76 with revlog.opener(filename) as fd:
77 if use_mmap:
77 if use_mmap:
78 try:
78 try:
79 data = util.buffer(util.mmapread(fd, data_length))
79 data = util.buffer(util.mmapread(fd, data_length))
80 except ValueError:
80 except ValueError:
81 # raised when the read file is too small
81 # raised when the read file is too small
82 data = b''
82 data = b''
83 else:
83 else:
84 data = fd.read(data_length)
84 data = fd.read(data_length)
85 except FileNotFoundError:
85 except FileNotFoundError:
86 return None
86 return None
87 if len(data) < data_length:
87 if len(data) < data_length:
88 return None
88 return None
89 return docket, data
89 return docket, data
90
90
91
91
92 def setup_persistent_nodemap(tr, revlog):
92 def setup_persistent_nodemap(tr, revlog):
93 """Install whatever is needed transaction side to persist a nodemap on disk
93 """Install whatever is needed transaction side to persist a nodemap on disk
94
94
95 (only actually persist the nodemap if this is relevant for this revlog)
95 (only actually persist the nodemap if this is relevant for this revlog)
96 """
96 """
97 if revlog._inline:
97 if revlog._inline:
98 return # inlined revlog are too small for this to be relevant
98 return # inlined revlog are too small for this to be relevant
99 if revlog._nodemap_file is None:
99 if revlog._nodemap_file is None:
100 return # we do not use persistent_nodemap on this revlog
100 return # we do not use persistent_nodemap on this revlog
101
101
102 # we need to happen after the changelog finalization, in that use "cl-"
102 # we need to happen after the changelog finalization, in that use "cl-"
103 callback_id = b"nm-revlog-persistent-nodemap-%s" % revlog._nodemap_file
103 callback_id = b"nm-revlog-persistent-nodemap-%s" % revlog._nodemap_file
104 if tr.hasfinalize(callback_id):
104 if tr.hasfinalize(callback_id):
105 return # no need to register again
105 return # no need to register again
106 tr.addpending(
106 tr.addpending(
107 callback_id, lambda tr: persist_nodemap(tr, revlog, pending=True)
107 callback_id, lambda tr: persist_nodemap(tr, revlog, pending=True)
108 )
108 )
109 tr.addfinalize(callback_id, lambda tr: persist_nodemap(tr, revlog))
109 tr.addfinalize(callback_id, lambda tr: persist_nodemap(tr, revlog))
110
110
111
111
112 class _NoTransaction:
112 class _NoTransaction:
113 """transaction like object to update the nodemap outside a transaction"""
113 """transaction like object to update the nodemap outside a transaction"""
114
114
115 def __init__(self):
115 def __init__(self):
116 self._postclose = {}
116 self._postclose = {}
117
117
118 def addpostclose(self, callback_id, callback_func):
118 def addpostclose(self, callback_id, callback_func):
119 self._postclose[callback_id] = callback_func
119 self._postclose[callback_id] = callback_func
120
120
121 def registertmp(self, *args, **kwargs):
121 def registertmp(self, *args, **kwargs):
122 pass
122 pass
123
123
124 def addbackup(self, *args, **kwargs):
124 def addbackup(self, *args, **kwargs):
125 pass
125 pass
126
126
127 def add(self, *args, **kwargs):
127 def add(self, *args, **kwargs):
128 pass
128 pass
129
129
130 def addabort(self, *args, **kwargs):
130 def addabort(self, *args, **kwargs):
131 pass
131 pass
132
132
133 def _report(self, *args):
133 def _report(self, *args):
134 pass
134 pass
135
135
136
136
137 def update_persistent_nodemap(revlog):
137 def update_persistent_nodemap(revlog):
138 """update the persistent nodemap right now
138 """update the persistent nodemap right now
139
139
140 To be used for updating the nodemap on disk outside of a normal transaction
140 To be used for updating the nodemap on disk outside of a normal transaction
141 setup (eg, `debugupdatecache`).
141 setup (eg, `debugupdatecache`).
142 """
142 """
143 if revlog._inline:
143 if revlog._inline:
144 return # inlined revlog are too small for this to be relevant
144 return # inlined revlog are too small for this to be relevant
145 if revlog._nodemap_file is None:
145 if revlog._nodemap_file is None:
146 return # we do not use persistent_nodemap on this revlog
146 return # we do not use persistent_nodemap on this revlog
147
147
148 notr = _NoTransaction()
148 notr = _NoTransaction()
149 persist_nodemap(notr, revlog)
149 persist_nodemap(notr, revlog)
150 for k in sorted(notr._postclose):
150 for k in sorted(notr._postclose):
151 notr._postclose[k](None)
151 notr._postclose[k](None)
152
152
153
153
154 def delete_nodemap(tr, repo, revlog):
154 def delete_nodemap(tr, repo, revlog):
155 """Delete nodemap data on disk for a given revlog"""
155 """Delete nodemap data on disk for a given revlog"""
156 prefix = revlog.radix
156 prefix = revlog.radix
157 pattern = re.compile(br"(^|/)%s(-[0-9a-f]+\.nd|\.n(\.a)?)$" % prefix)
157 pattern = re.compile(br"(^|/)%s(-[0-9a-f]+\.nd|\.n(\.a)?)$" % prefix)
158 dirpath = revlog.opener.dirname(revlog._indexfile)
158 dirpath = revlog.opener.dirname(revlog._indexfile)
159 for f in revlog.opener.listdir(dirpath):
159 for f in revlog.opener.listdir(dirpath):
160 if pattern.match(f):
160 if pattern.match(f):
161 repo.svfs.tryunlink(f)
161 repo.svfs.tryunlink(f)
162
162
163
163
164 def persist_nodemap(tr, revlog, pending=False, force=False):
164 def persist_nodemap(tr, revlog, pending=False, force=False):
165 """Write nodemap data on disk for a given revlog"""
165 """Write nodemap data on disk for a given revlog"""
166 if getattr(revlog, 'filteredrevs', ()):
166 if getattr(revlog, 'filteredrevs', ()):
167 raise error.ProgrammingError(
167 raise error.ProgrammingError(
168 "cannot persist nodemap of a filtered changelog"
168 "cannot persist nodemap of a filtered changelog"
169 )
169 )
170 if revlog._nodemap_file is None:
170 if revlog._nodemap_file is None:
171 if force:
171 if force:
172 revlog._nodemap_file = get_nodemap_file(revlog)
172 revlog._nodemap_file = get_nodemap_file(revlog)
173 else:
173 else:
174 msg = "calling persist nodemap on a revlog without the feature enabled"
174 msg = "calling persist nodemap on a revlog without the feature enabled"
175 raise error.ProgrammingError(msg)
175 raise error.ProgrammingError(msg)
176
176
177 can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental")
177 can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental")
178 ondisk_docket = revlog._nodemap_docket
178 ondisk_docket = revlog._nodemap_docket
179 feed_data = util.safehasattr(revlog.index, "update_nodemap_data")
179 feed_data = util.safehasattr(revlog.index, "update_nodemap_data")
180 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap")
180 use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap")
181
181
182 data = None
182 data = None
183 # first attemp an incremental update of the data
183 # first attemp an incremental update of the data
184 if can_incremental and ondisk_docket is not None:
184 if can_incremental and ondisk_docket is not None:
185 target_docket = revlog._nodemap_docket.copy()
185 target_docket = revlog._nodemap_docket.copy()
186 (
186 (
187 src_docket,
187 src_docket,
188 data_changed_count,
188 data_changed_count,
189 data,
189 data,
190 ) = revlog.index.nodemap_data_incremental()
190 ) = revlog.index.nodemap_data_incremental()
191 new_length = target_docket.data_length + len(data)
191 new_length = target_docket.data_length + len(data)
192 new_unused = target_docket.data_unused + data_changed_count
192 new_unused = target_docket.data_unused + data_changed_count
193 if src_docket != target_docket:
193 if src_docket != target_docket:
194 data = None
194 data = None
195 elif new_length <= (new_unused * 10): # under 10% of unused data
195 elif new_length <= (new_unused * 10): # under 10% of unused data
196 data = None
196 data = None
197 else:
197 else:
198 datafile = _rawdata_filepath(revlog, target_docket)
198 datafile = _rawdata_filepath(revlog, target_docket)
199 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
199 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
200 # store vfs
200 # store vfs
201 tr.add(datafile, target_docket.data_length)
201 tr.add(datafile, target_docket.data_length)
202 with revlog.opener(datafile, b'r+') as fd:
202 with revlog.opener(datafile, b'r+') as fd:
203 fd.seek(target_docket.data_length)
203 fd.seek(target_docket.data_length)
204 fd.write(data)
204 fd.write(data)
205 if feed_data:
205 if feed_data:
206 if use_mmap:
206 if use_mmap:
207 fd.seek(0)
207 fd.seek(0)
208 new_data = fd.read(new_length)
208 new_data = fd.read(new_length)
209 else:
209 else:
210 fd.flush()
210 fd.flush()
211 new_data = util.buffer(util.mmapread(fd, new_length))
211 new_data = util.buffer(util.mmapread(fd, new_length))
212 target_docket.data_length = new_length
212 target_docket.data_length = new_length
213 target_docket.data_unused = new_unused
213 target_docket.data_unused = new_unused
214
214
215 if data is None:
215 if data is None:
216 # otherwise fallback to a full new export
216 # otherwise fallback to a full new export
217 target_docket = NodeMapDocket()
217 target_docket = NodeMapDocket()
218 datafile = _rawdata_filepath(revlog, target_docket)
218 datafile = _rawdata_filepath(revlog, target_docket)
219 if util.safehasattr(revlog.index, "nodemap_data_all"):
219 if util.safehasattr(revlog.index, "nodemap_data_all"):
220 data = revlog.index.nodemap_data_all()
220 data = revlog.index.nodemap_data_all()
221 else:
221 else:
222 data = persistent_data(revlog.index)
222 data = persistent_data(revlog.index)
223 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
223 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
224 # store vfs
224 # store vfs
225
225
226 tryunlink = revlog.opener.tryunlink
226 tryunlink = revlog.opener.tryunlink
227
227
228 def abortck(tr):
228 def abortck(tr):
229 tryunlink(datafile)
229 tryunlink(datafile)
230
230
231 callback_id = b"delete-%s" % datafile
231 callback_id = b"delete-%s" % datafile
232
232
233 # some flavor of the transaction abort does not cleanup new file, it
233 # some flavor of the transaction abort does not cleanup new file, it
234 # simply empty them.
234 # simply empty them.
235 tr.addabort(callback_id, abortck)
235 tr.addabort(callback_id, abortck)
236 with revlog.opener(datafile, b'w+') as fd:
236 with revlog.opener(datafile, b'w+') as fd:
237 fd.write(data)
237 fd.write(data)
238 if feed_data:
238 if feed_data:
239 if use_mmap:
239 if use_mmap:
240 new_data = data
240 new_data = data
241 else:
241 else:
242 fd.flush()
242 fd.flush()
243 new_data = util.buffer(util.mmapread(fd, len(data)))
243 new_data = util.buffer(util.mmapread(fd, len(data)))
244 target_docket.data_length = len(data)
244 target_docket.data_length = len(data)
245 target_docket.tip_rev = revlog.tiprev()
245 target_docket.tip_rev = revlog.tiprev()
246 target_docket.tip_node = revlog.node(target_docket.tip_rev)
246 target_docket.tip_node = revlog.node(target_docket.tip_rev)
247 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
247 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
248 # store vfs
248 # store vfs
249 file_path = revlog._nodemap_file
249 file_path = revlog._nodemap_file
250 if pending:
250 if pending:
251 file_path += b'.a'
251 file_path += b'.a'
252 tr.registertmp(file_path)
252 tr.registertmp(file_path)
253 else:
253 else:
254 tr.addbackup(file_path)
254 tr.addbackup(file_path)
255
255
256 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
256 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
257 fp.write(target_docket.serialize())
257 fp.write(target_docket.serialize())
258 revlog._nodemap_docket = target_docket
258 revlog._nodemap_docket = target_docket
259 if feed_data:
259 if feed_data:
260 revlog.index.update_nodemap_data(target_docket, new_data)
260 revlog.index.update_nodemap_data(target_docket, new_data)
261
261
262 # search for old index file in all cases, some older process might have
262 # search for old index file in all cases, some older process might have
263 # left one behind.
263 # left one behind.
264 olds = _other_rawdata_filepath(revlog, target_docket)
264 olds = _other_rawdata_filepath(revlog, target_docket)
265 if olds:
265 if olds:
266 realvfs = getattr(revlog, '_realopener', revlog.opener)
266 realvfs = getattr(revlog, '_realopener', revlog.opener)
267
267
268 def cleanup(tr):
268 def cleanup(tr):
269 for oldfile in olds:
269 for oldfile in olds:
270 realvfs.tryunlink(oldfile)
270 realvfs.tryunlink(oldfile)
271
271
272 callback_id = b"revlog-cleanup-nodemap-%s" % revlog._nodemap_file
272 callback_id = b"revlog-cleanup-nodemap-%s" % revlog._nodemap_file
273 tr.addpostclose(callback_id, cleanup)
273 tr.addpostclose(callback_id, cleanup)
274
274
275
275
276 ### Nodemap docket file
276 ### Nodemap docket file
277 #
277 #
278 # The nodemap data are stored on disk using 2 files:
278 # The nodemap data are stored on disk using 2 files:
279 #
279 #
280 # * a raw data files containing a persistent nodemap
280 # * a raw data files containing a persistent nodemap
281 # (see `Nodemap Trie` section)
281 # (see `Nodemap Trie` section)
282 #
282 #
283 # * a small "docket" file containing medatadata
283 # * a small "docket" file containing medatadata
284 #
284 #
285 # While the nodemap data can be multiple tens of megabytes, the "docket" is
285 # While the nodemap data can be multiple tens of megabytes, the "docket" is
286 # small, it is easy to update it automatically or to duplicated its content
286 # small, it is easy to update it automatically or to duplicated its content
287 # during a transaction.
287 # during a transaction.
288 #
288 #
289 # Multiple raw data can exist at the same time (The currently valid one and a
289 # Multiple raw data can exist at the same time (The currently valid one and a
290 # new one beind used by an in progress transaction). To accomodate this, the
290 # new one beind used by an in progress transaction). To accomodate this, the
291 # filename hosting the raw data has a variable parts. The exact filename is
291 # filename hosting the raw data has a variable parts. The exact filename is
292 # specified inside the "docket" file.
292 # specified inside the "docket" file.
293 #
293 #
294 # The docket file contains information to find, qualify and validate the raw
294 # The docket file contains information to find, qualify and validate the raw
295 # data. Its content is currently very light, but it will expand as the on disk
295 # data. Its content is currently very light, but it will expand as the on disk
296 # nodemap gains the necessary features to be used in production.
296 # nodemap gains the necessary features to be used in production.
297
297
298 ONDISK_VERSION = 1
298 ONDISK_VERSION = 1
299 S_VERSION = struct.Struct(">B")
299 S_VERSION = struct.Struct(">B")
300 S_HEADER = struct.Struct(">BQQQQ")
300 S_HEADER = struct.Struct(">BQQQQ")
301
301
302
302
303 class NodeMapDocket:
303 class NodeMapDocket:
304 """metadata associated with persistent nodemap data
304 """metadata associated with persistent nodemap data
305
305
306 The persistent data may come from disk or be on their way to disk.
306 The persistent data may come from disk or be on their way to disk.
307 """
307 """
308
308
309 def __init__(self, uid=None):
309 def __init__(self, uid=None):
310 if uid is None:
310 if uid is None:
311 uid = docket_mod.make_uid()
311 uid = docket_mod.make_uid()
312 # a unique identifier for the data file:
312 # a unique identifier for the data file:
313 # - When new data are appended, it is preserved.
313 # - When new data are appended, it is preserved.
314 # - When a new data file is created, a new identifier is generated.
314 # - When a new data file is created, a new identifier is generated.
315 self.uid = uid
315 self.uid = uid
316 # the tipmost revision stored in the data file. This revision and all
316 # the tipmost revision stored in the data file. This revision and all
317 # revision before it are expected to be encoded in the data file.
317 # revision before it are expected to be encoded in the data file.
318 self.tip_rev = None
318 self.tip_rev = None
319 # the node of that tipmost revision, if it mismatch the current index
319 # the node of that tipmost revision, if it mismatch the current index
320 # data the docket is not valid for the current index and should be
320 # data the docket is not valid for the current index and should be
321 # discarded.
321 # discarded.
322 #
322 #
323 # note: this method is not perfect as some destructive operation could
323 # note: this method is not perfect as some destructive operation could
324 # preserve the same tip_rev + tip_node while altering lower revision.
324 # preserve the same tip_rev + tip_node while altering lower revision.
325 # However this multiple other caches have the same vulnerability (eg:
325 # However this multiple other caches have the same vulnerability (eg:
326 # brancmap cache).
326 # brancmap cache).
327 self.tip_node = None
327 self.tip_node = None
328 # the size (in bytes) of the persisted data to encode the nodemap valid
328 # the size (in bytes) of the persisted data to encode the nodemap valid
329 # for `tip_rev`.
329 # for `tip_rev`.
330 # - data file shorter than this are corrupted,
330 # - data file shorter than this are corrupted,
331 # - any extra data should be ignored.
331 # - any extra data should be ignored.
332 self.data_length = None
332 self.data_length = None
333 # the amount (in bytes) of "dead" data, still in the data file but no
333 # the amount (in bytes) of "dead" data, still in the data file but no
334 # longer used for the nodemap.
334 # longer used for the nodemap.
335 self.data_unused = 0
335 self.data_unused = 0
336
336
337 def copy(self):
337 def copy(self):
338 new = NodeMapDocket(uid=self.uid)
338 new = NodeMapDocket(uid=self.uid)
339 new.tip_rev = self.tip_rev
339 new.tip_rev = self.tip_rev
340 new.tip_node = self.tip_node
340 new.tip_node = self.tip_node
341 new.data_length = self.data_length
341 new.data_length = self.data_length
342 new.data_unused = self.data_unused
342 new.data_unused = self.data_unused
343 return new
343 return new
344
344
345 def __cmp__(self, other):
345 def __cmp__(self, other):
346 if self.uid < other.uid:
346 if self.uid < other.uid:
347 return -1
347 return -1
348 if self.uid > other.uid:
348 if self.uid > other.uid:
349 return 1
349 return 1
350 elif self.data_length < other.data_length:
350 elif self.data_length < other.data_length:
351 return -1
351 return -1
352 elif self.data_length > other.data_length:
352 elif self.data_length > other.data_length:
353 return 1
353 return 1
354 return 0
354 return 0
355
355
356 def __eq__(self, other):
356 def __eq__(self, other):
357 return self.uid == other.uid and self.data_length == other.data_length
357 return self.uid == other.uid and self.data_length == other.data_length
358
358
359 def serialize(self):
359 def serialize(self):
360 """return serialized bytes for a docket using the passed uid"""
360 """return serialized bytes for a docket using the passed uid"""
361 data = []
361 data = []
362 data.append(S_VERSION.pack(ONDISK_VERSION))
362 data.append(S_VERSION.pack(ONDISK_VERSION))
363 headers = (
363 headers = (
364 len(self.uid),
364 len(self.uid),
365 self.tip_rev,
365 self.tip_rev,
366 self.data_length,
366 self.data_length,
367 self.data_unused,
367 self.data_unused,
368 len(self.tip_node),
368 len(self.tip_node),
369 )
369 )
370 data.append(S_HEADER.pack(*headers))
370 data.append(S_HEADER.pack(*headers))
371 data.append(self.uid)
371 data.append(self.uid)
372 data.append(self.tip_node)
372 data.append(self.tip_node)
373 return b''.join(data)
373 return b''.join(data)
374
374
375
375
376 def _rawdata_filepath(revlog, docket):
376 def _rawdata_filepath(revlog, docket):
377 """The (vfs relative) nodemap's rawdata file for a given uid"""
377 """The (vfs relative) nodemap's rawdata file for a given uid"""
378 prefix = revlog.radix
378 prefix = revlog.radix
379 return b"%s-%s.nd" % (prefix, docket.uid)
379 return b"%s-%s.nd" % (prefix, docket.uid)
380
380
381
381
382 def _other_rawdata_filepath(revlog, docket):
382 def _other_rawdata_filepath(revlog, docket):
383 prefix = revlog.radix
383 prefix = revlog.radix
384 pattern = re.compile(br"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
384 pattern = re.compile(br"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
385 new_file_path = _rawdata_filepath(revlog, docket)
385 new_file_path = _rawdata_filepath(revlog, docket)
386 new_file_name = revlog.opener.basename(new_file_path)
386 new_file_name = revlog.opener.basename(new_file_path)
387 dirpath = revlog.opener.dirname(new_file_path)
387 dirpath = revlog.opener.dirname(new_file_path)
388 others = []
388 others = []
389 for f in revlog.opener.listdir(dirpath):
389 for f in revlog.opener.listdir(dirpath):
390 if pattern.match(f) and f != new_file_name:
390 if pattern.match(f) and f != new_file_name:
391 others.append(f)
391 others.append(f)
392 return others
392 return others
393
393
394
394
395 ### Nodemap Trie
395 ### Nodemap Trie
396 #
396 #
397 # This is a simple reference implementation to compute and persist a nodemap
397 # This is a simple reference implementation to compute and persist a nodemap
398 # trie. This reference implementation is write only. The python version of this
398 # trie. This reference implementation is write only. The python version of this
399 # is not expected to be actually used, since it wont provide performance
399 # is not expected to be actually used, since it wont provide performance
400 # improvement over existing non-persistent C implementation.
400 # improvement over existing non-persistent C implementation.
401 #
401 #
402 # The nodemap is persisted as Trie using 4bits-address/16-entries block. each
402 # The nodemap is persisted as Trie using 4bits-address/16-entries block. each
403 # revision can be adressed using its node shortest prefix.
403 # revision can be adressed using its node shortest prefix.
404 #
404 #
405 # The trie is stored as a sequence of block. Each block contains 16 entries
405 # The trie is stored as a sequence of block. Each block contains 16 entries
406 # (signed 64bit integer, big endian). Each entry can be one of the following:
406 # (signed 64bit integer, big endian). Each entry can be one of the following:
407 #
407 #
408 # * value >= 0 -> index of sub-block
408 # * value >= 0 -> index of sub-block
409 # * value == -1 -> no value
409 # * value == -1 -> no value
410 # * value < -1 -> encoded revision: rev = -(value+2)
410 # * value < -1 -> encoded revision: rev = -(value+2)
411 #
411 #
412 # See REV_OFFSET and _transform_rev below.
412 # See REV_OFFSET and _transform_rev below.
413 #
413 #
414 # The implementation focus on simplicity, not on performance. A Rust
414 # The implementation focus on simplicity, not on performance. A Rust
415 # implementation should provide a efficient version of the same binary
415 # implementation should provide a efficient version of the same binary
416 # persistence. This reference python implementation is never meant to be
416 # persistence. This reference python implementation is never meant to be
417 # extensively use in production.
417 # extensively use in production.
418
418
419
419
420 def persistent_data(index):
420 def persistent_data(index):
421 """return the persistent binary form for a nodemap for a given index"""
421 """return the persistent binary form for a nodemap for a given index"""
422 trie = _build_trie(index)
422 trie = _build_trie(index)
423 return _persist_trie(trie)
423 return _persist_trie(trie)
424
424
425
425
426 def update_persistent_data(index, root, max_idx, last_rev):
426 def update_persistent_data(index, root, max_idx, last_rev):
427 """return the incremental update for persistent nodemap from a given index"""
427 """return the incremental update for persistent nodemap from a given index"""
428 changed_block, trie = _update_trie(index, root, last_rev)
428 changed_block, trie = _update_trie(index, root, last_rev)
429 return (
429 return (
430 changed_block * S_BLOCK.size,
430 changed_block * S_BLOCK.size,
431 _persist_trie(trie, existing_idx=max_idx),
431 _persist_trie(trie, existing_idx=max_idx),
432 )
432 )
433
433
434
434
435 S_BLOCK = struct.Struct(">" + ("l" * 16))
435 S_BLOCK = struct.Struct(">" + ("l" * 16))
436
436
437 NO_ENTRY = -1
437 NO_ENTRY = -1
438 # rev 0 need to be -2 because 0 is used by block, -1 is a special value.
438 # rev 0 need to be -2 because 0 is used by block, -1 is a special value.
439 REV_OFFSET = 2
439 REV_OFFSET = 2
440
440
441
441
442 def _transform_rev(rev):
442 def _transform_rev(rev):
443 """Return the number used to represent the rev in the tree.
443 """Return the number used to represent the rev in the tree.
444
444
445 (or retrieve a rev number from such representation)
445 (or retrieve a rev number from such representation)
446
446
447 Note that this is an involution, a function equal to its inverse (i.e.
447 Note that this is an involution, a function equal to its inverse (i.e.
448 which gives the identity when applied to itself).
448 which gives the identity when applied to itself).
449 """
449 """
450 return -(rev + REV_OFFSET)
450 return -(rev + REV_OFFSET)
451
451
452
452
453 def _to_int(hex_digit):
453 def _to_int(hex_digit):
454 """turn an hexadecimal digit into a proper integer"""
454 """turn an hexadecimal digit into a proper integer"""
455 return int(hex_digit, 16)
455 return int(hex_digit, 16)
456
456
457
457
458 class Block(dict):
458 class Block(dict):
459 """represent a block of the Trie
459 """represent a block of the Trie
460
460
461 contains up to 16 entry indexed from 0 to 15"""
461 contains up to 16 entry indexed from 0 to 15"""
462
462
463 def __init__(self):
463 def __init__(self):
464 super(Block, self).__init__()
464 super(Block, self).__init__()
465 # If this block exist on disk, here is its ID
465 # If this block exist on disk, here is its ID
466 self.ondisk_id = None
466 self.ondisk_id = None
467
467
468 def __iter__(self):
468 def __iter__(self):
469 return iter(self.get(i) for i in range(16))
469 return iter(self.get(i) for i in range(16))
470
470
471
471
472 def _build_trie(index):
472 def _build_trie(index):
473 """build a nodemap trie
473 """build a nodemap trie
474
474
475 The nodemap stores revision number for each unique prefix.
475 The nodemap stores revision number for each unique prefix.
476
476
477 Each block is a dictionary with keys in `[0, 15]`. Values are either
477 Each block is a dictionary with keys in `[0, 15]`. Values are either
478 another block or a revision number.
478 another block or a revision number.
479 """
479 """
480 root = Block()
480 root = Block()
481 for rev in range(len(index)):
481 for rev in range(len(index)):
482 current_hex = hex(index[rev][7])
482 current_hex = hex(index[rev][7])
483 _insert_into_block(index, 0, root, rev, current_hex)
483 _insert_into_block(index, 0, root, rev, current_hex)
484 return root
484 return root
485
485
486
486
487 def _update_trie(index, root, last_rev):
487 def _update_trie(index, root, last_rev):
488 """consume"""
488 """consume"""
489 changed = 0
489 changed = 0
490 for rev in range(last_rev + 1, len(index)):
490 for rev in range(last_rev + 1, len(index)):
491 current_hex = hex(index[rev][7])
491 current_hex = hex(index[rev][7])
492 changed += _insert_into_block(index, 0, root, rev, current_hex)
492 changed += _insert_into_block(index, 0, root, rev, current_hex)
493 return changed, root
493 return changed, root
494
494
495
495
496 def _insert_into_block(index, level, block, current_rev, current_hex):
496 def _insert_into_block(index, level, block, current_rev, current_hex):
497 """insert a new revision in a block
497 """insert a new revision in a block
498
498
499 index: the index we are adding revision for
499 index: the index we are adding revision for
500 level: the depth of the current block in the trie
500 level: the depth of the current block in the trie
501 block: the block currently being considered
501 block: the block currently being considered
502 current_rev: the revision number we are adding
502 current_rev: the revision number we are adding
503 current_hex: the hexadecimal representation of the of that revision
503 current_hex: the hexadecimal representation of the of that revision
504 """
504 """
505 changed = 1
505 changed = 1
506 if block.ondisk_id is not None:
506 if block.ondisk_id is not None:
507 block.ondisk_id = None
507 block.ondisk_id = None
508 hex_digit = _to_int(current_hex[level : level + 1])
508 hex_digit = _to_int(current_hex[level : level + 1])
509 entry = block.get(hex_digit)
509 entry = block.get(hex_digit)
510 if entry is None:
510 if entry is None:
511 # no entry, simply store the revision number
511 # no entry, simply store the revision number
512 block[hex_digit] = current_rev
512 block[hex_digit] = current_rev
513 elif isinstance(entry, dict):
513 elif isinstance(entry, dict):
514 # need to recurse to an underlying block
514 # need to recurse to an underlying block
515 changed += _insert_into_block(
515 changed += _insert_into_block(
516 index, level + 1, entry, current_rev, current_hex
516 index, level + 1, entry, current_rev, current_hex
517 )
517 )
518 else:
518 else:
519 # collision with a previously unique prefix, inserting new
519 # collision with a previously unique prefix, inserting new
520 # vertices to fit both entry.
520 # vertices to fit both entry.
521 other_hex = hex(index[entry][7])
521 other_hex = hex(index[entry][7])
522 other_rev = entry
522 other_rev = entry
523 new = Block()
523 new = Block()
524 block[hex_digit] = new
524 block[hex_digit] = new
525 _insert_into_block(index, level + 1, new, other_rev, other_hex)
525 _insert_into_block(index, level + 1, new, other_rev, other_hex)
526 _insert_into_block(index, level + 1, new, current_rev, current_hex)
526 _insert_into_block(index, level + 1, new, current_rev, current_hex)
527 return changed
527 return changed
528
528
529
529
530 def _persist_trie(root, existing_idx=None):
530 def _persist_trie(root, existing_idx=None):
531 """turn a nodemap trie into persistent binary data
531 """turn a nodemap trie into persistent binary data
532
532
533 See `_build_trie` for nodemap trie structure"""
533 See `_build_trie` for nodemap trie structure"""
534 block_map = {}
534 block_map = {}
535 if existing_idx is not None:
535 if existing_idx is not None:
536 base_idx = existing_idx + 1
536 base_idx = existing_idx + 1
537 else:
537 else:
538 base_idx = 0
538 base_idx = 0
539 chunks = []
539 chunks = []
540 for tn in _walk_trie(root):
540 for tn in _walk_trie(root):
541 if tn.ondisk_id is not None:
541 if tn.ondisk_id is not None:
542 block_map[id(tn)] = tn.ondisk_id
542 block_map[id(tn)] = tn.ondisk_id
543 else:
543 else:
544 block_map[id(tn)] = len(chunks) + base_idx
544 block_map[id(tn)] = len(chunks) + base_idx
545 chunks.append(_persist_block(tn, block_map))
545 chunks.append(_persist_block(tn, block_map))
546 return b''.join(chunks)
546 return b''.join(chunks)
547
547
548
548
549 def _walk_trie(block):
549 def _walk_trie(block):
550 """yield all the block in a trie
550 """yield all the block in a trie
551
551
552 Children blocks are always yield before their parent block.
552 Children blocks are always yield before their parent block.
553 """
553 """
554 for (__, item) in sorted(block.items()):
554 for (__, item) in sorted(block.items()):
555 if isinstance(item, dict):
555 if isinstance(item, dict):
556 for sub_block in _walk_trie(item):
556 for sub_block in _walk_trie(item):
557 yield sub_block
557 yield sub_block
558 yield block
558 yield block
559
559
560
560
561 def _persist_block(block_node, block_map):
561 def _persist_block(block_node, block_map):
562 """produce persistent binary data for a single block
562 """produce persistent binary data for a single block
563
563
564 Children block are assumed to be already persisted and present in
564 Children block are assumed to be already persisted and present in
565 block_map.
565 block_map.
566 """
566 """
567 data = tuple(_to_value(v, block_map) for v in block_node)
567 data = tuple(_to_value(v, block_map) for v in block_node)
568 return S_BLOCK.pack(*data)
568 return S_BLOCK.pack(*data)
569
569
570
570
571 def _to_value(item, block_map):
571 def _to_value(item, block_map):
572 """persist any value as an integer"""
572 """persist any value as an integer"""
573 if item is None:
573 if item is None:
574 return NO_ENTRY
574 return NO_ENTRY
575 elif isinstance(item, dict):
575 elif isinstance(item, dict):
576 return block_map[id(item)]
576 return block_map[id(item)]
577 else:
577 else:
578 return _transform_rev(item)
578 return _transform_rev(item)
579
579
580
580
581 def parse_data(data):
581 def parse_data(data):
582 """parse parse nodemap data into a nodemap Trie"""
582 """parse parse nodemap data into a nodemap Trie"""
583 if (len(data) % S_BLOCK.size) != 0:
583 if (len(data) % S_BLOCK.size) != 0:
584 msg = b"nodemap data size is not a multiple of block size (%d): %d"
584 msg = b"nodemap data size is not a multiple of block size (%d): %d"
585 raise error.Abort(msg % (S_BLOCK.size, len(data)))
585 raise error.Abort(msg % (S_BLOCK.size, len(data)))
586 if not data:
586 if not data:
587 return Block(), None
587 return Block(), None
588 block_map = {}
588 block_map = {}
589 new_blocks = []
589 new_blocks = []
590 for i in range(0, len(data), S_BLOCK.size):
590 for i in range(0, len(data), S_BLOCK.size):
591 block = Block()
591 block = Block()
592 block.ondisk_id = len(block_map)
592 block.ondisk_id = len(block_map)
593 block_map[block.ondisk_id] = block
593 block_map[block.ondisk_id] = block
594 block_data = data[i : i + S_BLOCK.size]
594 block_data = data[i : i + S_BLOCK.size]
595 values = S_BLOCK.unpack(block_data)
595 values = S_BLOCK.unpack(block_data)
596 new_blocks.append((block, values))
596 new_blocks.append((block, values))
597 for b, values in new_blocks:
597 for b, values in new_blocks:
598 for idx, v in enumerate(values):
598 for idx, v in enumerate(values):
599 if v == NO_ENTRY:
599 if v == NO_ENTRY:
600 continue
600 continue
601 elif v >= 0:
601 elif v >= 0:
602 b[idx] = block_map[v]
602 b[idx] = block_map[v]
603 else:
603 else:
604 b[idx] = _transform_rev(v)
604 b[idx] = _transform_rev(v)
605 return block, i // S_BLOCK.size
605 return block, i // S_BLOCK.size
606
606
607
607
608 # debug utility
608 # debug utility
609
609
610
610
611 def check_data(ui, index, data):
611 def check_data(ui, index, data):
612 """verify that the provided nodemap data are valid for the given idex"""
612 """verify that the provided nodemap data are valid for the given idex"""
613 ret = 0
613 ret = 0
614 ui.status((b"revision in index: %d\n") % len(index))
614 ui.status((b"revisions in index: %d\n") % len(index))
615 root, __ = parse_data(data)
615 root, __ = parse_data(data)
616 all_revs = set(_all_revisions(root))
616 all_revs = set(_all_revisions(root))
617 ui.status((b"revision in nodemap: %d\n") % len(all_revs))
617 ui.status((b"revisions in nodemap: %d\n") % len(all_revs))
618 for r in range(len(index)):
618 for r in range(len(index)):
619 if r not in all_revs:
619 if r not in all_revs:
620 msg = b" revision missing from nodemap: %d\n" % r
620 msg = b" revision missing from nodemap: %d\n" % r
621 ui.write_err(msg)
621 ui.write_err(msg)
622 ret = 1
622 ret = 1
623 else:
623 else:
624 all_revs.remove(r)
624 all_revs.remove(r)
625 nm_rev = _find_node(root, hex(index[r][7]))
625 nm_rev = _find_node(root, hex(index[r][7]))
626 if nm_rev is None:
626 if nm_rev is None:
627 msg = b" revision node does not match any entries: %d\n" % r
627 msg = b" revision node does not match any entries: %d\n" % r
628 ui.write_err(msg)
628 ui.write_err(msg)
629 ret = 1
629 ret = 1
630 elif nm_rev != r:
630 elif nm_rev != r:
631 msg = (
631 msg = (
632 b" revision node does not match the expected revision: "
632 b" revision node does not match the expected revision: "
633 b"%d != %d\n" % (r, nm_rev)
633 b"%d != %d\n" % (r, nm_rev)
634 )
634 )
635 ui.write_err(msg)
635 ui.write_err(msg)
636 ret = 1
636 ret = 1
637
637
638 if all_revs:
638 if all_revs:
639 for r in sorted(all_revs):
639 for r in sorted(all_revs):
640 msg = b" extra revision in nodemap: %d\n" % r
640 msg = b" extra revisions in nodemap: %d\n" % r
641 ui.write_err(msg)
641 ui.write_err(msg)
642 ret = 1
642 ret = 1
643 return ret
643 return ret
644
644
645
645
646 def _all_revisions(root):
646 def _all_revisions(root):
647 """return all revisions stored in a Trie"""
647 """return all revisions stored in a Trie"""
648 for block in _walk_trie(root):
648 for block in _walk_trie(root):
649 for v in block:
649 for v in block:
650 if v is None or isinstance(v, Block):
650 if v is None or isinstance(v, Block):
651 continue
651 continue
652 yield v
652 yield v
653
653
654
654
655 def _find_node(block, node):
655 def _find_node(block, node):
656 """find the revision associated with a given node"""
656 """find the revision associated with a given node"""
657 entry = block.get(_to_int(node[0:1]))
657 entry = block.get(_to_int(node[0:1]))
658 if isinstance(entry, dict):
658 if isinstance(entry, dict):
659 return _find_node(entry, node[1:])
659 return _find_node(entry, node[1:])
660 return entry
660 return entry
661
661
662
662
663 def get_nodemap_file(revlog):
663 def get_nodemap_file(revlog):
664 if revlog._trypending:
664 if revlog._trypending:
665 pending_path = revlog.radix + b".n.a"
665 pending_path = revlog.radix + b".n.a"
666 if revlog.opener.exists(pending_path):
666 if revlog.opener.exists(pending_path):
667 return pending_path
667 return pending_path
668 return revlog.radix + b".n"
668 return revlog.radix + b".n"
@@ -1,1258 +1,1258 b''
1 ===================================
1 ===================================
2 Test the persistent on-disk nodemap
2 Test the persistent on-disk nodemap
3 ===================================
3 ===================================
4
4
5
5
6 $ cat << EOF >> $HGRCPATH
6 $ cat << EOF >> $HGRCPATH
7 > [format]
7 > [format]
8 > use-share-safe=yes
8 > use-share-safe=yes
9 > [extensions]
9 > [extensions]
10 > share=
10 > share=
11 > EOF
11 > EOF
12
12
13 #if no-rust
13 #if no-rust
14
14
15 $ cat << EOF >> $HGRCPATH
15 $ cat << EOF >> $HGRCPATH
16 > [format]
16 > [format]
17 > use-persistent-nodemap=yes
17 > use-persistent-nodemap=yes
18 > [devel]
18 > [devel]
19 > persistent-nodemap=yes
19 > persistent-nodemap=yes
20 > EOF
20 > EOF
21
21
22 #endif
22 #endif
23
23
24 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
24 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
25 $ cd test-repo
25 $ cd test-repo
26
26
27 Check handling of the default slow-path value
27 Check handling of the default slow-path value
28
28
29 #if no-pure no-rust
29 #if no-pure no-rust
30
30
31 $ hg id
31 $ hg id
32 abort: accessing `persistent-nodemap` repository without associated fast implementation.
32 abort: accessing `persistent-nodemap` repository without associated fast implementation.
33 (check `hg help config.format.use-persistent-nodemap` for details)
33 (check `hg help config.format.use-persistent-nodemap` for details)
34 [255]
34 [255]
35
35
36 Unlock further check (we are here to test the feature)
36 Unlock further check (we are here to test the feature)
37
37
38 $ cat << EOF >> $HGRCPATH
38 $ cat << EOF >> $HGRCPATH
39 > [storage]
39 > [storage]
40 > # to avoid spamming the test
40 > # to avoid spamming the test
41 > revlog.persistent-nodemap.slow-path=allow
41 > revlog.persistent-nodemap.slow-path=allow
42 > EOF
42 > EOF
43
43
44 #endif
44 #endif
45
45
46 #if rust
46 #if rust
47
47
48 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
48 Regression test for a previous bug in Rust/C FFI for the `Revlog_CAPI` capsule:
49 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
49 in places where `mercurial/cext/revlog.c` function signatures use `Py_ssize_t`
50 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
50 (64 bits on Linux x86_64), corresponding declarations in `rust/hg-cpython/src/cindex.rs`
51 incorrectly used `libc::c_int` (32 bits).
51 incorrectly used `libc::c_int` (32 bits).
52 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
52 As a result, -1 passed from Rust for the null revision became 4294967295 in C.
53
53
54 $ hg log -r 00000000
54 $ hg log -r 00000000
55 changeset: -1:000000000000
55 changeset: -1:000000000000
56 tag: tip
56 tag: tip
57 user:
57 user:
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59
59
60
60
61 #endif
61 #endif
62
62
63
63
64 $ hg debugformat
64 $ hg debugformat
65 format-variant repo
65 format-variant repo
66 fncache: yes
66 fncache: yes
67 dirstate-v2: no
67 dirstate-v2: no
68 tracked-hint: no
68 tracked-hint: no
69 dotencode: yes
69 dotencode: yes
70 generaldelta: yes
70 generaldelta: yes
71 share-safe: yes
71 share-safe: yes
72 sparserevlog: yes
72 sparserevlog: yes
73 persistent-nodemap: yes
73 persistent-nodemap: yes
74 copies-sdc: no
74 copies-sdc: no
75 revlog-v2: no
75 revlog-v2: no
76 changelog-v2: no
76 changelog-v2: no
77 plain-cl-delta: yes
77 plain-cl-delta: yes
78 compression: zlib (no-zstd !)
78 compression: zlib (no-zstd !)
79 compression: zstd (zstd !)
79 compression: zstd (zstd !)
80 compression-level: default
80 compression-level: default
81 $ hg debugbuilddag .+5000 --new-file
81 $ hg debugbuilddag .+5000 --new-file
82
82
83 $ hg debugnodemap --metadata
83 $ hg debugnodemap --metadata
84 uid: ???????? (glob)
84 uid: ???????? (glob)
85 tip-rev: 5000
85 tip-rev: 5000
86 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
86 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
87 data-length: 121088
87 data-length: 121088
88 data-unused: 0
88 data-unused: 0
89 data-unused: 0.000%
89 data-unused: 0.000%
90 $ f --size .hg/store/00changelog.n
90 $ f --size .hg/store/00changelog.n
91 .hg/store/00changelog.n: size=62
91 .hg/store/00changelog.n: size=62
92
92
93 Simple lookup works
93 Simple lookup works
94
94
95 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
95 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
96 $ hg log -r "$ANYNODE" --template '{rev}\n'
96 $ hg log -r "$ANYNODE" --template '{rev}\n'
97 5000
97 5000
98
98
99
99
100 #if rust
100 #if rust
101
101
102 $ f --sha256 .hg/store/00changelog-*.nd
102 $ f --sha256 .hg/store/00changelog-*.nd
103 .hg/store/00changelog-????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
103 .hg/store/00changelog-????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
104
104
105 $ f --sha256 .hg/store/00manifest-*.nd
105 $ f --sha256 .hg/store/00manifest-*.nd
106 .hg/store/00manifest-????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
106 .hg/store/00manifest-????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
107 $ hg debugnodemap --dump-new | f --sha256 --size
107 $ hg debugnodemap --dump-new | f --sha256 --size
108 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
108 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
109 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
109 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
110 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
110 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
111 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
111 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
112 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
112 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
113 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
113 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
114 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
114 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
115 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
115 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
116 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
116 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
117 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
117 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
118 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
118 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
119 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
119 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
120 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
120 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
121 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
121 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
122 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
122 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
123 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
123 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
124 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
124 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
125 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
125 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
126 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
126 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
127
127
128
128
129 #else
129 #else
130
130
131 $ f --sha256 .hg/store/00changelog-*.nd
131 $ f --sha256 .hg/store/00changelog-*.nd
132 .hg/store/00changelog-????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
132 .hg/store/00changelog-????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
133 $ hg debugnodemap --dump-new | f --sha256 --size
133 $ hg debugnodemap --dump-new | f --sha256 --size
134 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
134 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
135 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
135 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
136 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
136 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
137 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
137 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
138 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
138 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
139 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
139 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
140 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
140 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
141 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
141 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
142 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
142 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
143 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
143 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
144 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
144 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
145 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
145 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
146 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
146 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
147 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
147 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
148 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
148 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
149 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
149 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
150 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
150 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
151 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
151 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
152 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
152 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
153
153
154 #endif
154 #endif
155
155
156 $ hg debugnodemap --check
156 $ hg debugnodemap --check
157 revision in index: 5001
157 revisions in index: 5001
158 revision in nodemap: 5001
158 revisions in nodemap: 5001
159
159
160 add a new commit
160 add a new commit
161
161
162 $ hg up
162 $ hg up
163 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 $ echo foo > foo
164 $ echo foo > foo
165 $ hg add foo
165 $ hg add foo
166
166
167
167
168 Check slow-path config value handling
168 Check slow-path config value handling
169 -------------------------------------
169 -------------------------------------
170
170
171 #if no-pure no-rust
171 #if no-pure no-rust
172
172
173 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
173 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
174 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
174 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
175 falling back to default value: abort
175 falling back to default value: abort
176 abort: accessing `persistent-nodemap` repository without associated fast implementation.
176 abort: accessing `persistent-nodemap` repository without associated fast implementation.
177 (check `hg help config.format.use-persistent-nodemap` for details)
177 (check `hg help config.format.use-persistent-nodemap` for details)
178 [255]
178 [255]
179
179
180 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
180 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
181 warning: accessing `persistent-nodemap` repository without associated fast implementation.
181 warning: accessing `persistent-nodemap` repository without associated fast implementation.
182 (check `hg help config.format.use-persistent-nodemap` for details)
182 (check `hg help config.format.use-persistent-nodemap` for details)
183 changeset: 5000:6b02b8c7b966
183 changeset: 5000:6b02b8c7b966
184 tag: tip
184 tag: tip
185 user: debugbuilddag
185 user: debugbuilddag
186 date: Thu Jan 01 01:23:20 1970 +0000
186 date: Thu Jan 01 01:23:20 1970 +0000
187 summary: r5000
187 summary: r5000
188
188
189 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
189 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
190 abort: accessing `persistent-nodemap` repository without associated fast implementation.
190 abort: accessing `persistent-nodemap` repository without associated fast implementation.
191 (check `hg help config.format.use-persistent-nodemap` for details)
191 (check `hg help config.format.use-persistent-nodemap` for details)
192 [255]
192 [255]
193
193
194 #else
194 #else
195
195
196 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
196 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
197 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
197 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
198 falling back to default value: abort
198 falling back to default value: abort
199 6b02b8c7b966+ tip
199 6b02b8c7b966+ tip
200
200
201 #endif
201 #endif
202
202
203 $ hg ci -m 'foo'
203 $ hg ci -m 'foo'
204
204
205 #if no-pure no-rust
205 #if no-pure no-rust
206 $ hg debugnodemap --metadata
206 $ hg debugnodemap --metadata
207 uid: ???????? (glob)
207 uid: ???????? (glob)
208 tip-rev: 5001
208 tip-rev: 5001
209 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
209 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
210 data-length: 121088
210 data-length: 121088
211 data-unused: 0
211 data-unused: 0
212 data-unused: 0.000%
212 data-unused: 0.000%
213 #else
213 #else
214 $ hg debugnodemap --metadata
214 $ hg debugnodemap --metadata
215 uid: ???????? (glob)
215 uid: ???????? (glob)
216 tip-rev: 5001
216 tip-rev: 5001
217 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
217 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
218 data-length: 121344
218 data-length: 121344
219 data-unused: 256
219 data-unused: 256
220 data-unused: 0.211%
220 data-unused: 0.211%
221 #endif
221 #endif
222
222
223 $ f --size .hg/store/00changelog.n
223 $ f --size .hg/store/00changelog.n
224 .hg/store/00changelog.n: size=62
224 .hg/store/00changelog.n: size=62
225
225
226 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
226 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
227
227
228 #if pure
228 #if pure
229 $ f --sha256 .hg/store/00changelog-*.nd --size
229 $ f --sha256 .hg/store/00changelog-*.nd --size
230 .hg/store/00changelog-????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
230 .hg/store/00changelog-????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
231 #endif
231 #endif
232
232
233 #if rust
233 #if rust
234 $ f --sha256 .hg/store/00changelog-*.nd --size
234 $ f --sha256 .hg/store/00changelog-*.nd --size
235 .hg/store/00changelog-????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
235 .hg/store/00changelog-????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
236 #endif
236 #endif
237
237
238 #if no-pure no-rust
238 #if no-pure no-rust
239 $ f --sha256 .hg/store/00changelog-*.nd --size
239 $ f --sha256 .hg/store/00changelog-*.nd --size
240 .hg/store/00changelog-????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
240 .hg/store/00changelog-????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
241 #endif
241 #endif
242
242
243 $ hg debugnodemap --check
243 $ hg debugnodemap --check
244 revision in index: 5002
244 revisions in index: 5002
245 revision in nodemap: 5002
245 revisions in nodemap: 5002
246
246
247 Test code path without mmap
247 Test code path without mmap
248 ---------------------------
248 ---------------------------
249
249
250 $ echo bar > bar
250 $ echo bar > bar
251 $ hg add bar
251 $ hg add bar
252 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
252 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
253
253
254 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
254 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
255 revision in index: 5003
255 revisions in index: 5003
256 revision in nodemap: 5003
256 revisions in nodemap: 5003
257 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
257 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
258 revision in index: 5003
258 revisions in index: 5003
259 revision in nodemap: 5003
259 revisions in nodemap: 5003
260
260
261
261
262 #if pure
262 #if pure
263 $ hg debugnodemap --metadata
263 $ hg debugnodemap --metadata
264 uid: ???????? (glob)
264 uid: ???????? (glob)
265 tip-rev: 5002
265 tip-rev: 5002
266 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
266 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
267 data-length: 121600
267 data-length: 121600
268 data-unused: 512
268 data-unused: 512
269 data-unused: 0.421%
269 data-unused: 0.421%
270 $ f --sha256 .hg/store/00changelog-*.nd --size
270 $ f --sha256 .hg/store/00changelog-*.nd --size
271 .hg/store/00changelog-????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
271 .hg/store/00changelog-????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
272 #endif
272 #endif
273 #if rust
273 #if rust
274 $ hg debugnodemap --metadata
274 $ hg debugnodemap --metadata
275 uid: ???????? (glob)
275 uid: ???????? (glob)
276 tip-rev: 5002
276 tip-rev: 5002
277 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
277 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
278 data-length: 121600
278 data-length: 121600
279 data-unused: 512
279 data-unused: 512
280 data-unused: 0.421%
280 data-unused: 0.421%
281 $ f --sha256 .hg/store/00changelog-*.nd --size
281 $ f --sha256 .hg/store/00changelog-*.nd --size
282 .hg/store/00changelog-????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
282 .hg/store/00changelog-????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
283 #endif
283 #endif
284 #if no-pure no-rust
284 #if no-pure no-rust
285 $ hg debugnodemap --metadata
285 $ hg debugnodemap --metadata
286 uid: ???????? (glob)
286 uid: ???????? (glob)
287 tip-rev: 5002
287 tip-rev: 5002
288 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
288 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
289 data-length: 121088
289 data-length: 121088
290 data-unused: 0
290 data-unused: 0
291 data-unused: 0.000%
291 data-unused: 0.000%
292 $ f --sha256 .hg/store/00changelog-*.nd --size
292 $ f --sha256 .hg/store/00changelog-*.nd --size
293 .hg/store/00changelog-????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
293 .hg/store/00changelog-????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
294 #endif
294 #endif
295
295
296 Test force warming the cache
296 Test force warming the cache
297
297
298 $ rm .hg/store/00changelog.n
298 $ rm .hg/store/00changelog.n
299 $ hg debugnodemap --metadata
299 $ hg debugnodemap --metadata
300 $ hg debugupdatecache
300 $ hg debugupdatecache
301 #if pure
301 #if pure
302 $ hg debugnodemap --metadata
302 $ hg debugnodemap --metadata
303 uid: ???????? (glob)
303 uid: ???????? (glob)
304 tip-rev: 5002
304 tip-rev: 5002
305 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
305 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
306 data-length: 121088
306 data-length: 121088
307 data-unused: 0
307 data-unused: 0
308 data-unused: 0.000%
308 data-unused: 0.000%
309 #else
309 #else
310 $ hg debugnodemap --metadata
310 $ hg debugnodemap --metadata
311 uid: ???????? (glob)
311 uid: ???????? (glob)
312 tip-rev: 5002
312 tip-rev: 5002
313 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
313 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
314 data-length: 121088
314 data-length: 121088
315 data-unused: 0
315 data-unused: 0
316 data-unused: 0.000%
316 data-unused: 0.000%
317 #endif
317 #endif
318
318
319 Check out of sync nodemap
319 Check out of sync nodemap
320 =========================
320 =========================
321
321
322 First copy old data on the side.
322 First copy old data on the side.
323
323
324 $ mkdir ../tmp-copies
324 $ mkdir ../tmp-copies
325 $ cp .hg/store/00changelog-????????.nd .hg/store/00changelog.n ../tmp-copies
325 $ cp .hg/store/00changelog-????????.nd .hg/store/00changelog.n ../tmp-copies
326
326
327 Nodemap lagging behind
327 Nodemap lagging behind
328 ----------------------
328 ----------------------
329
329
330 make a new commit
330 make a new commit
331
331
332 $ echo bar2 > bar
332 $ echo bar2 > bar
333 $ hg ci -m 'bar2'
333 $ hg ci -m 'bar2'
334 $ NODE=`hg log -r tip -T '{node}\n'`
334 $ NODE=`hg log -r tip -T '{node}\n'`
335 $ hg log -r "$NODE" -T '{rev}\n'
335 $ hg log -r "$NODE" -T '{rev}\n'
336 5003
336 5003
337
337
338 If the nodemap is lagging behind, it can catch up fine
338 If the nodemap is lagging behind, it can catch up fine
339
339
340 $ hg debugnodemap --metadata
340 $ hg debugnodemap --metadata
341 uid: ???????? (glob)
341 uid: ???????? (glob)
342 tip-rev: 5003
342 tip-rev: 5003
343 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
343 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
344 data-length: 121344 (pure !)
344 data-length: 121344 (pure !)
345 data-length: 121344 (rust !)
345 data-length: 121344 (rust !)
346 data-length: 121152 (no-rust no-pure !)
346 data-length: 121152 (no-rust no-pure !)
347 data-unused: 192 (pure !)
347 data-unused: 192 (pure !)
348 data-unused: 192 (rust !)
348 data-unused: 192 (rust !)
349 data-unused: 0 (no-rust no-pure !)
349 data-unused: 0 (no-rust no-pure !)
350 data-unused: 0.158% (pure !)
350 data-unused: 0.158% (pure !)
351 data-unused: 0.158% (rust !)
351 data-unused: 0.158% (rust !)
352 data-unused: 0.000% (no-rust no-pure !)
352 data-unused: 0.000% (no-rust no-pure !)
353 $ cp -f ../tmp-copies/* .hg/store/
353 $ cp -f ../tmp-copies/* .hg/store/
354 $ hg debugnodemap --metadata
354 $ hg debugnodemap --metadata
355 uid: ???????? (glob)
355 uid: ???????? (glob)
356 tip-rev: 5002
356 tip-rev: 5002
357 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
357 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
358 data-length: 121088
358 data-length: 121088
359 data-unused: 0
359 data-unused: 0
360 data-unused: 0.000%
360 data-unused: 0.000%
361 $ hg log -r "$NODE" -T '{rev}\n'
361 $ hg log -r "$NODE" -T '{rev}\n'
362 5003
362 5003
363
363
364 changelog altered
364 changelog altered
365 -----------------
365 -----------------
366
366
367 If the nodemap is not gated behind a requirements, an unaware client can alter
367 If the nodemap is not gated behind a requirements, an unaware client can alter
368 the repository so the revlog used to generate the nodemap is not longer
368 the repository so the revlog used to generate the nodemap is not longer
369 compatible with the persistent nodemap. We need to detect that.
369 compatible with the persistent nodemap. We need to detect that.
370
370
371 $ hg up "$NODE~5"
371 $ hg up "$NODE~5"
372 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
372 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
373 $ echo bar > babar
373 $ echo bar > babar
374 $ hg add babar
374 $ hg add babar
375 $ hg ci -m 'babar'
375 $ hg ci -m 'babar'
376 created new head
376 created new head
377 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
377 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
378 $ hg log -r "$OTHERNODE" -T '{rev}\n'
378 $ hg log -r "$OTHERNODE" -T '{rev}\n'
379 5004
379 5004
380
380
381 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
381 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
382
382
383 the nodemap should detect the changelog have been tampered with and recover.
383 the nodemap should detect the changelog have been tampered with and recover.
384
384
385 $ hg debugnodemap --metadata
385 $ hg debugnodemap --metadata
386 uid: ???????? (glob)
386 uid: ???????? (glob)
387 tip-rev: 5002
387 tip-rev: 5002
388 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
388 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
389 data-length: 121536 (pure !)
389 data-length: 121536 (pure !)
390 data-length: 121088 (rust !)
390 data-length: 121088 (rust !)
391 data-length: 121088 (no-pure no-rust !)
391 data-length: 121088 (no-pure no-rust !)
392 data-unused: 448 (pure !)
392 data-unused: 448 (pure !)
393 data-unused: 0 (rust !)
393 data-unused: 0 (rust !)
394 data-unused: 0 (no-pure no-rust !)
394 data-unused: 0 (no-pure no-rust !)
395 data-unused: 0.000% (rust !)
395 data-unused: 0.000% (rust !)
396 data-unused: 0.369% (pure !)
396 data-unused: 0.369% (pure !)
397 data-unused: 0.000% (no-pure no-rust !)
397 data-unused: 0.000% (no-pure no-rust !)
398
398
399 $ cp -f ../tmp-copies/* .hg/store/
399 $ cp -f ../tmp-copies/* .hg/store/
400 $ hg debugnodemap --metadata
400 $ hg debugnodemap --metadata
401 uid: ???????? (glob)
401 uid: ???????? (glob)
402 tip-rev: 5002
402 tip-rev: 5002
403 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
403 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
404 data-length: 121088
404 data-length: 121088
405 data-unused: 0
405 data-unused: 0
406 data-unused: 0.000%
406 data-unused: 0.000%
407 $ hg log -r "$OTHERNODE" -T '{rev}\n'
407 $ hg log -r "$OTHERNODE" -T '{rev}\n'
408 5002
408 5002
409
409
410 missing data file
410 missing data file
411 -----------------
411 -----------------
412
412
413 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
413 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
414 > sed 's/uid: //'`
414 > sed 's/uid: //'`
415 $ FILE=.hg/store/00changelog-"${UUID}".nd
415 $ FILE=.hg/store/00changelog-"${UUID}".nd
416 $ mv $FILE ../tmp-data-file
416 $ mv $FILE ../tmp-data-file
417 $ cp .hg/store/00changelog.n ../tmp-docket
417 $ cp .hg/store/00changelog.n ../tmp-docket
418
418
419 mercurial don't crash
419 mercurial don't crash
420
420
421 $ hg log -r .
421 $ hg log -r .
422 changeset: 5002:b355ef8adce0
422 changeset: 5002:b355ef8adce0
423 tag: tip
423 tag: tip
424 parent: 4998:d918ad6d18d3
424 parent: 4998:d918ad6d18d3
425 user: test
425 user: test
426 date: Thu Jan 01 00:00:00 1970 +0000
426 date: Thu Jan 01 00:00:00 1970 +0000
427 summary: babar
427 summary: babar
428
428
429 $ hg debugnodemap --metadata
429 $ hg debugnodemap --metadata
430
430
431 $ hg debugupdatecache
431 $ hg debugupdatecache
432 $ hg debugnodemap --metadata
432 $ hg debugnodemap --metadata
433 uid: * (glob)
433 uid: * (glob)
434 tip-rev: 5002
434 tip-rev: 5002
435 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
435 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
436 data-length: 121088
436 data-length: 121088
437 data-unused: 0
437 data-unused: 0
438 data-unused: 0.000%
438 data-unused: 0.000%
439 $ mv ../tmp-data-file $FILE
439 $ mv ../tmp-data-file $FILE
440 $ mv ../tmp-docket .hg/store/00changelog.n
440 $ mv ../tmp-docket .hg/store/00changelog.n
441
441
442 Check transaction related property
442 Check transaction related property
443 ==================================
443 ==================================
444
444
445 An up to date nodemap should be available to shell hooks,
445 An up to date nodemap should be available to shell hooks,
446
446
447 $ echo dsljfl > a
447 $ echo dsljfl > a
448 $ hg add a
448 $ hg add a
449 $ hg ci -m a
449 $ hg ci -m a
450 $ hg debugnodemap --metadata
450 $ hg debugnodemap --metadata
451 uid: ???????? (glob)
451 uid: ???????? (glob)
452 tip-rev: 5003
452 tip-rev: 5003
453 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
453 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
454 data-length: 121088
454 data-length: 121088
455 data-unused: 0
455 data-unused: 0
456 data-unused: 0.000%
456 data-unused: 0.000%
457 $ echo babar2 > babar
457 $ echo babar2 > babar
458 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
458 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
459 uid: ???????? (glob)
459 uid: ???????? (glob)
460 tip-rev: 5004
460 tip-rev: 5004
461 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
461 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
462 data-length: 121280 (pure !)
462 data-length: 121280 (pure !)
463 data-length: 121280 (rust !)
463 data-length: 121280 (rust !)
464 data-length: 121088 (no-pure no-rust !)
464 data-length: 121088 (no-pure no-rust !)
465 data-unused: 192 (pure !)
465 data-unused: 192 (pure !)
466 data-unused: 192 (rust !)
466 data-unused: 192 (rust !)
467 data-unused: 0 (no-pure no-rust !)
467 data-unused: 0 (no-pure no-rust !)
468 data-unused: 0.158% (pure !)
468 data-unused: 0.158% (pure !)
469 data-unused: 0.158% (rust !)
469 data-unused: 0.158% (rust !)
470 data-unused: 0.000% (no-pure no-rust !)
470 data-unused: 0.000% (no-pure no-rust !)
471 $ hg debugnodemap --metadata
471 $ hg debugnodemap --metadata
472 uid: ???????? (glob)
472 uid: ???????? (glob)
473 tip-rev: 5004
473 tip-rev: 5004
474 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
474 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
475 data-length: 121280 (pure !)
475 data-length: 121280 (pure !)
476 data-length: 121280 (rust !)
476 data-length: 121280 (rust !)
477 data-length: 121088 (no-pure no-rust !)
477 data-length: 121088 (no-pure no-rust !)
478 data-unused: 192 (pure !)
478 data-unused: 192 (pure !)
479 data-unused: 192 (rust !)
479 data-unused: 192 (rust !)
480 data-unused: 0 (no-pure no-rust !)
480 data-unused: 0 (no-pure no-rust !)
481 data-unused: 0.158% (pure !)
481 data-unused: 0.158% (pure !)
482 data-unused: 0.158% (rust !)
482 data-unused: 0.158% (rust !)
483 data-unused: 0.000% (no-pure no-rust !)
483 data-unused: 0.000% (no-pure no-rust !)
484
484
485 Another process does not see the pending nodemap content during run.
485 Another process does not see the pending nodemap content during run.
486
486
487 $ echo qpoasp > a
487 $ echo qpoasp > a
488 $ hg ci -m a2 \
488 $ hg ci -m a2 \
489 > --config "hooks.pretxnclose=sh \"$RUNTESTDIR/testlib/wait-on-file\" 20 sync-repo-read sync-txn-pending" \
489 > --config "hooks.pretxnclose=sh \"$RUNTESTDIR/testlib/wait-on-file\" 20 sync-repo-read sync-txn-pending" \
490 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
490 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
491
491
492 (read the repository while the commit transaction is pending)
492 (read the repository while the commit transaction is pending)
493
493
494 $ sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-pending && \
494 $ sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-pending && \
495 > hg debugnodemap --metadata && \
495 > hg debugnodemap --metadata && \
496 > sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-close sync-repo-read
496 > sh "$RUNTESTDIR/testlib/wait-on-file" 20 sync-txn-close sync-repo-read
497 uid: ???????? (glob)
497 uid: ???????? (glob)
498 tip-rev: 5004
498 tip-rev: 5004
499 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
499 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
500 data-length: 121280 (pure !)
500 data-length: 121280 (pure !)
501 data-length: 121280 (rust !)
501 data-length: 121280 (rust !)
502 data-length: 121088 (no-pure no-rust !)
502 data-length: 121088 (no-pure no-rust !)
503 data-unused: 192 (pure !)
503 data-unused: 192 (pure !)
504 data-unused: 192 (rust !)
504 data-unused: 192 (rust !)
505 data-unused: 0 (no-pure no-rust !)
505 data-unused: 0 (no-pure no-rust !)
506 data-unused: 0.158% (pure !)
506 data-unused: 0.158% (pure !)
507 data-unused: 0.158% (rust !)
507 data-unused: 0.158% (rust !)
508 data-unused: 0.000% (no-pure no-rust !)
508 data-unused: 0.000% (no-pure no-rust !)
509 $ hg debugnodemap --metadata
509 $ hg debugnodemap --metadata
510 uid: ???????? (glob)
510 uid: ???????? (glob)
511 tip-rev: 5005
511 tip-rev: 5005
512 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
512 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
513 data-length: 121536 (pure !)
513 data-length: 121536 (pure !)
514 data-length: 121536 (rust !)
514 data-length: 121536 (rust !)
515 data-length: 121088 (no-pure no-rust !)
515 data-length: 121088 (no-pure no-rust !)
516 data-unused: 448 (pure !)
516 data-unused: 448 (pure !)
517 data-unused: 448 (rust !)
517 data-unused: 448 (rust !)
518 data-unused: 0 (no-pure no-rust !)
518 data-unused: 0 (no-pure no-rust !)
519 data-unused: 0.369% (pure !)
519 data-unused: 0.369% (pure !)
520 data-unused: 0.369% (rust !)
520 data-unused: 0.369% (rust !)
521 data-unused: 0.000% (no-pure no-rust !)
521 data-unused: 0.000% (no-pure no-rust !)
522
522
523 $ cat output.txt
523 $ cat output.txt
524
524
525 Check that a failing transaction will properly revert the data
525 Check that a failing transaction will properly revert the data
526
526
527 $ echo plakfe > a
527 $ echo plakfe > a
528 $ f --size --sha256 .hg/store/00changelog-*.nd
528 $ f --size --sha256 .hg/store/00changelog-*.nd
529 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
529 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
530 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
530 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
531 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
531 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
532 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
532 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
533 transaction abort!
533 transaction abort!
534 rollback completed
534 rollback completed
535 abort: This is a late abort
535 abort: This is a late abort
536 [255]
536 [255]
537 $ hg debugnodemap --metadata
537 $ hg debugnodemap --metadata
538 uid: ???????? (glob)
538 uid: ???????? (glob)
539 tip-rev: 5005
539 tip-rev: 5005
540 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
540 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
541 data-length: 121536 (pure !)
541 data-length: 121536 (pure !)
542 data-length: 121536 (rust !)
542 data-length: 121536 (rust !)
543 data-length: 121088 (no-pure no-rust !)
543 data-length: 121088 (no-pure no-rust !)
544 data-unused: 448 (pure !)
544 data-unused: 448 (pure !)
545 data-unused: 448 (rust !)
545 data-unused: 448 (rust !)
546 data-unused: 0 (no-pure no-rust !)
546 data-unused: 0 (no-pure no-rust !)
547 data-unused: 0.369% (pure !)
547 data-unused: 0.369% (pure !)
548 data-unused: 0.369% (rust !)
548 data-unused: 0.369% (rust !)
549 data-unused: 0.000% (no-pure no-rust !)
549 data-unused: 0.000% (no-pure no-rust !)
550 $ f --size --sha256 .hg/store/00changelog-*.nd
550 $ f --size --sha256 .hg/store/00changelog-*.nd
551 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
551 .hg/store/00changelog-????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
552 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
552 .hg/store/00changelog-????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
553 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
553 .hg/store/00changelog-????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
554
554
555 Check that removing content does not confuse the nodemap
555 Check that removing content does not confuse the nodemap
556 --------------------------------------------------------
556 --------------------------------------------------------
557
557
558 removing data with rollback
558 removing data with rollback
559
559
560 $ echo aso > a
560 $ echo aso > a
561 $ hg ci -m a4
561 $ hg ci -m a4
562 $ hg rollback
562 $ hg rollback
563 repository tip rolled back to revision 5005 (undo commit)
563 repository tip rolled back to revision 5005 (undo commit)
564 working directory now based on revision 5005
564 working directory now based on revision 5005
565 $ hg id -r .
565 $ hg id -r .
566 90d5d3ba2fc4 tip
566 90d5d3ba2fc4 tip
567
567
568 removing data with strip
568 removing data with strip
569
569
570 $ echo aso > a
570 $ echo aso > a
571 $ hg ci -m a4
571 $ hg ci -m a4
572 $ hg --config extensions.strip= strip -r . --no-backup
572 $ hg --config extensions.strip= strip -r . --no-backup
573 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
573 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
574 $ hg id -r . --traceback
574 $ hg id -r . --traceback
575 90d5d3ba2fc4 tip
575 90d5d3ba2fc4 tip
576
576
577 (be a good citizen and regenerate the nodemap)
577 (be a good citizen and regenerate the nodemap)
578 $ hg debugupdatecaches
578 $ hg debugupdatecaches
579 $ hg debugnodemap --metadata
579 $ hg debugnodemap --metadata
580 uid: * (glob)
580 uid: * (glob)
581 tip-rev: 5005
581 tip-rev: 5005
582 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
582 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
583 data-length: 121088
583 data-length: 121088
584 data-unused: 0
584 data-unused: 0
585 data-unused: 0.000%
585 data-unused: 0.000%
586
586
587 Check race condition when multiple process write new data to the repository
587 Check race condition when multiple process write new data to the repository
588 ---------------------------------------------------------------------------
588 ---------------------------------------------------------------------------
589
589
590 In this test, we check that two writers touching the repositories will not
590 In this test, we check that two writers touching the repositories will not
591 overwrite each other data. This test is prompted by the existent of issue6554.
591 overwrite each other data. This test is prompted by the existent of issue6554.
592 Where a writer ended up using and outdated docket to update the repository. See
592 Where a writer ended up using and outdated docket to update the repository. See
593 the dedicated extension for details on the race windows and read/write schedule
593 the dedicated extension for details on the race windows and read/write schedule
594 necessary to end up in this situation: testlib/persistent-nodemap-race-ext.py
594 necessary to end up in this situation: testlib/persistent-nodemap-race-ext.py
595
595
596 The issue was initially observed on a server with a high push trafic, but it
596 The issue was initially observed on a server with a high push trafic, but it
597 can be reproduced using a share and two commiting process which seems simpler.
597 can be reproduced using a share and two commiting process which seems simpler.
598
598
599 The test is Rust only as the other implementation does not use the same
599 The test is Rust only as the other implementation does not use the same
600 read/write patterns.
600 read/write patterns.
601
601
602 $ cd ..
602 $ cd ..
603
603
604 #if rust
604 #if rust
605
605
606 $ cp -R test-repo race-repo
606 $ cp -R test-repo race-repo
607 $ hg share race-repo ./other-wc --config format.use-share-safe=yes
607 $ hg share race-repo ./other-wc --config format.use-share-safe=yes
608 updating working directory
608 updating working directory
609 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
609 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
610 $ hg debugformat -R ./race-repo | egrep 'share-safe|persistent-nodemap'
610 $ hg debugformat -R ./race-repo | egrep 'share-safe|persistent-nodemap'
611 share-safe: yes
611 share-safe: yes
612 persistent-nodemap: yes
612 persistent-nodemap: yes
613 $ hg debugformat -R ./other-wc/ | egrep 'share-safe|persistent-nodemap'
613 $ hg debugformat -R ./other-wc/ | egrep 'share-safe|persistent-nodemap'
614 share-safe: yes
614 share-safe: yes
615 persistent-nodemap: yes
615 persistent-nodemap: yes
616 $ hg -R ./other-wc update 'min(head())'
616 $ hg -R ./other-wc update 'min(head())'
617 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
617 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
618 $ hg -R ./race-repo debugnodemap --metadata
618 $ hg -R ./race-repo debugnodemap --metadata
619 uid: 43c37dde
619 uid: 43c37dde
620 tip-rev: 5005
620 tip-rev: 5005
621 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
621 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
622 data-length: 121088
622 data-length: 121088
623 data-unused: 0
623 data-unused: 0
624 data-unused: 0.000%
624 data-unused: 0.000%
625 $ hg -R ./race-repo log -G -r 'head()'
625 $ hg -R ./race-repo log -G -r 'head()'
626 @ changeset: 5005:90d5d3ba2fc4
626 @ changeset: 5005:90d5d3ba2fc4
627 | tag: tip
627 | tag: tip
628 ~ user: test
628 ~ user: test
629 date: Thu Jan 01 00:00:00 1970 +0000
629 date: Thu Jan 01 00:00:00 1970 +0000
630 summary: a2
630 summary: a2
631
631
632 o changeset: 5001:16395c3cf7e2
632 o changeset: 5001:16395c3cf7e2
633 | user: test
633 | user: test
634 ~ date: Thu Jan 01 00:00:00 1970 +0000
634 ~ date: Thu Jan 01 00:00:00 1970 +0000
635 summary: foo
635 summary: foo
636
636
637 $ hg -R ./other-wc log -G -r 'head()'
637 $ hg -R ./other-wc log -G -r 'head()'
638 o changeset: 5005:90d5d3ba2fc4
638 o changeset: 5005:90d5d3ba2fc4
639 | tag: tip
639 | tag: tip
640 ~ user: test
640 ~ user: test
641 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
642 summary: a2
642 summary: a2
643
643
644 @ changeset: 5001:16395c3cf7e2
644 @ changeset: 5001:16395c3cf7e2
645 | user: test
645 | user: test
646 ~ date: Thu Jan 01 00:00:00 1970 +0000
646 ~ date: Thu Jan 01 00:00:00 1970 +0000
647 summary: foo
647 summary: foo
648
648
649 $ echo left-side-race > race-repo/left-side-race
649 $ echo left-side-race > race-repo/left-side-race
650 $ hg -R ./race-repo/ add race-repo/left-side-race
650 $ hg -R ./race-repo/ add race-repo/left-side-race
651
651
652 $ echo right-side-race > ./other-wc/right-side-race
652 $ echo right-side-race > ./other-wc/right-side-race
653 $ hg -R ./other-wc/ add ./other-wc/right-side-race
653 $ hg -R ./other-wc/ add ./other-wc/right-side-race
654
654
655 $ mkdir sync-files
655 $ mkdir sync-files
656 $ mkdir outputs
656 $ mkdir outputs
657 $ (
657 $ (
658 > hg -R ./race-repo/ commit -m left-side-commit \
658 > hg -R ./race-repo/ commit -m left-side-commit \
659 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
659 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
660 > --config 'devel.nodemap-race.role=left';
660 > --config 'devel.nodemap-race.role=left';
661 > touch sync-files/left-done
661 > touch sync-files/left-done
662 > ) > outputs/left.txt 2>&1 &
662 > ) > outputs/left.txt 2>&1 &
663 $ (
663 $ (
664 > hg -R ./other-wc/ commit -m right-side-commit \
664 > hg -R ./other-wc/ commit -m right-side-commit \
665 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
665 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
666 > --config 'devel.nodemap-race.role=right';
666 > --config 'devel.nodemap-race.role=right';
667 > touch sync-files/right-done
667 > touch sync-files/right-done
668 > ) > outputs/right.txt 2>&1 &
668 > ) > outputs/right.txt 2>&1 &
669 $ (
669 $ (
670 > hg -R ./race-repo/ check-nodemap-race \
670 > hg -R ./race-repo/ check-nodemap-race \
671 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
671 > --config "extensions.race=${RUNTESTDIR}/testlib/persistent-nodemap-race-ext.py" \
672 > --config 'devel.nodemap-race.role=reader';
672 > --config 'devel.nodemap-race.role=reader';
673 > touch sync-files/reader-done
673 > touch sync-files/reader-done
674 > ) > outputs/reader.txt 2>&1 &
674 > ) > outputs/reader.txt 2>&1 &
675 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/left-done
675 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/left-done
676 $ cat outputs/left.txt
676 $ cat outputs/left.txt
677 docket-details:
677 docket-details:
678 uid: 43c37dde
678 uid: 43c37dde
679 actual-tip: 5005
679 actual-tip: 5005
680 tip-rev: 5005
680 tip-rev: 5005
681 data-length: 121088
681 data-length: 121088
682 nodemap-race: left side locked and ready to commit
682 nodemap-race: left side locked and ready to commit
683 docket-details:
683 docket-details:
684 uid: 43c37dde
684 uid: 43c37dde
685 actual-tip: 5005
685 actual-tip: 5005
686 tip-rev: 5005
686 tip-rev: 5005
687 data-length: 121088
687 data-length: 121088
688 finalized changelog write
688 finalized changelog write
689 persisting changelog nodemap
689 persisting changelog nodemap
690 new data start at 121088
690 new data start at 121088
691 persisted changelog nodemap
691 persisted changelog nodemap
692 docket-details:
692 docket-details:
693 uid: 43c37dde
693 uid: 43c37dde
694 actual-tip: 5006
694 actual-tip: 5006
695 tip-rev: 5006
695 tip-rev: 5006
696 data-length: 121280
696 data-length: 121280
697 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/right-done
697 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/right-done
698 $ cat outputs/right.txt
698 $ cat outputs/right.txt
699 nodemap-race: right side start of the locking sequence
699 nodemap-race: right side start of the locking sequence
700 nodemap-race: right side reading changelog
700 nodemap-race: right side reading changelog
701 nodemap-race: right side reading of changelog is done
701 nodemap-race: right side reading of changelog is done
702 docket-details:
702 docket-details:
703 uid: 43c37dde
703 uid: 43c37dde
704 actual-tip: 5006
704 actual-tip: 5006
705 tip-rev: 5005
705 tip-rev: 5005
706 data-length: 121088
706 data-length: 121088
707 nodemap-race: right side ready to wait for the lock
707 nodemap-race: right side ready to wait for the lock
708 nodemap-race: right side locked and ready to commit
708 nodemap-race: right side locked and ready to commit
709 docket-details:
709 docket-details:
710 uid: 43c37dde
710 uid: 43c37dde
711 actual-tip: 5006
711 actual-tip: 5006
712 tip-rev: 5006
712 tip-rev: 5006
713 data-length: 121280
713 data-length: 121280
714 right ready to write, waiting for reader
714 right ready to write, waiting for reader
715 right proceeding with writing its changelog index and nodemap
715 right proceeding with writing its changelog index and nodemap
716 finalized changelog write
716 finalized changelog write
717 persisting changelog nodemap
717 persisting changelog nodemap
718 new data start at 121280
718 new data start at 121280
719 persisted changelog nodemap
719 persisted changelog nodemap
720 docket-details:
720 docket-details:
721 uid: 43c37dde
721 uid: 43c37dde
722 actual-tip: 5007
722 actual-tip: 5007
723 tip-rev: 5007
723 tip-rev: 5007
724 data-length: 121536
724 data-length: 121536
725 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/reader-done
725 $ sh "$RUNTESTDIR"/testlib/wait-on-file 10 sync-files/reader-done
726 $ cat outputs/reader.txt
726 $ cat outputs/reader.txt
727 reader: reading changelog
727 reader: reading changelog
728 reader ready to read the changelog, waiting for right
728 reader ready to read the changelog, waiting for right
729 reader: nodemap docket read
729 reader: nodemap docket read
730 record-data-length: 121280
730 record-data-length: 121280
731 actual-data-length: 121280
731 actual-data-length: 121280
732 file-actual-length: 121536
732 file-actual-length: 121536
733 reader: changelog read
733 reader: changelog read
734 docket-details:
734 docket-details:
735 uid: 43c37dde
735 uid: 43c37dde
736 actual-tip: 5006
736 actual-tip: 5006
737 tip-rev: 5006
737 tip-rev: 5006
738 data-length: 121280
738 data-length: 121280
739 tip-rev: 5006
739 tip-rev: 5006
740 tip-node: 492901161367
740 tip-node: 492901161367
741 node-rev: 5006
741 node-rev: 5006
742
742
743 $ hg -R ./race-repo log -G -r 'head()'
743 $ hg -R ./race-repo log -G -r 'head()'
744 o changeset: 5007:ac4a2abde241
744 o changeset: 5007:ac4a2abde241
745 | tag: tip
745 | tag: tip
746 ~ parent: 5001:16395c3cf7e2
746 ~ parent: 5001:16395c3cf7e2
747 user: test
747 user: test
748 date: Thu Jan 01 00:00:00 1970 +0000
748 date: Thu Jan 01 00:00:00 1970 +0000
749 summary: right-side-commit
749 summary: right-side-commit
750
750
751 @ changeset: 5006:492901161367
751 @ changeset: 5006:492901161367
752 | user: test
752 | user: test
753 ~ date: Thu Jan 01 00:00:00 1970 +0000
753 ~ date: Thu Jan 01 00:00:00 1970 +0000
754 summary: left-side-commit
754 summary: left-side-commit
755
755
756 $ hg -R ./other-wc log -G -r 'head()'
756 $ hg -R ./other-wc log -G -r 'head()'
757 @ changeset: 5007:ac4a2abde241
757 @ changeset: 5007:ac4a2abde241
758 | tag: tip
758 | tag: tip
759 ~ parent: 5001:16395c3cf7e2
759 ~ parent: 5001:16395c3cf7e2
760 user: test
760 user: test
761 date: Thu Jan 01 00:00:00 1970 +0000
761 date: Thu Jan 01 00:00:00 1970 +0000
762 summary: right-side-commit
762 summary: right-side-commit
763
763
764 o changeset: 5006:492901161367
764 o changeset: 5006:492901161367
765 | user: test
765 | user: test
766 ~ date: Thu Jan 01 00:00:00 1970 +0000
766 ~ date: Thu Jan 01 00:00:00 1970 +0000
767 summary: left-side-commit
767 summary: left-side-commit
768
768
769 #endif
769 #endif
770
770
771 Test upgrade / downgrade
771 Test upgrade / downgrade
772 ========================
772 ========================
773
773
774 $ cd ./test-repo/
774 $ cd ./test-repo/
775
775
776 downgrading
776 downgrading
777
777
778 $ cat << EOF >> .hg/hgrc
778 $ cat << EOF >> .hg/hgrc
779 > [format]
779 > [format]
780 > use-persistent-nodemap=no
780 > use-persistent-nodemap=no
781 > EOF
781 > EOF
782 $ hg debugformat -v
782 $ hg debugformat -v
783 format-variant repo config default
783 format-variant repo config default
784 fncache: yes yes yes
784 fncache: yes yes yes
785 dirstate-v2: no no no
785 dirstate-v2: no no no
786 tracked-hint: no no no
786 tracked-hint: no no no
787 dotencode: yes yes yes
787 dotencode: yes yes yes
788 generaldelta: yes yes yes
788 generaldelta: yes yes yes
789 share-safe: yes yes yes
789 share-safe: yes yes yes
790 sparserevlog: yes yes yes
790 sparserevlog: yes yes yes
791 persistent-nodemap: yes no no
791 persistent-nodemap: yes no no
792 copies-sdc: no no no
792 copies-sdc: no no no
793 revlog-v2: no no no
793 revlog-v2: no no no
794 changelog-v2: no no no
794 changelog-v2: no no no
795 plain-cl-delta: yes yes yes
795 plain-cl-delta: yes yes yes
796 compression: zlib zlib zlib (no-zstd !)
796 compression: zlib zlib zlib (no-zstd !)
797 compression: zstd zstd zstd (zstd !)
797 compression: zstd zstd zstd (zstd !)
798 compression-level: default default default
798 compression-level: default default default
799 $ hg debugupgraderepo --run --no-backup --quiet
799 $ hg debugupgraderepo --run --no-backup --quiet
800 upgrade will perform the following actions:
800 upgrade will perform the following actions:
801
801
802 requirements
802 requirements
803 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
803 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
804 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
804 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
805 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
805 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
806 removed: persistent-nodemap
806 removed: persistent-nodemap
807
807
808 processed revlogs:
808 processed revlogs:
809 - all-filelogs
809 - all-filelogs
810 - changelog
810 - changelog
811 - manifest
811 - manifest
812
812
813 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
813 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
814 [1]
814 [1]
815 $ hg debugnodemap --metadata
815 $ hg debugnodemap --metadata
816
816
817
817
818 upgrading
818 upgrading
819
819
820 $ cat << EOF >> .hg/hgrc
820 $ cat << EOF >> .hg/hgrc
821 > [format]
821 > [format]
822 > use-persistent-nodemap=yes
822 > use-persistent-nodemap=yes
823 > EOF
823 > EOF
824 $ hg debugformat -v
824 $ hg debugformat -v
825 format-variant repo config default
825 format-variant repo config default
826 fncache: yes yes yes
826 fncache: yes yes yes
827 dirstate-v2: no no no
827 dirstate-v2: no no no
828 tracked-hint: no no no
828 tracked-hint: no no no
829 dotencode: yes yes yes
829 dotencode: yes yes yes
830 generaldelta: yes yes yes
830 generaldelta: yes yes yes
831 share-safe: yes yes yes
831 share-safe: yes yes yes
832 sparserevlog: yes yes yes
832 sparserevlog: yes yes yes
833 persistent-nodemap: no yes no
833 persistent-nodemap: no yes no
834 copies-sdc: no no no
834 copies-sdc: no no no
835 revlog-v2: no no no
835 revlog-v2: no no no
836 changelog-v2: no no no
836 changelog-v2: no no no
837 plain-cl-delta: yes yes yes
837 plain-cl-delta: yes yes yes
838 compression: zlib zlib zlib (no-zstd !)
838 compression: zlib zlib zlib (no-zstd !)
839 compression: zstd zstd zstd (zstd !)
839 compression: zstd zstd zstd (zstd !)
840 compression-level: default default default
840 compression-level: default default default
841 $ hg debugupgraderepo --run --no-backup --quiet
841 $ hg debugupgraderepo --run --no-backup --quiet
842 upgrade will perform the following actions:
842 upgrade will perform the following actions:
843
843
844 requirements
844 requirements
845 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
845 preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
846 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
846 preserved: dotencode, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
847 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
847 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
848 added: persistent-nodemap
848 added: persistent-nodemap
849
849
850 processed revlogs:
850 processed revlogs:
851 - all-filelogs
851 - all-filelogs
852 - changelog
852 - changelog
853 - manifest
853 - manifest
854
854
855 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
855 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
856 00changelog-*.nd (glob)
856 00changelog-*.nd (glob)
857 00changelog.n
857 00changelog.n
858 00manifest-*.nd (glob)
858 00manifest-*.nd (glob)
859 00manifest.n
859 00manifest.n
860
860
861 $ hg debugnodemap --metadata
861 $ hg debugnodemap --metadata
862 uid: * (glob)
862 uid: * (glob)
863 tip-rev: 5005
863 tip-rev: 5005
864 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
864 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
865 data-length: 121088
865 data-length: 121088
866 data-unused: 0
866 data-unused: 0
867 data-unused: 0.000%
867 data-unused: 0.000%
868
868
869 Running unrelated upgrade
869 Running unrelated upgrade
870
870
871 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
871 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
872 upgrade will perform the following actions:
872 upgrade will perform the following actions:
873
873
874 requirements
874 requirements
875 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
875 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, share-safe, sparserevlog, store (no-zstd no-dirstate-v2 !)
876 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
876 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd no-dirstate-v2 !)
877 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
877 preserved: dotencode, use-dirstate-v2, fncache, generaldelta, persistent-nodemap, revlog-compression-zstd, revlogv1, share-safe, sparserevlog, store (zstd dirstate-v2 !)
878
878
879 optimisations: re-delta-all
879 optimisations: re-delta-all
880
880
881 processed revlogs:
881 processed revlogs:
882 - all-filelogs
882 - all-filelogs
883 - changelog
883 - changelog
884 - manifest
884 - manifest
885
885
886 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
886 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
887 00changelog-*.nd (glob)
887 00changelog-*.nd (glob)
888 00changelog.n
888 00changelog.n
889 00manifest-*.nd (glob)
889 00manifest-*.nd (glob)
890 00manifest.n
890 00manifest.n
891
891
892 $ hg debugnodemap --metadata
892 $ hg debugnodemap --metadata
893 uid: * (glob)
893 uid: * (glob)
894 tip-rev: 5005
894 tip-rev: 5005
895 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
895 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
896 data-length: 121088
896 data-length: 121088
897 data-unused: 0
897 data-unused: 0
898 data-unused: 0.000%
898 data-unused: 0.000%
899
899
900 Persistent nodemap and local/streaming clone
900 Persistent nodemap and local/streaming clone
901 ============================================
901 ============================================
902
902
903 $ cd ..
903 $ cd ..
904
904
905 standard clone
905 standard clone
906 --------------
906 --------------
907
907
908 The persistent nodemap should exist after a streaming clone
908 The persistent nodemap should exist after a streaming clone
909
909
910 $ hg clone --pull --quiet -U test-repo standard-clone
910 $ hg clone --pull --quiet -U test-repo standard-clone
911 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
911 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
912 00changelog-*.nd (glob)
912 00changelog-*.nd (glob)
913 00changelog.n
913 00changelog.n
914 00manifest-*.nd (glob)
914 00manifest-*.nd (glob)
915 00manifest.n
915 00manifest.n
916 $ hg -R standard-clone debugnodemap --metadata
916 $ hg -R standard-clone debugnodemap --metadata
917 uid: * (glob)
917 uid: * (glob)
918 tip-rev: 5005
918 tip-rev: 5005
919 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
919 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
920 data-length: 121088
920 data-length: 121088
921 data-unused: 0
921 data-unused: 0
922 data-unused: 0.000%
922 data-unused: 0.000%
923
923
924
924
925 local clone
925 local clone
926 ------------
926 ------------
927
927
928 The persistent nodemap should exist after a streaming clone
928 The persistent nodemap should exist after a streaming clone
929
929
930 $ hg clone -U test-repo local-clone
930 $ hg clone -U test-repo local-clone
931 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
931 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
932 00changelog-*.nd (glob)
932 00changelog-*.nd (glob)
933 00changelog.n
933 00changelog.n
934 00manifest-*.nd (glob)
934 00manifest-*.nd (glob)
935 00manifest.n
935 00manifest.n
936 $ hg -R local-clone debugnodemap --metadata
936 $ hg -R local-clone debugnodemap --metadata
937 uid: * (glob)
937 uid: * (glob)
938 tip-rev: 5005
938 tip-rev: 5005
939 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
939 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
940 data-length: 121088
940 data-length: 121088
941 data-unused: 0
941 data-unused: 0
942 data-unused: 0.000%
942 data-unused: 0.000%
943
943
944 Test various corruption case
944 Test various corruption case
945 ============================
945 ============================
946
946
947 Missing datafile
947 Missing datafile
948 ----------------
948 ----------------
949
949
950 Test behavior with a missing datafile
950 Test behavior with a missing datafile
951
951
952 $ hg clone --quiet --pull test-repo corruption-test-repo
952 $ hg clone --quiet --pull test-repo corruption-test-repo
953 $ ls -1 corruption-test-repo/.hg/store/00changelog*
953 $ ls -1 corruption-test-repo/.hg/store/00changelog*
954 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
954 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
955 corruption-test-repo/.hg/store/00changelog.d
955 corruption-test-repo/.hg/store/00changelog.d
956 corruption-test-repo/.hg/store/00changelog.i
956 corruption-test-repo/.hg/store/00changelog.i
957 corruption-test-repo/.hg/store/00changelog.n
957 corruption-test-repo/.hg/store/00changelog.n
958 $ rm corruption-test-repo/.hg/store/00changelog*.nd
958 $ rm corruption-test-repo/.hg/store/00changelog*.nd
959 $ hg log -R corruption-test-repo -r .
959 $ hg log -R corruption-test-repo -r .
960 changeset: 5005:90d5d3ba2fc4
960 changeset: 5005:90d5d3ba2fc4
961 tag: tip
961 tag: tip
962 user: test
962 user: test
963 date: Thu Jan 01 00:00:00 1970 +0000
963 date: Thu Jan 01 00:00:00 1970 +0000
964 summary: a2
964 summary: a2
965
965
966 $ ls -1 corruption-test-repo/.hg/store/00changelog*
966 $ ls -1 corruption-test-repo/.hg/store/00changelog*
967 corruption-test-repo/.hg/store/00changelog.d
967 corruption-test-repo/.hg/store/00changelog.d
968 corruption-test-repo/.hg/store/00changelog.i
968 corruption-test-repo/.hg/store/00changelog.i
969 corruption-test-repo/.hg/store/00changelog.n
969 corruption-test-repo/.hg/store/00changelog.n
970
970
971 Truncated data file
971 Truncated data file
972 -------------------
972 -------------------
973
973
974 Test behavior with a too short datafile
974 Test behavior with a too short datafile
975
975
976 rebuild the missing data
976 rebuild the missing data
977 $ hg -R corruption-test-repo debugupdatecache
977 $ hg -R corruption-test-repo debugupdatecache
978 $ ls -1 corruption-test-repo/.hg/store/00changelog*
978 $ ls -1 corruption-test-repo/.hg/store/00changelog*
979 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
979 corruption-test-repo/.hg/store/00changelog-*.nd (glob)
980 corruption-test-repo/.hg/store/00changelog.d
980 corruption-test-repo/.hg/store/00changelog.d
981 corruption-test-repo/.hg/store/00changelog.i
981 corruption-test-repo/.hg/store/00changelog.i
982 corruption-test-repo/.hg/store/00changelog.n
982 corruption-test-repo/.hg/store/00changelog.n
983
983
984 truncate the file
984 truncate the file
985
985
986 $ datafilepath=`ls corruption-test-repo/.hg/store/00changelog*.nd`
986 $ datafilepath=`ls corruption-test-repo/.hg/store/00changelog*.nd`
987 $ f -s $datafilepath
987 $ f -s $datafilepath
988 corruption-test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
988 corruption-test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
989 $ dd if=$datafilepath bs=1000 count=10 of=$datafilepath-tmp
989 $ dd if=$datafilepath bs=1000 count=10 of=$datafilepath-tmp
990 10+0 records in
990 10+0 records in
991 10+0 records out
991 10+0 records out
992 * bytes * (glob)
992 * bytes * (glob)
993 $ mv $datafilepath-tmp $datafilepath
993 $ mv $datafilepath-tmp $datafilepath
994 $ f -s $datafilepath
994 $ f -s $datafilepath
995 corruption-test-repo/.hg/store/00changelog-*.nd: size=10000 (glob)
995 corruption-test-repo/.hg/store/00changelog-*.nd: size=10000 (glob)
996
996
997 Check that Mercurial reaction to this event
997 Check that Mercurial reaction to this event
998
998
999 $ hg -R corruption-test-repo log -r . --traceback
999 $ hg -R corruption-test-repo log -r . --traceback
1000 changeset: 5005:90d5d3ba2fc4
1000 changeset: 5005:90d5d3ba2fc4
1001 tag: tip
1001 tag: tip
1002 user: test
1002 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1003 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: a2
1004 summary: a2
1005
1005
1006
1006
1007
1007
1008 stream clone
1008 stream clone
1009 ============
1009 ============
1010
1010
1011 The persistent nodemap should exist after a streaming clone
1011 The persistent nodemap should exist after a streaming clone
1012
1012
1013 Simple case
1013 Simple case
1014 -----------
1014 -----------
1015
1015
1016 No race condition
1016 No race condition
1017
1017
1018 $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
1018 $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
1019 adding [s] 00manifest.n (62 bytes)
1019 adding [s] 00manifest.n (62 bytes)
1020 adding [s] 00manifest-*.nd (118 KB) (glob)
1020 adding [s] 00manifest-*.nd (118 KB) (glob)
1021 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1021 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1022 adding [s] 00manifest.d (452 KB) (no-zstd !)
1022 adding [s] 00manifest.d (452 KB) (no-zstd !)
1023 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1023 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1024 adding [s] 00manifest.i (313 KB)
1024 adding [s] 00manifest.i (313 KB)
1025 adding [s] 00changelog.n (62 bytes)
1025 adding [s] 00changelog.n (62 bytes)
1026 adding [s] 00changelog-*.nd (118 KB) (glob)
1026 adding [s] 00changelog-*.nd (118 KB) (glob)
1027 adding [s] 00changelog.d (360 KB) (no-zstd !)
1027 adding [s] 00changelog.d (360 KB) (no-zstd !)
1028 adding [s] 00changelog.d (368 KB) (zstd !)
1028 adding [s] 00changelog.d (368 KB) (zstd !)
1029 adding [s] 00changelog.i (313 KB)
1029 adding [s] 00changelog.i (313 KB)
1030 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
1030 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
1031 00changelog-*.nd (glob)
1031 00changelog-*.nd (glob)
1032 00changelog.n
1032 00changelog.n
1033 00manifest-*.nd (glob)
1033 00manifest-*.nd (glob)
1034 00manifest.n
1034 00manifest.n
1035 $ hg -R stream-clone debugnodemap --metadata
1035 $ hg -R stream-clone debugnodemap --metadata
1036 uid: * (glob)
1036 uid: * (glob)
1037 tip-rev: 5005
1037 tip-rev: 5005
1038 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1038 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1039 data-length: 121088
1039 data-length: 121088
1040 data-unused: 0
1040 data-unused: 0
1041 data-unused: 0.000%
1041 data-unused: 0.000%
1042
1042
1043 new data appened
1043 new data appened
1044 -----------------
1044 -----------------
1045
1045
1046 Other commit happening on the server during the stream clone
1046 Other commit happening on the server during the stream clone
1047
1047
1048 setup the step-by-step stream cloning
1048 setup the step-by-step stream cloning
1049
1049
1050 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
1050 $ HG_TEST_STREAM_WALKED_FILE_1="$TESTTMP/sync_file_walked_1"
1051 $ export HG_TEST_STREAM_WALKED_FILE_1
1051 $ export HG_TEST_STREAM_WALKED_FILE_1
1052 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
1052 $ HG_TEST_STREAM_WALKED_FILE_2="$TESTTMP/sync_file_walked_2"
1053 $ export HG_TEST_STREAM_WALKED_FILE_2
1053 $ export HG_TEST_STREAM_WALKED_FILE_2
1054 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
1054 $ HG_TEST_STREAM_WALKED_FILE_3="$TESTTMP/sync_file_walked_3"
1055 $ export HG_TEST_STREAM_WALKED_FILE_3
1055 $ export HG_TEST_STREAM_WALKED_FILE_3
1056 $ cat << EOF >> test-repo/.hg/hgrc
1056 $ cat << EOF >> test-repo/.hg/hgrc
1057 > [extensions]
1057 > [extensions]
1058 > steps=$RUNTESTDIR/testlib/ext-stream-clone-steps.py
1058 > steps=$RUNTESTDIR/testlib/ext-stream-clone-steps.py
1059 > EOF
1059 > EOF
1060
1060
1061 Check and record file state beforehand
1061 Check and record file state beforehand
1062
1062
1063 $ f --size test-repo/.hg/store/00changelog*
1063 $ f --size test-repo/.hg/store/00changelog*
1064 test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
1064 test-repo/.hg/store/00changelog-*.nd: size=121088 (glob)
1065 test-repo/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1065 test-repo/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1066 test-repo/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1066 test-repo/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1067 test-repo/.hg/store/00changelog.d: size=368890 (no-zstd !)
1067 test-repo/.hg/store/00changelog.d: size=368890 (no-zstd !)
1068 test-repo/.hg/store/00changelog.i: size=320384
1068 test-repo/.hg/store/00changelog.i: size=320384
1069 test-repo/.hg/store/00changelog.n: size=62
1069 test-repo/.hg/store/00changelog.n: size=62
1070 $ hg -R test-repo debugnodemap --metadata | tee server-metadata.txt
1070 $ hg -R test-repo debugnodemap --metadata | tee server-metadata.txt
1071 uid: * (glob)
1071 uid: * (glob)
1072 tip-rev: 5005
1072 tip-rev: 5005
1073 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1073 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1074 data-length: 121088
1074 data-length: 121088
1075 data-unused: 0
1075 data-unused: 0
1076 data-unused: 0.000%
1076 data-unused: 0.000%
1077
1077
1078 Prepare a commit
1078 Prepare a commit
1079
1079
1080 $ echo foo >> test-repo/foo
1080 $ echo foo >> test-repo/foo
1081 $ hg -R test-repo/ add test-repo/foo
1081 $ hg -R test-repo/ add test-repo/foo
1082
1082
1083 Do a mix of clone and commit at the same time so that the file listed on disk differ at actual transfer time.
1083 Do a mix of clone and commit at the same time so that the file listed on disk differ at actual transfer time.
1084
1084
1085 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | egrep '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1085 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-1 --debug 2>> clone-output | egrep '00(changelog|manifest)' >> clone-output; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1086 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1086 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1087 $ hg -R test-repo/ commit -m foo
1087 $ hg -R test-repo/ commit -m foo
1088 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1088 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1089 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1089 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1090 $ cat clone-output
1090 $ cat clone-output
1091 adding [s] 00manifest.n (62 bytes)
1091 adding [s] 00manifest.n (62 bytes)
1092 adding [s] 00manifest-*.nd (118 KB) (glob)
1092 adding [s] 00manifest-*.nd (118 KB) (glob)
1093 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1093 adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
1094 adding [s] 00manifest.d (452 KB) (no-zstd !)
1094 adding [s] 00manifest.d (452 KB) (no-zstd !)
1095 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1095 adding [s] 00manifest.d (492 KB) (zstd bigendian !)
1096 adding [s] 00manifest.i (313 KB)
1096 adding [s] 00manifest.i (313 KB)
1097 adding [s] 00changelog.n (62 bytes)
1097 adding [s] 00changelog.n (62 bytes)
1098 adding [s] 00changelog-*.nd (118 KB) (glob)
1098 adding [s] 00changelog-*.nd (118 KB) (glob)
1099 adding [s] 00changelog.d (368 KB) (zstd !)
1099 adding [s] 00changelog.d (368 KB) (zstd !)
1100 adding [s] 00changelog.d (360 KB) (no-zstd !)
1100 adding [s] 00changelog.d (360 KB) (no-zstd !)
1101 adding [s] 00changelog.i (313 KB)
1101 adding [s] 00changelog.i (313 KB)
1102
1102
1103 Check the result state
1103 Check the result state
1104
1104
1105 $ f --size stream-clone-race-1/.hg/store/00changelog*
1105 $ f --size stream-clone-race-1/.hg/store/00changelog*
1106 stream-clone-race-1/.hg/store/00changelog-*.nd: size=121088 (glob)
1106 stream-clone-race-1/.hg/store/00changelog-*.nd: size=121088 (glob)
1107 stream-clone-race-1/.hg/store/00changelog.d: size=368890 (no-zstd !)
1107 stream-clone-race-1/.hg/store/00changelog.d: size=368890 (no-zstd !)
1108 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1108 stream-clone-race-1/.hg/store/00changelog.d: size=376891 (zstd no-bigendian !)
1109 stream-clone-race-1/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1109 stream-clone-race-1/.hg/store/00changelog.d: size=376889 (zstd bigendian !)
1110 stream-clone-race-1/.hg/store/00changelog.i: size=320384
1110 stream-clone-race-1/.hg/store/00changelog.i: size=320384
1111 stream-clone-race-1/.hg/store/00changelog.n: size=62
1111 stream-clone-race-1/.hg/store/00changelog.n: size=62
1112
1112
1113 $ hg -R stream-clone-race-1 debugnodemap --metadata | tee client-metadata.txt
1113 $ hg -R stream-clone-race-1 debugnodemap --metadata | tee client-metadata.txt
1114 uid: * (glob)
1114 uid: * (glob)
1115 tip-rev: 5005
1115 tip-rev: 5005
1116 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1116 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1117 data-length: 121088
1117 data-length: 121088
1118 data-unused: 0
1118 data-unused: 0
1119 data-unused: 0.000%
1119 data-unused: 0.000%
1120
1120
1121 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1121 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1122 (ie: the following diff should be empty)
1122 (ie: the following diff should be empty)
1123
1123
1124 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1124 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1125
1125
1126 #if no-rust no-pure
1126 #if no-rust no-pure
1127 $ diff -u server-metadata.txt client-metadata.txt
1127 $ diff -u server-metadata.txt client-metadata.txt
1128 --- server-metadata.txt * (glob)
1128 --- server-metadata.txt * (glob)
1129 +++ client-metadata.txt * (glob)
1129 +++ client-metadata.txt * (glob)
1130 @@ -1,4 +1,4 @@
1130 @@ -1,4 +1,4 @@
1131 -uid: * (glob)
1131 -uid: * (glob)
1132 +uid: * (glob)
1132 +uid: * (glob)
1133 tip-rev: 5005
1133 tip-rev: 5005
1134 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1134 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
1135 data-length: 121088
1135 data-length: 121088
1136 [1]
1136 [1]
1137 #else
1137 #else
1138 $ diff -u server-metadata.txt client-metadata.txt
1138 $ diff -u server-metadata.txt client-metadata.txt
1139 #endif
1139 #endif
1140
1140
1141
1141
1142 Clean up after the test.
1142 Clean up after the test.
1143
1143
1144 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_1"
1144 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_1"
1145 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_2"
1145 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_2"
1146 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_3"
1146 $ rm -f "$HG_TEST_STREAM_WALKED_FILE_3"
1147
1147
1148 full regeneration
1148 full regeneration
1149 -----------------
1149 -----------------
1150
1150
1151 A full nodemap is generated
1151 A full nodemap is generated
1152
1152
1153 (ideally this test would append enough data to make sure the nodemap data file
1153 (ideally this test would append enough data to make sure the nodemap data file
1154 get changed, however to make thing simpler we will force the regeneration for
1154 get changed, however to make thing simpler we will force the regeneration for
1155 this test.
1155 this test.
1156
1156
1157 Check the initial state
1157 Check the initial state
1158
1158
1159 $ f --size test-repo/.hg/store/00changelog*
1159 $ f --size test-repo/.hg/store/00changelog*
1160 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1160 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1161 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1161 test-repo/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1162 test-repo/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1162 test-repo/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1163 test-repo/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1163 test-repo/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1164 test-repo/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1164 test-repo/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1165 test-repo/.hg/store/00changelog.d: size=368949 (no-zstd !)
1165 test-repo/.hg/store/00changelog.d: size=368949 (no-zstd !)
1166 test-repo/.hg/store/00changelog.i: size=320448
1166 test-repo/.hg/store/00changelog.i: size=320448
1167 test-repo/.hg/store/00changelog.n: size=62
1167 test-repo/.hg/store/00changelog.n: size=62
1168 $ hg -R test-repo debugnodemap --metadata | tee server-metadata-2.txt
1168 $ hg -R test-repo debugnodemap --metadata | tee server-metadata-2.txt
1169 uid: * (glob)
1169 uid: * (glob)
1170 tip-rev: 5006
1170 tip-rev: 5006
1171 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1171 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1172 data-length: 121344 (rust !)
1172 data-length: 121344 (rust !)
1173 data-length: 121344 (pure !)
1173 data-length: 121344 (pure !)
1174 data-length: 121152 (no-rust no-pure !)
1174 data-length: 121152 (no-rust no-pure !)
1175 data-unused: 192 (rust !)
1175 data-unused: 192 (rust !)
1176 data-unused: 192 (pure !)
1176 data-unused: 192 (pure !)
1177 data-unused: 0 (no-rust no-pure !)
1177 data-unused: 0 (no-rust no-pure !)
1178 data-unused: 0.158% (rust !)
1178 data-unused: 0.158% (rust !)
1179 data-unused: 0.158% (pure !)
1179 data-unused: 0.158% (pure !)
1180 data-unused: 0.000% (no-rust no-pure !)
1180 data-unused: 0.000% (no-rust no-pure !)
1181
1181
1182 Performe the mix of clone and full refresh of the nodemap, so that the files
1182 Performe the mix of clone and full refresh of the nodemap, so that the files
1183 (and filenames) are different between listing time and actual transfer time.
1183 (and filenames) are different between listing time and actual transfer time.
1184
1184
1185 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-2 --debug 2>> clone-output-2 | egrep '00(changelog|manifest)' >> clone-output-2; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1185 $ (hg clone -U --stream ssh://user@dummy/test-repo stream-clone-race-2 --debug 2>> clone-output-2 | egrep '00(changelog|manifest)' >> clone-output-2; touch $HG_TEST_STREAM_WALKED_FILE_3) &
1186 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1186 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_1
1187 $ rm test-repo/.hg/store/00changelog.n
1187 $ rm test-repo/.hg/store/00changelog.n
1188 $ rm test-repo/.hg/store/00changelog-*.nd
1188 $ rm test-repo/.hg/store/00changelog-*.nd
1189 $ hg -R test-repo/ debugupdatecache
1189 $ hg -R test-repo/ debugupdatecache
1190 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1190 $ touch $HG_TEST_STREAM_WALKED_FILE_2
1191 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1191 $ $RUNTESTDIR/testlib/wait-on-file 10 $HG_TEST_STREAM_WALKED_FILE_3
1192
1192
1193 (note: the stream clone code wronly pick the `undo.` files)
1193 (note: the stream clone code wronly pick the `undo.` files)
1194
1194
1195 $ cat clone-output-2
1195 $ cat clone-output-2
1196 adding [s] 00manifest.n (62 bytes)
1196 adding [s] 00manifest.n (62 bytes)
1197 adding [s] 00manifest-*.nd (118 KB) (glob)
1197 adding [s] 00manifest-*.nd (118 KB) (glob)
1198 adding [s] 00manifest.d (492 KB) (zstd !)
1198 adding [s] 00manifest.d (492 KB) (zstd !)
1199 adding [s] 00manifest.d (452 KB) (no-zstd !)
1199 adding [s] 00manifest.d (452 KB) (no-zstd !)
1200 adding [s] 00manifest.i (313 KB)
1200 adding [s] 00manifest.i (313 KB)
1201 adding [s] 00changelog.n (62 bytes)
1201 adding [s] 00changelog.n (62 bytes)
1202 adding [s] 00changelog-*.nd (118 KB) (glob)
1202 adding [s] 00changelog-*.nd (118 KB) (glob)
1203 adding [s] 00changelog.d (360 KB) (no-zstd !)
1203 adding [s] 00changelog.d (360 KB) (no-zstd !)
1204 adding [s] 00changelog.d (368 KB) (zstd !)
1204 adding [s] 00changelog.d (368 KB) (zstd !)
1205 adding [s] 00changelog.i (313 KB)
1205 adding [s] 00changelog.i (313 KB)
1206
1206
1207 Check the result.
1207 Check the result.
1208
1208
1209 $ f --size stream-clone-race-2/.hg/store/00changelog*
1209 $ f --size stream-clone-race-2/.hg/store/00changelog*
1210 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1210 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (rust !)
1211 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1211 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121344 (glob) (pure !)
1212 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1212 stream-clone-race-2/.hg/store/00changelog-*.nd: size=121152 (glob) (no-rust no-pure !)
1213 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1213 stream-clone-race-2/.hg/store/00changelog.d: size=376950 (zstd no-bigendian !)
1214 stream-clone-race-2/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1214 stream-clone-race-2/.hg/store/00changelog.d: size=376948 (zstd bigendian !)
1215 stream-clone-race-2/.hg/store/00changelog.d: size=368949 (no-zstd !)
1215 stream-clone-race-2/.hg/store/00changelog.d: size=368949 (no-zstd !)
1216 stream-clone-race-2/.hg/store/00changelog.i: size=320448
1216 stream-clone-race-2/.hg/store/00changelog.i: size=320448
1217 stream-clone-race-2/.hg/store/00changelog.n: size=62
1217 stream-clone-race-2/.hg/store/00changelog.n: size=62
1218
1218
1219 $ hg -R stream-clone-race-2 debugnodemap --metadata | tee client-metadata-2.txt
1219 $ hg -R stream-clone-race-2 debugnodemap --metadata | tee client-metadata-2.txt
1220 uid: * (glob)
1220 uid: * (glob)
1221 tip-rev: 5006
1221 tip-rev: 5006
1222 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1222 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1223 data-length: 121344 (rust !)
1223 data-length: 121344 (rust !)
1224 data-unused: 192 (rust !)
1224 data-unused: 192 (rust !)
1225 data-unused: 0.158% (rust !)
1225 data-unused: 0.158% (rust !)
1226 data-length: 121152 (no-rust no-pure !)
1226 data-length: 121152 (no-rust no-pure !)
1227 data-unused: 0 (no-rust no-pure !)
1227 data-unused: 0 (no-rust no-pure !)
1228 data-unused: 0.000% (no-rust no-pure !)
1228 data-unused: 0.000% (no-rust no-pure !)
1229 data-length: 121344 (pure !)
1229 data-length: 121344 (pure !)
1230 data-unused: 192 (pure !)
1230 data-unused: 192 (pure !)
1231 data-unused: 0.158% (pure !)
1231 data-unused: 0.158% (pure !)
1232
1232
1233 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1233 We get a usable nodemap, so no rewrite would be needed and the metadata should be identical
1234 (ie: the following diff should be empty)
1234 (ie: the following diff should be empty)
1235
1235
1236 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1236 This isn't the case for the `no-rust` `no-pure` implementation as it use a very minimal nodemap implementation that unconditionnaly rewrite the nodemap "all the time".
1237
1237
1238 #if no-rust no-pure
1238 #if no-rust no-pure
1239 $ diff -u server-metadata-2.txt client-metadata-2.txt
1239 $ diff -u server-metadata-2.txt client-metadata-2.txt
1240 --- server-metadata-2.txt * (glob)
1240 --- server-metadata-2.txt * (glob)
1241 +++ client-metadata-2.txt * (glob)
1241 +++ client-metadata-2.txt * (glob)
1242 @@ -1,4 +1,4 @@
1242 @@ -1,4 +1,4 @@
1243 -uid: * (glob)
1243 -uid: * (glob)
1244 +uid: * (glob)
1244 +uid: * (glob)
1245 tip-rev: 5006
1245 tip-rev: 5006
1246 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1246 tip-node: ed2ec1eef9aa2a0ec5057c51483bc148d03e810b
1247 data-length: 121152
1247 data-length: 121152
1248 [1]
1248 [1]
1249 #else
1249 #else
1250 $ diff -u server-metadata-2.txt client-metadata-2.txt
1250 $ diff -u server-metadata-2.txt client-metadata-2.txt
1251 #endif
1251 #endif
1252
1252
1253 Clean up after the test
1253 Clean up after the test
1254
1254
1255 $ rm -f $HG_TEST_STREAM_WALKED_FILE_1
1255 $ rm -f $HG_TEST_STREAM_WALKED_FILE_1
1256 $ rm -f $HG_TEST_STREAM_WALKED_FILE_2
1256 $ rm -f $HG_TEST_STREAM_WALKED_FILE_2
1257 $ rm -f $HG_TEST_STREAM_WALKED_FILE_3
1257 $ rm -f $HG_TEST_STREAM_WALKED_FILE_3
1258
1258
General Comments 0
You need to be logged in to leave comments. Login now