##// END OF EJS Templates
nodemap: automatically "vacuum" the persistent nodemap when too sparse...
marmoute -
r45126:c70bcaf7 default
parent child Browse files
Show More
@@ -1,1580 +1,1579
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18
18
19 def loadconfigtable(ui, extname, configtable):
19 def loadconfigtable(ui, extname, configtable):
20 """update config item known to the ui with the extension ones"""
20 """update config item known to the ui with the extension ones"""
21 for section, items in sorted(configtable.items()):
21 for section, items in sorted(configtable.items()):
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
23 knownkeys = set(knownitems)
23 knownkeys = set(knownitems)
24 newkeys = set(items)
24 newkeys = set(items)
25 for key in sorted(knownkeys & newkeys):
25 for key in sorted(knownkeys & newkeys):
26 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg = b"extension '%s' overwrite config item '%s.%s'"
27 msg %= (extname, section, key)
27 msg %= (extname, section, key)
28 ui.develwarn(msg, config=b'warn-config')
28 ui.develwarn(msg, config=b'warn-config')
29
29
30 knownitems.update(items)
30 knownitems.update(items)
31
31
32
32
33 class configitem(object):
33 class configitem(object):
34 """represent a known config item
34 """represent a known config item
35
35
36 :section: the official config section where to find this item,
36 :section: the official config section where to find this item,
37 :name: the official name within the section,
37 :name: the official name within the section,
38 :default: default value for this item,
38 :default: default value for this item,
39 :alias: optional list of tuples as alternatives,
39 :alias: optional list of tuples as alternatives,
40 :generic: this is a generic definition, match name using regular expression.
40 :generic: this is a generic definition, match name using regular expression.
41 """
41 """
42
42
43 def __init__(
43 def __init__(
44 self,
44 self,
45 section,
45 section,
46 name,
46 name,
47 default=None,
47 default=None,
48 alias=(),
48 alias=(),
49 generic=False,
49 generic=False,
50 priority=0,
50 priority=0,
51 experimental=False,
51 experimental=False,
52 ):
52 ):
53 self.section = section
53 self.section = section
54 self.name = name
54 self.name = name
55 self.default = default
55 self.default = default
56 self.alias = list(alias)
56 self.alias = list(alias)
57 self.generic = generic
57 self.generic = generic
58 self.priority = priority
58 self.priority = priority
59 self.experimental = experimental
59 self.experimental = experimental
60 self._re = None
60 self._re = None
61 if generic:
61 if generic:
62 self._re = re.compile(self.name)
62 self._re = re.compile(self.name)
63
63
64
64
65 class itemregister(dict):
65 class itemregister(dict):
66 """A specialized dictionary that can handle wild-card selection"""
66 """A specialized dictionary that can handle wild-card selection"""
67
67
68 def __init__(self):
68 def __init__(self):
69 super(itemregister, self).__init__()
69 super(itemregister, self).__init__()
70 self._generics = set()
70 self._generics = set()
71
71
72 def update(self, other):
72 def update(self, other):
73 super(itemregister, self).update(other)
73 super(itemregister, self).update(other)
74 self._generics.update(other._generics)
74 self._generics.update(other._generics)
75
75
76 def __setitem__(self, key, item):
76 def __setitem__(self, key, item):
77 super(itemregister, self).__setitem__(key, item)
77 super(itemregister, self).__setitem__(key, item)
78 if item.generic:
78 if item.generic:
79 self._generics.add(item)
79 self._generics.add(item)
80
80
81 def get(self, key):
81 def get(self, key):
82 baseitem = super(itemregister, self).get(key)
82 baseitem = super(itemregister, self).get(key)
83 if baseitem is not None and not baseitem.generic:
83 if baseitem is not None and not baseitem.generic:
84 return baseitem
84 return baseitem
85
85
86 # search for a matching generic item
86 # search for a matching generic item
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
88 for item in generics:
88 for item in generics:
89 # we use 'match' instead of 'search' to make the matching simpler
89 # we use 'match' instead of 'search' to make the matching simpler
90 # for people unfamiliar with regular expression. Having the match
90 # for people unfamiliar with regular expression. Having the match
91 # rooted to the start of the string will produce less surprising
91 # rooted to the start of the string will produce less surprising
92 # result for user writing simple regex for sub-attribute.
92 # result for user writing simple regex for sub-attribute.
93 #
93 #
94 # For example using "color\..*" match produces an unsurprising
94 # For example using "color\..*" match produces an unsurprising
95 # result, while using search could suddenly match apparently
95 # result, while using search could suddenly match apparently
96 # unrelated configuration that happens to contains "color."
96 # unrelated configuration that happens to contains "color."
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
98 # some match to avoid the need to prefix most pattern with "^".
98 # some match to avoid the need to prefix most pattern with "^".
99 # The "^" seems more error prone.
99 # The "^" seems more error prone.
100 if item._re.match(key):
100 if item._re.match(key):
101 return item
101 return item
102
102
103 return None
103 return None
104
104
105
105
106 coreitems = {}
106 coreitems = {}
107
107
108
108
109 def _register(configtable, *args, **kwargs):
109 def _register(configtable, *args, **kwargs):
110 item = configitem(*args, **kwargs)
110 item = configitem(*args, **kwargs)
111 section = configtable.setdefault(item.section, itemregister())
111 section = configtable.setdefault(item.section, itemregister())
112 if item.name in section:
112 if item.name in section:
113 msg = b"duplicated config item registration for '%s.%s'"
113 msg = b"duplicated config item registration for '%s.%s'"
114 raise error.ProgrammingError(msg % (item.section, item.name))
114 raise error.ProgrammingError(msg % (item.section, item.name))
115 section[item.name] = item
115 section[item.name] = item
116
116
117
117
118 # special value for case where the default is derived from other values
118 # special value for case where the default is derived from other values
119 dynamicdefault = object()
119 dynamicdefault = object()
120
120
121 # Registering actual config items
121 # Registering actual config items
122
122
123
123
124 def getitemregister(configtable):
124 def getitemregister(configtable):
125 f = functools.partial(_register, configtable)
125 f = functools.partial(_register, configtable)
126 # export pseudo enum as configitem.*
126 # export pseudo enum as configitem.*
127 f.dynamicdefault = dynamicdefault
127 f.dynamicdefault = dynamicdefault
128 return f
128 return f
129
129
130
130
131 coreconfigitem = getitemregister(coreitems)
131 coreconfigitem = getitemregister(coreitems)
132
132
133
133
134 def _registerdiffopts(section, configprefix=b''):
134 def _registerdiffopts(section, configprefix=b''):
135 coreconfigitem(
135 coreconfigitem(
136 section, configprefix + b'nodates', default=False,
136 section, configprefix + b'nodates', default=False,
137 )
137 )
138 coreconfigitem(
138 coreconfigitem(
139 section, configprefix + b'showfunc', default=False,
139 section, configprefix + b'showfunc', default=False,
140 )
140 )
141 coreconfigitem(
141 coreconfigitem(
142 section, configprefix + b'unified', default=None,
142 section, configprefix + b'unified', default=None,
143 )
143 )
144 coreconfigitem(
144 coreconfigitem(
145 section, configprefix + b'git', default=False,
145 section, configprefix + b'git', default=False,
146 )
146 )
147 coreconfigitem(
147 coreconfigitem(
148 section, configprefix + b'ignorews', default=False,
148 section, configprefix + b'ignorews', default=False,
149 )
149 )
150 coreconfigitem(
150 coreconfigitem(
151 section, configprefix + b'ignorewsamount', default=False,
151 section, configprefix + b'ignorewsamount', default=False,
152 )
152 )
153 coreconfigitem(
153 coreconfigitem(
154 section, configprefix + b'ignoreblanklines', default=False,
154 section, configprefix + b'ignoreblanklines', default=False,
155 )
155 )
156 coreconfigitem(
156 coreconfigitem(
157 section, configprefix + b'ignorewseol', default=False,
157 section, configprefix + b'ignorewseol', default=False,
158 )
158 )
159 coreconfigitem(
159 coreconfigitem(
160 section, configprefix + b'nobinary', default=False,
160 section, configprefix + b'nobinary', default=False,
161 )
161 )
162 coreconfigitem(
162 coreconfigitem(
163 section, configprefix + b'noprefix', default=False,
163 section, configprefix + b'noprefix', default=False,
164 )
164 )
165 coreconfigitem(
165 coreconfigitem(
166 section, configprefix + b'word-diff', default=False,
166 section, configprefix + b'word-diff', default=False,
167 )
167 )
168
168
169
169
170 coreconfigitem(
170 coreconfigitem(
171 b'alias', b'.*', default=dynamicdefault, generic=True,
171 b'alias', b'.*', default=dynamicdefault, generic=True,
172 )
172 )
173 coreconfigitem(
173 coreconfigitem(
174 b'auth', b'cookiefile', default=None,
174 b'auth', b'cookiefile', default=None,
175 )
175 )
176 _registerdiffopts(section=b'annotate')
176 _registerdiffopts(section=b'annotate')
177 # bookmarks.pushing: internal hack for discovery
177 # bookmarks.pushing: internal hack for discovery
178 coreconfigitem(
178 coreconfigitem(
179 b'bookmarks', b'pushing', default=list,
179 b'bookmarks', b'pushing', default=list,
180 )
180 )
181 # bundle.mainreporoot: internal hack for bundlerepo
181 # bundle.mainreporoot: internal hack for bundlerepo
182 coreconfigitem(
182 coreconfigitem(
183 b'bundle', b'mainreporoot', default=b'',
183 b'bundle', b'mainreporoot', default=b'',
184 )
184 )
185 coreconfigitem(
185 coreconfigitem(
186 b'censor', b'policy', default=b'abort', experimental=True,
186 b'censor', b'policy', default=b'abort', experimental=True,
187 )
187 )
188 coreconfigitem(
188 coreconfigitem(
189 b'chgserver', b'idletimeout', default=3600,
189 b'chgserver', b'idletimeout', default=3600,
190 )
190 )
191 coreconfigitem(
191 coreconfigitem(
192 b'chgserver', b'skiphash', default=False,
192 b'chgserver', b'skiphash', default=False,
193 )
193 )
194 coreconfigitem(
194 coreconfigitem(
195 b'cmdserver', b'log', default=None,
195 b'cmdserver', b'log', default=None,
196 )
196 )
197 coreconfigitem(
197 coreconfigitem(
198 b'cmdserver', b'max-log-files', default=7,
198 b'cmdserver', b'max-log-files', default=7,
199 )
199 )
200 coreconfigitem(
200 coreconfigitem(
201 b'cmdserver', b'max-log-size', default=b'1 MB',
201 b'cmdserver', b'max-log-size', default=b'1 MB',
202 )
202 )
203 coreconfigitem(
203 coreconfigitem(
204 b'cmdserver', b'max-repo-cache', default=0, experimental=True,
204 b'cmdserver', b'max-repo-cache', default=0, experimental=True,
205 )
205 )
206 coreconfigitem(
206 coreconfigitem(
207 b'cmdserver', b'message-encodings', default=list, experimental=True,
207 b'cmdserver', b'message-encodings', default=list, experimental=True,
208 )
208 )
209 coreconfigitem(
209 coreconfigitem(
210 b'cmdserver',
210 b'cmdserver',
211 b'track-log',
211 b'track-log',
212 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
212 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
213 )
213 )
214 coreconfigitem(
214 coreconfigitem(
215 b'color', b'.*', default=None, generic=True,
215 b'color', b'.*', default=None, generic=True,
216 )
216 )
217 coreconfigitem(
217 coreconfigitem(
218 b'color', b'mode', default=b'auto',
218 b'color', b'mode', default=b'auto',
219 )
219 )
220 coreconfigitem(
220 coreconfigitem(
221 b'color', b'pagermode', default=dynamicdefault,
221 b'color', b'pagermode', default=dynamicdefault,
222 )
222 )
223 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
223 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
224 coreconfigitem(
224 coreconfigitem(
225 b'commands', b'commit.post-status', default=False,
225 b'commands', b'commit.post-status', default=False,
226 )
226 )
227 coreconfigitem(
227 coreconfigitem(
228 b'commands', b'grep.all-files', default=False, experimental=True,
228 b'commands', b'grep.all-files', default=False, experimental=True,
229 )
229 )
230 coreconfigitem(
230 coreconfigitem(
231 b'commands', b'merge.require-rev', default=False,
231 b'commands', b'merge.require-rev', default=False,
232 )
232 )
233 coreconfigitem(
233 coreconfigitem(
234 b'commands', b'push.require-revs', default=False,
234 b'commands', b'push.require-revs', default=False,
235 )
235 )
236 coreconfigitem(
236 coreconfigitem(
237 b'commands', b'resolve.confirm', default=False,
237 b'commands', b'resolve.confirm', default=False,
238 )
238 )
239 coreconfigitem(
239 coreconfigitem(
240 b'commands', b'resolve.explicit-re-merge', default=False,
240 b'commands', b'resolve.explicit-re-merge', default=False,
241 )
241 )
242 coreconfigitem(
242 coreconfigitem(
243 b'commands', b'resolve.mark-check', default=b'none',
243 b'commands', b'resolve.mark-check', default=b'none',
244 )
244 )
245 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
245 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
246 coreconfigitem(
246 coreconfigitem(
247 b'commands', b'show.aliasprefix', default=list,
247 b'commands', b'show.aliasprefix', default=list,
248 )
248 )
249 coreconfigitem(
249 coreconfigitem(
250 b'commands', b'status.relative', default=False,
250 b'commands', b'status.relative', default=False,
251 )
251 )
252 coreconfigitem(
252 coreconfigitem(
253 b'commands', b'status.skipstates', default=[], experimental=True,
253 b'commands', b'status.skipstates', default=[], experimental=True,
254 )
254 )
255 coreconfigitem(
255 coreconfigitem(
256 b'commands', b'status.terse', default=b'',
256 b'commands', b'status.terse', default=b'',
257 )
257 )
258 coreconfigitem(
258 coreconfigitem(
259 b'commands', b'status.verbose', default=False,
259 b'commands', b'status.verbose', default=False,
260 )
260 )
261 coreconfigitem(
261 coreconfigitem(
262 b'commands', b'update.check', default=None,
262 b'commands', b'update.check', default=None,
263 )
263 )
264 coreconfigitem(
264 coreconfigitem(
265 b'commands', b'update.requiredest', default=False,
265 b'commands', b'update.requiredest', default=False,
266 )
266 )
267 coreconfigitem(
267 coreconfigitem(
268 b'committemplate', b'.*', default=None, generic=True,
268 b'committemplate', b'.*', default=None, generic=True,
269 )
269 )
270 coreconfigitem(
270 coreconfigitem(
271 b'convert', b'bzr.saverev', default=True,
271 b'convert', b'bzr.saverev', default=True,
272 )
272 )
273 coreconfigitem(
273 coreconfigitem(
274 b'convert', b'cvsps.cache', default=True,
274 b'convert', b'cvsps.cache', default=True,
275 )
275 )
276 coreconfigitem(
276 coreconfigitem(
277 b'convert', b'cvsps.fuzz', default=60,
277 b'convert', b'cvsps.fuzz', default=60,
278 )
278 )
279 coreconfigitem(
279 coreconfigitem(
280 b'convert', b'cvsps.logencoding', default=None,
280 b'convert', b'cvsps.logencoding', default=None,
281 )
281 )
282 coreconfigitem(
282 coreconfigitem(
283 b'convert', b'cvsps.mergefrom', default=None,
283 b'convert', b'cvsps.mergefrom', default=None,
284 )
284 )
285 coreconfigitem(
285 coreconfigitem(
286 b'convert', b'cvsps.mergeto', default=None,
286 b'convert', b'cvsps.mergeto', default=None,
287 )
287 )
288 coreconfigitem(
288 coreconfigitem(
289 b'convert', b'git.committeractions', default=lambda: [b'messagedifferent'],
289 b'convert', b'git.committeractions', default=lambda: [b'messagedifferent'],
290 )
290 )
291 coreconfigitem(
291 coreconfigitem(
292 b'convert', b'git.extrakeys', default=list,
292 b'convert', b'git.extrakeys', default=list,
293 )
293 )
294 coreconfigitem(
294 coreconfigitem(
295 b'convert', b'git.findcopiesharder', default=False,
295 b'convert', b'git.findcopiesharder', default=False,
296 )
296 )
297 coreconfigitem(
297 coreconfigitem(
298 b'convert', b'git.remoteprefix', default=b'remote',
298 b'convert', b'git.remoteprefix', default=b'remote',
299 )
299 )
300 coreconfigitem(
300 coreconfigitem(
301 b'convert', b'git.renamelimit', default=400,
301 b'convert', b'git.renamelimit', default=400,
302 )
302 )
303 coreconfigitem(
303 coreconfigitem(
304 b'convert', b'git.saverev', default=True,
304 b'convert', b'git.saverev', default=True,
305 )
305 )
306 coreconfigitem(
306 coreconfigitem(
307 b'convert', b'git.similarity', default=50,
307 b'convert', b'git.similarity', default=50,
308 )
308 )
309 coreconfigitem(
309 coreconfigitem(
310 b'convert', b'git.skipsubmodules', default=False,
310 b'convert', b'git.skipsubmodules', default=False,
311 )
311 )
312 coreconfigitem(
312 coreconfigitem(
313 b'convert', b'hg.clonebranches', default=False,
313 b'convert', b'hg.clonebranches', default=False,
314 )
314 )
315 coreconfigitem(
315 coreconfigitem(
316 b'convert', b'hg.ignoreerrors', default=False,
316 b'convert', b'hg.ignoreerrors', default=False,
317 )
317 )
318 coreconfigitem(
318 coreconfigitem(
319 b'convert', b'hg.preserve-hash', default=False,
319 b'convert', b'hg.preserve-hash', default=False,
320 )
320 )
321 coreconfigitem(
321 coreconfigitem(
322 b'convert', b'hg.revs', default=None,
322 b'convert', b'hg.revs', default=None,
323 )
323 )
324 coreconfigitem(
324 coreconfigitem(
325 b'convert', b'hg.saverev', default=False,
325 b'convert', b'hg.saverev', default=False,
326 )
326 )
327 coreconfigitem(
327 coreconfigitem(
328 b'convert', b'hg.sourcename', default=None,
328 b'convert', b'hg.sourcename', default=None,
329 )
329 )
330 coreconfigitem(
330 coreconfigitem(
331 b'convert', b'hg.startrev', default=None,
331 b'convert', b'hg.startrev', default=None,
332 )
332 )
333 coreconfigitem(
333 coreconfigitem(
334 b'convert', b'hg.tagsbranch', default=b'default',
334 b'convert', b'hg.tagsbranch', default=b'default',
335 )
335 )
336 coreconfigitem(
336 coreconfigitem(
337 b'convert', b'hg.usebranchnames', default=True,
337 b'convert', b'hg.usebranchnames', default=True,
338 )
338 )
339 coreconfigitem(
339 coreconfigitem(
340 b'convert', b'ignoreancestorcheck', default=False, experimental=True,
340 b'convert', b'ignoreancestorcheck', default=False, experimental=True,
341 )
341 )
342 coreconfigitem(
342 coreconfigitem(
343 b'convert', b'localtimezone', default=False,
343 b'convert', b'localtimezone', default=False,
344 )
344 )
345 coreconfigitem(
345 coreconfigitem(
346 b'convert', b'p4.encoding', default=dynamicdefault,
346 b'convert', b'p4.encoding', default=dynamicdefault,
347 )
347 )
348 coreconfigitem(
348 coreconfigitem(
349 b'convert', b'p4.startrev', default=0,
349 b'convert', b'p4.startrev', default=0,
350 )
350 )
351 coreconfigitem(
351 coreconfigitem(
352 b'convert', b'skiptags', default=False,
352 b'convert', b'skiptags', default=False,
353 )
353 )
354 coreconfigitem(
354 coreconfigitem(
355 b'convert', b'svn.debugsvnlog', default=True,
355 b'convert', b'svn.debugsvnlog', default=True,
356 )
356 )
357 coreconfigitem(
357 coreconfigitem(
358 b'convert', b'svn.trunk', default=None,
358 b'convert', b'svn.trunk', default=None,
359 )
359 )
360 coreconfigitem(
360 coreconfigitem(
361 b'convert', b'svn.tags', default=None,
361 b'convert', b'svn.tags', default=None,
362 )
362 )
363 coreconfigitem(
363 coreconfigitem(
364 b'convert', b'svn.branches', default=None,
364 b'convert', b'svn.branches', default=None,
365 )
365 )
366 coreconfigitem(
366 coreconfigitem(
367 b'convert', b'svn.startrev', default=0,
367 b'convert', b'svn.startrev', default=0,
368 )
368 )
369 coreconfigitem(
369 coreconfigitem(
370 b'debug', b'dirstate.delaywrite', default=0,
370 b'debug', b'dirstate.delaywrite', default=0,
371 )
371 )
372 coreconfigitem(
372 coreconfigitem(
373 b'defaults', b'.*', default=None, generic=True,
373 b'defaults', b'.*', default=None, generic=True,
374 )
374 )
375 coreconfigitem(
375 coreconfigitem(
376 b'devel', b'all-warnings', default=False,
376 b'devel', b'all-warnings', default=False,
377 )
377 )
378 coreconfigitem(
378 coreconfigitem(
379 b'devel', b'bundle2.debug', default=False,
379 b'devel', b'bundle2.debug', default=False,
380 )
380 )
381 coreconfigitem(
381 coreconfigitem(
382 b'devel', b'bundle.delta', default=b'',
382 b'devel', b'bundle.delta', default=b'',
383 )
383 )
384 coreconfigitem(
384 coreconfigitem(
385 b'devel', b'cache-vfs', default=None,
385 b'devel', b'cache-vfs', default=None,
386 )
386 )
387 coreconfigitem(
387 coreconfigitem(
388 b'devel', b'check-locks', default=False,
388 b'devel', b'check-locks', default=False,
389 )
389 )
390 coreconfigitem(
390 coreconfigitem(
391 b'devel', b'check-relroot', default=False,
391 b'devel', b'check-relroot', default=False,
392 )
392 )
393 coreconfigitem(
393 coreconfigitem(
394 b'devel', b'default-date', default=None,
394 b'devel', b'default-date', default=None,
395 )
395 )
396 coreconfigitem(
396 coreconfigitem(
397 b'devel', b'deprec-warn', default=False,
397 b'devel', b'deprec-warn', default=False,
398 )
398 )
399 coreconfigitem(
399 coreconfigitem(
400 b'devel', b'disableloaddefaultcerts', default=False,
400 b'devel', b'disableloaddefaultcerts', default=False,
401 )
401 )
402 coreconfigitem(
402 coreconfigitem(
403 b'devel', b'warn-empty-changegroup', default=False,
403 b'devel', b'warn-empty-changegroup', default=False,
404 )
404 )
405 coreconfigitem(
405 coreconfigitem(
406 b'devel', b'legacy.exchange', default=list,
406 b'devel', b'legacy.exchange', default=list,
407 )
407 )
408 # TODO before getting `persistent-nodemap` out of experimental
408 # TODO before getting `persistent-nodemap` out of experimental
409 #
409 #
410 # * regenerate a new nodemap when the unused/total ration is to high
411 # * decide for a "status" of the persistent nodemap and associated location
410 # * decide for a "status" of the persistent nodemap and associated location
412 # - part of the store next the revlog itself (new requirements)
411 # - part of the store next the revlog itself (new requirements)
413 # - part of the cache directory
412 # - part of the cache directory
414 # - part of an `index` directory
413 # - part of an `index` directory
415 # (https://www.mercurial-scm.org/wiki/ComputedIndexPlan)
414 # (https://www.mercurial-scm.org/wiki/ComputedIndexPlan)
416 # * do we want to use this for more than just changelog? if so we need:
415 # * do we want to use this for more than just changelog? if so we need:
417 # - simpler "pending" logic for them
416 # - simpler "pending" logic for them
418 # - double check the memory story (we dont want to keep all revlog in memory)
417 # - double check the memory story (we dont want to keep all revlog in memory)
419 # - think about the naming scheme if we are in "cache"
418 # - think about the naming scheme if we are in "cache"
420 # * increment the version format to "1" and freeze it.
419 # * increment the version format to "1" and freeze it.
421 coreconfigitem(
420 coreconfigitem(
422 b'devel', b'persistent-nodemap', default=False,
421 b'devel', b'persistent-nodemap', default=False,
423 )
422 )
424 coreconfigitem(
423 coreconfigitem(
425 b'devel', b'servercafile', default=b'',
424 b'devel', b'servercafile', default=b'',
426 )
425 )
427 coreconfigitem(
426 coreconfigitem(
428 b'devel', b'serverexactprotocol', default=b'',
427 b'devel', b'serverexactprotocol', default=b'',
429 )
428 )
430 coreconfigitem(
429 coreconfigitem(
431 b'devel', b'serverrequirecert', default=False,
430 b'devel', b'serverrequirecert', default=False,
432 )
431 )
433 coreconfigitem(
432 coreconfigitem(
434 b'devel', b'strip-obsmarkers', default=True,
433 b'devel', b'strip-obsmarkers', default=True,
435 )
434 )
436 coreconfigitem(
435 coreconfigitem(
437 b'devel', b'warn-config', default=None,
436 b'devel', b'warn-config', default=None,
438 )
437 )
439 coreconfigitem(
438 coreconfigitem(
440 b'devel', b'warn-config-default', default=None,
439 b'devel', b'warn-config-default', default=None,
441 )
440 )
442 coreconfigitem(
441 coreconfigitem(
443 b'devel', b'user.obsmarker', default=None,
442 b'devel', b'user.obsmarker', default=None,
444 )
443 )
445 coreconfigitem(
444 coreconfigitem(
446 b'devel', b'warn-config-unknown', default=None,
445 b'devel', b'warn-config-unknown', default=None,
447 )
446 )
448 coreconfigitem(
447 coreconfigitem(
449 b'devel', b'debug.copies', default=False,
448 b'devel', b'debug.copies', default=False,
450 )
449 )
451 coreconfigitem(
450 coreconfigitem(
452 b'devel', b'debug.extensions', default=False,
451 b'devel', b'debug.extensions', default=False,
453 )
452 )
454 coreconfigitem(
453 coreconfigitem(
455 b'devel', b'debug.repo-filters', default=False,
454 b'devel', b'debug.repo-filters', default=False,
456 )
455 )
457 coreconfigitem(
456 coreconfigitem(
458 b'devel', b'debug.peer-request', default=False,
457 b'devel', b'debug.peer-request', default=False,
459 )
458 )
460 coreconfigitem(
459 coreconfigitem(
461 b'devel', b'discovery.randomize', default=True,
460 b'devel', b'discovery.randomize', default=True,
462 )
461 )
463 _registerdiffopts(section=b'diff')
462 _registerdiffopts(section=b'diff')
464 coreconfigitem(
463 coreconfigitem(
465 b'email', b'bcc', default=None,
464 b'email', b'bcc', default=None,
466 )
465 )
467 coreconfigitem(
466 coreconfigitem(
468 b'email', b'cc', default=None,
467 b'email', b'cc', default=None,
469 )
468 )
470 coreconfigitem(
469 coreconfigitem(
471 b'email', b'charsets', default=list,
470 b'email', b'charsets', default=list,
472 )
471 )
473 coreconfigitem(
472 coreconfigitem(
474 b'email', b'from', default=None,
473 b'email', b'from', default=None,
475 )
474 )
476 coreconfigitem(
475 coreconfigitem(
477 b'email', b'method', default=b'smtp',
476 b'email', b'method', default=b'smtp',
478 )
477 )
479 coreconfigitem(
478 coreconfigitem(
480 b'email', b'reply-to', default=None,
479 b'email', b'reply-to', default=None,
481 )
480 )
482 coreconfigitem(
481 coreconfigitem(
483 b'email', b'to', default=None,
482 b'email', b'to', default=None,
484 )
483 )
485 coreconfigitem(
484 coreconfigitem(
486 b'experimental', b'archivemetatemplate', default=dynamicdefault,
485 b'experimental', b'archivemetatemplate', default=dynamicdefault,
487 )
486 )
488 coreconfigitem(
487 coreconfigitem(
489 b'experimental', b'auto-publish', default=b'publish',
488 b'experimental', b'auto-publish', default=b'publish',
490 )
489 )
491 coreconfigitem(
490 coreconfigitem(
492 b'experimental', b'bundle-phases', default=False,
491 b'experimental', b'bundle-phases', default=False,
493 )
492 )
494 coreconfigitem(
493 coreconfigitem(
495 b'experimental', b'bundle2-advertise', default=True,
494 b'experimental', b'bundle2-advertise', default=True,
496 )
495 )
497 coreconfigitem(
496 coreconfigitem(
498 b'experimental', b'bundle2-output-capture', default=False,
497 b'experimental', b'bundle2-output-capture', default=False,
499 )
498 )
500 coreconfigitem(
499 coreconfigitem(
501 b'experimental', b'bundle2.pushback', default=False,
500 b'experimental', b'bundle2.pushback', default=False,
502 )
501 )
503 coreconfigitem(
502 coreconfigitem(
504 b'experimental', b'bundle2lazylocking', default=False,
503 b'experimental', b'bundle2lazylocking', default=False,
505 )
504 )
506 coreconfigitem(
505 coreconfigitem(
507 b'experimental', b'bundlecomplevel', default=None,
506 b'experimental', b'bundlecomplevel', default=None,
508 )
507 )
509 coreconfigitem(
508 coreconfigitem(
510 b'experimental', b'bundlecomplevel.bzip2', default=None,
509 b'experimental', b'bundlecomplevel.bzip2', default=None,
511 )
510 )
512 coreconfigitem(
511 coreconfigitem(
513 b'experimental', b'bundlecomplevel.gzip', default=None,
512 b'experimental', b'bundlecomplevel.gzip', default=None,
514 )
513 )
515 coreconfigitem(
514 coreconfigitem(
516 b'experimental', b'bundlecomplevel.none', default=None,
515 b'experimental', b'bundlecomplevel.none', default=None,
517 )
516 )
518 coreconfigitem(
517 coreconfigitem(
519 b'experimental', b'bundlecomplevel.zstd', default=None,
518 b'experimental', b'bundlecomplevel.zstd', default=None,
520 )
519 )
521 coreconfigitem(
520 coreconfigitem(
522 b'experimental', b'changegroup3', default=False,
521 b'experimental', b'changegroup3', default=False,
523 )
522 )
524 coreconfigitem(
523 coreconfigitem(
525 b'experimental', b'cleanup-as-archived', default=False,
524 b'experimental', b'cleanup-as-archived', default=False,
526 )
525 )
527 coreconfigitem(
526 coreconfigitem(
528 b'experimental', b'clientcompressionengines', default=list,
527 b'experimental', b'clientcompressionengines', default=list,
529 )
528 )
530 coreconfigitem(
529 coreconfigitem(
531 b'experimental', b'copytrace', default=b'on',
530 b'experimental', b'copytrace', default=b'on',
532 )
531 )
533 coreconfigitem(
532 coreconfigitem(
534 b'experimental', b'copytrace.movecandidateslimit', default=100,
533 b'experimental', b'copytrace.movecandidateslimit', default=100,
535 )
534 )
536 coreconfigitem(
535 coreconfigitem(
537 b'experimental', b'copytrace.sourcecommitlimit', default=100,
536 b'experimental', b'copytrace.sourcecommitlimit', default=100,
538 )
537 )
539 coreconfigitem(
538 coreconfigitem(
540 b'experimental', b'copies.read-from', default=b"filelog-only",
539 b'experimental', b'copies.read-from', default=b"filelog-only",
541 )
540 )
542 coreconfigitem(
541 coreconfigitem(
543 b'experimental', b'copies.write-to', default=b'filelog-only',
542 b'experimental', b'copies.write-to', default=b'filelog-only',
544 )
543 )
545 coreconfigitem(
544 coreconfigitem(
546 b'experimental', b'crecordtest', default=None,
545 b'experimental', b'crecordtest', default=None,
547 )
546 )
548 coreconfigitem(
547 coreconfigitem(
549 b'experimental', b'directaccess', default=False,
548 b'experimental', b'directaccess', default=False,
550 )
549 )
551 coreconfigitem(
550 coreconfigitem(
552 b'experimental', b'directaccess.revnums', default=False,
551 b'experimental', b'directaccess.revnums', default=False,
553 )
552 )
554 coreconfigitem(
553 coreconfigitem(
555 b'experimental', b'editortmpinhg', default=False,
554 b'experimental', b'editortmpinhg', default=False,
556 )
555 )
557 coreconfigitem(
556 coreconfigitem(
558 b'experimental', b'evolution', default=list,
557 b'experimental', b'evolution', default=list,
559 )
558 )
560 coreconfigitem(
559 coreconfigitem(
561 b'experimental',
560 b'experimental',
562 b'evolution.allowdivergence',
561 b'evolution.allowdivergence',
563 default=False,
562 default=False,
564 alias=[(b'experimental', b'allowdivergence')],
563 alias=[(b'experimental', b'allowdivergence')],
565 )
564 )
566 coreconfigitem(
565 coreconfigitem(
567 b'experimental', b'evolution.allowunstable', default=None,
566 b'experimental', b'evolution.allowunstable', default=None,
568 )
567 )
569 coreconfigitem(
568 coreconfigitem(
570 b'experimental', b'evolution.createmarkers', default=None,
569 b'experimental', b'evolution.createmarkers', default=None,
571 )
570 )
572 coreconfigitem(
571 coreconfigitem(
573 b'experimental',
572 b'experimental',
574 b'evolution.effect-flags',
573 b'evolution.effect-flags',
575 default=True,
574 default=True,
576 alias=[(b'experimental', b'effect-flags')],
575 alias=[(b'experimental', b'effect-flags')],
577 )
576 )
578 coreconfigitem(
577 coreconfigitem(
579 b'experimental', b'evolution.exchange', default=None,
578 b'experimental', b'evolution.exchange', default=None,
580 )
579 )
581 coreconfigitem(
580 coreconfigitem(
582 b'experimental', b'evolution.bundle-obsmarker', default=False,
581 b'experimental', b'evolution.bundle-obsmarker', default=False,
583 )
582 )
584 coreconfigitem(
583 coreconfigitem(
585 b'experimental', b'log.topo', default=False,
584 b'experimental', b'log.topo', default=False,
586 )
585 )
587 coreconfigitem(
586 coreconfigitem(
588 b'experimental', b'evolution.report-instabilities', default=True,
587 b'experimental', b'evolution.report-instabilities', default=True,
589 )
588 )
590 coreconfigitem(
589 coreconfigitem(
591 b'experimental', b'evolution.track-operation', default=True,
590 b'experimental', b'evolution.track-operation', default=True,
592 )
591 )
593 # repo-level config to exclude a revset visibility
592 # repo-level config to exclude a revset visibility
594 #
593 #
595 # The target use case is to use `share` to expose different subset of the same
594 # The target use case is to use `share` to expose different subset of the same
596 # repository, especially server side. See also `server.view`.
595 # repository, especially server side. See also `server.view`.
597 coreconfigitem(
596 coreconfigitem(
598 b'experimental', b'extra-filter-revs', default=None,
597 b'experimental', b'extra-filter-revs', default=None,
599 )
598 )
600 coreconfigitem(
599 coreconfigitem(
601 b'experimental', b'maxdeltachainspan', default=-1,
600 b'experimental', b'maxdeltachainspan', default=-1,
602 )
601 )
603 coreconfigitem(
602 coreconfigitem(
604 b'experimental', b'mergetempdirprefix', default=None,
603 b'experimental', b'mergetempdirprefix', default=None,
605 )
604 )
606 coreconfigitem(
605 coreconfigitem(
607 b'experimental', b'mmapindexthreshold', default=None,
606 b'experimental', b'mmapindexthreshold', default=None,
608 )
607 )
609 coreconfigitem(
608 coreconfigitem(
610 b'experimental', b'narrow', default=False,
609 b'experimental', b'narrow', default=False,
611 )
610 )
612 coreconfigitem(
611 coreconfigitem(
613 b'experimental', b'nonnormalparanoidcheck', default=False,
612 b'experimental', b'nonnormalparanoidcheck', default=False,
614 )
613 )
615 coreconfigitem(
614 coreconfigitem(
616 b'experimental', b'exportableenviron', default=list,
615 b'experimental', b'exportableenviron', default=list,
617 )
616 )
618 coreconfigitem(
617 coreconfigitem(
619 b'experimental', b'extendedheader.index', default=None,
618 b'experimental', b'extendedheader.index', default=None,
620 )
619 )
621 coreconfigitem(
620 coreconfigitem(
622 b'experimental', b'extendedheader.similarity', default=False,
621 b'experimental', b'extendedheader.similarity', default=False,
623 )
622 )
624 coreconfigitem(
623 coreconfigitem(
625 b'experimental', b'graphshorten', default=False,
624 b'experimental', b'graphshorten', default=False,
626 )
625 )
627 coreconfigitem(
626 coreconfigitem(
628 b'experimental', b'graphstyle.parent', default=dynamicdefault,
627 b'experimental', b'graphstyle.parent', default=dynamicdefault,
629 )
628 )
630 coreconfigitem(
629 coreconfigitem(
631 b'experimental', b'graphstyle.missing', default=dynamicdefault,
630 b'experimental', b'graphstyle.missing', default=dynamicdefault,
632 )
631 )
633 coreconfigitem(
632 coreconfigitem(
634 b'experimental', b'graphstyle.grandparent', default=dynamicdefault,
633 b'experimental', b'graphstyle.grandparent', default=dynamicdefault,
635 )
634 )
636 coreconfigitem(
635 coreconfigitem(
637 b'experimental', b'hook-track-tags', default=False,
636 b'experimental', b'hook-track-tags', default=False,
638 )
637 )
639 coreconfigitem(
638 coreconfigitem(
640 b'experimental', b'httppeer.advertise-v2', default=False,
639 b'experimental', b'httppeer.advertise-v2', default=False,
641 )
640 )
642 coreconfigitem(
641 coreconfigitem(
643 b'experimental', b'httppeer.v2-encoder-order', default=None,
642 b'experimental', b'httppeer.v2-encoder-order', default=None,
644 )
643 )
645 coreconfigitem(
644 coreconfigitem(
646 b'experimental', b'httppostargs', default=False,
645 b'experimental', b'httppostargs', default=False,
647 )
646 )
648 coreconfigitem(
647 coreconfigitem(
649 b'experimental', b'mergedriver', default=None,
648 b'experimental', b'mergedriver', default=None,
650 )
649 )
651 coreconfigitem(b'experimental', b'nointerrupt', default=False)
650 coreconfigitem(b'experimental', b'nointerrupt', default=False)
652 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
651 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
653
652
654 coreconfigitem(
653 coreconfigitem(
655 b'experimental', b'obsmarkers-exchange-debug', default=False,
654 b'experimental', b'obsmarkers-exchange-debug', default=False,
656 )
655 )
657 coreconfigitem(
656 coreconfigitem(
658 b'experimental', b'remotenames', default=False,
657 b'experimental', b'remotenames', default=False,
659 )
658 )
660 coreconfigitem(
659 coreconfigitem(
661 b'experimental', b'removeemptydirs', default=True,
660 b'experimental', b'removeemptydirs', default=True,
662 )
661 )
663 coreconfigitem(
662 coreconfigitem(
664 b'experimental', b'revert.interactive.select-to-keep', default=False,
663 b'experimental', b'revert.interactive.select-to-keep', default=False,
665 )
664 )
666 coreconfigitem(
665 coreconfigitem(
667 b'experimental', b'revisions.prefixhexnode', default=False,
666 b'experimental', b'revisions.prefixhexnode', default=False,
668 )
667 )
669 coreconfigitem(
668 coreconfigitem(
670 b'experimental', b'revlogv2', default=None,
669 b'experimental', b'revlogv2', default=None,
671 )
670 )
672 coreconfigitem(
671 coreconfigitem(
673 b'experimental', b'revisions.disambiguatewithin', default=None,
672 b'experimental', b'revisions.disambiguatewithin', default=None,
674 )
673 )
675 coreconfigitem(
674 coreconfigitem(
676 b'experimental', b'rust.index', default=False,
675 b'experimental', b'rust.index', default=False,
677 )
676 )
678 coreconfigitem(
677 coreconfigitem(
679 b'experimental', b'exp-persistent-nodemap', default=False,
678 b'experimental', b'exp-persistent-nodemap', default=False,
680 )
679 )
681 coreconfigitem(
680 coreconfigitem(
682 b'experimental', b'exp-persistent-nodemap.mmap', default=True,
681 b'experimental', b'exp-persistent-nodemap.mmap', default=True,
683 )
682 )
684 coreconfigitem(
683 coreconfigitem(
685 b'experimental', b'server.filesdata.recommended-batch-size', default=50000,
684 b'experimental', b'server.filesdata.recommended-batch-size', default=50000,
686 )
685 )
687 coreconfigitem(
686 coreconfigitem(
688 b'experimental',
687 b'experimental',
689 b'server.manifestdata.recommended-batch-size',
688 b'server.manifestdata.recommended-batch-size',
690 default=100000,
689 default=100000,
691 )
690 )
692 coreconfigitem(
691 coreconfigitem(
693 b'experimental', b'server.stream-narrow-clones', default=False,
692 b'experimental', b'server.stream-narrow-clones', default=False,
694 )
693 )
695 coreconfigitem(
694 coreconfigitem(
696 b'experimental', b'single-head-per-branch', default=False,
695 b'experimental', b'single-head-per-branch', default=False,
697 )
696 )
698 coreconfigitem(
697 coreconfigitem(
699 b'experimental',
698 b'experimental',
700 b'single-head-per-branch:account-closed-heads',
699 b'single-head-per-branch:account-closed-heads',
701 default=False,
700 default=False,
702 )
701 )
703 coreconfigitem(
702 coreconfigitem(
704 b'experimental', b'sshserver.support-v2', default=False,
703 b'experimental', b'sshserver.support-v2', default=False,
705 )
704 )
706 coreconfigitem(
705 coreconfigitem(
707 b'experimental', b'sparse-read', default=False,
706 b'experimental', b'sparse-read', default=False,
708 )
707 )
709 coreconfigitem(
708 coreconfigitem(
710 b'experimental', b'sparse-read.density-threshold', default=0.50,
709 b'experimental', b'sparse-read.density-threshold', default=0.50,
711 )
710 )
712 coreconfigitem(
711 coreconfigitem(
713 b'experimental', b'sparse-read.min-gap-size', default=b'65K',
712 b'experimental', b'sparse-read.min-gap-size', default=b'65K',
714 )
713 )
715 coreconfigitem(
714 coreconfigitem(
716 b'experimental', b'treemanifest', default=False,
715 b'experimental', b'treemanifest', default=False,
717 )
716 )
718 coreconfigitem(
717 coreconfigitem(
719 b'experimental', b'update.atomic-file', default=False,
718 b'experimental', b'update.atomic-file', default=False,
720 )
719 )
721 coreconfigitem(
720 coreconfigitem(
722 b'experimental', b'sshpeer.advertise-v2', default=False,
721 b'experimental', b'sshpeer.advertise-v2', default=False,
723 )
722 )
724 coreconfigitem(
723 coreconfigitem(
725 b'experimental', b'web.apiserver', default=False,
724 b'experimental', b'web.apiserver', default=False,
726 )
725 )
727 coreconfigitem(
726 coreconfigitem(
728 b'experimental', b'web.api.http-v2', default=False,
727 b'experimental', b'web.api.http-v2', default=False,
729 )
728 )
730 coreconfigitem(
729 coreconfigitem(
731 b'experimental', b'web.api.debugreflect', default=False,
730 b'experimental', b'web.api.debugreflect', default=False,
732 )
731 )
733 coreconfigitem(
732 coreconfigitem(
734 b'experimental', b'worker.wdir-get-thread-safe', default=False,
733 b'experimental', b'worker.wdir-get-thread-safe', default=False,
735 )
734 )
736 coreconfigitem(
735 coreconfigitem(
737 b'experimental', b'worker.repository-upgrade', default=False,
736 b'experimental', b'worker.repository-upgrade', default=False,
738 )
737 )
739 coreconfigitem(
738 coreconfigitem(
740 b'experimental', b'xdiff', default=False,
739 b'experimental', b'xdiff', default=False,
741 )
740 )
742 coreconfigitem(
741 coreconfigitem(
743 b'extensions', b'.*', default=None, generic=True,
742 b'extensions', b'.*', default=None, generic=True,
744 )
743 )
745 coreconfigitem(
744 coreconfigitem(
746 b'extdata', b'.*', default=None, generic=True,
745 b'extdata', b'.*', default=None, generic=True,
747 )
746 )
748 coreconfigitem(
747 coreconfigitem(
749 b'format', b'bookmarks-in-store', default=False,
748 b'format', b'bookmarks-in-store', default=False,
750 )
749 )
751 coreconfigitem(
750 coreconfigitem(
752 b'format', b'chunkcachesize', default=None, experimental=True,
751 b'format', b'chunkcachesize', default=None, experimental=True,
753 )
752 )
754 coreconfigitem(
753 coreconfigitem(
755 b'format', b'dotencode', default=True,
754 b'format', b'dotencode', default=True,
756 )
755 )
757 coreconfigitem(
756 coreconfigitem(
758 b'format', b'generaldelta', default=False, experimental=True,
757 b'format', b'generaldelta', default=False, experimental=True,
759 )
758 )
760 coreconfigitem(
759 coreconfigitem(
761 b'format', b'manifestcachesize', default=None, experimental=True,
760 b'format', b'manifestcachesize', default=None, experimental=True,
762 )
761 )
763 coreconfigitem(
762 coreconfigitem(
764 b'format', b'maxchainlen', default=dynamicdefault, experimental=True,
763 b'format', b'maxchainlen', default=dynamicdefault, experimental=True,
765 )
764 )
766 coreconfigitem(
765 coreconfigitem(
767 b'format', b'obsstore-version', default=None,
766 b'format', b'obsstore-version', default=None,
768 )
767 )
769 coreconfigitem(
768 coreconfigitem(
770 b'format', b'sparse-revlog', default=True,
769 b'format', b'sparse-revlog', default=True,
771 )
770 )
772 coreconfigitem(
771 coreconfigitem(
773 b'format',
772 b'format',
774 b'revlog-compression',
773 b'revlog-compression',
775 default=lambda: [b'zlib'],
774 default=lambda: [b'zlib'],
776 alias=[(b'experimental', b'format.compression')],
775 alias=[(b'experimental', b'format.compression')],
777 )
776 )
778 coreconfigitem(
777 coreconfigitem(
779 b'format', b'usefncache', default=True,
778 b'format', b'usefncache', default=True,
780 )
779 )
781 coreconfigitem(
780 coreconfigitem(
782 b'format', b'usegeneraldelta', default=True,
781 b'format', b'usegeneraldelta', default=True,
783 )
782 )
784 coreconfigitem(
783 coreconfigitem(
785 b'format', b'usestore', default=True,
784 b'format', b'usestore', default=True,
786 )
785 )
787 coreconfigitem(
786 coreconfigitem(
788 b'format',
787 b'format',
789 b'exp-use-copies-side-data-changeset',
788 b'exp-use-copies-side-data-changeset',
790 default=False,
789 default=False,
791 experimental=True,
790 experimental=True,
792 )
791 )
793 coreconfigitem(
792 coreconfigitem(
794 b'format', b'exp-use-side-data', default=False, experimental=True,
793 b'format', b'exp-use-side-data', default=False, experimental=True,
795 )
794 )
796 coreconfigitem(
795 coreconfigitem(
797 b'format', b'internal-phase', default=False, experimental=True,
796 b'format', b'internal-phase', default=False, experimental=True,
798 )
797 )
799 coreconfigitem(
798 coreconfigitem(
800 b'fsmonitor', b'warn_when_unused', default=True,
799 b'fsmonitor', b'warn_when_unused', default=True,
801 )
800 )
802 coreconfigitem(
801 coreconfigitem(
803 b'fsmonitor', b'warn_update_file_count', default=50000,
802 b'fsmonitor', b'warn_update_file_count', default=50000,
804 )
803 )
805 coreconfigitem(
804 coreconfigitem(
806 b'help', br'hidden-command\..*', default=False, generic=True,
805 b'help', br'hidden-command\..*', default=False, generic=True,
807 )
806 )
808 coreconfigitem(
807 coreconfigitem(
809 b'help', br'hidden-topic\..*', default=False, generic=True,
808 b'help', br'hidden-topic\..*', default=False, generic=True,
810 )
809 )
811 coreconfigitem(
810 coreconfigitem(
812 b'hooks', b'.*', default=dynamicdefault, generic=True,
811 b'hooks', b'.*', default=dynamicdefault, generic=True,
813 )
812 )
814 coreconfigitem(
813 coreconfigitem(
815 b'hgweb-paths', b'.*', default=list, generic=True,
814 b'hgweb-paths', b'.*', default=list, generic=True,
816 )
815 )
817 coreconfigitem(
816 coreconfigitem(
818 b'hostfingerprints', b'.*', default=list, generic=True,
817 b'hostfingerprints', b'.*', default=list, generic=True,
819 )
818 )
820 coreconfigitem(
819 coreconfigitem(
821 b'hostsecurity', b'ciphers', default=None,
820 b'hostsecurity', b'ciphers', default=None,
822 )
821 )
823 coreconfigitem(
822 coreconfigitem(
824 b'hostsecurity', b'disabletls10warning', default=False,
823 b'hostsecurity', b'disabletls10warning', default=False,
825 )
824 )
826 coreconfigitem(
825 coreconfigitem(
827 b'hostsecurity', b'minimumprotocol', default=dynamicdefault,
826 b'hostsecurity', b'minimumprotocol', default=dynamicdefault,
828 )
827 )
829 coreconfigitem(
828 coreconfigitem(
830 b'hostsecurity',
829 b'hostsecurity',
831 b'.*:minimumprotocol$',
830 b'.*:minimumprotocol$',
832 default=dynamicdefault,
831 default=dynamicdefault,
833 generic=True,
832 generic=True,
834 )
833 )
835 coreconfigitem(
834 coreconfigitem(
836 b'hostsecurity', b'.*:ciphers$', default=dynamicdefault, generic=True,
835 b'hostsecurity', b'.*:ciphers$', default=dynamicdefault, generic=True,
837 )
836 )
838 coreconfigitem(
837 coreconfigitem(
839 b'hostsecurity', b'.*:fingerprints$', default=list, generic=True,
838 b'hostsecurity', b'.*:fingerprints$', default=list, generic=True,
840 )
839 )
841 coreconfigitem(
840 coreconfigitem(
842 b'hostsecurity', b'.*:verifycertsfile$', default=None, generic=True,
841 b'hostsecurity', b'.*:verifycertsfile$', default=None, generic=True,
843 )
842 )
844
843
845 coreconfigitem(
844 coreconfigitem(
846 b'http_proxy', b'always', default=False,
845 b'http_proxy', b'always', default=False,
847 )
846 )
848 coreconfigitem(
847 coreconfigitem(
849 b'http_proxy', b'host', default=None,
848 b'http_proxy', b'host', default=None,
850 )
849 )
851 coreconfigitem(
850 coreconfigitem(
852 b'http_proxy', b'no', default=list,
851 b'http_proxy', b'no', default=list,
853 )
852 )
854 coreconfigitem(
853 coreconfigitem(
855 b'http_proxy', b'passwd', default=None,
854 b'http_proxy', b'passwd', default=None,
856 )
855 )
857 coreconfigitem(
856 coreconfigitem(
858 b'http_proxy', b'user', default=None,
857 b'http_proxy', b'user', default=None,
859 )
858 )
860
859
861 coreconfigitem(
860 coreconfigitem(
862 b'http', b'timeout', default=None,
861 b'http', b'timeout', default=None,
863 )
862 )
864
863
865 coreconfigitem(
864 coreconfigitem(
866 b'logtoprocess', b'commandexception', default=None,
865 b'logtoprocess', b'commandexception', default=None,
867 )
866 )
868 coreconfigitem(
867 coreconfigitem(
869 b'logtoprocess', b'commandfinish', default=None,
868 b'logtoprocess', b'commandfinish', default=None,
870 )
869 )
871 coreconfigitem(
870 coreconfigitem(
872 b'logtoprocess', b'command', default=None,
871 b'logtoprocess', b'command', default=None,
873 )
872 )
874 coreconfigitem(
873 coreconfigitem(
875 b'logtoprocess', b'develwarn', default=None,
874 b'logtoprocess', b'develwarn', default=None,
876 )
875 )
877 coreconfigitem(
876 coreconfigitem(
878 b'logtoprocess', b'uiblocked', default=None,
877 b'logtoprocess', b'uiblocked', default=None,
879 )
878 )
880 coreconfigitem(
879 coreconfigitem(
881 b'merge', b'checkunknown', default=b'abort',
880 b'merge', b'checkunknown', default=b'abort',
882 )
881 )
883 coreconfigitem(
882 coreconfigitem(
884 b'merge', b'checkignored', default=b'abort',
883 b'merge', b'checkignored', default=b'abort',
885 )
884 )
886 coreconfigitem(
885 coreconfigitem(
887 b'experimental', b'merge.checkpathconflicts', default=False,
886 b'experimental', b'merge.checkpathconflicts', default=False,
888 )
887 )
889 coreconfigitem(
888 coreconfigitem(
890 b'merge', b'followcopies', default=True,
889 b'merge', b'followcopies', default=True,
891 )
890 )
892 coreconfigitem(
891 coreconfigitem(
893 b'merge', b'on-failure', default=b'continue',
892 b'merge', b'on-failure', default=b'continue',
894 )
893 )
895 coreconfigitem(
894 coreconfigitem(
896 b'merge', b'preferancestor', default=lambda: [b'*'], experimental=True,
895 b'merge', b'preferancestor', default=lambda: [b'*'], experimental=True,
897 )
896 )
898 coreconfigitem(
897 coreconfigitem(
899 b'merge', b'strict-capability-check', default=False,
898 b'merge', b'strict-capability-check', default=False,
900 )
899 )
901 coreconfigitem(
900 coreconfigitem(
902 b'merge-tools', b'.*', default=None, generic=True,
901 b'merge-tools', b'.*', default=None, generic=True,
903 )
902 )
904 coreconfigitem(
903 coreconfigitem(
905 b'merge-tools',
904 b'merge-tools',
906 br'.*\.args$',
905 br'.*\.args$',
907 default=b"$local $base $other",
906 default=b"$local $base $other",
908 generic=True,
907 generic=True,
909 priority=-1,
908 priority=-1,
910 )
909 )
911 coreconfigitem(
910 coreconfigitem(
912 b'merge-tools', br'.*\.binary$', default=False, generic=True, priority=-1,
911 b'merge-tools', br'.*\.binary$', default=False, generic=True, priority=-1,
913 )
912 )
914 coreconfigitem(
913 coreconfigitem(
915 b'merge-tools', br'.*\.check$', default=list, generic=True, priority=-1,
914 b'merge-tools', br'.*\.check$', default=list, generic=True, priority=-1,
916 )
915 )
917 coreconfigitem(
916 coreconfigitem(
918 b'merge-tools',
917 b'merge-tools',
919 br'.*\.checkchanged$',
918 br'.*\.checkchanged$',
920 default=False,
919 default=False,
921 generic=True,
920 generic=True,
922 priority=-1,
921 priority=-1,
923 )
922 )
924 coreconfigitem(
923 coreconfigitem(
925 b'merge-tools',
924 b'merge-tools',
926 br'.*\.executable$',
925 br'.*\.executable$',
927 default=dynamicdefault,
926 default=dynamicdefault,
928 generic=True,
927 generic=True,
929 priority=-1,
928 priority=-1,
930 )
929 )
931 coreconfigitem(
930 coreconfigitem(
932 b'merge-tools', br'.*\.fixeol$', default=False, generic=True, priority=-1,
931 b'merge-tools', br'.*\.fixeol$', default=False, generic=True, priority=-1,
933 )
932 )
934 coreconfigitem(
933 coreconfigitem(
935 b'merge-tools', br'.*\.gui$', default=False, generic=True, priority=-1,
934 b'merge-tools', br'.*\.gui$', default=False, generic=True, priority=-1,
936 )
935 )
937 coreconfigitem(
936 coreconfigitem(
938 b'merge-tools',
937 b'merge-tools',
939 br'.*\.mergemarkers$',
938 br'.*\.mergemarkers$',
940 default=b'basic',
939 default=b'basic',
941 generic=True,
940 generic=True,
942 priority=-1,
941 priority=-1,
943 )
942 )
944 coreconfigitem(
943 coreconfigitem(
945 b'merge-tools',
944 b'merge-tools',
946 br'.*\.mergemarkertemplate$',
945 br'.*\.mergemarkertemplate$',
947 default=dynamicdefault, # take from ui.mergemarkertemplate
946 default=dynamicdefault, # take from ui.mergemarkertemplate
948 generic=True,
947 generic=True,
949 priority=-1,
948 priority=-1,
950 )
949 )
951 coreconfigitem(
950 coreconfigitem(
952 b'merge-tools', br'.*\.priority$', default=0, generic=True, priority=-1,
951 b'merge-tools', br'.*\.priority$', default=0, generic=True, priority=-1,
953 )
952 )
954 coreconfigitem(
953 coreconfigitem(
955 b'merge-tools',
954 b'merge-tools',
956 br'.*\.premerge$',
955 br'.*\.premerge$',
957 default=dynamicdefault,
956 default=dynamicdefault,
958 generic=True,
957 generic=True,
959 priority=-1,
958 priority=-1,
960 )
959 )
961 coreconfigitem(
960 coreconfigitem(
962 b'merge-tools', br'.*\.symlink$', default=False, generic=True, priority=-1,
961 b'merge-tools', br'.*\.symlink$', default=False, generic=True, priority=-1,
963 )
962 )
964 coreconfigitem(
963 coreconfigitem(
965 b'pager', b'attend-.*', default=dynamicdefault, generic=True,
964 b'pager', b'attend-.*', default=dynamicdefault, generic=True,
966 )
965 )
967 coreconfigitem(
966 coreconfigitem(
968 b'pager', b'ignore', default=list,
967 b'pager', b'ignore', default=list,
969 )
968 )
970 coreconfigitem(
969 coreconfigitem(
971 b'pager', b'pager', default=dynamicdefault,
970 b'pager', b'pager', default=dynamicdefault,
972 )
971 )
973 coreconfigitem(
972 coreconfigitem(
974 b'patch', b'eol', default=b'strict',
973 b'patch', b'eol', default=b'strict',
975 )
974 )
976 coreconfigitem(
975 coreconfigitem(
977 b'patch', b'fuzz', default=2,
976 b'patch', b'fuzz', default=2,
978 )
977 )
979 coreconfigitem(
978 coreconfigitem(
980 b'paths', b'default', default=None,
979 b'paths', b'default', default=None,
981 )
980 )
982 coreconfigitem(
981 coreconfigitem(
983 b'paths', b'default-push', default=None,
982 b'paths', b'default-push', default=None,
984 )
983 )
985 coreconfigitem(
984 coreconfigitem(
986 b'paths', b'.*', default=None, generic=True,
985 b'paths', b'.*', default=None, generic=True,
987 )
986 )
988 coreconfigitem(
987 coreconfigitem(
989 b'phases', b'checksubrepos', default=b'follow',
988 b'phases', b'checksubrepos', default=b'follow',
990 )
989 )
991 coreconfigitem(
990 coreconfigitem(
992 b'phases', b'new-commit', default=b'draft',
991 b'phases', b'new-commit', default=b'draft',
993 )
992 )
994 coreconfigitem(
993 coreconfigitem(
995 b'phases', b'publish', default=True,
994 b'phases', b'publish', default=True,
996 )
995 )
997 coreconfigitem(
996 coreconfigitem(
998 b'profiling', b'enabled', default=False,
997 b'profiling', b'enabled', default=False,
999 )
998 )
1000 coreconfigitem(
999 coreconfigitem(
1001 b'profiling', b'format', default=b'text',
1000 b'profiling', b'format', default=b'text',
1002 )
1001 )
1003 coreconfigitem(
1002 coreconfigitem(
1004 b'profiling', b'freq', default=1000,
1003 b'profiling', b'freq', default=1000,
1005 )
1004 )
1006 coreconfigitem(
1005 coreconfigitem(
1007 b'profiling', b'limit', default=30,
1006 b'profiling', b'limit', default=30,
1008 )
1007 )
1009 coreconfigitem(
1008 coreconfigitem(
1010 b'profiling', b'nested', default=0,
1009 b'profiling', b'nested', default=0,
1011 )
1010 )
1012 coreconfigitem(
1011 coreconfigitem(
1013 b'profiling', b'output', default=None,
1012 b'profiling', b'output', default=None,
1014 )
1013 )
1015 coreconfigitem(
1014 coreconfigitem(
1016 b'profiling', b'showmax', default=0.999,
1015 b'profiling', b'showmax', default=0.999,
1017 )
1016 )
1018 coreconfigitem(
1017 coreconfigitem(
1019 b'profiling', b'showmin', default=dynamicdefault,
1018 b'profiling', b'showmin', default=dynamicdefault,
1020 )
1019 )
1021 coreconfigitem(
1020 coreconfigitem(
1022 b'profiling', b'showtime', default=True,
1021 b'profiling', b'showtime', default=True,
1023 )
1022 )
1024 coreconfigitem(
1023 coreconfigitem(
1025 b'profiling', b'sort', default=b'inlinetime',
1024 b'profiling', b'sort', default=b'inlinetime',
1026 )
1025 )
1027 coreconfigitem(
1026 coreconfigitem(
1028 b'profiling', b'statformat', default=b'hotpath',
1027 b'profiling', b'statformat', default=b'hotpath',
1029 )
1028 )
1030 coreconfigitem(
1029 coreconfigitem(
1031 b'profiling', b'time-track', default=dynamicdefault,
1030 b'profiling', b'time-track', default=dynamicdefault,
1032 )
1031 )
1033 coreconfigitem(
1032 coreconfigitem(
1034 b'profiling', b'type', default=b'stat',
1033 b'profiling', b'type', default=b'stat',
1035 )
1034 )
1036 coreconfigitem(
1035 coreconfigitem(
1037 b'progress', b'assume-tty', default=False,
1036 b'progress', b'assume-tty', default=False,
1038 )
1037 )
1039 coreconfigitem(
1038 coreconfigitem(
1040 b'progress', b'changedelay', default=1,
1039 b'progress', b'changedelay', default=1,
1041 )
1040 )
1042 coreconfigitem(
1041 coreconfigitem(
1043 b'progress', b'clear-complete', default=True,
1042 b'progress', b'clear-complete', default=True,
1044 )
1043 )
1045 coreconfigitem(
1044 coreconfigitem(
1046 b'progress', b'debug', default=False,
1045 b'progress', b'debug', default=False,
1047 )
1046 )
1048 coreconfigitem(
1047 coreconfigitem(
1049 b'progress', b'delay', default=3,
1048 b'progress', b'delay', default=3,
1050 )
1049 )
1051 coreconfigitem(
1050 coreconfigitem(
1052 b'progress', b'disable', default=False,
1051 b'progress', b'disable', default=False,
1053 )
1052 )
1054 coreconfigitem(
1053 coreconfigitem(
1055 b'progress', b'estimateinterval', default=60.0,
1054 b'progress', b'estimateinterval', default=60.0,
1056 )
1055 )
1057 coreconfigitem(
1056 coreconfigitem(
1058 b'progress',
1057 b'progress',
1059 b'format',
1058 b'format',
1060 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1059 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1061 )
1060 )
1062 coreconfigitem(
1061 coreconfigitem(
1063 b'progress', b'refresh', default=0.1,
1062 b'progress', b'refresh', default=0.1,
1064 )
1063 )
1065 coreconfigitem(
1064 coreconfigitem(
1066 b'progress', b'width', default=dynamicdefault,
1065 b'progress', b'width', default=dynamicdefault,
1067 )
1066 )
1068 coreconfigitem(
1067 coreconfigitem(
1069 b'pull', b'confirm', default=False,
1068 b'pull', b'confirm', default=False,
1070 )
1069 )
1071 coreconfigitem(
1070 coreconfigitem(
1072 b'push', b'pushvars.server', default=False,
1071 b'push', b'pushvars.server', default=False,
1073 )
1072 )
1074 coreconfigitem(
1073 coreconfigitem(
1075 b'rewrite',
1074 b'rewrite',
1076 b'backup-bundle',
1075 b'backup-bundle',
1077 default=True,
1076 default=True,
1078 alias=[(b'ui', b'history-editing-backup')],
1077 alias=[(b'ui', b'history-editing-backup')],
1079 )
1078 )
1080 coreconfigitem(
1079 coreconfigitem(
1081 b'rewrite', b'update-timestamp', default=False,
1080 b'rewrite', b'update-timestamp', default=False,
1082 )
1081 )
1083 coreconfigitem(
1082 coreconfigitem(
1084 b'storage', b'new-repo-backend', default=b'revlogv1', experimental=True,
1083 b'storage', b'new-repo-backend', default=b'revlogv1', experimental=True,
1085 )
1084 )
1086 coreconfigitem(
1085 coreconfigitem(
1087 b'storage',
1086 b'storage',
1088 b'revlog.optimize-delta-parent-choice',
1087 b'revlog.optimize-delta-parent-choice',
1089 default=True,
1088 default=True,
1090 alias=[(b'format', b'aggressivemergedeltas')],
1089 alias=[(b'format', b'aggressivemergedeltas')],
1091 )
1090 )
1092 coreconfigitem(
1091 coreconfigitem(
1093 b'storage', b'revlog.reuse-external-delta', default=True,
1092 b'storage', b'revlog.reuse-external-delta', default=True,
1094 )
1093 )
1095 coreconfigitem(
1094 coreconfigitem(
1096 b'storage', b'revlog.reuse-external-delta-parent', default=None,
1095 b'storage', b'revlog.reuse-external-delta-parent', default=None,
1097 )
1096 )
1098 coreconfigitem(
1097 coreconfigitem(
1099 b'storage', b'revlog.zlib.level', default=None,
1098 b'storage', b'revlog.zlib.level', default=None,
1100 )
1099 )
1101 coreconfigitem(
1100 coreconfigitem(
1102 b'storage', b'revlog.zstd.level', default=None,
1101 b'storage', b'revlog.zstd.level', default=None,
1103 )
1102 )
1104 coreconfigitem(
1103 coreconfigitem(
1105 b'server', b'bookmarks-pushkey-compat', default=True,
1104 b'server', b'bookmarks-pushkey-compat', default=True,
1106 )
1105 )
1107 coreconfigitem(
1106 coreconfigitem(
1108 b'server', b'bundle1', default=True,
1107 b'server', b'bundle1', default=True,
1109 )
1108 )
1110 coreconfigitem(
1109 coreconfigitem(
1111 b'server', b'bundle1gd', default=None,
1110 b'server', b'bundle1gd', default=None,
1112 )
1111 )
1113 coreconfigitem(
1112 coreconfigitem(
1114 b'server', b'bundle1.pull', default=None,
1113 b'server', b'bundle1.pull', default=None,
1115 )
1114 )
1116 coreconfigitem(
1115 coreconfigitem(
1117 b'server', b'bundle1gd.pull', default=None,
1116 b'server', b'bundle1gd.pull', default=None,
1118 )
1117 )
1119 coreconfigitem(
1118 coreconfigitem(
1120 b'server', b'bundle1.push', default=None,
1119 b'server', b'bundle1.push', default=None,
1121 )
1120 )
1122 coreconfigitem(
1121 coreconfigitem(
1123 b'server', b'bundle1gd.push', default=None,
1122 b'server', b'bundle1gd.push', default=None,
1124 )
1123 )
1125 coreconfigitem(
1124 coreconfigitem(
1126 b'server',
1125 b'server',
1127 b'bundle2.stream',
1126 b'bundle2.stream',
1128 default=True,
1127 default=True,
1129 alias=[(b'experimental', b'bundle2.stream')],
1128 alias=[(b'experimental', b'bundle2.stream')],
1130 )
1129 )
1131 coreconfigitem(
1130 coreconfigitem(
1132 b'server', b'compressionengines', default=list,
1131 b'server', b'compressionengines', default=list,
1133 )
1132 )
1134 coreconfigitem(
1133 coreconfigitem(
1135 b'server', b'concurrent-push-mode', default=b'check-related',
1134 b'server', b'concurrent-push-mode', default=b'check-related',
1136 )
1135 )
1137 coreconfigitem(
1136 coreconfigitem(
1138 b'server', b'disablefullbundle', default=False,
1137 b'server', b'disablefullbundle', default=False,
1139 )
1138 )
1140 coreconfigitem(
1139 coreconfigitem(
1141 b'server', b'maxhttpheaderlen', default=1024,
1140 b'server', b'maxhttpheaderlen', default=1024,
1142 )
1141 )
1143 coreconfigitem(
1142 coreconfigitem(
1144 b'server', b'pullbundle', default=False,
1143 b'server', b'pullbundle', default=False,
1145 )
1144 )
1146 coreconfigitem(
1145 coreconfigitem(
1147 b'server', b'preferuncompressed', default=False,
1146 b'server', b'preferuncompressed', default=False,
1148 )
1147 )
1149 coreconfigitem(
1148 coreconfigitem(
1150 b'server', b'streamunbundle', default=False,
1149 b'server', b'streamunbundle', default=False,
1151 )
1150 )
1152 coreconfigitem(
1151 coreconfigitem(
1153 b'server', b'uncompressed', default=True,
1152 b'server', b'uncompressed', default=True,
1154 )
1153 )
1155 coreconfigitem(
1154 coreconfigitem(
1156 b'server', b'uncompressedallowsecret', default=False,
1155 b'server', b'uncompressedallowsecret', default=False,
1157 )
1156 )
1158 coreconfigitem(
1157 coreconfigitem(
1159 b'server', b'view', default=b'served',
1158 b'server', b'view', default=b'served',
1160 )
1159 )
1161 coreconfigitem(
1160 coreconfigitem(
1162 b'server', b'validate', default=False,
1161 b'server', b'validate', default=False,
1163 )
1162 )
1164 coreconfigitem(
1163 coreconfigitem(
1165 b'server', b'zliblevel', default=-1,
1164 b'server', b'zliblevel', default=-1,
1166 )
1165 )
1167 coreconfigitem(
1166 coreconfigitem(
1168 b'server', b'zstdlevel', default=3,
1167 b'server', b'zstdlevel', default=3,
1169 )
1168 )
1170 coreconfigitem(
1169 coreconfigitem(
1171 b'share', b'pool', default=None,
1170 b'share', b'pool', default=None,
1172 )
1171 )
1173 coreconfigitem(
1172 coreconfigitem(
1174 b'share', b'poolnaming', default=b'identity',
1173 b'share', b'poolnaming', default=b'identity',
1175 )
1174 )
1176 coreconfigitem(
1175 coreconfigitem(
1177 b'shelve', b'maxbackups', default=10,
1176 b'shelve', b'maxbackups', default=10,
1178 )
1177 )
1179 coreconfigitem(
1178 coreconfigitem(
1180 b'smtp', b'host', default=None,
1179 b'smtp', b'host', default=None,
1181 )
1180 )
1182 coreconfigitem(
1181 coreconfigitem(
1183 b'smtp', b'local_hostname', default=None,
1182 b'smtp', b'local_hostname', default=None,
1184 )
1183 )
1185 coreconfigitem(
1184 coreconfigitem(
1186 b'smtp', b'password', default=None,
1185 b'smtp', b'password', default=None,
1187 )
1186 )
1188 coreconfigitem(
1187 coreconfigitem(
1189 b'smtp', b'port', default=dynamicdefault,
1188 b'smtp', b'port', default=dynamicdefault,
1190 )
1189 )
1191 coreconfigitem(
1190 coreconfigitem(
1192 b'smtp', b'tls', default=b'none',
1191 b'smtp', b'tls', default=b'none',
1193 )
1192 )
1194 coreconfigitem(
1193 coreconfigitem(
1195 b'smtp', b'username', default=None,
1194 b'smtp', b'username', default=None,
1196 )
1195 )
1197 coreconfigitem(
1196 coreconfigitem(
1198 b'sparse', b'missingwarning', default=True, experimental=True,
1197 b'sparse', b'missingwarning', default=True, experimental=True,
1199 )
1198 )
1200 coreconfigitem(
1199 coreconfigitem(
1201 b'subrepos',
1200 b'subrepos',
1202 b'allowed',
1201 b'allowed',
1203 default=dynamicdefault, # to make backporting simpler
1202 default=dynamicdefault, # to make backporting simpler
1204 )
1203 )
1205 coreconfigitem(
1204 coreconfigitem(
1206 b'subrepos', b'hg:allowed', default=dynamicdefault,
1205 b'subrepos', b'hg:allowed', default=dynamicdefault,
1207 )
1206 )
1208 coreconfigitem(
1207 coreconfigitem(
1209 b'subrepos', b'git:allowed', default=dynamicdefault,
1208 b'subrepos', b'git:allowed', default=dynamicdefault,
1210 )
1209 )
1211 coreconfigitem(
1210 coreconfigitem(
1212 b'subrepos', b'svn:allowed', default=dynamicdefault,
1211 b'subrepos', b'svn:allowed', default=dynamicdefault,
1213 )
1212 )
1214 coreconfigitem(
1213 coreconfigitem(
1215 b'templates', b'.*', default=None, generic=True,
1214 b'templates', b'.*', default=None, generic=True,
1216 )
1215 )
1217 coreconfigitem(
1216 coreconfigitem(
1218 b'templateconfig', b'.*', default=dynamicdefault, generic=True,
1217 b'templateconfig', b'.*', default=dynamicdefault, generic=True,
1219 )
1218 )
1220 coreconfigitem(
1219 coreconfigitem(
1221 b'trusted', b'groups', default=list,
1220 b'trusted', b'groups', default=list,
1222 )
1221 )
1223 coreconfigitem(
1222 coreconfigitem(
1224 b'trusted', b'users', default=list,
1223 b'trusted', b'users', default=list,
1225 )
1224 )
1226 coreconfigitem(
1225 coreconfigitem(
1227 b'ui', b'_usedassubrepo', default=False,
1226 b'ui', b'_usedassubrepo', default=False,
1228 )
1227 )
1229 coreconfigitem(
1228 coreconfigitem(
1230 b'ui', b'allowemptycommit', default=False,
1229 b'ui', b'allowemptycommit', default=False,
1231 )
1230 )
1232 coreconfigitem(
1231 coreconfigitem(
1233 b'ui', b'archivemeta', default=True,
1232 b'ui', b'archivemeta', default=True,
1234 )
1233 )
1235 coreconfigitem(
1234 coreconfigitem(
1236 b'ui', b'askusername', default=False,
1235 b'ui', b'askusername', default=False,
1237 )
1236 )
1238 coreconfigitem(
1237 coreconfigitem(
1239 b'ui', b'clonebundlefallback', default=False,
1238 b'ui', b'clonebundlefallback', default=False,
1240 )
1239 )
1241 coreconfigitem(
1240 coreconfigitem(
1242 b'ui', b'clonebundleprefers', default=list,
1241 b'ui', b'clonebundleprefers', default=list,
1243 )
1242 )
1244 coreconfigitem(
1243 coreconfigitem(
1245 b'ui', b'clonebundles', default=True,
1244 b'ui', b'clonebundles', default=True,
1246 )
1245 )
1247 coreconfigitem(
1246 coreconfigitem(
1248 b'ui', b'color', default=b'auto',
1247 b'ui', b'color', default=b'auto',
1249 )
1248 )
1250 coreconfigitem(
1249 coreconfigitem(
1251 b'ui', b'commitsubrepos', default=False,
1250 b'ui', b'commitsubrepos', default=False,
1252 )
1251 )
1253 coreconfigitem(
1252 coreconfigitem(
1254 b'ui', b'debug', default=False,
1253 b'ui', b'debug', default=False,
1255 )
1254 )
1256 coreconfigitem(
1255 coreconfigitem(
1257 b'ui', b'debugger', default=None,
1256 b'ui', b'debugger', default=None,
1258 )
1257 )
1259 coreconfigitem(
1258 coreconfigitem(
1260 b'ui', b'editor', default=dynamicdefault,
1259 b'ui', b'editor', default=dynamicdefault,
1261 )
1260 )
1262 coreconfigitem(
1261 coreconfigitem(
1263 b'ui', b'fallbackencoding', default=None,
1262 b'ui', b'fallbackencoding', default=None,
1264 )
1263 )
1265 coreconfigitem(
1264 coreconfigitem(
1266 b'ui', b'forcecwd', default=None,
1265 b'ui', b'forcecwd', default=None,
1267 )
1266 )
1268 coreconfigitem(
1267 coreconfigitem(
1269 b'ui', b'forcemerge', default=None,
1268 b'ui', b'forcemerge', default=None,
1270 )
1269 )
1271 coreconfigitem(
1270 coreconfigitem(
1272 b'ui', b'formatdebug', default=False,
1271 b'ui', b'formatdebug', default=False,
1273 )
1272 )
1274 coreconfigitem(
1273 coreconfigitem(
1275 b'ui', b'formatjson', default=False,
1274 b'ui', b'formatjson', default=False,
1276 )
1275 )
1277 coreconfigitem(
1276 coreconfigitem(
1278 b'ui', b'formatted', default=None,
1277 b'ui', b'formatted', default=None,
1279 )
1278 )
1280 coreconfigitem(
1279 coreconfigitem(
1281 b'ui', b'graphnodetemplate', default=None,
1280 b'ui', b'graphnodetemplate', default=None,
1282 )
1281 )
1283 coreconfigitem(
1282 coreconfigitem(
1284 b'ui', b'interactive', default=None,
1283 b'ui', b'interactive', default=None,
1285 )
1284 )
1286 coreconfigitem(
1285 coreconfigitem(
1287 b'ui', b'interface', default=None,
1286 b'ui', b'interface', default=None,
1288 )
1287 )
1289 coreconfigitem(
1288 coreconfigitem(
1290 b'ui', b'interface.chunkselector', default=None,
1289 b'ui', b'interface.chunkselector', default=None,
1291 )
1290 )
1292 coreconfigitem(
1291 coreconfigitem(
1293 b'ui', b'large-file-limit', default=10000000,
1292 b'ui', b'large-file-limit', default=10000000,
1294 )
1293 )
1295 coreconfigitem(
1294 coreconfigitem(
1296 b'ui', b'logblockedtimes', default=False,
1295 b'ui', b'logblockedtimes', default=False,
1297 )
1296 )
1298 coreconfigitem(
1297 coreconfigitem(
1299 b'ui', b'logtemplate', default=None,
1298 b'ui', b'logtemplate', default=None,
1300 )
1299 )
1301 coreconfigitem(
1300 coreconfigitem(
1302 b'ui', b'merge', default=None,
1301 b'ui', b'merge', default=None,
1303 )
1302 )
1304 coreconfigitem(
1303 coreconfigitem(
1305 b'ui', b'mergemarkers', default=b'basic',
1304 b'ui', b'mergemarkers', default=b'basic',
1306 )
1305 )
1307 coreconfigitem(
1306 coreconfigitem(
1308 b'ui',
1307 b'ui',
1309 b'mergemarkertemplate',
1308 b'mergemarkertemplate',
1310 default=(
1309 default=(
1311 b'{node|short} '
1310 b'{node|short} '
1312 b'{ifeq(tags, "tip", "", '
1311 b'{ifeq(tags, "tip", "", '
1313 b'ifeq(tags, "", "", "{tags} "))}'
1312 b'ifeq(tags, "", "", "{tags} "))}'
1314 b'{if(bookmarks, "{bookmarks} ")}'
1313 b'{if(bookmarks, "{bookmarks} ")}'
1315 b'{ifeq(branch, "default", "", "{branch} ")}'
1314 b'{ifeq(branch, "default", "", "{branch} ")}'
1316 b'- {author|user}: {desc|firstline}'
1315 b'- {author|user}: {desc|firstline}'
1317 ),
1316 ),
1318 )
1317 )
1319 coreconfigitem(
1318 coreconfigitem(
1320 b'ui', b'message-output', default=b'stdio',
1319 b'ui', b'message-output', default=b'stdio',
1321 )
1320 )
1322 coreconfigitem(
1321 coreconfigitem(
1323 b'ui', b'nontty', default=False,
1322 b'ui', b'nontty', default=False,
1324 )
1323 )
1325 coreconfigitem(
1324 coreconfigitem(
1326 b'ui', b'origbackuppath', default=None,
1325 b'ui', b'origbackuppath', default=None,
1327 )
1326 )
1328 coreconfigitem(
1327 coreconfigitem(
1329 b'ui', b'paginate', default=True,
1328 b'ui', b'paginate', default=True,
1330 )
1329 )
1331 coreconfigitem(
1330 coreconfigitem(
1332 b'ui', b'patch', default=None,
1331 b'ui', b'patch', default=None,
1333 )
1332 )
1334 coreconfigitem(
1333 coreconfigitem(
1335 b'ui', b'pre-merge-tool-output-template', default=None,
1334 b'ui', b'pre-merge-tool-output-template', default=None,
1336 )
1335 )
1337 coreconfigitem(
1336 coreconfigitem(
1338 b'ui', b'portablefilenames', default=b'warn',
1337 b'ui', b'portablefilenames', default=b'warn',
1339 )
1338 )
1340 coreconfigitem(
1339 coreconfigitem(
1341 b'ui', b'promptecho', default=False,
1340 b'ui', b'promptecho', default=False,
1342 )
1341 )
1343 coreconfigitem(
1342 coreconfigitem(
1344 b'ui', b'quiet', default=False,
1343 b'ui', b'quiet', default=False,
1345 )
1344 )
1346 coreconfigitem(
1345 coreconfigitem(
1347 b'ui', b'quietbookmarkmove', default=False,
1346 b'ui', b'quietbookmarkmove', default=False,
1348 )
1347 )
1349 coreconfigitem(
1348 coreconfigitem(
1350 b'ui', b'relative-paths', default=b'legacy',
1349 b'ui', b'relative-paths', default=b'legacy',
1351 )
1350 )
1352 coreconfigitem(
1351 coreconfigitem(
1353 b'ui', b'remotecmd', default=b'hg',
1352 b'ui', b'remotecmd', default=b'hg',
1354 )
1353 )
1355 coreconfigitem(
1354 coreconfigitem(
1356 b'ui', b'report_untrusted', default=True,
1355 b'ui', b'report_untrusted', default=True,
1357 )
1356 )
1358 coreconfigitem(
1357 coreconfigitem(
1359 b'ui', b'rollback', default=True,
1358 b'ui', b'rollback', default=True,
1360 )
1359 )
1361 coreconfigitem(
1360 coreconfigitem(
1362 b'ui', b'signal-safe-lock', default=True,
1361 b'ui', b'signal-safe-lock', default=True,
1363 )
1362 )
1364 coreconfigitem(
1363 coreconfigitem(
1365 b'ui', b'slash', default=False,
1364 b'ui', b'slash', default=False,
1366 )
1365 )
1367 coreconfigitem(
1366 coreconfigitem(
1368 b'ui', b'ssh', default=b'ssh',
1367 b'ui', b'ssh', default=b'ssh',
1369 )
1368 )
1370 coreconfigitem(
1369 coreconfigitem(
1371 b'ui', b'ssherrorhint', default=None,
1370 b'ui', b'ssherrorhint', default=None,
1372 )
1371 )
1373 coreconfigitem(
1372 coreconfigitem(
1374 b'ui', b'statuscopies', default=False,
1373 b'ui', b'statuscopies', default=False,
1375 )
1374 )
1376 coreconfigitem(
1375 coreconfigitem(
1377 b'ui', b'strict', default=False,
1376 b'ui', b'strict', default=False,
1378 )
1377 )
1379 coreconfigitem(
1378 coreconfigitem(
1380 b'ui', b'style', default=b'',
1379 b'ui', b'style', default=b'',
1381 )
1380 )
1382 coreconfigitem(
1381 coreconfigitem(
1383 b'ui', b'supportcontact', default=None,
1382 b'ui', b'supportcontact', default=None,
1384 )
1383 )
1385 coreconfigitem(
1384 coreconfigitem(
1386 b'ui', b'textwidth', default=78,
1385 b'ui', b'textwidth', default=78,
1387 )
1386 )
1388 coreconfigitem(
1387 coreconfigitem(
1389 b'ui', b'timeout', default=b'600',
1388 b'ui', b'timeout', default=b'600',
1390 )
1389 )
1391 coreconfigitem(
1390 coreconfigitem(
1392 b'ui', b'timeout.warn', default=0,
1391 b'ui', b'timeout.warn', default=0,
1393 )
1392 )
1394 coreconfigitem(
1393 coreconfigitem(
1395 b'ui', b'traceback', default=False,
1394 b'ui', b'traceback', default=False,
1396 )
1395 )
1397 coreconfigitem(
1396 coreconfigitem(
1398 b'ui', b'tweakdefaults', default=False,
1397 b'ui', b'tweakdefaults', default=False,
1399 )
1398 )
1400 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
1399 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
1401 coreconfigitem(
1400 coreconfigitem(
1402 b'ui', b'verbose', default=False,
1401 b'ui', b'verbose', default=False,
1403 )
1402 )
1404 coreconfigitem(
1403 coreconfigitem(
1405 b'verify', b'skipflags', default=None,
1404 b'verify', b'skipflags', default=None,
1406 )
1405 )
1407 coreconfigitem(
1406 coreconfigitem(
1408 b'web', b'allowbz2', default=False,
1407 b'web', b'allowbz2', default=False,
1409 )
1408 )
1410 coreconfigitem(
1409 coreconfigitem(
1411 b'web', b'allowgz', default=False,
1410 b'web', b'allowgz', default=False,
1412 )
1411 )
1413 coreconfigitem(
1412 coreconfigitem(
1414 b'web', b'allow-pull', alias=[(b'web', b'allowpull')], default=True,
1413 b'web', b'allow-pull', alias=[(b'web', b'allowpull')], default=True,
1415 )
1414 )
1416 coreconfigitem(
1415 coreconfigitem(
1417 b'web', b'allow-push', alias=[(b'web', b'allow_push')], default=list,
1416 b'web', b'allow-push', alias=[(b'web', b'allow_push')], default=list,
1418 )
1417 )
1419 coreconfigitem(
1418 coreconfigitem(
1420 b'web', b'allowzip', default=False,
1419 b'web', b'allowzip', default=False,
1421 )
1420 )
1422 coreconfigitem(
1421 coreconfigitem(
1423 b'web', b'archivesubrepos', default=False,
1422 b'web', b'archivesubrepos', default=False,
1424 )
1423 )
1425 coreconfigitem(
1424 coreconfigitem(
1426 b'web', b'cache', default=True,
1425 b'web', b'cache', default=True,
1427 )
1426 )
1428 coreconfigitem(
1427 coreconfigitem(
1429 b'web', b'comparisoncontext', default=5,
1428 b'web', b'comparisoncontext', default=5,
1430 )
1429 )
1431 coreconfigitem(
1430 coreconfigitem(
1432 b'web', b'contact', default=None,
1431 b'web', b'contact', default=None,
1433 )
1432 )
1434 coreconfigitem(
1433 coreconfigitem(
1435 b'web', b'deny_push', default=list,
1434 b'web', b'deny_push', default=list,
1436 )
1435 )
1437 coreconfigitem(
1436 coreconfigitem(
1438 b'web', b'guessmime', default=False,
1437 b'web', b'guessmime', default=False,
1439 )
1438 )
1440 coreconfigitem(
1439 coreconfigitem(
1441 b'web', b'hidden', default=False,
1440 b'web', b'hidden', default=False,
1442 )
1441 )
1443 coreconfigitem(
1442 coreconfigitem(
1444 b'web', b'labels', default=list,
1443 b'web', b'labels', default=list,
1445 )
1444 )
1446 coreconfigitem(
1445 coreconfigitem(
1447 b'web', b'logoimg', default=b'hglogo.png',
1446 b'web', b'logoimg', default=b'hglogo.png',
1448 )
1447 )
1449 coreconfigitem(
1448 coreconfigitem(
1450 b'web', b'logourl', default=b'https://mercurial-scm.org/',
1449 b'web', b'logourl', default=b'https://mercurial-scm.org/',
1451 )
1450 )
1452 coreconfigitem(
1451 coreconfigitem(
1453 b'web', b'accesslog', default=b'-',
1452 b'web', b'accesslog', default=b'-',
1454 )
1453 )
1455 coreconfigitem(
1454 coreconfigitem(
1456 b'web', b'address', default=b'',
1455 b'web', b'address', default=b'',
1457 )
1456 )
1458 coreconfigitem(
1457 coreconfigitem(
1459 b'web', b'allow-archive', alias=[(b'web', b'allow_archive')], default=list,
1458 b'web', b'allow-archive', alias=[(b'web', b'allow_archive')], default=list,
1460 )
1459 )
1461 coreconfigitem(
1460 coreconfigitem(
1462 b'web', b'allow_read', default=list,
1461 b'web', b'allow_read', default=list,
1463 )
1462 )
1464 coreconfigitem(
1463 coreconfigitem(
1465 b'web', b'baseurl', default=None,
1464 b'web', b'baseurl', default=None,
1466 )
1465 )
1467 coreconfigitem(
1466 coreconfigitem(
1468 b'web', b'cacerts', default=None,
1467 b'web', b'cacerts', default=None,
1469 )
1468 )
1470 coreconfigitem(
1469 coreconfigitem(
1471 b'web', b'certificate', default=None,
1470 b'web', b'certificate', default=None,
1472 )
1471 )
1473 coreconfigitem(
1472 coreconfigitem(
1474 b'web', b'collapse', default=False,
1473 b'web', b'collapse', default=False,
1475 )
1474 )
1476 coreconfigitem(
1475 coreconfigitem(
1477 b'web', b'csp', default=None,
1476 b'web', b'csp', default=None,
1478 )
1477 )
1479 coreconfigitem(
1478 coreconfigitem(
1480 b'web', b'deny_read', default=list,
1479 b'web', b'deny_read', default=list,
1481 )
1480 )
1482 coreconfigitem(
1481 coreconfigitem(
1483 b'web', b'descend', default=True,
1482 b'web', b'descend', default=True,
1484 )
1483 )
1485 coreconfigitem(
1484 coreconfigitem(
1486 b'web', b'description', default=b"",
1485 b'web', b'description', default=b"",
1487 )
1486 )
1488 coreconfigitem(
1487 coreconfigitem(
1489 b'web', b'encoding', default=lambda: encoding.encoding,
1488 b'web', b'encoding', default=lambda: encoding.encoding,
1490 )
1489 )
1491 coreconfigitem(
1490 coreconfigitem(
1492 b'web', b'errorlog', default=b'-',
1491 b'web', b'errorlog', default=b'-',
1493 )
1492 )
1494 coreconfigitem(
1493 coreconfigitem(
1495 b'web', b'ipv6', default=False,
1494 b'web', b'ipv6', default=False,
1496 )
1495 )
1497 coreconfigitem(
1496 coreconfigitem(
1498 b'web', b'maxchanges', default=10,
1497 b'web', b'maxchanges', default=10,
1499 )
1498 )
1500 coreconfigitem(
1499 coreconfigitem(
1501 b'web', b'maxfiles', default=10,
1500 b'web', b'maxfiles', default=10,
1502 )
1501 )
1503 coreconfigitem(
1502 coreconfigitem(
1504 b'web', b'maxshortchanges', default=60,
1503 b'web', b'maxshortchanges', default=60,
1505 )
1504 )
1506 coreconfigitem(
1505 coreconfigitem(
1507 b'web', b'motd', default=b'',
1506 b'web', b'motd', default=b'',
1508 )
1507 )
1509 coreconfigitem(
1508 coreconfigitem(
1510 b'web', b'name', default=dynamicdefault,
1509 b'web', b'name', default=dynamicdefault,
1511 )
1510 )
1512 coreconfigitem(
1511 coreconfigitem(
1513 b'web', b'port', default=8000,
1512 b'web', b'port', default=8000,
1514 )
1513 )
1515 coreconfigitem(
1514 coreconfigitem(
1516 b'web', b'prefix', default=b'',
1515 b'web', b'prefix', default=b'',
1517 )
1516 )
1518 coreconfigitem(
1517 coreconfigitem(
1519 b'web', b'push_ssl', default=True,
1518 b'web', b'push_ssl', default=True,
1520 )
1519 )
1521 coreconfigitem(
1520 coreconfigitem(
1522 b'web', b'refreshinterval', default=20,
1521 b'web', b'refreshinterval', default=20,
1523 )
1522 )
1524 coreconfigitem(
1523 coreconfigitem(
1525 b'web', b'server-header', default=None,
1524 b'web', b'server-header', default=None,
1526 )
1525 )
1527 coreconfigitem(
1526 coreconfigitem(
1528 b'web', b'static', default=None,
1527 b'web', b'static', default=None,
1529 )
1528 )
1530 coreconfigitem(
1529 coreconfigitem(
1531 b'web', b'staticurl', default=None,
1530 b'web', b'staticurl', default=None,
1532 )
1531 )
1533 coreconfigitem(
1532 coreconfigitem(
1534 b'web', b'stripes', default=1,
1533 b'web', b'stripes', default=1,
1535 )
1534 )
1536 coreconfigitem(
1535 coreconfigitem(
1537 b'web', b'style', default=b'paper',
1536 b'web', b'style', default=b'paper',
1538 )
1537 )
1539 coreconfigitem(
1538 coreconfigitem(
1540 b'web', b'templates', default=None,
1539 b'web', b'templates', default=None,
1541 )
1540 )
1542 coreconfigitem(
1541 coreconfigitem(
1543 b'web', b'view', default=b'served', experimental=True,
1542 b'web', b'view', default=b'served', experimental=True,
1544 )
1543 )
1545 coreconfigitem(
1544 coreconfigitem(
1546 b'worker', b'backgroundclose', default=dynamicdefault,
1545 b'worker', b'backgroundclose', default=dynamicdefault,
1547 )
1546 )
1548 # Windows defaults to a limit of 512 open files. A buffer of 128
1547 # Windows defaults to a limit of 512 open files. A buffer of 128
1549 # should give us enough headway.
1548 # should give us enough headway.
1550 coreconfigitem(
1549 coreconfigitem(
1551 b'worker', b'backgroundclosemaxqueue', default=384,
1550 b'worker', b'backgroundclosemaxqueue', default=384,
1552 )
1551 )
1553 coreconfigitem(
1552 coreconfigitem(
1554 b'worker', b'backgroundcloseminfilecount', default=2048,
1553 b'worker', b'backgroundcloseminfilecount', default=2048,
1555 )
1554 )
1556 coreconfigitem(
1555 coreconfigitem(
1557 b'worker', b'backgroundclosethreadcount', default=4,
1556 b'worker', b'backgroundclosethreadcount', default=4,
1558 )
1557 )
1559 coreconfigitem(
1558 coreconfigitem(
1560 b'worker', b'enabled', default=True,
1559 b'worker', b'enabled', default=True,
1561 )
1560 )
1562 coreconfigitem(
1561 coreconfigitem(
1563 b'worker', b'numcpus', default=None,
1562 b'worker', b'numcpus', default=None,
1564 )
1563 )
1565
1564
1566 # Rebase related configuration moved to core because other extension are doing
1565 # Rebase related configuration moved to core because other extension are doing
1567 # strange things. For example, shelve import the extensions to reuse some bit
1566 # strange things. For example, shelve import the extensions to reuse some bit
1568 # without formally loading it.
1567 # without formally loading it.
1569 coreconfigitem(
1568 coreconfigitem(
1570 b'commands', b'rebase.requiredest', default=False,
1569 b'commands', b'rebase.requiredest', default=False,
1571 )
1570 )
1572 coreconfigitem(
1571 coreconfigitem(
1573 b'experimental', b'rebaseskipobsolete', default=True,
1572 b'experimental', b'rebaseskipobsolete', default=True,
1574 )
1573 )
1575 coreconfigitem(
1574 coreconfigitem(
1576 b'rebase', b'singletransaction', default=False,
1575 b'rebase', b'singletransaction', default=False,
1577 )
1576 )
1578 coreconfigitem(
1577 coreconfigitem(
1579 b'rebase', b'experimental.inmemory', default=False,
1578 b'rebase', b'experimental.inmemory', default=False,
1580 )
1579 )
@@ -1,625 +1,628
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 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import errno
11 import errno
12 import os
12 import os
13 import re
13 import re
14 import struct
14 import struct
15
15
16 from .. import (
16 from .. import (
17 error,
17 error,
18 node as nodemod,
18 node as nodemod,
19 util,
19 util,
20 )
20 )
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 persisted_data(revlog):
28 def persisted_data(revlog):
29 """read the nodemap for a revlog from disk"""
29 """read the nodemap for a revlog from disk"""
30 if revlog.nodemap_file is None:
30 if revlog.nodemap_file is None:
31 return None
31 return None
32 pdata = revlog.opener.tryread(revlog.nodemap_file)
32 pdata = revlog.opener.tryread(revlog.nodemap_file)
33 if not pdata:
33 if not pdata:
34 return None
34 return None
35 offset = 0
35 offset = 0
36 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size])
36 (version,) = S_VERSION.unpack(pdata[offset : offset + S_VERSION.size])
37 if version != ONDISK_VERSION:
37 if version != ONDISK_VERSION:
38 return None
38 return None
39 offset += S_VERSION.size
39 offset += S_VERSION.size
40 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
40 headers = S_HEADER.unpack(pdata[offset : offset + S_HEADER.size])
41 uid_size, tip_rev, data_length, data_unused, tip_node_size = headers
41 uid_size, tip_rev, data_length, data_unused, tip_node_size = headers
42 offset += S_HEADER.size
42 offset += S_HEADER.size
43 docket = NodeMapDocket(pdata[offset : offset + uid_size])
43 docket = NodeMapDocket(pdata[offset : offset + uid_size])
44 offset += uid_size
44 offset += uid_size
45 docket.tip_rev = tip_rev
45 docket.tip_rev = tip_rev
46 docket.tip_node = pdata[offset : offset + tip_node_size]
46 docket.tip_node = pdata[offset : offset + tip_node_size]
47 docket.data_length = data_length
47 docket.data_length = data_length
48 docket.data_unused = data_unused
48 docket.data_unused = data_unused
49
49
50 filename = _rawdata_filepath(revlog, docket)
50 filename = _rawdata_filepath(revlog, docket)
51 use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap")
51 use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap")
52 try:
52 try:
53 with revlog.opener(filename) as fd:
53 with revlog.opener(filename) as fd:
54 if use_mmap:
54 if use_mmap:
55 data = util.buffer(util.mmapread(fd, data_length))
55 data = util.buffer(util.mmapread(fd, data_length))
56 else:
56 else:
57 data = fd.read(data_length)
57 data = fd.read(data_length)
58 except OSError as e:
58 except OSError as e:
59 if e.errno != errno.ENOENT:
59 if e.errno != errno.ENOENT:
60 raise
60 raise
61 if len(data) < data_length:
61 if len(data) < data_length:
62 return None
62 return None
63 return docket, data
63 return docket, data
64
64
65
65
66 def setup_persistent_nodemap(tr, revlog):
66 def setup_persistent_nodemap(tr, revlog):
67 """Install whatever is needed transaction side to persist a nodemap on disk
67 """Install whatever is needed transaction side to persist a nodemap on disk
68
68
69 (only actually persist the nodemap if this is relevant for this revlog)
69 (only actually persist the nodemap if this is relevant for this revlog)
70 """
70 """
71 if revlog._inline:
71 if revlog._inline:
72 return # inlined revlog are too small for this to be relevant
72 return # inlined revlog are too small for this to be relevant
73 if revlog.nodemap_file is None:
73 if revlog.nodemap_file is None:
74 return # we do not use persistent_nodemap on this revlog
74 return # we do not use persistent_nodemap on this revlog
75
75
76 # we need to happen after the changelog finalization, in that use "cl-"
76 # we need to happen after the changelog finalization, in that use "cl-"
77 callback_id = b"nm-revlog-persistent-nodemap-%s" % revlog.nodemap_file
77 callback_id = b"nm-revlog-persistent-nodemap-%s" % revlog.nodemap_file
78 if tr.hasfinalize(callback_id):
78 if tr.hasfinalize(callback_id):
79 return # no need to register again
79 return # no need to register again
80 tr.addpending(
80 tr.addpending(
81 callback_id, lambda tr: _persist_nodemap(tr, revlog, pending=True)
81 callback_id, lambda tr: _persist_nodemap(tr, revlog, pending=True)
82 )
82 )
83 tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog))
83 tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog))
84
84
85
85
86 class _NoTransaction(object):
86 class _NoTransaction(object):
87 """transaction like object to update the nodemap outside a transaction
87 """transaction like object to update the nodemap outside a transaction
88 """
88 """
89
89
90 def __init__(self):
90 def __init__(self):
91 self._postclose = {}
91 self._postclose = {}
92
92
93 def addpostclose(self, callback_id, callback_func):
93 def addpostclose(self, callback_id, callback_func):
94 self._postclose[callback_id] = callback_func
94 self._postclose[callback_id] = callback_func
95
95
96 def registertmp(self, *args, **kwargs):
96 def registertmp(self, *args, **kwargs):
97 pass
97 pass
98
98
99 def addbackup(self, *args, **kwargs):
99 def addbackup(self, *args, **kwargs):
100 pass
100 pass
101
101
102 def add(self, *args, **kwargs):
102 def add(self, *args, **kwargs):
103 pass
103 pass
104
104
105 def addabort(self, *args, **kwargs):
105 def addabort(self, *args, **kwargs):
106 pass
106 pass
107
107
108
108
109 def update_persistent_nodemap(revlog):
109 def update_persistent_nodemap(revlog):
110 """update the persistent nodemap right now
110 """update the persistent nodemap right now
111
111
112 To be used for updating the nodemap on disk outside of a normal transaction
112 To be used for updating the nodemap on disk outside of a normal transaction
113 setup (eg, `debugupdatecache`).
113 setup (eg, `debugupdatecache`).
114 """
114 """
115 notr = _NoTransaction()
115 notr = _NoTransaction()
116 _persist_nodemap(notr, revlog)
116 _persist_nodemap(notr, revlog)
117 for k in sorted(notr._postclose):
117 for k in sorted(notr._postclose):
118 notr._postclose[k](None)
118 notr._postclose[k](None)
119
119
120
120
121 def _persist_nodemap(tr, revlog, pending=False):
121 def _persist_nodemap(tr, revlog, pending=False):
122 """Write nodemap data on disk for a given revlog
122 """Write nodemap data on disk for a given revlog
123 """
123 """
124 if getattr(revlog, 'filteredrevs', ()):
124 if getattr(revlog, 'filteredrevs', ()):
125 raise error.ProgrammingError(
125 raise error.ProgrammingError(
126 "cannot persist nodemap of a filtered changelog"
126 "cannot persist nodemap of a filtered changelog"
127 )
127 )
128 if revlog.nodemap_file is None:
128 if revlog.nodemap_file is None:
129 msg = "calling persist nodemap on a revlog without the feature enableb"
129 msg = "calling persist nodemap on a revlog without the feature enableb"
130 raise error.ProgrammingError(msg)
130 raise error.ProgrammingError(msg)
131
131
132 can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental")
132 can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental")
133 ondisk_docket = revlog._nodemap_docket
133 ondisk_docket = revlog._nodemap_docket
134 feed_data = util.safehasattr(revlog.index, "update_nodemap_data")
134 feed_data = util.safehasattr(revlog.index, "update_nodemap_data")
135 use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap")
135 use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap")
136
136
137 data = None
137 data = None
138 # first attemp an incremental update of the data
138 # first attemp an incremental update of the data
139 if can_incremental and ondisk_docket is not None:
139 if can_incremental and ondisk_docket is not None:
140 target_docket = revlog._nodemap_docket.copy()
140 target_docket = revlog._nodemap_docket.copy()
141 (
141 (
142 src_docket,
142 src_docket,
143 data_changed_count,
143 data_changed_count,
144 data,
144 data,
145 ) = revlog.index.nodemap_data_incremental()
145 ) = revlog.index.nodemap_data_incremental()
146 new_length = target_docket.data_length + len(data)
147 new_unused = target_docket.data_unused + data_changed_count
146 if src_docket != target_docket:
148 if src_docket != target_docket:
147 data = None
149 data = None
150 elif new_length <= (new_unused * 10): # under 10% of unused data
151 data = None
148 else:
152 else:
149 datafile = _rawdata_filepath(revlog, target_docket)
153 datafile = _rawdata_filepath(revlog, target_docket)
150 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
154 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
151 # store vfs
155 # store vfs
152 new_length = target_docket.data_length + len(data)
153 tr.add(datafile, target_docket.data_length)
156 tr.add(datafile, target_docket.data_length)
154 with revlog.opener(datafile, b'r+') as fd:
157 with revlog.opener(datafile, b'r+') as fd:
155 fd.seek(target_docket.data_length)
158 fd.seek(target_docket.data_length)
156 fd.write(data)
159 fd.write(data)
157 if feed_data:
160 if feed_data:
158 if use_mmap:
161 if use_mmap:
159 fd.seek(0)
162 fd.seek(0)
160 new_data = fd.read(new_length)
163 new_data = fd.read(new_length)
161 else:
164 else:
162 fd.flush()
165 fd.flush()
163 new_data = util.buffer(util.mmapread(fd, new_length))
166 new_data = util.buffer(util.mmapread(fd, new_length))
164 target_docket.data_length = new_length
167 target_docket.data_length = new_length
165 target_docket.data_unused += data_changed_count
168 target_docket.data_unused = new_unused
166
169
167 if data is None:
170 if data is None:
168 # otherwise fallback to a full new export
171 # otherwise fallback to a full new export
169 target_docket = NodeMapDocket()
172 target_docket = NodeMapDocket()
170 datafile = _rawdata_filepath(revlog, target_docket)
173 datafile = _rawdata_filepath(revlog, target_docket)
171 if util.safehasattr(revlog.index, "nodemap_data_all"):
174 if util.safehasattr(revlog.index, "nodemap_data_all"):
172 data = revlog.index.nodemap_data_all()
175 data = revlog.index.nodemap_data_all()
173 else:
176 else:
174 data = persistent_data(revlog.index)
177 data = persistent_data(revlog.index)
175 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
178 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
176 # store vfs
179 # store vfs
177
180
178 tryunlink = revlog.opener.tryunlink
181 tryunlink = revlog.opener.tryunlink
179
182
180 def abortck(tr):
183 def abortck(tr):
181 tryunlink(datafile)
184 tryunlink(datafile)
182
185
183 callback_id = b"delete-%s" % datafile
186 callback_id = b"delete-%s" % datafile
184
187
185 # some flavor of the transaction abort does not cleanup new file, it
188 # some flavor of the transaction abort does not cleanup new file, it
186 # simply empty them.
189 # simply empty them.
187 tr.addabort(callback_id, abortck)
190 tr.addabort(callback_id, abortck)
188 with revlog.opener(datafile, b'w+') as fd:
191 with revlog.opener(datafile, b'w+') as fd:
189 fd.write(data)
192 fd.write(data)
190 if feed_data:
193 if feed_data:
191 if use_mmap:
194 if use_mmap:
192 new_data = data
195 new_data = data
193 else:
196 else:
194 fd.flush()
197 fd.flush()
195 new_data = util.buffer(util.mmapread(fd, len(data)))
198 new_data = util.buffer(util.mmapread(fd, len(data)))
196 target_docket.data_length = len(data)
199 target_docket.data_length = len(data)
197 target_docket.tip_rev = revlog.tiprev()
200 target_docket.tip_rev = revlog.tiprev()
198 target_docket.tip_node = revlog.node(target_docket.tip_rev)
201 target_docket.tip_node = revlog.node(target_docket.tip_rev)
199 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
202 # EXP-TODO: if this is a cache, this should use a cache vfs, not a
200 # store vfs
203 # store vfs
201 file_path = revlog.nodemap_file
204 file_path = revlog.nodemap_file
202 if pending:
205 if pending:
203 file_path += b'.a'
206 file_path += b'.a'
204 tr.registertmp(file_path)
207 tr.registertmp(file_path)
205 else:
208 else:
206 tr.addbackup(file_path)
209 tr.addbackup(file_path)
207
210
208 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
211 with revlog.opener(file_path, b'w', atomictemp=True) as fp:
209 fp.write(target_docket.serialize())
212 fp.write(target_docket.serialize())
210 revlog._nodemap_docket = target_docket
213 revlog._nodemap_docket = target_docket
211 if feed_data:
214 if feed_data:
212 revlog.index.update_nodemap_data(target_docket, new_data)
215 revlog.index.update_nodemap_data(target_docket, new_data)
213
216
214 # search for old index file in all cases, some older process might have
217 # search for old index file in all cases, some older process might have
215 # left one behind.
218 # left one behind.
216 olds = _other_rawdata_filepath(revlog, target_docket)
219 olds = _other_rawdata_filepath(revlog, target_docket)
217 if olds:
220 if olds:
218 realvfs = getattr(revlog, '_realopener', revlog.opener)
221 realvfs = getattr(revlog, '_realopener', revlog.opener)
219
222
220 def cleanup(tr):
223 def cleanup(tr):
221 for oldfile in olds:
224 for oldfile in olds:
222 realvfs.tryunlink(oldfile)
225 realvfs.tryunlink(oldfile)
223
226
224 callback_id = b"revlog-cleanup-nodemap-%s" % revlog.nodemap_file
227 callback_id = b"revlog-cleanup-nodemap-%s" % revlog.nodemap_file
225 tr.addpostclose(callback_id, cleanup)
228 tr.addpostclose(callback_id, cleanup)
226
229
227
230
228 ### Nodemap docket file
231 ### Nodemap docket file
229 #
232 #
230 # The nodemap data are stored on disk using 2 files:
233 # The nodemap data are stored on disk using 2 files:
231 #
234 #
232 # * a raw data files containing a persistent nodemap
235 # * a raw data files containing a persistent nodemap
233 # (see `Nodemap Trie` section)
236 # (see `Nodemap Trie` section)
234 #
237 #
235 # * a small "docket" file containing medatadata
238 # * a small "docket" file containing medatadata
236 #
239 #
237 # While the nodemap data can be multiple tens of megabytes, the "docket" is
240 # While the nodemap data can be multiple tens of megabytes, the "docket" is
238 # small, it is easy to update it automatically or to duplicated its content
241 # small, it is easy to update it automatically or to duplicated its content
239 # during a transaction.
242 # during a transaction.
240 #
243 #
241 # Multiple raw data can exist at the same time (The currently valid one and a
244 # Multiple raw data can exist at the same time (The currently valid one and a
242 # new one beind used by an in progress transaction). To accomodate this, the
245 # new one beind used by an in progress transaction). To accomodate this, the
243 # filename hosting the raw data has a variable parts. The exact filename is
246 # filename hosting the raw data has a variable parts. The exact filename is
244 # specified inside the "docket" file.
247 # specified inside the "docket" file.
245 #
248 #
246 # The docket file contains information to find, qualify and validate the raw
249 # The docket file contains information to find, qualify and validate the raw
247 # data. Its content is currently very light, but it will expand as the on disk
250 # data. Its content is currently very light, but it will expand as the on disk
248 # nodemap gains the necessary features to be used in production.
251 # nodemap gains the necessary features to be used in production.
249
252
250 # version 0 is experimental, no BC garantee, do no use outside of tests.
253 # version 0 is experimental, no BC garantee, do no use outside of tests.
251 ONDISK_VERSION = 0
254 ONDISK_VERSION = 0
252 S_VERSION = struct.Struct(">B")
255 S_VERSION = struct.Struct(">B")
253 S_HEADER = struct.Struct(">BQQQQ")
256 S_HEADER = struct.Struct(">BQQQQ")
254
257
255 ID_SIZE = 8
258 ID_SIZE = 8
256
259
257
260
258 def _make_uid():
261 def _make_uid():
259 """return a new unique identifier.
262 """return a new unique identifier.
260
263
261 The identifier is random and composed of ascii characters."""
264 The identifier is random and composed of ascii characters."""
262 return nodemod.hex(os.urandom(ID_SIZE))
265 return nodemod.hex(os.urandom(ID_SIZE))
263
266
264
267
265 class NodeMapDocket(object):
268 class NodeMapDocket(object):
266 """metadata associated with persistent nodemap data
269 """metadata associated with persistent nodemap data
267
270
268 The persistent data may come from disk or be on their way to disk.
271 The persistent data may come from disk or be on their way to disk.
269 """
272 """
270
273
271 def __init__(self, uid=None):
274 def __init__(self, uid=None):
272 if uid is None:
275 if uid is None:
273 uid = _make_uid()
276 uid = _make_uid()
274 # a unique identifier for the data file:
277 # a unique identifier for the data file:
275 # - When new data are appended, it is preserved.
278 # - When new data are appended, it is preserved.
276 # - When a new data file is created, a new identifier is generated.
279 # - When a new data file is created, a new identifier is generated.
277 self.uid = uid
280 self.uid = uid
278 # the tipmost revision stored in the data file. This revision and all
281 # the tipmost revision stored in the data file. This revision and all
279 # revision before it are expected to be encoded in the data file.
282 # revision before it are expected to be encoded in the data file.
280 self.tip_rev = None
283 self.tip_rev = None
281 # the node of that tipmost revision, if it mismatch the current index
284 # the node of that tipmost revision, if it mismatch the current index
282 # data the docket is not valid for the current index and should be
285 # data the docket is not valid for the current index and should be
283 # discarded.
286 # discarded.
284 #
287 #
285 # note: this method is not perfect as some destructive operation could
288 # note: this method is not perfect as some destructive operation could
286 # preserve the same tip_rev + tip_node while altering lower revision.
289 # preserve the same tip_rev + tip_node while altering lower revision.
287 # However this multiple other caches have the same vulnerability (eg:
290 # However this multiple other caches have the same vulnerability (eg:
288 # brancmap cache).
291 # brancmap cache).
289 self.tip_node = None
292 self.tip_node = None
290 # the size (in bytes) of the persisted data to encode the nodemap valid
293 # the size (in bytes) of the persisted data to encode the nodemap valid
291 # for `tip_rev`.
294 # for `tip_rev`.
292 # - data file shorter than this are corrupted,
295 # - data file shorter than this are corrupted,
293 # - any extra data should be ignored.
296 # - any extra data should be ignored.
294 self.data_length = None
297 self.data_length = None
295 # the amount (in bytes) of "dead" data, still in the data file but no
298 # the amount (in bytes) of "dead" data, still in the data file but no
296 # longer used for the nodemap.
299 # longer used for the nodemap.
297 self.data_unused = 0
300 self.data_unused = 0
298
301
299 def copy(self):
302 def copy(self):
300 new = NodeMapDocket(uid=self.uid)
303 new = NodeMapDocket(uid=self.uid)
301 new.tip_rev = self.tip_rev
304 new.tip_rev = self.tip_rev
302 new.tip_node = self.tip_node
305 new.tip_node = self.tip_node
303 new.data_length = self.data_length
306 new.data_length = self.data_length
304 new.data_unused = self.data_unused
307 new.data_unused = self.data_unused
305 return new
308 return new
306
309
307 def __cmp__(self, other):
310 def __cmp__(self, other):
308 if self.uid < other.uid:
311 if self.uid < other.uid:
309 return -1
312 return -1
310 if self.uid > other.uid:
313 if self.uid > other.uid:
311 return 1
314 return 1
312 elif self.data_length < other.data_length:
315 elif self.data_length < other.data_length:
313 return -1
316 return -1
314 elif self.data_length > other.data_length:
317 elif self.data_length > other.data_length:
315 return 1
318 return 1
316 return 0
319 return 0
317
320
318 def __eq__(self, other):
321 def __eq__(self, other):
319 return self.uid == other.uid and self.data_length == other.data_length
322 return self.uid == other.uid and self.data_length == other.data_length
320
323
321 def serialize(self):
324 def serialize(self):
322 """return serialized bytes for a docket using the passed uid"""
325 """return serialized bytes for a docket using the passed uid"""
323 data = []
326 data = []
324 data.append(S_VERSION.pack(ONDISK_VERSION))
327 data.append(S_VERSION.pack(ONDISK_VERSION))
325 headers = (
328 headers = (
326 len(self.uid),
329 len(self.uid),
327 self.tip_rev,
330 self.tip_rev,
328 self.data_length,
331 self.data_length,
329 self.data_unused,
332 self.data_unused,
330 len(self.tip_node),
333 len(self.tip_node),
331 )
334 )
332 data.append(S_HEADER.pack(*headers))
335 data.append(S_HEADER.pack(*headers))
333 data.append(self.uid)
336 data.append(self.uid)
334 data.append(self.tip_node)
337 data.append(self.tip_node)
335 return b''.join(data)
338 return b''.join(data)
336
339
337
340
338 def _rawdata_filepath(revlog, docket):
341 def _rawdata_filepath(revlog, docket):
339 """The (vfs relative) nodemap's rawdata file for a given uid"""
342 """The (vfs relative) nodemap's rawdata file for a given uid"""
340 if revlog.nodemap_file.endswith(b'.n.a'):
343 if revlog.nodemap_file.endswith(b'.n.a'):
341 prefix = revlog.nodemap_file[:-4]
344 prefix = revlog.nodemap_file[:-4]
342 else:
345 else:
343 prefix = revlog.nodemap_file[:-2]
346 prefix = revlog.nodemap_file[:-2]
344 return b"%s-%s.nd" % (prefix, docket.uid)
347 return b"%s-%s.nd" % (prefix, docket.uid)
345
348
346
349
347 def _other_rawdata_filepath(revlog, docket):
350 def _other_rawdata_filepath(revlog, docket):
348 prefix = revlog.nodemap_file[:-2]
351 prefix = revlog.nodemap_file[:-2]
349 pattern = re.compile(br"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
352 pattern = re.compile(br"(^|/)%s-[0-9a-f]+\.nd$" % prefix)
350 new_file_path = _rawdata_filepath(revlog, docket)
353 new_file_path = _rawdata_filepath(revlog, docket)
351 new_file_name = revlog.opener.basename(new_file_path)
354 new_file_name = revlog.opener.basename(new_file_path)
352 dirpath = revlog.opener.dirname(new_file_path)
355 dirpath = revlog.opener.dirname(new_file_path)
353 others = []
356 others = []
354 for f in revlog.opener.listdir(dirpath):
357 for f in revlog.opener.listdir(dirpath):
355 if pattern.match(f) and f != new_file_name:
358 if pattern.match(f) and f != new_file_name:
356 others.append(f)
359 others.append(f)
357 return others
360 return others
358
361
359
362
360 ### Nodemap Trie
363 ### Nodemap Trie
361 #
364 #
362 # This is a simple reference implementation to compute and persist a nodemap
365 # This is a simple reference implementation to compute and persist a nodemap
363 # trie. This reference implementation is write only. The python version of this
366 # trie. This reference implementation is write only. The python version of this
364 # is not expected to be actually used, since it wont provide performance
367 # is not expected to be actually used, since it wont provide performance
365 # improvement over existing non-persistent C implementation.
368 # improvement over existing non-persistent C implementation.
366 #
369 #
367 # The nodemap is persisted as Trie using 4bits-address/16-entries block. each
370 # The nodemap is persisted as Trie using 4bits-address/16-entries block. each
368 # revision can be adressed using its node shortest prefix.
371 # revision can be adressed using its node shortest prefix.
369 #
372 #
370 # The trie is stored as a sequence of block. Each block contains 16 entries
373 # The trie is stored as a sequence of block. Each block contains 16 entries
371 # (signed 64bit integer, big endian). Each entry can be one of the following:
374 # (signed 64bit integer, big endian). Each entry can be one of the following:
372 #
375 #
373 # * value >= 0 -> index of sub-block
376 # * value >= 0 -> index of sub-block
374 # * value == -1 -> no value
377 # * value == -1 -> no value
375 # * value < -1 -> a revision value: rev = -(value+10)
378 # * value < -1 -> a revision value: rev = -(value+10)
376 #
379 #
377 # The implementation focus on simplicity, not on performance. A Rust
380 # The implementation focus on simplicity, not on performance. A Rust
378 # implementation should provide a efficient version of the same binary
381 # implementation should provide a efficient version of the same binary
379 # persistence. This reference python implementation is never meant to be
382 # persistence. This reference python implementation is never meant to be
380 # extensively use in production.
383 # extensively use in production.
381
384
382
385
383 def persistent_data(index):
386 def persistent_data(index):
384 """return the persistent binary form for a nodemap for a given index
387 """return the persistent binary form for a nodemap for a given index
385 """
388 """
386 trie = _build_trie(index)
389 trie = _build_trie(index)
387 return _persist_trie(trie)
390 return _persist_trie(trie)
388
391
389
392
390 def update_persistent_data(index, root, max_idx, last_rev):
393 def update_persistent_data(index, root, max_idx, last_rev):
391 """return the incremental update for persistent nodemap from a given index
394 """return the incremental update for persistent nodemap from a given index
392 """
395 """
393 changed_block, trie = _update_trie(index, root, last_rev)
396 changed_block, trie = _update_trie(index, root, last_rev)
394 return (
397 return (
395 changed_block * S_BLOCK.size,
398 changed_block * S_BLOCK.size,
396 _persist_trie(trie, existing_idx=max_idx),
399 _persist_trie(trie, existing_idx=max_idx),
397 )
400 )
398
401
399
402
400 S_BLOCK = struct.Struct(">" + ("l" * 16))
403 S_BLOCK = struct.Struct(">" + ("l" * 16))
401
404
402 NO_ENTRY = -1
405 NO_ENTRY = -1
403 # rev 0 need to be -2 because 0 is used by block, -1 is a special value.
406 # rev 0 need to be -2 because 0 is used by block, -1 is a special value.
404 REV_OFFSET = 2
407 REV_OFFSET = 2
405
408
406
409
407 def _transform_rev(rev):
410 def _transform_rev(rev):
408 """Return the number used to represent the rev in the tree.
411 """Return the number used to represent the rev in the tree.
409
412
410 (or retrieve a rev number from such representation)
413 (or retrieve a rev number from such representation)
411
414
412 Note that this is an involution, a function equal to its inverse (i.e.
415 Note that this is an involution, a function equal to its inverse (i.e.
413 which gives the identity when applied to itself).
416 which gives the identity when applied to itself).
414 """
417 """
415 return -(rev + REV_OFFSET)
418 return -(rev + REV_OFFSET)
416
419
417
420
418 def _to_int(hex_digit):
421 def _to_int(hex_digit):
419 """turn an hexadecimal digit into a proper integer"""
422 """turn an hexadecimal digit into a proper integer"""
420 return int(hex_digit, 16)
423 return int(hex_digit, 16)
421
424
422
425
423 class Block(dict):
426 class Block(dict):
424 """represent a block of the Trie
427 """represent a block of the Trie
425
428
426 contains up to 16 entry indexed from 0 to 15"""
429 contains up to 16 entry indexed from 0 to 15"""
427
430
428 def __init__(self):
431 def __init__(self):
429 super(Block, self).__init__()
432 super(Block, self).__init__()
430 # If this block exist on disk, here is its ID
433 # If this block exist on disk, here is its ID
431 self.ondisk_id = None
434 self.ondisk_id = None
432
435
433 def __iter__(self):
436 def __iter__(self):
434 return iter(self.get(i) for i in range(16))
437 return iter(self.get(i) for i in range(16))
435
438
436
439
437 def _build_trie(index):
440 def _build_trie(index):
438 """build a nodemap trie
441 """build a nodemap trie
439
442
440 The nodemap stores revision number for each unique prefix.
443 The nodemap stores revision number for each unique prefix.
441
444
442 Each block is a dictionary with keys in `[0, 15]`. Values are either
445 Each block is a dictionary with keys in `[0, 15]`. Values are either
443 another block or a revision number.
446 another block or a revision number.
444 """
447 """
445 root = Block()
448 root = Block()
446 for rev in range(len(index)):
449 for rev in range(len(index)):
447 hex = nodemod.hex(index[rev][7])
450 hex = nodemod.hex(index[rev][7])
448 _insert_into_block(index, 0, root, rev, hex)
451 _insert_into_block(index, 0, root, rev, hex)
449 return root
452 return root
450
453
451
454
452 def _update_trie(index, root, last_rev):
455 def _update_trie(index, root, last_rev):
453 """consume"""
456 """consume"""
454 changed = 0
457 changed = 0
455 for rev in range(last_rev + 1, len(index)):
458 for rev in range(last_rev + 1, len(index)):
456 hex = nodemod.hex(index[rev][7])
459 hex = nodemod.hex(index[rev][7])
457 changed += _insert_into_block(index, 0, root, rev, hex)
460 changed += _insert_into_block(index, 0, root, rev, hex)
458 return changed, root
461 return changed, root
459
462
460
463
461 def _insert_into_block(index, level, block, current_rev, current_hex):
464 def _insert_into_block(index, level, block, current_rev, current_hex):
462 """insert a new revision in a block
465 """insert a new revision in a block
463
466
464 index: the index we are adding revision for
467 index: the index we are adding revision for
465 level: the depth of the current block in the trie
468 level: the depth of the current block in the trie
466 block: the block currently being considered
469 block: the block currently being considered
467 current_rev: the revision number we are adding
470 current_rev: the revision number we are adding
468 current_hex: the hexadecimal representation of the of that revision
471 current_hex: the hexadecimal representation of the of that revision
469 """
472 """
470 changed = 1
473 changed = 1
471 if block.ondisk_id is not None:
474 if block.ondisk_id is not None:
472 block.ondisk_id = None
475 block.ondisk_id = None
473 hex_digit = _to_int(current_hex[level : level + 1])
476 hex_digit = _to_int(current_hex[level : level + 1])
474 entry = block.get(hex_digit)
477 entry = block.get(hex_digit)
475 if entry is None:
478 if entry is None:
476 # no entry, simply store the revision number
479 # no entry, simply store the revision number
477 block[hex_digit] = current_rev
480 block[hex_digit] = current_rev
478 elif isinstance(entry, dict):
481 elif isinstance(entry, dict):
479 # need to recurse to an underlying block
482 # need to recurse to an underlying block
480 changed += _insert_into_block(
483 changed += _insert_into_block(
481 index, level + 1, entry, current_rev, current_hex
484 index, level + 1, entry, current_rev, current_hex
482 )
485 )
483 else:
486 else:
484 # collision with a previously unique prefix, inserting new
487 # collision with a previously unique prefix, inserting new
485 # vertices to fit both entry.
488 # vertices to fit both entry.
486 other_hex = nodemod.hex(index[entry][7])
489 other_hex = nodemod.hex(index[entry][7])
487 other_rev = entry
490 other_rev = entry
488 new = Block()
491 new = Block()
489 block[hex_digit] = new
492 block[hex_digit] = new
490 _insert_into_block(index, level + 1, new, other_rev, other_hex)
493 _insert_into_block(index, level + 1, new, other_rev, other_hex)
491 _insert_into_block(index, level + 1, new, current_rev, current_hex)
494 _insert_into_block(index, level + 1, new, current_rev, current_hex)
492 return changed
495 return changed
493
496
494
497
495 def _persist_trie(root, existing_idx=None):
498 def _persist_trie(root, existing_idx=None):
496 """turn a nodemap trie into persistent binary data
499 """turn a nodemap trie into persistent binary data
497
500
498 See `_build_trie` for nodemap trie structure"""
501 See `_build_trie` for nodemap trie structure"""
499 block_map = {}
502 block_map = {}
500 if existing_idx is not None:
503 if existing_idx is not None:
501 base_idx = existing_idx + 1
504 base_idx = existing_idx + 1
502 else:
505 else:
503 base_idx = 0
506 base_idx = 0
504 chunks = []
507 chunks = []
505 for tn in _walk_trie(root):
508 for tn in _walk_trie(root):
506 if tn.ondisk_id is not None:
509 if tn.ondisk_id is not None:
507 block_map[id(tn)] = tn.ondisk_id
510 block_map[id(tn)] = tn.ondisk_id
508 else:
511 else:
509 block_map[id(tn)] = len(chunks) + base_idx
512 block_map[id(tn)] = len(chunks) + base_idx
510 chunks.append(_persist_block(tn, block_map))
513 chunks.append(_persist_block(tn, block_map))
511 return b''.join(chunks)
514 return b''.join(chunks)
512
515
513
516
514 def _walk_trie(block):
517 def _walk_trie(block):
515 """yield all the block in a trie
518 """yield all the block in a trie
516
519
517 Children blocks are always yield before their parent block.
520 Children blocks are always yield before their parent block.
518 """
521 """
519 for (_, item) in sorted(block.items()):
522 for (_, item) in sorted(block.items()):
520 if isinstance(item, dict):
523 if isinstance(item, dict):
521 for sub_block in _walk_trie(item):
524 for sub_block in _walk_trie(item):
522 yield sub_block
525 yield sub_block
523 yield block
526 yield block
524
527
525
528
526 def _persist_block(block_node, block_map):
529 def _persist_block(block_node, block_map):
527 """produce persistent binary data for a single block
530 """produce persistent binary data for a single block
528
531
529 Children block are assumed to be already persisted and present in
532 Children block are assumed to be already persisted and present in
530 block_map.
533 block_map.
531 """
534 """
532 data = tuple(_to_value(v, block_map) for v in block_node)
535 data = tuple(_to_value(v, block_map) for v in block_node)
533 return S_BLOCK.pack(*data)
536 return S_BLOCK.pack(*data)
534
537
535
538
536 def _to_value(item, block_map):
539 def _to_value(item, block_map):
537 """persist any value as an integer"""
540 """persist any value as an integer"""
538 if item is None:
541 if item is None:
539 return NO_ENTRY
542 return NO_ENTRY
540 elif isinstance(item, dict):
543 elif isinstance(item, dict):
541 return block_map[id(item)]
544 return block_map[id(item)]
542 else:
545 else:
543 return _transform_rev(item)
546 return _transform_rev(item)
544
547
545
548
546 def parse_data(data):
549 def parse_data(data):
547 """parse parse nodemap data into a nodemap Trie"""
550 """parse parse nodemap data into a nodemap Trie"""
548 if (len(data) % S_BLOCK.size) != 0:
551 if (len(data) % S_BLOCK.size) != 0:
549 msg = "nodemap data size is not a multiple of block size (%d): %d"
552 msg = "nodemap data size is not a multiple of block size (%d): %d"
550 raise error.Abort(msg % (S_BLOCK.size, len(data)))
553 raise error.Abort(msg % (S_BLOCK.size, len(data)))
551 if not data:
554 if not data:
552 return Block(), None
555 return Block(), None
553 block_map = {}
556 block_map = {}
554 new_blocks = []
557 new_blocks = []
555 for i in range(0, len(data), S_BLOCK.size):
558 for i in range(0, len(data), S_BLOCK.size):
556 block = Block()
559 block = Block()
557 block.ondisk_id = len(block_map)
560 block.ondisk_id = len(block_map)
558 block_map[block.ondisk_id] = block
561 block_map[block.ondisk_id] = block
559 block_data = data[i : i + S_BLOCK.size]
562 block_data = data[i : i + S_BLOCK.size]
560 values = S_BLOCK.unpack(block_data)
563 values = S_BLOCK.unpack(block_data)
561 new_blocks.append((block, values))
564 new_blocks.append((block, values))
562 for b, values in new_blocks:
565 for b, values in new_blocks:
563 for idx, v in enumerate(values):
566 for idx, v in enumerate(values):
564 if v == NO_ENTRY:
567 if v == NO_ENTRY:
565 continue
568 continue
566 elif v >= 0:
569 elif v >= 0:
567 b[idx] = block_map[v]
570 b[idx] = block_map[v]
568 else:
571 else:
569 b[idx] = _transform_rev(v)
572 b[idx] = _transform_rev(v)
570 return block, i // S_BLOCK.size
573 return block, i // S_BLOCK.size
571
574
572
575
573 # debug utility
576 # debug utility
574
577
575
578
576 def check_data(ui, index, data):
579 def check_data(ui, index, data):
577 """verify that the provided nodemap data are valid for the given idex"""
580 """verify that the provided nodemap data are valid for the given idex"""
578 ret = 0
581 ret = 0
579 ui.status((b"revision in index: %d\n") % len(index))
582 ui.status((b"revision in index: %d\n") % len(index))
580 root, __ = parse_data(data)
583 root, __ = parse_data(data)
581 all_revs = set(_all_revisions(root))
584 all_revs = set(_all_revisions(root))
582 ui.status((b"revision in nodemap: %d\n") % len(all_revs))
585 ui.status((b"revision in nodemap: %d\n") % len(all_revs))
583 for r in range(len(index)):
586 for r in range(len(index)):
584 if r not in all_revs:
587 if r not in all_revs:
585 msg = b" revision missing from nodemap: %d\n" % r
588 msg = b" revision missing from nodemap: %d\n" % r
586 ui.write_err(msg)
589 ui.write_err(msg)
587 ret = 1
590 ret = 1
588 else:
591 else:
589 all_revs.remove(r)
592 all_revs.remove(r)
590 nm_rev = _find_node(root, nodemod.hex(index[r][7]))
593 nm_rev = _find_node(root, nodemod.hex(index[r][7]))
591 if nm_rev is None:
594 if nm_rev is None:
592 msg = b" revision node does not match any entries: %d\n" % r
595 msg = b" revision node does not match any entries: %d\n" % r
593 ui.write_err(msg)
596 ui.write_err(msg)
594 ret = 1
597 ret = 1
595 elif nm_rev != r:
598 elif nm_rev != r:
596 msg = (
599 msg = (
597 b" revision node does not match the expected revision: "
600 b" revision node does not match the expected revision: "
598 b"%d != %d\n" % (r, nm_rev)
601 b"%d != %d\n" % (r, nm_rev)
599 )
602 )
600 ui.write_err(msg)
603 ui.write_err(msg)
601 ret = 1
604 ret = 1
602
605
603 if all_revs:
606 if all_revs:
604 for r in sorted(all_revs):
607 for r in sorted(all_revs):
605 msg = b" extra revision in nodemap: %d\n" % r
608 msg = b" extra revision in nodemap: %d\n" % r
606 ui.write_err(msg)
609 ui.write_err(msg)
607 ret = 1
610 ret = 1
608 return ret
611 return ret
609
612
610
613
611 def _all_revisions(root):
614 def _all_revisions(root):
612 """return all revisions stored in a Trie"""
615 """return all revisions stored in a Trie"""
613 for block in _walk_trie(root):
616 for block in _walk_trie(root):
614 for v in block:
617 for v in block:
615 if v is None or isinstance(v, Block):
618 if v is None or isinstance(v, Block):
616 continue
619 continue
617 yield v
620 yield v
618
621
619
622
620 def _find_node(block, node):
623 def _find_node(block, node):
621 """find the revision associated with a given node"""
624 """find the revision associated with a given node"""
622 entry = block.get(_to_int(node[0:1]))
625 entry = block.get(_to_int(node[0:1]))
623 if isinstance(entry, dict):
626 if isinstance(entry, dict):
624 return _find_node(entry, node[1:])
627 return _find_node(entry, node[1:])
625 return entry
628 return entry
@@ -1,413 +1,413
1 ===================================
1 ===================================
2 Test the persistent on-disk nodemap
2 Test the persistent on-disk nodemap
3 ===================================
3 ===================================
4
4
5 $ hg init test-repo
5 $ hg init test-repo
6 $ cd test-repo
6 $ cd test-repo
7 $ cat << EOF >> .hg/hgrc
7 $ cat << EOF >> .hg/hgrc
8 > [experimental]
8 > [experimental]
9 > exp-persistent-nodemap=yes
9 > exp-persistent-nodemap=yes
10 > [devel]
10 > [devel]
11 > persistent-nodemap=yes
11 > persistent-nodemap=yes
12 > EOF
12 > EOF
13 $ hg debugbuilddag .+5000
13 $ hg debugbuilddag .+5000
14 $ hg debugnodemap --metadata
14 $ hg debugnodemap --metadata
15 uid: ???????????????? (glob)
15 uid: ???????????????? (glob)
16 tip-rev: 5000
16 tip-rev: 5000
17 tip-node: 06ddac466af534d365326c13c3879f97caca3cb1
17 tip-node: 06ddac466af534d365326c13c3879f97caca3cb1
18 data-length: 122880
18 data-length: 122880
19 data-unused: 0
19 data-unused: 0
20 data-unused: 0.000%
20 data-unused: 0.000%
21 $ f --size .hg/store/00changelog.n
21 $ f --size .hg/store/00changelog.n
22 .hg/store/00changelog.n: size=70
22 .hg/store/00changelog.n: size=70
23
23
24 Simple lookup works
24 Simple lookup works
25
25
26 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
26 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
27 $ hg log -r "$ANYNODE" --template '{rev}\n'
27 $ hg log -r "$ANYNODE" --template '{rev}\n'
28 5000
28 5000
29
29
30
30
31 #if rust
31 #if rust
32
32
33 $ f --sha256 .hg/store/00changelog-*.nd
33 $ f --sha256 .hg/store/00changelog-*.nd
34 .hg/store/00changelog-????????????????.nd: sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6 (glob)
34 .hg/store/00changelog-????????????????.nd: sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6 (glob)
35 $ hg debugnodemap --dump-new | f --sha256 --size
35 $ hg debugnodemap --dump-new | f --sha256 --size
36 size=122880, sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
36 size=122880, sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
37 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
37 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
38 size=122880, sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
38 size=122880, sha256=1e38e9ffaa45cad13f15c1a9880ad606f4241e8beea2f61b4d5365abadfb55f6
39 0000: 00 00 00 76 00 00 01 65 00 00 00 95 00 00 01 34 |...v...e.......4|
39 0000: 00 00 00 76 00 00 01 65 00 00 00 95 00 00 01 34 |...v...e.......4|
40 0010: 00 00 00 19 00 00 01 69 00 00 00 ab 00 00 00 4b |.......i.......K|
40 0010: 00 00 00 19 00 00 01 69 00 00 00 ab 00 00 00 4b |.......i.......K|
41 0020: 00 00 00 07 00 00 01 4c 00 00 00 f8 00 00 00 8f |.......L........|
41 0020: 00 00 00 07 00 00 01 4c 00 00 00 f8 00 00 00 8f |.......L........|
42 0030: 00 00 00 c0 00 00 00 a7 00 00 00 89 00 00 01 46 |...............F|
42 0030: 00 00 00 c0 00 00 00 a7 00 00 00 89 00 00 01 46 |...............F|
43 0040: 00 00 00 92 00 00 01 bc 00 00 00 71 00 00 00 ac |...........q....|
43 0040: 00 00 00 92 00 00 01 bc 00 00 00 71 00 00 00 ac |...........q....|
44 0050: 00 00 00 af 00 00 00 b4 00 00 00 34 00 00 01 ca |...........4....|
44 0050: 00 00 00 af 00 00 00 b4 00 00 00 34 00 00 01 ca |...........4....|
45 0060: 00 00 00 23 00 00 01 45 00 00 00 2d 00 00 00 b2 |...#...E...-....|
45 0060: 00 00 00 23 00 00 01 45 00 00 00 2d 00 00 00 b2 |...#...E...-....|
46 0070: 00 00 00 56 00 00 01 0f 00 00 00 4e 00 00 02 4c |...V.......N...L|
46 0070: 00 00 00 56 00 00 01 0f 00 00 00 4e 00 00 02 4c |...V.......N...L|
47 0080: 00 00 00 e7 00 00 00 cd 00 00 01 5b 00 00 00 78 |...........[...x|
47 0080: 00 00 00 e7 00 00 00 cd 00 00 01 5b 00 00 00 78 |...........[...x|
48 0090: 00 00 00 e3 00 00 01 8e 00 00 00 4f 00 00 00 b1 |...........O....|
48 0090: 00 00 00 e3 00 00 01 8e 00 00 00 4f 00 00 00 b1 |...........O....|
49 00a0: 00 00 00 30 00 00 00 11 00 00 00 25 00 00 00 d2 |...0.......%....|
49 00a0: 00 00 00 30 00 00 00 11 00 00 00 25 00 00 00 d2 |...0.......%....|
50 00b0: 00 00 00 ec 00 00 00 69 00 00 01 2b 00 00 01 2e |.......i...+....|
50 00b0: 00 00 00 ec 00 00 00 69 00 00 01 2b 00 00 01 2e |.......i...+....|
51 00c0: 00 00 00 aa 00 00 00 15 00 00 00 3a 00 00 01 4e |...........:...N|
51 00c0: 00 00 00 aa 00 00 00 15 00 00 00 3a 00 00 01 4e |...........:...N|
52 00d0: 00 00 00 4d 00 00 00 9d 00 00 00 8e 00 00 00 a4 |...M............|
52 00d0: 00 00 00 4d 00 00 00 9d 00 00 00 8e 00 00 00 a4 |...M............|
53 00e0: 00 00 00 c3 00 00 00 eb 00 00 00 29 00 00 00 ad |...........)....|
53 00e0: 00 00 00 c3 00 00 00 eb 00 00 00 29 00 00 00 ad |...........)....|
54 00f0: 00 00 01 3a 00 00 01 32 00 00 00 04 00 00 00 53 |...:...2.......S|
54 00f0: 00 00 01 3a 00 00 01 32 00 00 00 04 00 00 00 53 |...:...2.......S|
55
55
56
56
57 #else
57 #else
58
58
59 $ f --sha256 .hg/store/00changelog-*.nd
59 $ f --sha256 .hg/store/00changelog-*.nd
60 .hg/store/00changelog-????????????????.nd: sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
60 .hg/store/00changelog-????????????????.nd: sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7 (glob)
61 $ hg debugnodemap --dump-new | f --sha256 --size
61 $ hg debugnodemap --dump-new | f --sha256 --size
62 size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
62 size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
63 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
63 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
64 size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
64 size=122880, sha256=b961925120e1c9bc345c199b2cc442abc477029fdece37ef9d99cbe59c0558b7
65 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
65 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
66 0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff |................|
66 0010: ff ff ff ff ff ff ff ff ff ff fa c2 ff ff ff ff |................|
67 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
67 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
68 0030: ff ff ff ff ff ff ed b3 ff ff ff ff ff ff ff ff |................|
68 0030: ff ff ff ff ff ff ed b3 ff ff ff ff ff ff ff ff |................|
69 0040: ff ff ff ff ff ff ee 34 00 00 00 00 ff ff ff ff |.......4........|
69 0040: ff ff ff ff ff ff ee 34 00 00 00 00 ff ff ff ff |.......4........|
70 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
70 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
71 0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
71 0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
72 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
72 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
73 0080: ff ff ff ff ff ff f8 50 ff ff ff ff ff ff ff ff |.......P........|
73 0080: ff ff ff ff ff ff f8 50 ff ff ff ff ff ff ff ff |.......P........|
74 0090: ff ff ff ff ff ff ff ff ff ff ec c7 ff ff ff ff |................|
74 0090: ff ff ff ff ff ff ff ff ff ff ec c7 ff ff ff ff |................|
75 00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
75 00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
76 00b0: ff ff ff ff ff ff fa be ff ff f2 fc ff ff ff ff |................|
76 00b0: ff ff ff ff ff ff fa be ff ff f2 fc ff ff ff ff |................|
77 00c0: ff ff ff ff ff ff ef ea ff ff ff ff ff ff f9 17 |................|
77 00c0: ff ff ff ff ff ff ef ea ff ff ff ff ff ff f9 17 |................|
78 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
78 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
79 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
79 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
80 00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
80 00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
81
81
82 #endif
82 #endif
83
83
84 $ hg debugnodemap --check
84 $ hg debugnodemap --check
85 revision in index: 5001
85 revision in index: 5001
86 revision in nodemap: 5001
86 revision in nodemap: 5001
87
87
88 add a new commit
88 add a new commit
89
89
90 $ hg up
90 $ hg up
91 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 $ echo foo > foo
92 $ echo foo > foo
93 $ hg add foo
93 $ hg add foo
94 $ hg ci -m 'foo'
94 $ hg ci -m 'foo'
95
95
96 #if no-pure no-rust
96 #if no-pure no-rust
97 $ hg debugnodemap --metadata
97 $ hg debugnodemap --metadata
98 uid: ???????????????? (glob)
98 uid: ???????????????? (glob)
99 tip-rev: 5001
99 tip-rev: 5001
100 tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
100 tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
101 data-length: 122880
101 data-length: 122880
102 data-unused: 0
102 data-unused: 0
103 data-unused: 0.000%
103 data-unused: 0.000%
104 #else
104 #else
105 $ hg debugnodemap --metadata
105 $ hg debugnodemap --metadata
106 uid: ???????????????? (glob)
106 uid: ???????????????? (glob)
107 tip-rev: 5001
107 tip-rev: 5001
108 tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
108 tip-node: 2dd9b5258caa46469ff07d4a3da1eb3529a51f49
109 data-length: 123072
109 data-length: 123072
110 data-unused: 192
110 data-unused: 192
111 data-unused: 0.156%
111 data-unused: 0.156%
112 #endif
112 #endif
113
113
114 $ f --size .hg/store/00changelog.n
114 $ f --size .hg/store/00changelog.n
115 .hg/store/00changelog.n: size=70
115 .hg/store/00changelog.n: size=70
116
116
117 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
117 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
118
118
119 #if pure
119 #if pure
120 $ f --sha256 .hg/store/00changelog-*.nd --size
120 $ f --sha256 .hg/store/00changelog-*.nd --size
121 .hg/store/00changelog-????????????????.nd: size=123072, sha256=136472751566c8198ff09e306a7d2f9bd18bd32298d614752b73da4d6df23340 (glob)
121 .hg/store/00changelog-????????????????.nd: size=123072, sha256=136472751566c8198ff09e306a7d2f9bd18bd32298d614752b73da4d6df23340 (glob)
122 #endif
122 #endif
123
123
124 #if rust
124 #if rust
125 $ f --sha256 .hg/store/00changelog-*.nd --size
125 $ f --sha256 .hg/store/00changelog-*.nd --size
126 .hg/store/00changelog-????????????????.nd: size=123072, sha256=ccc8a43310ace13812fcc648683e259346754ef934c12dd238cf9b7fadfe9a4b (glob)
126 .hg/store/00changelog-????????????????.nd: size=123072, sha256=ccc8a43310ace13812fcc648683e259346754ef934c12dd238cf9b7fadfe9a4b (glob)
127 #endif
127 #endif
128
128
129 #if no-pure no-rust
129 #if no-pure no-rust
130 $ f --sha256 .hg/store/00changelog-*.nd --size
130 $ f --sha256 .hg/store/00changelog-*.nd --size
131 .hg/store/00changelog-????????????????.nd: size=122880, sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
131 .hg/store/00changelog-????????????????.nd: size=122880, sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
132 #endif
132 #endif
133
133
134 $ hg debugnodemap --check
134 $ hg debugnodemap --check
135 revision in index: 5002
135 revision in index: 5002
136 revision in nodemap: 5002
136 revision in nodemap: 5002
137
137
138 Test code path without mmap
138 Test code path without mmap
139 ---------------------------
139 ---------------------------
140
140
141 $ echo bar > bar
141 $ echo bar > bar
142 $ hg add bar
142 $ hg add bar
143 $ hg ci -m 'bar' --config experimental.exp-persistent-nodemap.mmap=no
143 $ hg ci -m 'bar' --config experimental.exp-persistent-nodemap.mmap=no
144
144
145 $ hg debugnodemap --check --config experimental.exp-persistent-nodemap.mmap=yes
145 $ hg debugnodemap --check --config experimental.exp-persistent-nodemap.mmap=yes
146 revision in index: 5003
146 revision in index: 5003
147 revision in nodemap: 5003
147 revision in nodemap: 5003
148 $ hg debugnodemap --check --config experimental.exp-persistent-nodemap.mmap=no
148 $ hg debugnodemap --check --config experimental.exp-persistent-nodemap.mmap=no
149 revision in index: 5003
149 revision in index: 5003
150 revision in nodemap: 5003
150 revision in nodemap: 5003
151
151
152
152
153 #if pure
153 #if pure
154 $ hg debugnodemap --metadata
154 $ hg debugnodemap --metadata
155 uid: ???????????????? (glob)
155 uid: ???????????????? (glob)
156 tip-rev: 5002
156 tip-rev: 5002
157 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
157 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
158 data-length: 123328
158 data-length: 123328
159 data-unused: 384
159 data-unused: 384
160 data-unused: 0.311%
160 data-unused: 0.311%
161 $ f --sha256 .hg/store/00changelog-*.nd --size
161 $ f --sha256 .hg/store/00changelog-*.nd --size
162 .hg/store/00changelog-????????????????.nd: size=123328, sha256=10d26e9776b6596af0f89143a54eba8cc581e929c38242a02a7b0760698c6c70 (glob)
162 .hg/store/00changelog-????????????????.nd: size=123328, sha256=10d26e9776b6596af0f89143a54eba8cc581e929c38242a02a7b0760698c6c70 (glob)
163 #endif
163 #endif
164 #if rust
164 #if rust
165 $ hg debugnodemap --metadata
165 $ hg debugnodemap --metadata
166 uid: ???????????????? (glob)
166 uid: ???????????????? (glob)
167 tip-rev: 5002
167 tip-rev: 5002
168 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
168 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
169 data-length: 123328
169 data-length: 123328
170 data-unused: 384
170 data-unused: 384
171 data-unused: 0.311%
171 data-unused: 0.311%
172 $ f --sha256 .hg/store/00changelog-*.nd --size
172 $ f --sha256 .hg/store/00changelog-*.nd --size
173 .hg/store/00changelog-????????????????.nd: size=123328, sha256=081eec9eb6708f2bf085d939b4c97bc0b6762bc8336bc4b93838f7fffa1516bf (glob)
173 .hg/store/00changelog-????????????????.nd: size=123328, sha256=081eec9eb6708f2bf085d939b4c97bc0b6762bc8336bc4b93838f7fffa1516bf (glob)
174 #endif
174 #endif
175 #if no-pure no-rust
175 #if no-pure no-rust
176 $ hg debugnodemap --metadata
176 $ hg debugnodemap --metadata
177 uid: ???????????????? (glob)
177 uid: ???????????????? (glob)
178 tip-rev: 5002
178 tip-rev: 5002
179 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
179 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
180 data-length: 122944
180 data-length: 122944
181 data-unused: 0
181 data-unused: 0
182 data-unused: 0.000%
182 data-unused: 0.000%
183 $ f --sha256 .hg/store/00changelog-*.nd --size
183 $ f --sha256 .hg/store/00changelog-*.nd --size
184 .hg/store/00changelog-????????????????.nd: size=122944, sha256=755976b22b64ab680401b45395953504e64e7fa8c31ac570f58dee21e15f9bc0 (glob)
184 .hg/store/00changelog-????????????????.nd: size=122944, sha256=755976b22b64ab680401b45395953504e64e7fa8c31ac570f58dee21e15f9bc0 (glob)
185 #endif
185 #endif
186
186
187 Test force warming the cache
187 Test force warming the cache
188
188
189 $ rm .hg/store/00changelog.n
189 $ rm .hg/store/00changelog.n
190 $ hg debugnodemap --metadata
190 $ hg debugnodemap --metadata
191 $ hg debugupdatecache
191 $ hg debugupdatecache
192 #if pure
192 #if pure
193 $ hg debugnodemap --metadata
193 $ hg debugnodemap --metadata
194 uid: ???????????????? (glob)
194 uid: ???????????????? (glob)
195 tip-rev: 5002
195 tip-rev: 5002
196 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
196 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
197 data-length: 122944
197 data-length: 122944
198 data-unused: 0
198 data-unused: 0
199 data-unused: 0.000%
199 data-unused: 0.000%
200 #else
200 #else
201 $ hg debugnodemap --metadata
201 $ hg debugnodemap --metadata
202 uid: ???????????????? (glob)
202 uid: ???????????????? (glob)
203 tip-rev: 5002
203 tip-rev: 5002
204 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
204 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
205 data-length: 122944
205 data-length: 122944
206 data-unused: 0
206 data-unused: 0
207 data-unused: 0.000%
207 data-unused: 0.000%
208 #endif
208 #endif
209
209
210 Check out of sync nodemap
210 Check out of sync nodemap
211 =========================
211 =========================
212
212
213 First copy old data on the side.
213 First copy old data on the side.
214
214
215 $ mkdir ../tmp-copies
215 $ mkdir ../tmp-copies
216 $ cp .hg/store/00changelog-????????????????.nd .hg/store/00changelog.n ../tmp-copies
216 $ cp .hg/store/00changelog-????????????????.nd .hg/store/00changelog.n ../tmp-copies
217
217
218 Nodemap lagging behind
218 Nodemap lagging behind
219 ----------------------
219 ----------------------
220
220
221 make a new commit
221 make a new commit
222
222
223 $ echo bar2 > bar
223 $ echo bar2 > bar
224 $ hg ci -m 'bar2'
224 $ hg ci -m 'bar2'
225 $ NODE=`hg log -r tip -T '{node}\n'`
225 $ NODE=`hg log -r tip -T '{node}\n'`
226 $ hg log -r "$NODE" -T '{rev}\n'
226 $ hg log -r "$NODE" -T '{rev}\n'
227 5003
227 5003
228
228
229 If the nodemap is lagging behind, it can catch up fine
229 If the nodemap is lagging behind, it can catch up fine
230
230
231 $ hg debugnodemap --metadata
231 $ hg debugnodemap --metadata
232 uid: ???????????????? (glob)
232 uid: ???????????????? (glob)
233 tip-rev: 5003
233 tip-rev: 5003
234 tip-node: 5c049e9c4a4af159bdcd65dce1b6bf303a0da6cf
234 tip-node: 5c049e9c4a4af159bdcd65dce1b6bf303a0da6cf
235 data-length: 123200 (pure !)
235 data-length: 123200 (pure !)
236 data-length: 123200 (rust !)
236 data-length: 123200 (rust !)
237 data-length: 122944 (no-rust no-pure !)
237 data-length: 122944 (no-rust no-pure !)
238 data-unused: 256 (pure !)
238 data-unused: 256 (pure !)
239 data-unused: 256 (rust !)
239 data-unused: 256 (rust !)
240 data-unused: 0 (no-rust no-pure !)
240 data-unused: 0 (no-rust no-pure !)
241 data-unused: 0.208% (pure !)
241 data-unused: 0.208% (pure !)
242 data-unused: 0.208% (rust !)
242 data-unused: 0.208% (rust !)
243 data-unused: 0.000% (no-rust no-pure !)
243 data-unused: 0.000% (no-rust no-pure !)
244 $ cp -f ../tmp-copies/* .hg/store/
244 $ cp -f ../tmp-copies/* .hg/store/
245 $ hg debugnodemap --metadata
245 $ hg debugnodemap --metadata
246 uid: ???????????????? (glob)
246 uid: ???????????????? (glob)
247 tip-rev: 5002
247 tip-rev: 5002
248 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
248 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
249 data-length: 122944
249 data-length: 122944
250 data-unused: 0
250 data-unused: 0
251 data-unused: 0.000%
251 data-unused: 0.000%
252 $ hg log -r "$NODE" -T '{rev}\n'
252 $ hg log -r "$NODE" -T '{rev}\n'
253 5003
253 5003
254
254
255 changelog altered
255 changelog altered
256 -----------------
256 -----------------
257
257
258 If the nodemap is not gated behind a requirements, an unaware client can alter
258 If the nodemap is not gated behind a requirements, an unaware client can alter
259 the repository so the revlog used to generate the nodemap is not longer
259 the repository so the revlog used to generate the nodemap is not longer
260 compatible with the persistent nodemap. We need to detect that.
260 compatible with the persistent nodemap. We need to detect that.
261
261
262 $ hg up "$NODE~5"
262 $ hg up "$NODE~5"
263 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
263 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
264 $ echo bar > babar
264 $ echo bar > babar
265 $ hg add babar
265 $ hg add babar
266 $ hg ci -m 'babar'
266 $ hg ci -m 'babar'
267 created new head
267 created new head
268 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
268 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
269 $ hg log -r "$OTHERNODE" -T '{rev}\n'
269 $ hg log -r "$OTHERNODE" -T '{rev}\n'
270 5004
270 5004
271
271
272 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
272 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
273
273
274 the nodemap should detect the changelog have been tampered with and recover.
274 the nodemap should detect the changelog have been tampered with and recover.
275
275
276 $ hg debugnodemap --metadata
276 $ hg debugnodemap --metadata
277 uid: ???????????????? (glob)
277 uid: ???????????????? (glob)
278 tip-rev: 5002
278 tip-rev: 5002
279 tip-node: 42bf3068c7ddfdfded53c4eb11d02266faeebfee
279 tip-node: 42bf3068c7ddfdfded53c4eb11d02266faeebfee
280 data-length: 123456 (pure !)
280 data-length: 123456 (pure !)
281 data-length: 246464 (rust !)
281 data-length: 123008 (rust !)
282 data-length: 123008 (no-pure no-rust !)
282 data-length: 123008 (no-pure no-rust !)
283 data-unused: 448 (pure !)
283 data-unused: 448 (pure !)
284 data-unused: 123904 (rust !)
284 data-unused: 0 (rust !)
285 data-unused: 0 (no-pure no-rust !)
285 data-unused: 0 (no-pure no-rust !)
286 data-unused: 50.273% (rust !)
286 data-unused: 0.000% (rust !)
287 data-unused: 0.363% (pure !)
287 data-unused: 0.363% (pure !)
288 data-unused: 0.000% (no-pure no-rust !)
288 data-unused: 0.000% (no-pure no-rust !)
289
289
290 $ cp -f ../tmp-copies/* .hg/store/
290 $ cp -f ../tmp-copies/* .hg/store/
291 $ hg debugnodemap --metadata
291 $ hg debugnodemap --metadata
292 uid: ???????????????? (glob)
292 uid: ???????????????? (glob)
293 tip-rev: 5002
293 tip-rev: 5002
294 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
294 tip-node: 6ce944fafcee85af91f29ea5b51654cc6101ad7e
295 data-length: 122944
295 data-length: 122944
296 data-unused: 0
296 data-unused: 0
297 data-unused: 0.000%
297 data-unused: 0.000%
298 $ hg log -r "$OTHERNODE" -T '{rev}\n'
298 $ hg log -r "$OTHERNODE" -T '{rev}\n'
299 5002
299 5002
300
300
301 Check transaction related property
301 Check transaction related property
302 ==================================
302 ==================================
303
303
304 An up to date nodemap should be available to shell hooks,
304 An up to date nodemap should be available to shell hooks,
305
305
306 $ echo dsljfl > a
306 $ echo dsljfl > a
307 $ hg add a
307 $ hg add a
308 $ hg ci -m a
308 $ hg ci -m a
309 $ hg debugnodemap --metadata
309 $ hg debugnodemap --metadata
310 uid: ???????????????? (glob)
310 uid: ???????????????? (glob)
311 tip-rev: 5003
311 tip-rev: 5003
312 tip-node: c91af76d172f1053cca41b83f7c2e4e514fe2bcf
312 tip-node: c91af76d172f1053cca41b83f7c2e4e514fe2bcf
313 data-length: 123008
313 data-length: 123008
314 data-unused: 0
314 data-unused: 0
315 data-unused: 0.000%
315 data-unused: 0.000%
316 $ echo babar2 > babar
316 $ echo babar2 > babar
317 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
317 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
318 uid: ???????????????? (glob)
318 uid: ???????????????? (glob)
319 tip-rev: 5004
319 tip-rev: 5004
320 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
320 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
321 data-length: 123328 (pure !)
321 data-length: 123328 (pure !)
322 data-length: 123328 (rust !)
322 data-length: 123328 (rust !)
323 data-length: 123136 (no-pure no-rust !)
323 data-length: 123136 (no-pure no-rust !)
324 data-unused: 192 (pure !)
324 data-unused: 192 (pure !)
325 data-unused: 192 (rust !)
325 data-unused: 192 (rust !)
326 data-unused: 0 (no-pure no-rust !)
326 data-unused: 0 (no-pure no-rust !)
327 data-unused: 0.156% (pure !)
327 data-unused: 0.156% (pure !)
328 data-unused: 0.156% (rust !)
328 data-unused: 0.156% (rust !)
329 data-unused: 0.000% (no-pure no-rust !)
329 data-unused: 0.000% (no-pure no-rust !)
330 $ hg debugnodemap --metadata
330 $ hg debugnodemap --metadata
331 uid: ???????????????? (glob)
331 uid: ???????????????? (glob)
332 tip-rev: 5004
332 tip-rev: 5004
333 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
333 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
334 data-length: 123328 (pure !)
334 data-length: 123328 (pure !)
335 data-length: 123328 (rust !)
335 data-length: 123328 (rust !)
336 data-length: 123136 (no-pure no-rust !)
336 data-length: 123136 (no-pure no-rust !)
337 data-unused: 192 (pure !)
337 data-unused: 192 (pure !)
338 data-unused: 192 (rust !)
338 data-unused: 192 (rust !)
339 data-unused: 0 (no-pure no-rust !)
339 data-unused: 0 (no-pure no-rust !)
340 data-unused: 0.156% (pure !)
340 data-unused: 0.156% (pure !)
341 data-unused: 0.156% (rust !)
341 data-unused: 0.156% (rust !)
342 data-unused: 0.000% (no-pure no-rust !)
342 data-unused: 0.000% (no-pure no-rust !)
343
343
344 Another process does not see the pending nodemap content during run.
344 Another process does not see the pending nodemap content during run.
345
345
346 $ PATH=$RUNTESTDIR/testlib/:$PATH
346 $ PATH=$RUNTESTDIR/testlib/:$PATH
347 $ echo qpoasp > a
347 $ echo qpoasp > a
348 $ hg ci -m a2 \
348 $ hg ci -m a2 \
349 > --config "hooks.pretxnclose=wait-on-file 20 sync-repo-read sync-txn-pending" \
349 > --config "hooks.pretxnclose=wait-on-file 20 sync-repo-read sync-txn-pending" \
350 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
350 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
351
351
352 (read the repository while the commit transaction is pending)
352 (read the repository while the commit transaction is pending)
353
353
354 $ wait-on-file 20 sync-txn-pending && \
354 $ wait-on-file 20 sync-txn-pending && \
355 > hg debugnodemap --metadata && \
355 > hg debugnodemap --metadata && \
356 > wait-on-file 20 sync-txn-close sync-repo-read
356 > wait-on-file 20 sync-txn-close sync-repo-read
357 uid: ???????????????? (glob)
357 uid: ???????????????? (glob)
358 tip-rev: 5004
358 tip-rev: 5004
359 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
359 tip-node: ba87cd9559559e4b91b28cb140d003985315e031
360 data-length: 123328 (pure !)
360 data-length: 123328 (pure !)
361 data-length: 123328 (rust !)
361 data-length: 123328 (rust !)
362 data-length: 123136 (no-pure no-rust !)
362 data-length: 123136 (no-pure no-rust !)
363 data-unused: 192 (pure !)
363 data-unused: 192 (pure !)
364 data-unused: 192 (rust !)
364 data-unused: 192 (rust !)
365 data-unused: 0 (no-pure no-rust !)
365 data-unused: 0 (no-pure no-rust !)
366 data-unused: 0.156% (pure !)
366 data-unused: 0.156% (pure !)
367 data-unused: 0.156% (rust !)
367 data-unused: 0.156% (rust !)
368 data-unused: 0.000% (no-pure no-rust !)
368 data-unused: 0.000% (no-pure no-rust !)
369 $ hg debugnodemap --metadata
369 $ hg debugnodemap --metadata
370 uid: ???????????????? (glob)
370 uid: ???????????????? (glob)
371 tip-rev: 5005
371 tip-rev: 5005
372 tip-node: bae4d45c759e30f1cb1a40e1382cf0e0414154db
372 tip-node: bae4d45c759e30f1cb1a40e1382cf0e0414154db
373 data-length: 123584 (pure !)
373 data-length: 123584 (pure !)
374 data-length: 123584 (rust !)
374 data-length: 123584 (rust !)
375 data-length: 123136 (no-pure no-rust !)
375 data-length: 123136 (no-pure no-rust !)
376 data-unused: 448 (pure !)
376 data-unused: 448 (pure !)
377 data-unused: 448 (rust !)
377 data-unused: 448 (rust !)
378 data-unused: 0 (no-pure no-rust !)
378 data-unused: 0 (no-pure no-rust !)
379 data-unused: 0.363% (pure !)
379 data-unused: 0.363% (pure !)
380 data-unused: 0.363% (rust !)
380 data-unused: 0.363% (rust !)
381 data-unused: 0.000% (no-pure no-rust !)
381 data-unused: 0.000% (no-pure no-rust !)
382
382
383 $ cat output.txt
383 $ cat output.txt
384
384
385 Check that a failing transaction will properly revert the data
385 Check that a failing transaction will properly revert the data
386
386
387 $ echo plakfe > a
387 $ echo plakfe > a
388 $ f --size --sha256 .hg/store/00changelog-*.nd
388 $ f --size --sha256 .hg/store/00changelog-*.nd
389 .hg/store/00changelog-????????????????.nd: size=123584, sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) (pure !)
389 .hg/store/00changelog-????????????????.nd: size=123584, sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) (pure !)
390 .hg/store/00changelog-????????????????.nd: size=123584, sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) (rust !)
390 .hg/store/00changelog-????????????????.nd: size=123584, sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) (rust !)
391 .hg/store/00changelog-????????????????.nd: size=123136, sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) (no-pure no-rust !)
391 .hg/store/00changelog-????????????????.nd: size=123136, sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) (no-pure no-rust !)
392 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
392 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
393 transaction abort!
393 transaction abort!
394 rollback completed
394 rollback completed
395 abort: This is a late abort
395 abort: This is a late abort
396 [255]
396 [255]
397 $ hg debugnodemap --metadata
397 $ hg debugnodemap --metadata
398 uid: ???????????????? (glob)
398 uid: ???????????????? (glob)
399 tip-rev: 5005
399 tip-rev: 5005
400 tip-node: bae4d45c759e30f1cb1a40e1382cf0e0414154db
400 tip-node: bae4d45c759e30f1cb1a40e1382cf0e0414154db
401 data-length: 123584 (pure !)
401 data-length: 123584 (pure !)
402 data-length: 123584 (rust !)
402 data-length: 123584 (rust !)
403 data-length: 123136 (no-pure no-rust !)
403 data-length: 123136 (no-pure no-rust !)
404 data-unused: 448 (pure !)
404 data-unused: 448 (pure !)
405 data-unused: 448 (rust !)
405 data-unused: 448 (rust !)
406 data-unused: 0 (no-pure no-rust !)
406 data-unused: 0 (no-pure no-rust !)
407 data-unused: 0.363% (pure !)
407 data-unused: 0.363% (pure !)
408 data-unused: 0.363% (rust !)
408 data-unused: 0.363% (rust !)
409 data-unused: 0.000% (no-pure no-rust !)
409 data-unused: 0.000% (no-pure no-rust !)
410 $ f --size --sha256 .hg/store/00changelog-*.nd
410 $ f --size --sha256 .hg/store/00changelog-*.nd
411 .hg/store/00changelog-????????????????.nd: size=123584, sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) (pure !)
411 .hg/store/00changelog-????????????????.nd: size=123584, sha256=8c6cef6fd3d3fac291968793ee19a4be6d0b8375e9508bd5c7d4a8879e8df180 (glob) (pure !)
412 .hg/store/00changelog-????????????????.nd: size=123584, sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) (rust !)
412 .hg/store/00changelog-????????????????.nd: size=123584, sha256=eb9e9a4bcafdb5e1344bc8a0cbb3288b2106413b8efae6265fb8a7973d7e97f9 (glob) (rust !)
413 .hg/store/00changelog-????????????????.nd: size=123136, sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) (no-pure no-rust !)
413 .hg/store/00changelog-????????????????.nd: size=123136, sha256=4f504f5a834db3811ced50ab3e9e80bcae3581bb0f9b13a7a9f94b7fc34bcebe (glob) (no-pure no-rust !)
General Comments 0
You need to be logged in to leave comments. Login now