##// END OF EJS Templates
dirstate: add a synchronisation point in the middle of the read...
Raphaël Gomès -
r51129:2be6d578 stable
parent child Browse files
Show More
@@ -1,2912 +1,2922
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
8
9 import functools
9 import functools
10 import re
10 import re
11
11
12 from . import (
12 from . import (
13 encoding,
13 encoding,
14 error,
14 error,
15 )
15 )
16
16
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = b"extension '%s' overwrite config item '%s.%s'"
25 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config=b'warn-config')
27 ui.develwarn(msg, config=b'warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31
31
32 class configitem:
32 class configitem:
33 """represent a known config item
33 """represent a known config item
34
34
35 :section: the official config section where to find this item,
35 :section: the official config section where to find this item,
36 :name: the official name within the section,
36 :name: the official name within the section,
37 :default: default value for this item,
37 :default: default value for this item,
38 :alias: optional list of tuples as alternatives,
38 :alias: optional list of tuples as alternatives,
39 :generic: this is a generic definition, match name using regular expression.
39 :generic: this is a generic definition, match name using regular expression.
40 """
40 """
41
41
42 def __init__(
42 def __init__(
43 self,
43 self,
44 section,
44 section,
45 name,
45 name,
46 default=None,
46 default=None,
47 alias=(),
47 alias=(),
48 generic=False,
48 generic=False,
49 priority=0,
49 priority=0,
50 experimental=False,
50 experimental=False,
51 ):
51 ):
52 self.section = section
52 self.section = section
53 self.name = name
53 self.name = name
54 self.default = default
54 self.default = default
55 self.alias = list(alias)
55 self.alias = list(alias)
56 self.generic = generic
56 self.generic = generic
57 self.priority = priority
57 self.priority = priority
58 self.experimental = experimental
58 self.experimental = experimental
59 self._re = None
59 self._re = None
60 if generic:
60 if generic:
61 self._re = re.compile(self.name)
61 self._re = re.compile(self.name)
62
62
63
63
64 class itemregister(dict):
64 class itemregister(dict):
65 """A specialized dictionary that can handle wild-card selection"""
65 """A specialized dictionary that can handle wild-card selection"""
66
66
67 def __init__(self):
67 def __init__(self):
68 super(itemregister, self).__init__()
68 super(itemregister, self).__init__()
69 self._generics = set()
69 self._generics = set()
70
70
71 def update(self, other):
71 def update(self, other):
72 super(itemregister, self).update(other)
72 super(itemregister, self).update(other)
73 self._generics.update(other._generics)
73 self._generics.update(other._generics)
74
74
75 def __setitem__(self, key, item):
75 def __setitem__(self, key, item):
76 super(itemregister, self).__setitem__(key, item)
76 super(itemregister, self).__setitem__(key, item)
77 if item.generic:
77 if item.generic:
78 self._generics.add(item)
78 self._generics.add(item)
79
79
80 def get(self, key):
80 def get(self, key):
81 baseitem = super(itemregister, self).get(key)
81 baseitem = super(itemregister, self).get(key)
82 if baseitem is not None and not baseitem.generic:
82 if baseitem is not None and not baseitem.generic:
83 return baseitem
83 return baseitem
84
84
85 # search for a matching generic item
85 # search for a matching generic item
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 for item in generics:
87 for item in generics:
88 # we use 'match' instead of 'search' to make the matching simpler
88 # we use 'match' instead of 'search' to make the matching simpler
89 # for people unfamiliar with regular expression. Having the match
89 # for people unfamiliar with regular expression. Having the match
90 # rooted to the start of the string will produce less surprising
90 # rooted to the start of the string will produce less surprising
91 # result for user writing simple regex for sub-attribute.
91 # result for user writing simple regex for sub-attribute.
92 #
92 #
93 # For example using "color\..*" match produces an unsurprising
93 # For example using "color\..*" match produces an unsurprising
94 # result, while using search could suddenly match apparently
94 # result, while using search could suddenly match apparently
95 # unrelated configuration that happens to contains "color."
95 # unrelated configuration that happens to contains "color."
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # some match to avoid the need to prefix most pattern with "^".
97 # some match to avoid the need to prefix most pattern with "^".
98 # The "^" seems more error prone.
98 # The "^" seems more error prone.
99 if item._re.match(key):
99 if item._re.match(key):
100 return item
100 return item
101
101
102 return None
102 return None
103
103
104
104
105 coreitems = {}
105 coreitems = {}
106
106
107
107
108 def _register(configtable, *args, **kwargs):
108 def _register(configtable, *args, **kwargs):
109 item = configitem(*args, **kwargs)
109 item = configitem(*args, **kwargs)
110 section = configtable.setdefault(item.section, itemregister())
110 section = configtable.setdefault(item.section, itemregister())
111 if item.name in section:
111 if item.name in section:
112 msg = b"duplicated config item registration for '%s.%s'"
112 msg = b"duplicated config item registration for '%s.%s'"
113 raise error.ProgrammingError(msg % (item.section, item.name))
113 raise error.ProgrammingError(msg % (item.section, item.name))
114 section[item.name] = item
114 section[item.name] = item
115
115
116
116
117 # special value for case where the default is derived from other values
117 # special value for case where the default is derived from other values
118 dynamicdefault = object()
118 dynamicdefault = object()
119
119
120 # Registering actual config items
120 # Registering actual config items
121
121
122
122
123 def getitemregister(configtable):
123 def getitemregister(configtable):
124 f = functools.partial(_register, configtable)
124 f = functools.partial(_register, configtable)
125 # export pseudo enum as configitem.*
125 # export pseudo enum as configitem.*
126 f.dynamicdefault = dynamicdefault
126 f.dynamicdefault = dynamicdefault
127 return f
127 return f
128
128
129
129
130 coreconfigitem = getitemregister(coreitems)
130 coreconfigitem = getitemregister(coreitems)
131
131
132
132
133 def _registerdiffopts(section, configprefix=b''):
133 def _registerdiffopts(section, configprefix=b''):
134 coreconfigitem(
134 coreconfigitem(
135 section,
135 section,
136 configprefix + b'nodates',
136 configprefix + b'nodates',
137 default=False,
137 default=False,
138 )
138 )
139 coreconfigitem(
139 coreconfigitem(
140 section,
140 section,
141 configprefix + b'showfunc',
141 configprefix + b'showfunc',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(
144 coreconfigitem(
145 section,
145 section,
146 configprefix + b'unified',
146 configprefix + b'unified',
147 default=None,
147 default=None,
148 )
148 )
149 coreconfigitem(
149 coreconfigitem(
150 section,
150 section,
151 configprefix + b'git',
151 configprefix + b'git',
152 default=False,
152 default=False,
153 )
153 )
154 coreconfigitem(
154 coreconfigitem(
155 section,
155 section,
156 configprefix + b'ignorews',
156 configprefix + b'ignorews',
157 default=False,
157 default=False,
158 )
158 )
159 coreconfigitem(
159 coreconfigitem(
160 section,
160 section,
161 configprefix + b'ignorewsamount',
161 configprefix + b'ignorewsamount',
162 default=False,
162 default=False,
163 )
163 )
164 coreconfigitem(
164 coreconfigitem(
165 section,
165 section,
166 configprefix + b'ignoreblanklines',
166 configprefix + b'ignoreblanklines',
167 default=False,
167 default=False,
168 )
168 )
169 coreconfigitem(
169 coreconfigitem(
170 section,
170 section,
171 configprefix + b'ignorewseol',
171 configprefix + b'ignorewseol',
172 default=False,
172 default=False,
173 )
173 )
174 coreconfigitem(
174 coreconfigitem(
175 section,
175 section,
176 configprefix + b'nobinary',
176 configprefix + b'nobinary',
177 default=False,
177 default=False,
178 )
178 )
179 coreconfigitem(
179 coreconfigitem(
180 section,
180 section,
181 configprefix + b'noprefix',
181 configprefix + b'noprefix',
182 default=False,
182 default=False,
183 )
183 )
184 coreconfigitem(
184 coreconfigitem(
185 section,
185 section,
186 configprefix + b'word-diff',
186 configprefix + b'word-diff',
187 default=False,
187 default=False,
188 )
188 )
189
189
190
190
191 coreconfigitem(
191 coreconfigitem(
192 b'alias',
192 b'alias',
193 b'.*',
193 b'.*',
194 default=dynamicdefault,
194 default=dynamicdefault,
195 generic=True,
195 generic=True,
196 )
196 )
197 coreconfigitem(
197 coreconfigitem(
198 b'auth',
198 b'auth',
199 b'cookiefile',
199 b'cookiefile',
200 default=None,
200 default=None,
201 )
201 )
202 _registerdiffopts(section=b'annotate')
202 _registerdiffopts(section=b'annotate')
203 # bookmarks.pushing: internal hack for discovery
203 # bookmarks.pushing: internal hack for discovery
204 coreconfigitem(
204 coreconfigitem(
205 b'bookmarks',
205 b'bookmarks',
206 b'pushing',
206 b'pushing',
207 default=list,
207 default=list,
208 )
208 )
209 # bundle.mainreporoot: internal hack for bundlerepo
209 # bundle.mainreporoot: internal hack for bundlerepo
210 coreconfigitem(
210 coreconfigitem(
211 b'bundle',
211 b'bundle',
212 b'mainreporoot',
212 b'mainreporoot',
213 default=b'',
213 default=b'',
214 )
214 )
215 coreconfigitem(
215 coreconfigitem(
216 b'censor',
216 b'censor',
217 b'policy',
217 b'policy',
218 default=b'abort',
218 default=b'abort',
219 experimental=True,
219 experimental=True,
220 )
220 )
221 coreconfigitem(
221 coreconfigitem(
222 b'chgserver',
222 b'chgserver',
223 b'idletimeout',
223 b'idletimeout',
224 default=3600,
224 default=3600,
225 )
225 )
226 coreconfigitem(
226 coreconfigitem(
227 b'chgserver',
227 b'chgserver',
228 b'skiphash',
228 b'skiphash',
229 default=False,
229 default=False,
230 )
230 )
231 coreconfigitem(
231 coreconfigitem(
232 b'cmdserver',
232 b'cmdserver',
233 b'log',
233 b'log',
234 default=None,
234 default=None,
235 )
235 )
236 coreconfigitem(
236 coreconfigitem(
237 b'cmdserver',
237 b'cmdserver',
238 b'max-log-files',
238 b'max-log-files',
239 default=7,
239 default=7,
240 )
240 )
241 coreconfigitem(
241 coreconfigitem(
242 b'cmdserver',
242 b'cmdserver',
243 b'max-log-size',
243 b'max-log-size',
244 default=b'1 MB',
244 default=b'1 MB',
245 )
245 )
246 coreconfigitem(
246 coreconfigitem(
247 b'cmdserver',
247 b'cmdserver',
248 b'max-repo-cache',
248 b'max-repo-cache',
249 default=0,
249 default=0,
250 experimental=True,
250 experimental=True,
251 )
251 )
252 coreconfigitem(
252 coreconfigitem(
253 b'cmdserver',
253 b'cmdserver',
254 b'message-encodings',
254 b'message-encodings',
255 default=list,
255 default=list,
256 )
256 )
257 coreconfigitem(
257 coreconfigitem(
258 b'cmdserver',
258 b'cmdserver',
259 b'track-log',
259 b'track-log',
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 )
261 )
262 coreconfigitem(
262 coreconfigitem(
263 b'cmdserver',
263 b'cmdserver',
264 b'shutdown-on-interrupt',
264 b'shutdown-on-interrupt',
265 default=True,
265 default=True,
266 )
266 )
267 coreconfigitem(
267 coreconfigitem(
268 b'color',
268 b'color',
269 b'.*',
269 b'.*',
270 default=None,
270 default=None,
271 generic=True,
271 generic=True,
272 )
272 )
273 coreconfigitem(
273 coreconfigitem(
274 b'color',
274 b'color',
275 b'mode',
275 b'mode',
276 default=b'auto',
276 default=b'auto',
277 )
277 )
278 coreconfigitem(
278 coreconfigitem(
279 b'color',
279 b'color',
280 b'pagermode',
280 b'pagermode',
281 default=dynamicdefault,
281 default=dynamicdefault,
282 )
282 )
283 coreconfigitem(
283 coreconfigitem(
284 b'command-templates',
284 b'command-templates',
285 b'graphnode',
285 b'graphnode',
286 default=None,
286 default=None,
287 alias=[(b'ui', b'graphnodetemplate')],
287 alias=[(b'ui', b'graphnodetemplate')],
288 )
288 )
289 coreconfigitem(
289 coreconfigitem(
290 b'command-templates',
290 b'command-templates',
291 b'log',
291 b'log',
292 default=None,
292 default=None,
293 alias=[(b'ui', b'logtemplate')],
293 alias=[(b'ui', b'logtemplate')],
294 )
294 )
295 coreconfigitem(
295 coreconfigitem(
296 b'command-templates',
296 b'command-templates',
297 b'mergemarker',
297 b'mergemarker',
298 default=(
298 default=(
299 b'{node|short} '
299 b'{node|short} '
300 b'{ifeq(tags, "tip", "", '
300 b'{ifeq(tags, "tip", "", '
301 b'ifeq(tags, "", "", "{tags} "))}'
301 b'ifeq(tags, "", "", "{tags} "))}'
302 b'{if(bookmarks, "{bookmarks} ")}'
302 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'- {author|user}: {desc|firstline}'
304 b'- {author|user}: {desc|firstline}'
305 ),
305 ),
306 alias=[(b'ui', b'mergemarkertemplate')],
306 alias=[(b'ui', b'mergemarkertemplate')],
307 )
307 )
308 coreconfigitem(
308 coreconfigitem(
309 b'command-templates',
309 b'command-templates',
310 b'pre-merge-tool-output',
310 b'pre-merge-tool-output',
311 default=None,
311 default=None,
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 )
313 )
314 coreconfigitem(
314 coreconfigitem(
315 b'command-templates',
315 b'command-templates',
316 b'oneline-summary',
316 b'oneline-summary',
317 default=None,
317 default=None,
318 )
318 )
319 coreconfigitem(
319 coreconfigitem(
320 b'command-templates',
320 b'command-templates',
321 b'oneline-summary.*',
321 b'oneline-summary.*',
322 default=dynamicdefault,
322 default=dynamicdefault,
323 generic=True,
323 generic=True,
324 )
324 )
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 coreconfigitem(
326 coreconfigitem(
327 b'commands',
327 b'commands',
328 b'commit.post-status',
328 b'commit.post-status',
329 default=False,
329 default=False,
330 )
330 )
331 coreconfigitem(
331 coreconfigitem(
332 b'commands',
332 b'commands',
333 b'grep.all-files',
333 b'grep.all-files',
334 default=False,
334 default=False,
335 experimental=True,
335 experimental=True,
336 )
336 )
337 coreconfigitem(
337 coreconfigitem(
338 b'commands',
338 b'commands',
339 b'merge.require-rev',
339 b'merge.require-rev',
340 default=False,
340 default=False,
341 )
341 )
342 coreconfigitem(
342 coreconfigitem(
343 b'commands',
343 b'commands',
344 b'push.require-revs',
344 b'push.require-revs',
345 default=False,
345 default=False,
346 )
346 )
347 coreconfigitem(
347 coreconfigitem(
348 b'commands',
348 b'commands',
349 b'resolve.confirm',
349 b'resolve.confirm',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem(
352 coreconfigitem(
353 b'commands',
353 b'commands',
354 b'resolve.explicit-re-merge',
354 b'resolve.explicit-re-merge',
355 default=False,
355 default=False,
356 )
356 )
357 coreconfigitem(
357 coreconfigitem(
358 b'commands',
358 b'commands',
359 b'resolve.mark-check',
359 b'resolve.mark-check',
360 default=b'none',
360 default=b'none',
361 )
361 )
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 coreconfigitem(
363 coreconfigitem(
364 b'commands',
364 b'commands',
365 b'show.aliasprefix',
365 b'show.aliasprefix',
366 default=list,
366 default=list,
367 )
367 )
368 coreconfigitem(
368 coreconfigitem(
369 b'commands',
369 b'commands',
370 b'status.relative',
370 b'status.relative',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem(
373 coreconfigitem(
374 b'commands',
374 b'commands',
375 b'status.skipstates',
375 b'status.skipstates',
376 default=[],
376 default=[],
377 experimental=True,
377 experimental=True,
378 )
378 )
379 coreconfigitem(
379 coreconfigitem(
380 b'commands',
380 b'commands',
381 b'status.terse',
381 b'status.terse',
382 default=b'',
382 default=b'',
383 )
383 )
384 coreconfigitem(
384 coreconfigitem(
385 b'commands',
385 b'commands',
386 b'status.verbose',
386 b'status.verbose',
387 default=False,
387 default=False,
388 )
388 )
389 coreconfigitem(
389 coreconfigitem(
390 b'commands',
390 b'commands',
391 b'update.check',
391 b'update.check',
392 default=None,
392 default=None,
393 )
393 )
394 coreconfigitem(
394 coreconfigitem(
395 b'commands',
395 b'commands',
396 b'update.requiredest',
396 b'update.requiredest',
397 default=False,
397 default=False,
398 )
398 )
399 coreconfigitem(
399 coreconfigitem(
400 b'committemplate',
400 b'committemplate',
401 b'.*',
401 b'.*',
402 default=None,
402 default=None,
403 generic=True,
403 generic=True,
404 )
404 )
405 coreconfigitem(
405 coreconfigitem(
406 b'convert',
406 b'convert',
407 b'bzr.saverev',
407 b'bzr.saverev',
408 default=True,
408 default=True,
409 )
409 )
410 coreconfigitem(
410 coreconfigitem(
411 b'convert',
411 b'convert',
412 b'cvsps.cache',
412 b'cvsps.cache',
413 default=True,
413 default=True,
414 )
414 )
415 coreconfigitem(
415 coreconfigitem(
416 b'convert',
416 b'convert',
417 b'cvsps.fuzz',
417 b'cvsps.fuzz',
418 default=60,
418 default=60,
419 )
419 )
420 coreconfigitem(
420 coreconfigitem(
421 b'convert',
421 b'convert',
422 b'cvsps.logencoding',
422 b'cvsps.logencoding',
423 default=None,
423 default=None,
424 )
424 )
425 coreconfigitem(
425 coreconfigitem(
426 b'convert',
426 b'convert',
427 b'cvsps.mergefrom',
427 b'cvsps.mergefrom',
428 default=None,
428 default=None,
429 )
429 )
430 coreconfigitem(
430 coreconfigitem(
431 b'convert',
431 b'convert',
432 b'cvsps.mergeto',
432 b'cvsps.mergeto',
433 default=None,
433 default=None,
434 )
434 )
435 coreconfigitem(
435 coreconfigitem(
436 b'convert',
436 b'convert',
437 b'git.committeractions',
437 b'git.committeractions',
438 default=lambda: [b'messagedifferent'],
438 default=lambda: [b'messagedifferent'],
439 )
439 )
440 coreconfigitem(
440 coreconfigitem(
441 b'convert',
441 b'convert',
442 b'git.extrakeys',
442 b'git.extrakeys',
443 default=list,
443 default=list,
444 )
444 )
445 coreconfigitem(
445 coreconfigitem(
446 b'convert',
446 b'convert',
447 b'git.findcopiesharder',
447 b'git.findcopiesharder',
448 default=False,
448 default=False,
449 )
449 )
450 coreconfigitem(
450 coreconfigitem(
451 b'convert',
451 b'convert',
452 b'git.remoteprefix',
452 b'git.remoteprefix',
453 default=b'remote',
453 default=b'remote',
454 )
454 )
455 coreconfigitem(
455 coreconfigitem(
456 b'convert',
456 b'convert',
457 b'git.renamelimit',
457 b'git.renamelimit',
458 default=400,
458 default=400,
459 )
459 )
460 coreconfigitem(
460 coreconfigitem(
461 b'convert',
461 b'convert',
462 b'git.saverev',
462 b'git.saverev',
463 default=True,
463 default=True,
464 )
464 )
465 coreconfigitem(
465 coreconfigitem(
466 b'convert',
466 b'convert',
467 b'git.similarity',
467 b'git.similarity',
468 default=50,
468 default=50,
469 )
469 )
470 coreconfigitem(
470 coreconfigitem(
471 b'convert',
471 b'convert',
472 b'git.skipsubmodules',
472 b'git.skipsubmodules',
473 default=False,
473 default=False,
474 )
474 )
475 coreconfigitem(
475 coreconfigitem(
476 b'convert',
476 b'convert',
477 b'hg.clonebranches',
477 b'hg.clonebranches',
478 default=False,
478 default=False,
479 )
479 )
480 coreconfigitem(
480 coreconfigitem(
481 b'convert',
481 b'convert',
482 b'hg.ignoreerrors',
482 b'hg.ignoreerrors',
483 default=False,
483 default=False,
484 )
484 )
485 coreconfigitem(
485 coreconfigitem(
486 b'convert',
486 b'convert',
487 b'hg.preserve-hash',
487 b'hg.preserve-hash',
488 default=False,
488 default=False,
489 )
489 )
490 coreconfigitem(
490 coreconfigitem(
491 b'convert',
491 b'convert',
492 b'hg.revs',
492 b'hg.revs',
493 default=None,
493 default=None,
494 )
494 )
495 coreconfigitem(
495 coreconfigitem(
496 b'convert',
496 b'convert',
497 b'hg.saverev',
497 b'hg.saverev',
498 default=False,
498 default=False,
499 )
499 )
500 coreconfigitem(
500 coreconfigitem(
501 b'convert',
501 b'convert',
502 b'hg.sourcename',
502 b'hg.sourcename',
503 default=None,
503 default=None,
504 )
504 )
505 coreconfigitem(
505 coreconfigitem(
506 b'convert',
506 b'convert',
507 b'hg.startrev',
507 b'hg.startrev',
508 default=None,
508 default=None,
509 )
509 )
510 coreconfigitem(
510 coreconfigitem(
511 b'convert',
511 b'convert',
512 b'hg.tagsbranch',
512 b'hg.tagsbranch',
513 default=b'default',
513 default=b'default',
514 )
514 )
515 coreconfigitem(
515 coreconfigitem(
516 b'convert',
516 b'convert',
517 b'hg.usebranchnames',
517 b'hg.usebranchnames',
518 default=True,
518 default=True,
519 )
519 )
520 coreconfigitem(
520 coreconfigitem(
521 b'convert',
521 b'convert',
522 b'ignoreancestorcheck',
522 b'ignoreancestorcheck',
523 default=False,
523 default=False,
524 experimental=True,
524 experimental=True,
525 )
525 )
526 coreconfigitem(
526 coreconfigitem(
527 b'convert',
527 b'convert',
528 b'localtimezone',
528 b'localtimezone',
529 default=False,
529 default=False,
530 )
530 )
531 coreconfigitem(
531 coreconfigitem(
532 b'convert',
532 b'convert',
533 b'p4.encoding',
533 b'p4.encoding',
534 default=dynamicdefault,
534 default=dynamicdefault,
535 )
535 )
536 coreconfigitem(
536 coreconfigitem(
537 b'convert',
537 b'convert',
538 b'p4.startrev',
538 b'p4.startrev',
539 default=0,
539 default=0,
540 )
540 )
541 coreconfigitem(
541 coreconfigitem(
542 b'convert',
542 b'convert',
543 b'skiptags',
543 b'skiptags',
544 default=False,
544 default=False,
545 )
545 )
546 coreconfigitem(
546 coreconfigitem(
547 b'convert',
547 b'convert',
548 b'svn.debugsvnlog',
548 b'svn.debugsvnlog',
549 default=True,
549 default=True,
550 )
550 )
551 coreconfigitem(
551 coreconfigitem(
552 b'convert',
552 b'convert',
553 b'svn.trunk',
553 b'svn.trunk',
554 default=None,
554 default=None,
555 )
555 )
556 coreconfigitem(
556 coreconfigitem(
557 b'convert',
557 b'convert',
558 b'svn.tags',
558 b'svn.tags',
559 default=None,
559 default=None,
560 )
560 )
561 coreconfigitem(
561 coreconfigitem(
562 b'convert',
562 b'convert',
563 b'svn.branches',
563 b'svn.branches',
564 default=None,
564 default=None,
565 )
565 )
566 coreconfigitem(
566 coreconfigitem(
567 b'convert',
567 b'convert',
568 b'svn.startrev',
568 b'svn.startrev',
569 default=0,
569 default=0,
570 )
570 )
571 coreconfigitem(
571 coreconfigitem(
572 b'convert',
572 b'convert',
573 b'svn.dangerous-set-commit-dates',
573 b'svn.dangerous-set-commit-dates',
574 default=False,
574 default=False,
575 )
575 )
576 coreconfigitem(
576 coreconfigitem(
577 b'debug',
577 b'debug',
578 b'dirstate.delaywrite',
578 b'dirstate.delaywrite',
579 default=0,
579 default=0,
580 )
580 )
581 coreconfigitem(
581 coreconfigitem(
582 b'debug',
582 b'debug',
583 b'revlog.verifyposition.changelog',
583 b'revlog.verifyposition.changelog',
584 default=b'',
584 default=b'',
585 )
585 )
586 coreconfigitem(
586 coreconfigitem(
587 b'debug',
587 b'debug',
588 b'revlog.debug-delta',
588 b'revlog.debug-delta',
589 default=False,
589 default=False,
590 )
590 )
591 coreconfigitem(
591 coreconfigitem(
592 b'defaults',
592 b'defaults',
593 b'.*',
593 b'.*',
594 default=None,
594 default=None,
595 generic=True,
595 generic=True,
596 )
596 )
597 coreconfigitem(
597 coreconfigitem(
598 b'devel',
598 b'devel',
599 b'all-warnings',
599 b'all-warnings',
600 default=False,
600 default=False,
601 )
601 )
602 coreconfigitem(
602 coreconfigitem(
603 b'devel',
603 b'devel',
604 b'bundle2.debug',
604 b'bundle2.debug',
605 default=False,
605 default=False,
606 )
606 )
607 coreconfigitem(
607 coreconfigitem(
608 b'devel',
608 b'devel',
609 b'bundle.delta',
609 b'bundle.delta',
610 default=b'',
610 default=b'',
611 )
611 )
612 coreconfigitem(
612 coreconfigitem(
613 b'devel',
613 b'devel',
614 b'cache-vfs',
614 b'cache-vfs',
615 default=None,
615 default=None,
616 )
616 )
617 coreconfigitem(
617 coreconfigitem(
618 b'devel',
618 b'devel',
619 b'check-locks',
619 b'check-locks',
620 default=False,
620 default=False,
621 )
621 )
622 coreconfigitem(
622 coreconfigitem(
623 b'devel',
623 b'devel',
624 b'check-relroot',
624 b'check-relroot',
625 default=False,
625 default=False,
626 )
626 )
627 # Track copy information for all file, not just "added" one (very slow)
627 # Track copy information for all file, not just "added" one (very slow)
628 coreconfigitem(
628 coreconfigitem(
629 b'devel',
629 b'devel',
630 b'copy-tracing.trace-all-files',
630 b'copy-tracing.trace-all-files',
631 default=False,
631 default=False,
632 )
632 )
633 coreconfigitem(
633 coreconfigitem(
634 b'devel',
634 b'devel',
635 b'default-date',
635 b'default-date',
636 default=None,
636 default=None,
637 )
637 )
638 coreconfigitem(
638 coreconfigitem(
639 b'devel',
639 b'devel',
640 b'deprec-warn',
640 b'deprec-warn',
641 default=False,
641 default=False,
642 )
642 )
643 # possible values:
643 # possible values:
644 # - auto (the default)
644 # - auto (the default)
645 # - force-append
645 # - force-append
646 # - force-new
646 # - force-new
647 coreconfigitem(
647 coreconfigitem(
648 b'devel',
648 b'devel',
649 b'dirstate.v2.data_update_mode',
649 b'dirstate.v2.data_update_mode',
650 default="auto",
650 default="auto",
651 )
651 )
652 coreconfigitem(
652 coreconfigitem(
653 b'devel',
653 b'devel',
654 b'disableloaddefaultcerts',
654 b'disableloaddefaultcerts',
655 default=False,
655 default=False,
656 )
656 )
657 coreconfigitem(
657 coreconfigitem(
658 b'devel',
658 b'devel',
659 b'warn-empty-changegroup',
659 b'warn-empty-changegroup',
660 default=False,
660 default=False,
661 )
661 )
662 coreconfigitem(
662 coreconfigitem(
663 b'devel',
663 b'devel',
664 b'legacy.exchange',
664 b'legacy.exchange',
665 default=list,
665 default=list,
666 )
666 )
667 # When True, revlogs use a special reference version of the nodemap, that is not
667 # When True, revlogs use a special reference version of the nodemap, that is not
668 # performant but is "known" to behave properly.
668 # performant but is "known" to behave properly.
669 coreconfigitem(
669 coreconfigitem(
670 b'devel',
670 b'devel',
671 b'persistent-nodemap',
671 b'persistent-nodemap',
672 default=False,
672 default=False,
673 )
673 )
674 coreconfigitem(
674 coreconfigitem(
675 b'devel',
675 b'devel',
676 b'servercafile',
676 b'servercafile',
677 default=b'',
677 default=b'',
678 )
678 )
679 coreconfigitem(
679 coreconfigitem(
680 b'devel',
680 b'devel',
681 b'serverexactprotocol',
681 b'serverexactprotocol',
682 default=b'',
682 default=b'',
683 )
683 )
684 coreconfigitem(
684 coreconfigitem(
685 b'devel',
685 b'devel',
686 b'serverrequirecert',
686 b'serverrequirecert',
687 default=False,
687 default=False,
688 )
688 )
689 # Makes the status algorithm wait for the existence of this file
689 # Makes the status algorithm wait for the existence of this file
690 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
690 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
691 # seconds) before taking the lock and writing the dirstate.
691 # seconds) before taking the lock and writing the dirstate.
692 # Status signals that it's ready to wait by creating a file
692 # Status signals that it's ready to wait by creating a file
693 # with the same name + `.waiting`.
693 # with the same name + `.waiting`.
694 # Useful when testing race conditions.
694 # Useful when testing race conditions.
695 coreconfigitem(
695 coreconfigitem(
696 b'devel',
696 b'devel',
697 b'sync.status.pre-dirstate-write-file',
697 b'sync.status.pre-dirstate-write-file',
698 default=None,
698 default=None,
699 )
699 )
700 coreconfigitem(
700 coreconfigitem(
701 b'devel',
701 b'devel',
702 b'sync.status.pre-dirstate-write-file-timeout',
702 b'sync.status.pre-dirstate-write-file-timeout',
703 default=2,
703 default=2,
704 )
704 )
705 coreconfigitem(
705 coreconfigitem(
706 b'devel',
706 b'devel',
707 b'sync.dirstate.post-docket-read-file',
708 default=None,
709 )
710 coreconfigitem(
711 b'devel',
712 b'sync.dirstate.post-docket-read-file-timeout',
713 default=2,
714 )
715 coreconfigitem(
716 b'devel',
707 b'sync.dirstate.pre-read-file',
717 b'sync.dirstate.pre-read-file',
708 default=None,
718 default=None,
709 )
719 )
710 coreconfigitem(
720 coreconfigitem(
711 b'devel',
721 b'devel',
712 b'sync.dirstate.pre-read-file-timeout',
722 b'sync.dirstate.pre-read-file-timeout',
713 default=2,
723 default=2,
714 )
724 )
715 coreconfigitem(
725 coreconfigitem(
716 b'devel',
726 b'devel',
717 b'strip-obsmarkers',
727 b'strip-obsmarkers',
718 default=True,
728 default=True,
719 )
729 )
720 coreconfigitem(
730 coreconfigitem(
721 b'devel',
731 b'devel',
722 b'warn-config',
732 b'warn-config',
723 default=None,
733 default=None,
724 )
734 )
725 coreconfigitem(
735 coreconfigitem(
726 b'devel',
736 b'devel',
727 b'warn-config-default',
737 b'warn-config-default',
728 default=None,
738 default=None,
729 )
739 )
730 coreconfigitem(
740 coreconfigitem(
731 b'devel',
741 b'devel',
732 b'user.obsmarker',
742 b'user.obsmarker',
733 default=None,
743 default=None,
734 )
744 )
735 coreconfigitem(
745 coreconfigitem(
736 b'devel',
746 b'devel',
737 b'warn-config-unknown',
747 b'warn-config-unknown',
738 default=None,
748 default=None,
739 )
749 )
740 coreconfigitem(
750 coreconfigitem(
741 b'devel',
751 b'devel',
742 b'debug.copies',
752 b'debug.copies',
743 default=False,
753 default=False,
744 )
754 )
745 coreconfigitem(
755 coreconfigitem(
746 b'devel',
756 b'devel',
747 b'copy-tracing.multi-thread',
757 b'copy-tracing.multi-thread',
748 default=True,
758 default=True,
749 )
759 )
750 coreconfigitem(
760 coreconfigitem(
751 b'devel',
761 b'devel',
752 b'debug.extensions',
762 b'debug.extensions',
753 default=False,
763 default=False,
754 )
764 )
755 coreconfigitem(
765 coreconfigitem(
756 b'devel',
766 b'devel',
757 b'debug.repo-filters',
767 b'debug.repo-filters',
758 default=False,
768 default=False,
759 )
769 )
760 coreconfigitem(
770 coreconfigitem(
761 b'devel',
771 b'devel',
762 b'debug.peer-request',
772 b'debug.peer-request',
763 default=False,
773 default=False,
764 )
774 )
765 # If discovery.exchange-heads is False, the discovery will not start with
775 # If discovery.exchange-heads is False, the discovery will not start with
766 # remote head fetching and local head querying.
776 # remote head fetching and local head querying.
767 coreconfigitem(
777 coreconfigitem(
768 b'devel',
778 b'devel',
769 b'discovery.exchange-heads',
779 b'discovery.exchange-heads',
770 default=True,
780 default=True,
771 )
781 )
772 # If discovery.grow-sample is False, the sample size used in set discovery will
782 # If discovery.grow-sample is False, the sample size used in set discovery will
773 # not be increased through the process
783 # not be increased through the process
774 coreconfigitem(
784 coreconfigitem(
775 b'devel',
785 b'devel',
776 b'discovery.grow-sample',
786 b'discovery.grow-sample',
777 default=True,
787 default=True,
778 )
788 )
779 # When discovery.grow-sample.dynamic is True, the default, the sample size is
789 # When discovery.grow-sample.dynamic is True, the default, the sample size is
780 # adapted to the shape of the undecided set (it is set to the max of:
790 # adapted to the shape of the undecided set (it is set to the max of:
781 # <target-size>, len(roots(undecided)), len(heads(undecided)
791 # <target-size>, len(roots(undecided)), len(heads(undecided)
782 coreconfigitem(
792 coreconfigitem(
783 b'devel',
793 b'devel',
784 b'discovery.grow-sample.dynamic',
794 b'discovery.grow-sample.dynamic',
785 default=True,
795 default=True,
786 )
796 )
787 # discovery.grow-sample.rate control the rate at which the sample grow
797 # discovery.grow-sample.rate control the rate at which the sample grow
788 coreconfigitem(
798 coreconfigitem(
789 b'devel',
799 b'devel',
790 b'discovery.grow-sample.rate',
800 b'discovery.grow-sample.rate',
791 default=1.05,
801 default=1.05,
792 )
802 )
793 # If discovery.randomize is False, random sampling during discovery are
803 # If discovery.randomize is False, random sampling during discovery are
794 # deterministic. It is meant for integration tests.
804 # deterministic. It is meant for integration tests.
795 coreconfigitem(
805 coreconfigitem(
796 b'devel',
806 b'devel',
797 b'discovery.randomize',
807 b'discovery.randomize',
798 default=True,
808 default=True,
799 )
809 )
800 # Control the initial size of the discovery sample
810 # Control the initial size of the discovery sample
801 coreconfigitem(
811 coreconfigitem(
802 b'devel',
812 b'devel',
803 b'discovery.sample-size',
813 b'discovery.sample-size',
804 default=200,
814 default=200,
805 )
815 )
806 # Control the initial size of the discovery for initial change
816 # Control the initial size of the discovery for initial change
807 coreconfigitem(
817 coreconfigitem(
808 b'devel',
818 b'devel',
809 b'discovery.sample-size.initial',
819 b'discovery.sample-size.initial',
810 default=100,
820 default=100,
811 )
821 )
812 _registerdiffopts(section=b'diff')
822 _registerdiffopts(section=b'diff')
813 coreconfigitem(
823 coreconfigitem(
814 b'diff',
824 b'diff',
815 b'merge',
825 b'merge',
816 default=False,
826 default=False,
817 experimental=True,
827 experimental=True,
818 )
828 )
819 coreconfigitem(
829 coreconfigitem(
820 b'email',
830 b'email',
821 b'bcc',
831 b'bcc',
822 default=None,
832 default=None,
823 )
833 )
824 coreconfigitem(
834 coreconfigitem(
825 b'email',
835 b'email',
826 b'cc',
836 b'cc',
827 default=None,
837 default=None,
828 )
838 )
829 coreconfigitem(
839 coreconfigitem(
830 b'email',
840 b'email',
831 b'charsets',
841 b'charsets',
832 default=list,
842 default=list,
833 )
843 )
834 coreconfigitem(
844 coreconfigitem(
835 b'email',
845 b'email',
836 b'from',
846 b'from',
837 default=None,
847 default=None,
838 )
848 )
839 coreconfigitem(
849 coreconfigitem(
840 b'email',
850 b'email',
841 b'method',
851 b'method',
842 default=b'smtp',
852 default=b'smtp',
843 )
853 )
844 coreconfigitem(
854 coreconfigitem(
845 b'email',
855 b'email',
846 b'reply-to',
856 b'reply-to',
847 default=None,
857 default=None,
848 )
858 )
849 coreconfigitem(
859 coreconfigitem(
850 b'email',
860 b'email',
851 b'to',
861 b'to',
852 default=None,
862 default=None,
853 )
863 )
854 coreconfigitem(
864 coreconfigitem(
855 b'experimental',
865 b'experimental',
856 b'archivemetatemplate',
866 b'archivemetatemplate',
857 default=dynamicdefault,
867 default=dynamicdefault,
858 )
868 )
859 coreconfigitem(
869 coreconfigitem(
860 b'experimental',
870 b'experimental',
861 b'auto-publish',
871 b'auto-publish',
862 default=b'publish',
872 default=b'publish',
863 )
873 )
864 coreconfigitem(
874 coreconfigitem(
865 b'experimental',
875 b'experimental',
866 b'bundle-phases',
876 b'bundle-phases',
867 default=False,
877 default=False,
868 )
878 )
869 coreconfigitem(
879 coreconfigitem(
870 b'experimental',
880 b'experimental',
871 b'bundle2-advertise',
881 b'bundle2-advertise',
872 default=True,
882 default=True,
873 )
883 )
874 coreconfigitem(
884 coreconfigitem(
875 b'experimental',
885 b'experimental',
876 b'bundle2-output-capture',
886 b'bundle2-output-capture',
877 default=False,
887 default=False,
878 )
888 )
879 coreconfigitem(
889 coreconfigitem(
880 b'experimental',
890 b'experimental',
881 b'bundle2.pushback',
891 b'bundle2.pushback',
882 default=False,
892 default=False,
883 )
893 )
884 coreconfigitem(
894 coreconfigitem(
885 b'experimental',
895 b'experimental',
886 b'bundle2lazylocking',
896 b'bundle2lazylocking',
887 default=False,
897 default=False,
888 )
898 )
889 coreconfigitem(
899 coreconfigitem(
890 b'experimental',
900 b'experimental',
891 b'bundlecomplevel',
901 b'bundlecomplevel',
892 default=None,
902 default=None,
893 )
903 )
894 coreconfigitem(
904 coreconfigitem(
895 b'experimental',
905 b'experimental',
896 b'bundlecomplevel.bzip2',
906 b'bundlecomplevel.bzip2',
897 default=None,
907 default=None,
898 )
908 )
899 coreconfigitem(
909 coreconfigitem(
900 b'experimental',
910 b'experimental',
901 b'bundlecomplevel.gzip',
911 b'bundlecomplevel.gzip',
902 default=None,
912 default=None,
903 )
913 )
904 coreconfigitem(
914 coreconfigitem(
905 b'experimental',
915 b'experimental',
906 b'bundlecomplevel.none',
916 b'bundlecomplevel.none',
907 default=None,
917 default=None,
908 )
918 )
909 coreconfigitem(
919 coreconfigitem(
910 b'experimental',
920 b'experimental',
911 b'bundlecomplevel.zstd',
921 b'bundlecomplevel.zstd',
912 default=None,
922 default=None,
913 )
923 )
914 coreconfigitem(
924 coreconfigitem(
915 b'experimental',
925 b'experimental',
916 b'bundlecompthreads',
926 b'bundlecompthreads',
917 default=None,
927 default=None,
918 )
928 )
919 coreconfigitem(
929 coreconfigitem(
920 b'experimental',
930 b'experimental',
921 b'bundlecompthreads.bzip2',
931 b'bundlecompthreads.bzip2',
922 default=None,
932 default=None,
923 )
933 )
924 coreconfigitem(
934 coreconfigitem(
925 b'experimental',
935 b'experimental',
926 b'bundlecompthreads.gzip',
936 b'bundlecompthreads.gzip',
927 default=None,
937 default=None,
928 )
938 )
929 coreconfigitem(
939 coreconfigitem(
930 b'experimental',
940 b'experimental',
931 b'bundlecompthreads.none',
941 b'bundlecompthreads.none',
932 default=None,
942 default=None,
933 )
943 )
934 coreconfigitem(
944 coreconfigitem(
935 b'experimental',
945 b'experimental',
936 b'bundlecompthreads.zstd',
946 b'bundlecompthreads.zstd',
937 default=None,
947 default=None,
938 )
948 )
939 coreconfigitem(
949 coreconfigitem(
940 b'experimental',
950 b'experimental',
941 b'changegroup3',
951 b'changegroup3',
942 default=False,
952 default=False,
943 )
953 )
944 coreconfigitem(
954 coreconfigitem(
945 b'experimental',
955 b'experimental',
946 b'changegroup4',
956 b'changegroup4',
947 default=False,
957 default=False,
948 )
958 )
949 coreconfigitem(
959 coreconfigitem(
950 b'experimental',
960 b'experimental',
951 b'cleanup-as-archived',
961 b'cleanup-as-archived',
952 default=False,
962 default=False,
953 )
963 )
954 coreconfigitem(
964 coreconfigitem(
955 b'experimental',
965 b'experimental',
956 b'clientcompressionengines',
966 b'clientcompressionengines',
957 default=list,
967 default=list,
958 )
968 )
959 coreconfigitem(
969 coreconfigitem(
960 b'experimental',
970 b'experimental',
961 b'copytrace',
971 b'copytrace',
962 default=b'on',
972 default=b'on',
963 )
973 )
964 coreconfigitem(
974 coreconfigitem(
965 b'experimental',
975 b'experimental',
966 b'copytrace.movecandidateslimit',
976 b'copytrace.movecandidateslimit',
967 default=100,
977 default=100,
968 )
978 )
969 coreconfigitem(
979 coreconfigitem(
970 b'experimental',
980 b'experimental',
971 b'copytrace.sourcecommitlimit',
981 b'copytrace.sourcecommitlimit',
972 default=100,
982 default=100,
973 )
983 )
974 coreconfigitem(
984 coreconfigitem(
975 b'experimental',
985 b'experimental',
976 b'copies.read-from',
986 b'copies.read-from',
977 default=b"filelog-only",
987 default=b"filelog-only",
978 )
988 )
979 coreconfigitem(
989 coreconfigitem(
980 b'experimental',
990 b'experimental',
981 b'copies.write-to',
991 b'copies.write-to',
982 default=b'filelog-only',
992 default=b'filelog-only',
983 )
993 )
984 coreconfigitem(
994 coreconfigitem(
985 b'experimental',
995 b'experimental',
986 b'crecordtest',
996 b'crecordtest',
987 default=None,
997 default=None,
988 )
998 )
989 coreconfigitem(
999 coreconfigitem(
990 b'experimental',
1000 b'experimental',
991 b'directaccess',
1001 b'directaccess',
992 default=False,
1002 default=False,
993 )
1003 )
994 coreconfigitem(
1004 coreconfigitem(
995 b'experimental',
1005 b'experimental',
996 b'directaccess.revnums',
1006 b'directaccess.revnums',
997 default=False,
1007 default=False,
998 )
1008 )
999 coreconfigitem(
1009 coreconfigitem(
1000 b'experimental',
1010 b'experimental',
1001 b'editortmpinhg',
1011 b'editortmpinhg',
1002 default=False,
1012 default=False,
1003 )
1013 )
1004 coreconfigitem(
1014 coreconfigitem(
1005 b'experimental',
1015 b'experimental',
1006 b'evolution',
1016 b'evolution',
1007 default=list,
1017 default=list,
1008 )
1018 )
1009 coreconfigitem(
1019 coreconfigitem(
1010 b'experimental',
1020 b'experimental',
1011 b'evolution.allowdivergence',
1021 b'evolution.allowdivergence',
1012 default=False,
1022 default=False,
1013 alias=[(b'experimental', b'allowdivergence')],
1023 alias=[(b'experimental', b'allowdivergence')],
1014 )
1024 )
1015 coreconfigitem(
1025 coreconfigitem(
1016 b'experimental',
1026 b'experimental',
1017 b'evolution.allowunstable',
1027 b'evolution.allowunstable',
1018 default=None,
1028 default=None,
1019 )
1029 )
1020 coreconfigitem(
1030 coreconfigitem(
1021 b'experimental',
1031 b'experimental',
1022 b'evolution.createmarkers',
1032 b'evolution.createmarkers',
1023 default=None,
1033 default=None,
1024 )
1034 )
1025 coreconfigitem(
1035 coreconfigitem(
1026 b'experimental',
1036 b'experimental',
1027 b'evolution.effect-flags',
1037 b'evolution.effect-flags',
1028 default=True,
1038 default=True,
1029 alias=[(b'experimental', b'effect-flags')],
1039 alias=[(b'experimental', b'effect-flags')],
1030 )
1040 )
1031 coreconfigitem(
1041 coreconfigitem(
1032 b'experimental',
1042 b'experimental',
1033 b'evolution.exchange',
1043 b'evolution.exchange',
1034 default=None,
1044 default=None,
1035 )
1045 )
1036 coreconfigitem(
1046 coreconfigitem(
1037 b'experimental',
1047 b'experimental',
1038 b'evolution.bundle-obsmarker',
1048 b'evolution.bundle-obsmarker',
1039 default=False,
1049 default=False,
1040 )
1050 )
1041 coreconfigitem(
1051 coreconfigitem(
1042 b'experimental',
1052 b'experimental',
1043 b'evolution.bundle-obsmarker:mandatory',
1053 b'evolution.bundle-obsmarker:mandatory',
1044 default=True,
1054 default=True,
1045 )
1055 )
1046 coreconfigitem(
1056 coreconfigitem(
1047 b'experimental',
1057 b'experimental',
1048 b'log.topo',
1058 b'log.topo',
1049 default=False,
1059 default=False,
1050 )
1060 )
1051 coreconfigitem(
1061 coreconfigitem(
1052 b'experimental',
1062 b'experimental',
1053 b'evolution.report-instabilities',
1063 b'evolution.report-instabilities',
1054 default=True,
1064 default=True,
1055 )
1065 )
1056 coreconfigitem(
1066 coreconfigitem(
1057 b'experimental',
1067 b'experimental',
1058 b'evolution.track-operation',
1068 b'evolution.track-operation',
1059 default=True,
1069 default=True,
1060 )
1070 )
1061 # repo-level config to exclude a revset visibility
1071 # repo-level config to exclude a revset visibility
1062 #
1072 #
1063 # The target use case is to use `share` to expose different subset of the same
1073 # The target use case is to use `share` to expose different subset of the same
1064 # repository, especially server side. See also `server.view`.
1074 # repository, especially server side. See also `server.view`.
1065 coreconfigitem(
1075 coreconfigitem(
1066 b'experimental',
1076 b'experimental',
1067 b'extra-filter-revs',
1077 b'extra-filter-revs',
1068 default=None,
1078 default=None,
1069 )
1079 )
1070 coreconfigitem(
1080 coreconfigitem(
1071 b'experimental',
1081 b'experimental',
1072 b'maxdeltachainspan',
1082 b'maxdeltachainspan',
1073 default=-1,
1083 default=-1,
1074 )
1084 )
1075 # tracks files which were undeleted (merge might delete them but we explicitly
1085 # tracks files which were undeleted (merge might delete them but we explicitly
1076 # kept/undeleted them) and creates new filenodes for them
1086 # kept/undeleted them) and creates new filenodes for them
1077 coreconfigitem(
1087 coreconfigitem(
1078 b'experimental',
1088 b'experimental',
1079 b'merge-track-salvaged',
1089 b'merge-track-salvaged',
1080 default=False,
1090 default=False,
1081 )
1091 )
1082 coreconfigitem(
1092 coreconfigitem(
1083 b'experimental',
1093 b'experimental',
1084 b'mmapindexthreshold',
1094 b'mmapindexthreshold',
1085 default=None,
1095 default=None,
1086 )
1096 )
1087 coreconfigitem(
1097 coreconfigitem(
1088 b'experimental',
1098 b'experimental',
1089 b'narrow',
1099 b'narrow',
1090 default=False,
1100 default=False,
1091 )
1101 )
1092 coreconfigitem(
1102 coreconfigitem(
1093 b'experimental',
1103 b'experimental',
1094 b'nonnormalparanoidcheck',
1104 b'nonnormalparanoidcheck',
1095 default=False,
1105 default=False,
1096 )
1106 )
1097 coreconfigitem(
1107 coreconfigitem(
1098 b'experimental',
1108 b'experimental',
1099 b'exportableenviron',
1109 b'exportableenviron',
1100 default=list,
1110 default=list,
1101 )
1111 )
1102 coreconfigitem(
1112 coreconfigitem(
1103 b'experimental',
1113 b'experimental',
1104 b'extendedheader.index',
1114 b'extendedheader.index',
1105 default=None,
1115 default=None,
1106 )
1116 )
1107 coreconfigitem(
1117 coreconfigitem(
1108 b'experimental',
1118 b'experimental',
1109 b'extendedheader.similarity',
1119 b'extendedheader.similarity',
1110 default=False,
1120 default=False,
1111 )
1121 )
1112 coreconfigitem(
1122 coreconfigitem(
1113 b'experimental',
1123 b'experimental',
1114 b'graphshorten',
1124 b'graphshorten',
1115 default=False,
1125 default=False,
1116 )
1126 )
1117 coreconfigitem(
1127 coreconfigitem(
1118 b'experimental',
1128 b'experimental',
1119 b'graphstyle.parent',
1129 b'graphstyle.parent',
1120 default=dynamicdefault,
1130 default=dynamicdefault,
1121 )
1131 )
1122 coreconfigitem(
1132 coreconfigitem(
1123 b'experimental',
1133 b'experimental',
1124 b'graphstyle.missing',
1134 b'graphstyle.missing',
1125 default=dynamicdefault,
1135 default=dynamicdefault,
1126 )
1136 )
1127 coreconfigitem(
1137 coreconfigitem(
1128 b'experimental',
1138 b'experimental',
1129 b'graphstyle.grandparent',
1139 b'graphstyle.grandparent',
1130 default=dynamicdefault,
1140 default=dynamicdefault,
1131 )
1141 )
1132 coreconfigitem(
1142 coreconfigitem(
1133 b'experimental',
1143 b'experimental',
1134 b'hook-track-tags',
1144 b'hook-track-tags',
1135 default=False,
1145 default=False,
1136 )
1146 )
1137 coreconfigitem(
1147 coreconfigitem(
1138 b'experimental',
1148 b'experimental',
1139 b'httppostargs',
1149 b'httppostargs',
1140 default=False,
1150 default=False,
1141 )
1151 )
1142 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1152 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1143 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1153 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1144
1154
1145 coreconfigitem(
1155 coreconfigitem(
1146 b'experimental',
1156 b'experimental',
1147 b'obsmarkers-exchange-debug',
1157 b'obsmarkers-exchange-debug',
1148 default=False,
1158 default=False,
1149 )
1159 )
1150 coreconfigitem(
1160 coreconfigitem(
1151 b'experimental',
1161 b'experimental',
1152 b'remotenames',
1162 b'remotenames',
1153 default=False,
1163 default=False,
1154 )
1164 )
1155 coreconfigitem(
1165 coreconfigitem(
1156 b'experimental',
1166 b'experimental',
1157 b'removeemptydirs',
1167 b'removeemptydirs',
1158 default=True,
1168 default=True,
1159 )
1169 )
1160 coreconfigitem(
1170 coreconfigitem(
1161 b'experimental',
1171 b'experimental',
1162 b'revert.interactive.select-to-keep',
1172 b'revert.interactive.select-to-keep',
1163 default=False,
1173 default=False,
1164 )
1174 )
1165 coreconfigitem(
1175 coreconfigitem(
1166 b'experimental',
1176 b'experimental',
1167 b'revisions.prefixhexnode',
1177 b'revisions.prefixhexnode',
1168 default=False,
1178 default=False,
1169 )
1179 )
1170 # "out of experimental" todo list.
1180 # "out of experimental" todo list.
1171 #
1181 #
1172 # * include management of a persistent nodemap in the main docket
1182 # * include management of a persistent nodemap in the main docket
1173 # * enforce a "no-truncate" policy for mmap safety
1183 # * enforce a "no-truncate" policy for mmap safety
1174 # - for censoring operation
1184 # - for censoring operation
1175 # - for stripping operation
1185 # - for stripping operation
1176 # - for rollback operation
1186 # - for rollback operation
1177 # * proper streaming (race free) of the docket file
1187 # * proper streaming (race free) of the docket file
1178 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1188 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1179 # * Exchange-wise, we will also need to do something more efficient than
1189 # * Exchange-wise, we will also need to do something more efficient than
1180 # keeping references to the affected revlogs, especially memory-wise when
1190 # keeping references to the affected revlogs, especially memory-wise when
1181 # rewriting sidedata.
1191 # rewriting sidedata.
1182 # * introduce a proper solution to reduce the number of filelog related files.
1192 # * introduce a proper solution to reduce the number of filelog related files.
1183 # * use caching for reading sidedata (similar to what we do for data).
1193 # * use caching for reading sidedata (similar to what we do for data).
1184 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1194 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1185 # * Improvement to consider
1195 # * Improvement to consider
1186 # - avoid compression header in chunk using the default compression?
1196 # - avoid compression header in chunk using the default compression?
1187 # - forbid "inline" compression mode entirely?
1197 # - forbid "inline" compression mode entirely?
1188 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1198 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1189 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1199 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1190 # - keep track of chain base or size (probably not that useful anymore)
1200 # - keep track of chain base or size (probably not that useful anymore)
1191 coreconfigitem(
1201 coreconfigitem(
1192 b'experimental',
1202 b'experimental',
1193 b'revlogv2',
1203 b'revlogv2',
1194 default=None,
1204 default=None,
1195 )
1205 )
1196 coreconfigitem(
1206 coreconfigitem(
1197 b'experimental',
1207 b'experimental',
1198 b'revisions.disambiguatewithin',
1208 b'revisions.disambiguatewithin',
1199 default=None,
1209 default=None,
1200 )
1210 )
1201 coreconfigitem(
1211 coreconfigitem(
1202 b'experimental',
1212 b'experimental',
1203 b'rust.index',
1213 b'rust.index',
1204 default=False,
1214 default=False,
1205 )
1215 )
1206 coreconfigitem(
1216 coreconfigitem(
1207 b'experimental',
1217 b'experimental',
1208 b'server.filesdata.recommended-batch-size',
1218 b'server.filesdata.recommended-batch-size',
1209 default=50000,
1219 default=50000,
1210 )
1220 )
1211 coreconfigitem(
1221 coreconfigitem(
1212 b'experimental',
1222 b'experimental',
1213 b'server.manifestdata.recommended-batch-size',
1223 b'server.manifestdata.recommended-batch-size',
1214 default=100000,
1224 default=100000,
1215 )
1225 )
1216 coreconfigitem(
1226 coreconfigitem(
1217 b'experimental',
1227 b'experimental',
1218 b'server.stream-narrow-clones',
1228 b'server.stream-narrow-clones',
1219 default=False,
1229 default=False,
1220 )
1230 )
1221 coreconfigitem(
1231 coreconfigitem(
1222 b'experimental',
1232 b'experimental',
1223 b'single-head-per-branch',
1233 b'single-head-per-branch',
1224 default=False,
1234 default=False,
1225 )
1235 )
1226 coreconfigitem(
1236 coreconfigitem(
1227 b'experimental',
1237 b'experimental',
1228 b'single-head-per-branch:account-closed-heads',
1238 b'single-head-per-branch:account-closed-heads',
1229 default=False,
1239 default=False,
1230 )
1240 )
1231 coreconfigitem(
1241 coreconfigitem(
1232 b'experimental',
1242 b'experimental',
1233 b'single-head-per-branch:public-changes-only',
1243 b'single-head-per-branch:public-changes-only',
1234 default=False,
1244 default=False,
1235 )
1245 )
1236 coreconfigitem(
1246 coreconfigitem(
1237 b'experimental',
1247 b'experimental',
1238 b'sparse-read',
1248 b'sparse-read',
1239 default=False,
1249 default=False,
1240 )
1250 )
1241 coreconfigitem(
1251 coreconfigitem(
1242 b'experimental',
1252 b'experimental',
1243 b'sparse-read.density-threshold',
1253 b'sparse-read.density-threshold',
1244 default=0.50,
1254 default=0.50,
1245 )
1255 )
1246 coreconfigitem(
1256 coreconfigitem(
1247 b'experimental',
1257 b'experimental',
1248 b'sparse-read.min-gap-size',
1258 b'sparse-read.min-gap-size',
1249 default=b'65K',
1259 default=b'65K',
1250 )
1260 )
1251 coreconfigitem(
1261 coreconfigitem(
1252 b'experimental',
1262 b'experimental',
1253 b'treemanifest',
1263 b'treemanifest',
1254 default=False,
1264 default=False,
1255 )
1265 )
1256 coreconfigitem(
1266 coreconfigitem(
1257 b'experimental',
1267 b'experimental',
1258 b'update.atomic-file',
1268 b'update.atomic-file',
1259 default=False,
1269 default=False,
1260 )
1270 )
1261 coreconfigitem(
1271 coreconfigitem(
1262 b'experimental',
1272 b'experimental',
1263 b'web.full-garbage-collection-rate',
1273 b'web.full-garbage-collection-rate',
1264 default=1, # still forcing a full collection on each request
1274 default=1, # still forcing a full collection on each request
1265 )
1275 )
1266 coreconfigitem(
1276 coreconfigitem(
1267 b'experimental',
1277 b'experimental',
1268 b'worker.wdir-get-thread-safe',
1278 b'worker.wdir-get-thread-safe',
1269 default=False,
1279 default=False,
1270 )
1280 )
1271 coreconfigitem(
1281 coreconfigitem(
1272 b'experimental',
1282 b'experimental',
1273 b'worker.repository-upgrade',
1283 b'worker.repository-upgrade',
1274 default=False,
1284 default=False,
1275 )
1285 )
1276 coreconfigitem(
1286 coreconfigitem(
1277 b'experimental',
1287 b'experimental',
1278 b'xdiff',
1288 b'xdiff',
1279 default=False,
1289 default=False,
1280 )
1290 )
1281 coreconfigitem(
1291 coreconfigitem(
1282 b'extensions',
1292 b'extensions',
1283 b'[^:]*',
1293 b'[^:]*',
1284 default=None,
1294 default=None,
1285 generic=True,
1295 generic=True,
1286 )
1296 )
1287 coreconfigitem(
1297 coreconfigitem(
1288 b'extensions',
1298 b'extensions',
1289 b'[^:]*:required',
1299 b'[^:]*:required',
1290 default=False,
1300 default=False,
1291 generic=True,
1301 generic=True,
1292 )
1302 )
1293 coreconfigitem(
1303 coreconfigitem(
1294 b'extdata',
1304 b'extdata',
1295 b'.*',
1305 b'.*',
1296 default=None,
1306 default=None,
1297 generic=True,
1307 generic=True,
1298 )
1308 )
1299 coreconfigitem(
1309 coreconfigitem(
1300 b'format',
1310 b'format',
1301 b'bookmarks-in-store',
1311 b'bookmarks-in-store',
1302 default=False,
1312 default=False,
1303 )
1313 )
1304 coreconfigitem(
1314 coreconfigitem(
1305 b'format',
1315 b'format',
1306 b'chunkcachesize',
1316 b'chunkcachesize',
1307 default=None,
1317 default=None,
1308 experimental=True,
1318 experimental=True,
1309 )
1319 )
1310 coreconfigitem(
1320 coreconfigitem(
1311 # Enable this dirstate format *when creating a new repository*.
1321 # Enable this dirstate format *when creating a new repository*.
1312 # Which format to use for existing repos is controlled by .hg/requires
1322 # Which format to use for existing repos is controlled by .hg/requires
1313 b'format',
1323 b'format',
1314 b'use-dirstate-v2',
1324 b'use-dirstate-v2',
1315 default=False,
1325 default=False,
1316 experimental=True,
1326 experimental=True,
1317 alias=[(b'format', b'exp-rc-dirstate-v2')],
1327 alias=[(b'format', b'exp-rc-dirstate-v2')],
1318 )
1328 )
1319 coreconfigitem(
1329 coreconfigitem(
1320 b'format',
1330 b'format',
1321 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1331 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1322 default=False,
1332 default=False,
1323 experimental=True,
1333 experimental=True,
1324 )
1334 )
1325 coreconfigitem(
1335 coreconfigitem(
1326 b'format',
1336 b'format',
1327 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1337 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1328 default=False,
1338 default=False,
1329 experimental=True,
1339 experimental=True,
1330 )
1340 )
1331 coreconfigitem(
1341 coreconfigitem(
1332 b'format',
1342 b'format',
1333 b'use-dirstate-tracked-hint',
1343 b'use-dirstate-tracked-hint',
1334 default=False,
1344 default=False,
1335 experimental=True,
1345 experimental=True,
1336 )
1346 )
1337 coreconfigitem(
1347 coreconfigitem(
1338 b'format',
1348 b'format',
1339 b'use-dirstate-tracked-hint.version',
1349 b'use-dirstate-tracked-hint.version',
1340 default=1,
1350 default=1,
1341 experimental=True,
1351 experimental=True,
1342 )
1352 )
1343 coreconfigitem(
1353 coreconfigitem(
1344 b'format',
1354 b'format',
1345 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1355 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1346 default=False,
1356 default=False,
1347 experimental=True,
1357 experimental=True,
1348 )
1358 )
1349 coreconfigitem(
1359 coreconfigitem(
1350 b'format',
1360 b'format',
1351 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1361 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1352 default=False,
1362 default=False,
1353 experimental=True,
1363 experimental=True,
1354 )
1364 )
1355 coreconfigitem(
1365 coreconfigitem(
1356 b'format',
1366 b'format',
1357 b'dotencode',
1367 b'dotencode',
1358 default=True,
1368 default=True,
1359 )
1369 )
1360 coreconfigitem(
1370 coreconfigitem(
1361 b'format',
1371 b'format',
1362 b'generaldelta',
1372 b'generaldelta',
1363 default=False,
1373 default=False,
1364 experimental=True,
1374 experimental=True,
1365 )
1375 )
1366 coreconfigitem(
1376 coreconfigitem(
1367 b'format',
1377 b'format',
1368 b'manifestcachesize',
1378 b'manifestcachesize',
1369 default=None,
1379 default=None,
1370 experimental=True,
1380 experimental=True,
1371 )
1381 )
1372 coreconfigitem(
1382 coreconfigitem(
1373 b'format',
1383 b'format',
1374 b'maxchainlen',
1384 b'maxchainlen',
1375 default=dynamicdefault,
1385 default=dynamicdefault,
1376 experimental=True,
1386 experimental=True,
1377 )
1387 )
1378 coreconfigitem(
1388 coreconfigitem(
1379 b'format',
1389 b'format',
1380 b'obsstore-version',
1390 b'obsstore-version',
1381 default=None,
1391 default=None,
1382 )
1392 )
1383 coreconfigitem(
1393 coreconfigitem(
1384 b'format',
1394 b'format',
1385 b'sparse-revlog',
1395 b'sparse-revlog',
1386 default=True,
1396 default=True,
1387 )
1397 )
1388 coreconfigitem(
1398 coreconfigitem(
1389 b'format',
1399 b'format',
1390 b'revlog-compression',
1400 b'revlog-compression',
1391 default=lambda: [b'zstd', b'zlib'],
1401 default=lambda: [b'zstd', b'zlib'],
1392 alias=[(b'experimental', b'format.compression')],
1402 alias=[(b'experimental', b'format.compression')],
1393 )
1403 )
1394 # Experimental TODOs:
1404 # Experimental TODOs:
1395 #
1405 #
1396 # * Same as for revlogv2 (but for the reduction of the number of files)
1406 # * Same as for revlogv2 (but for the reduction of the number of files)
1397 # * Actually computing the rank of changesets
1407 # * Actually computing the rank of changesets
1398 # * Improvement to investigate
1408 # * Improvement to investigate
1399 # - storing .hgtags fnode
1409 # - storing .hgtags fnode
1400 # - storing branch related identifier
1410 # - storing branch related identifier
1401
1411
1402 coreconfigitem(
1412 coreconfigitem(
1403 b'format',
1413 b'format',
1404 b'exp-use-changelog-v2',
1414 b'exp-use-changelog-v2',
1405 default=None,
1415 default=None,
1406 experimental=True,
1416 experimental=True,
1407 )
1417 )
1408 coreconfigitem(
1418 coreconfigitem(
1409 b'format',
1419 b'format',
1410 b'usefncache',
1420 b'usefncache',
1411 default=True,
1421 default=True,
1412 )
1422 )
1413 coreconfigitem(
1423 coreconfigitem(
1414 b'format',
1424 b'format',
1415 b'usegeneraldelta',
1425 b'usegeneraldelta',
1416 default=True,
1426 default=True,
1417 )
1427 )
1418 coreconfigitem(
1428 coreconfigitem(
1419 b'format',
1429 b'format',
1420 b'usestore',
1430 b'usestore',
1421 default=True,
1431 default=True,
1422 )
1432 )
1423
1433
1424
1434
1425 def _persistent_nodemap_default():
1435 def _persistent_nodemap_default():
1426 """compute `use-persistent-nodemap` default value
1436 """compute `use-persistent-nodemap` default value
1427
1437
1428 The feature is disabled unless a fast implementation is available.
1438 The feature is disabled unless a fast implementation is available.
1429 """
1439 """
1430 from . import policy
1440 from . import policy
1431
1441
1432 return policy.importrust('revlog') is not None
1442 return policy.importrust('revlog') is not None
1433
1443
1434
1444
1435 coreconfigitem(
1445 coreconfigitem(
1436 b'format',
1446 b'format',
1437 b'use-persistent-nodemap',
1447 b'use-persistent-nodemap',
1438 default=_persistent_nodemap_default,
1448 default=_persistent_nodemap_default,
1439 )
1449 )
1440 coreconfigitem(
1450 coreconfigitem(
1441 b'format',
1451 b'format',
1442 b'exp-use-copies-side-data-changeset',
1452 b'exp-use-copies-side-data-changeset',
1443 default=False,
1453 default=False,
1444 experimental=True,
1454 experimental=True,
1445 )
1455 )
1446 coreconfigitem(
1456 coreconfigitem(
1447 b'format',
1457 b'format',
1448 b'use-share-safe',
1458 b'use-share-safe',
1449 default=True,
1459 default=True,
1450 )
1460 )
1451 coreconfigitem(
1461 coreconfigitem(
1452 b'format',
1462 b'format',
1453 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1463 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1454 default=False,
1464 default=False,
1455 experimental=True,
1465 experimental=True,
1456 )
1466 )
1457 coreconfigitem(
1467 coreconfigitem(
1458 b'format',
1468 b'format',
1459 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1469 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1460 default=False,
1470 default=False,
1461 experimental=True,
1471 experimental=True,
1462 )
1472 )
1463
1473
1464 # Moving this on by default means we are confident about the scaling of phases.
1474 # Moving this on by default means we are confident about the scaling of phases.
1465 # This is not garanteed to be the case at the time this message is written.
1475 # This is not garanteed to be the case at the time this message is written.
1466 coreconfigitem(
1476 coreconfigitem(
1467 b'format',
1477 b'format',
1468 b'use-internal-phase',
1478 b'use-internal-phase',
1469 default=False,
1479 default=False,
1470 experimental=True,
1480 experimental=True,
1471 )
1481 )
1472 # The interaction between the archived phase and obsolescence markers needs to
1482 # The interaction between the archived phase and obsolescence markers needs to
1473 # be sorted out before wider usage of this are to be considered.
1483 # be sorted out before wider usage of this are to be considered.
1474 #
1484 #
1475 # At the time this message is written, behavior when archiving obsolete
1485 # At the time this message is written, behavior when archiving obsolete
1476 # changeset differ significantly from stripping. As part of stripping, we also
1486 # changeset differ significantly from stripping. As part of stripping, we also
1477 # remove the obsolescence marker associated to the stripped changesets,
1487 # remove the obsolescence marker associated to the stripped changesets,
1478 # revealing the precedecessors changesets when applicable. When archiving, we
1488 # revealing the precedecessors changesets when applicable. When archiving, we
1479 # don't touch the obsolescence markers, keeping everything hidden. This can
1489 # don't touch the obsolescence markers, keeping everything hidden. This can
1480 # result in quite confusing situation for people combining exchanging draft
1490 # result in quite confusing situation for people combining exchanging draft
1481 # with the archived phases. As some markers needed by others may be skipped
1491 # with the archived phases. As some markers needed by others may be skipped
1482 # during exchange.
1492 # during exchange.
1483 coreconfigitem(
1493 coreconfigitem(
1484 b'format',
1494 b'format',
1485 b'exp-archived-phase',
1495 b'exp-archived-phase',
1486 default=False,
1496 default=False,
1487 experimental=True,
1497 experimental=True,
1488 )
1498 )
1489 coreconfigitem(
1499 coreconfigitem(
1490 b'shelve',
1500 b'shelve',
1491 b'store',
1501 b'store',
1492 default=b'internal',
1502 default=b'internal',
1493 experimental=True,
1503 experimental=True,
1494 )
1504 )
1495 coreconfigitem(
1505 coreconfigitem(
1496 b'fsmonitor',
1506 b'fsmonitor',
1497 b'warn_when_unused',
1507 b'warn_when_unused',
1498 default=True,
1508 default=True,
1499 )
1509 )
1500 coreconfigitem(
1510 coreconfigitem(
1501 b'fsmonitor',
1511 b'fsmonitor',
1502 b'warn_update_file_count',
1512 b'warn_update_file_count',
1503 default=50000,
1513 default=50000,
1504 )
1514 )
1505 coreconfigitem(
1515 coreconfigitem(
1506 b'fsmonitor',
1516 b'fsmonitor',
1507 b'warn_update_file_count_rust',
1517 b'warn_update_file_count_rust',
1508 default=400000,
1518 default=400000,
1509 )
1519 )
1510 coreconfigitem(
1520 coreconfigitem(
1511 b'help',
1521 b'help',
1512 br'hidden-command\..*',
1522 br'hidden-command\..*',
1513 default=False,
1523 default=False,
1514 generic=True,
1524 generic=True,
1515 )
1525 )
1516 coreconfigitem(
1526 coreconfigitem(
1517 b'help',
1527 b'help',
1518 br'hidden-topic\..*',
1528 br'hidden-topic\..*',
1519 default=False,
1529 default=False,
1520 generic=True,
1530 generic=True,
1521 )
1531 )
1522 coreconfigitem(
1532 coreconfigitem(
1523 b'hooks',
1533 b'hooks',
1524 b'[^:]*',
1534 b'[^:]*',
1525 default=dynamicdefault,
1535 default=dynamicdefault,
1526 generic=True,
1536 generic=True,
1527 )
1537 )
1528 coreconfigitem(
1538 coreconfigitem(
1529 b'hooks',
1539 b'hooks',
1530 b'.*:run-with-plain',
1540 b'.*:run-with-plain',
1531 default=True,
1541 default=True,
1532 generic=True,
1542 generic=True,
1533 )
1543 )
1534 coreconfigitem(
1544 coreconfigitem(
1535 b'hgweb-paths',
1545 b'hgweb-paths',
1536 b'.*',
1546 b'.*',
1537 default=list,
1547 default=list,
1538 generic=True,
1548 generic=True,
1539 )
1549 )
1540 coreconfigitem(
1550 coreconfigitem(
1541 b'hostfingerprints',
1551 b'hostfingerprints',
1542 b'.*',
1552 b'.*',
1543 default=list,
1553 default=list,
1544 generic=True,
1554 generic=True,
1545 )
1555 )
1546 coreconfigitem(
1556 coreconfigitem(
1547 b'hostsecurity',
1557 b'hostsecurity',
1548 b'ciphers',
1558 b'ciphers',
1549 default=None,
1559 default=None,
1550 )
1560 )
1551 coreconfigitem(
1561 coreconfigitem(
1552 b'hostsecurity',
1562 b'hostsecurity',
1553 b'minimumprotocol',
1563 b'minimumprotocol',
1554 default=dynamicdefault,
1564 default=dynamicdefault,
1555 )
1565 )
1556 coreconfigitem(
1566 coreconfigitem(
1557 b'hostsecurity',
1567 b'hostsecurity',
1558 b'.*:minimumprotocol$',
1568 b'.*:minimumprotocol$',
1559 default=dynamicdefault,
1569 default=dynamicdefault,
1560 generic=True,
1570 generic=True,
1561 )
1571 )
1562 coreconfigitem(
1572 coreconfigitem(
1563 b'hostsecurity',
1573 b'hostsecurity',
1564 b'.*:ciphers$',
1574 b'.*:ciphers$',
1565 default=dynamicdefault,
1575 default=dynamicdefault,
1566 generic=True,
1576 generic=True,
1567 )
1577 )
1568 coreconfigitem(
1578 coreconfigitem(
1569 b'hostsecurity',
1579 b'hostsecurity',
1570 b'.*:fingerprints$',
1580 b'.*:fingerprints$',
1571 default=list,
1581 default=list,
1572 generic=True,
1582 generic=True,
1573 )
1583 )
1574 coreconfigitem(
1584 coreconfigitem(
1575 b'hostsecurity',
1585 b'hostsecurity',
1576 b'.*:verifycertsfile$',
1586 b'.*:verifycertsfile$',
1577 default=None,
1587 default=None,
1578 generic=True,
1588 generic=True,
1579 )
1589 )
1580
1590
1581 coreconfigitem(
1591 coreconfigitem(
1582 b'http_proxy',
1592 b'http_proxy',
1583 b'always',
1593 b'always',
1584 default=False,
1594 default=False,
1585 )
1595 )
1586 coreconfigitem(
1596 coreconfigitem(
1587 b'http_proxy',
1597 b'http_proxy',
1588 b'host',
1598 b'host',
1589 default=None,
1599 default=None,
1590 )
1600 )
1591 coreconfigitem(
1601 coreconfigitem(
1592 b'http_proxy',
1602 b'http_proxy',
1593 b'no',
1603 b'no',
1594 default=list,
1604 default=list,
1595 )
1605 )
1596 coreconfigitem(
1606 coreconfigitem(
1597 b'http_proxy',
1607 b'http_proxy',
1598 b'passwd',
1608 b'passwd',
1599 default=None,
1609 default=None,
1600 )
1610 )
1601 coreconfigitem(
1611 coreconfigitem(
1602 b'http_proxy',
1612 b'http_proxy',
1603 b'user',
1613 b'user',
1604 default=None,
1614 default=None,
1605 )
1615 )
1606
1616
1607 coreconfigitem(
1617 coreconfigitem(
1608 b'http',
1618 b'http',
1609 b'timeout',
1619 b'timeout',
1610 default=None,
1620 default=None,
1611 )
1621 )
1612
1622
1613 coreconfigitem(
1623 coreconfigitem(
1614 b'logtoprocess',
1624 b'logtoprocess',
1615 b'commandexception',
1625 b'commandexception',
1616 default=None,
1626 default=None,
1617 )
1627 )
1618 coreconfigitem(
1628 coreconfigitem(
1619 b'logtoprocess',
1629 b'logtoprocess',
1620 b'commandfinish',
1630 b'commandfinish',
1621 default=None,
1631 default=None,
1622 )
1632 )
1623 coreconfigitem(
1633 coreconfigitem(
1624 b'logtoprocess',
1634 b'logtoprocess',
1625 b'command',
1635 b'command',
1626 default=None,
1636 default=None,
1627 )
1637 )
1628 coreconfigitem(
1638 coreconfigitem(
1629 b'logtoprocess',
1639 b'logtoprocess',
1630 b'develwarn',
1640 b'develwarn',
1631 default=None,
1641 default=None,
1632 )
1642 )
1633 coreconfigitem(
1643 coreconfigitem(
1634 b'logtoprocess',
1644 b'logtoprocess',
1635 b'uiblocked',
1645 b'uiblocked',
1636 default=None,
1646 default=None,
1637 )
1647 )
1638 coreconfigitem(
1648 coreconfigitem(
1639 b'merge',
1649 b'merge',
1640 b'checkunknown',
1650 b'checkunknown',
1641 default=b'abort',
1651 default=b'abort',
1642 )
1652 )
1643 coreconfigitem(
1653 coreconfigitem(
1644 b'merge',
1654 b'merge',
1645 b'checkignored',
1655 b'checkignored',
1646 default=b'abort',
1656 default=b'abort',
1647 )
1657 )
1648 coreconfigitem(
1658 coreconfigitem(
1649 b'experimental',
1659 b'experimental',
1650 b'merge.checkpathconflicts',
1660 b'merge.checkpathconflicts',
1651 default=False,
1661 default=False,
1652 )
1662 )
1653 coreconfigitem(
1663 coreconfigitem(
1654 b'merge',
1664 b'merge',
1655 b'followcopies',
1665 b'followcopies',
1656 default=True,
1666 default=True,
1657 )
1667 )
1658 coreconfigitem(
1668 coreconfigitem(
1659 b'merge',
1669 b'merge',
1660 b'on-failure',
1670 b'on-failure',
1661 default=b'continue',
1671 default=b'continue',
1662 )
1672 )
1663 coreconfigitem(
1673 coreconfigitem(
1664 b'merge',
1674 b'merge',
1665 b'preferancestor',
1675 b'preferancestor',
1666 default=lambda: [b'*'],
1676 default=lambda: [b'*'],
1667 experimental=True,
1677 experimental=True,
1668 )
1678 )
1669 coreconfigitem(
1679 coreconfigitem(
1670 b'merge',
1680 b'merge',
1671 b'strict-capability-check',
1681 b'strict-capability-check',
1672 default=False,
1682 default=False,
1673 )
1683 )
1674 coreconfigitem(
1684 coreconfigitem(
1675 b'merge',
1685 b'merge',
1676 b'disable-partial-tools',
1686 b'disable-partial-tools',
1677 default=False,
1687 default=False,
1678 experimental=True,
1688 experimental=True,
1679 )
1689 )
1680 coreconfigitem(
1690 coreconfigitem(
1681 b'partial-merge-tools',
1691 b'partial-merge-tools',
1682 b'.*',
1692 b'.*',
1683 default=None,
1693 default=None,
1684 generic=True,
1694 generic=True,
1685 experimental=True,
1695 experimental=True,
1686 )
1696 )
1687 coreconfigitem(
1697 coreconfigitem(
1688 b'partial-merge-tools',
1698 b'partial-merge-tools',
1689 br'.*\.patterns',
1699 br'.*\.patterns',
1690 default=dynamicdefault,
1700 default=dynamicdefault,
1691 generic=True,
1701 generic=True,
1692 priority=-1,
1702 priority=-1,
1693 experimental=True,
1703 experimental=True,
1694 )
1704 )
1695 coreconfigitem(
1705 coreconfigitem(
1696 b'partial-merge-tools',
1706 b'partial-merge-tools',
1697 br'.*\.executable$',
1707 br'.*\.executable$',
1698 default=dynamicdefault,
1708 default=dynamicdefault,
1699 generic=True,
1709 generic=True,
1700 priority=-1,
1710 priority=-1,
1701 experimental=True,
1711 experimental=True,
1702 )
1712 )
1703 coreconfigitem(
1713 coreconfigitem(
1704 b'partial-merge-tools',
1714 b'partial-merge-tools',
1705 br'.*\.order',
1715 br'.*\.order',
1706 default=0,
1716 default=0,
1707 generic=True,
1717 generic=True,
1708 priority=-1,
1718 priority=-1,
1709 experimental=True,
1719 experimental=True,
1710 )
1720 )
1711 coreconfigitem(
1721 coreconfigitem(
1712 b'partial-merge-tools',
1722 b'partial-merge-tools',
1713 br'.*\.args',
1723 br'.*\.args',
1714 default=b"$local $base $other",
1724 default=b"$local $base $other",
1715 generic=True,
1725 generic=True,
1716 priority=-1,
1726 priority=-1,
1717 experimental=True,
1727 experimental=True,
1718 )
1728 )
1719 coreconfigitem(
1729 coreconfigitem(
1720 b'partial-merge-tools',
1730 b'partial-merge-tools',
1721 br'.*\.disable',
1731 br'.*\.disable',
1722 default=False,
1732 default=False,
1723 generic=True,
1733 generic=True,
1724 priority=-1,
1734 priority=-1,
1725 experimental=True,
1735 experimental=True,
1726 )
1736 )
1727 coreconfigitem(
1737 coreconfigitem(
1728 b'merge-tools',
1738 b'merge-tools',
1729 b'.*',
1739 b'.*',
1730 default=None,
1740 default=None,
1731 generic=True,
1741 generic=True,
1732 )
1742 )
1733 coreconfigitem(
1743 coreconfigitem(
1734 b'merge-tools',
1744 b'merge-tools',
1735 br'.*\.args$',
1745 br'.*\.args$',
1736 default=b"$local $base $other",
1746 default=b"$local $base $other",
1737 generic=True,
1747 generic=True,
1738 priority=-1,
1748 priority=-1,
1739 )
1749 )
1740 coreconfigitem(
1750 coreconfigitem(
1741 b'merge-tools',
1751 b'merge-tools',
1742 br'.*\.binary$',
1752 br'.*\.binary$',
1743 default=False,
1753 default=False,
1744 generic=True,
1754 generic=True,
1745 priority=-1,
1755 priority=-1,
1746 )
1756 )
1747 coreconfigitem(
1757 coreconfigitem(
1748 b'merge-tools',
1758 b'merge-tools',
1749 br'.*\.check$',
1759 br'.*\.check$',
1750 default=list,
1760 default=list,
1751 generic=True,
1761 generic=True,
1752 priority=-1,
1762 priority=-1,
1753 )
1763 )
1754 coreconfigitem(
1764 coreconfigitem(
1755 b'merge-tools',
1765 b'merge-tools',
1756 br'.*\.checkchanged$',
1766 br'.*\.checkchanged$',
1757 default=False,
1767 default=False,
1758 generic=True,
1768 generic=True,
1759 priority=-1,
1769 priority=-1,
1760 )
1770 )
1761 coreconfigitem(
1771 coreconfigitem(
1762 b'merge-tools',
1772 b'merge-tools',
1763 br'.*\.executable$',
1773 br'.*\.executable$',
1764 default=dynamicdefault,
1774 default=dynamicdefault,
1765 generic=True,
1775 generic=True,
1766 priority=-1,
1776 priority=-1,
1767 )
1777 )
1768 coreconfigitem(
1778 coreconfigitem(
1769 b'merge-tools',
1779 b'merge-tools',
1770 br'.*\.fixeol$',
1780 br'.*\.fixeol$',
1771 default=False,
1781 default=False,
1772 generic=True,
1782 generic=True,
1773 priority=-1,
1783 priority=-1,
1774 )
1784 )
1775 coreconfigitem(
1785 coreconfigitem(
1776 b'merge-tools',
1786 b'merge-tools',
1777 br'.*\.gui$',
1787 br'.*\.gui$',
1778 default=False,
1788 default=False,
1779 generic=True,
1789 generic=True,
1780 priority=-1,
1790 priority=-1,
1781 )
1791 )
1782 coreconfigitem(
1792 coreconfigitem(
1783 b'merge-tools',
1793 b'merge-tools',
1784 br'.*\.mergemarkers$',
1794 br'.*\.mergemarkers$',
1785 default=b'basic',
1795 default=b'basic',
1786 generic=True,
1796 generic=True,
1787 priority=-1,
1797 priority=-1,
1788 )
1798 )
1789 coreconfigitem(
1799 coreconfigitem(
1790 b'merge-tools',
1800 b'merge-tools',
1791 br'.*\.mergemarkertemplate$',
1801 br'.*\.mergemarkertemplate$',
1792 default=dynamicdefault, # take from command-templates.mergemarker
1802 default=dynamicdefault, # take from command-templates.mergemarker
1793 generic=True,
1803 generic=True,
1794 priority=-1,
1804 priority=-1,
1795 )
1805 )
1796 coreconfigitem(
1806 coreconfigitem(
1797 b'merge-tools',
1807 b'merge-tools',
1798 br'.*\.priority$',
1808 br'.*\.priority$',
1799 default=0,
1809 default=0,
1800 generic=True,
1810 generic=True,
1801 priority=-1,
1811 priority=-1,
1802 )
1812 )
1803 coreconfigitem(
1813 coreconfigitem(
1804 b'merge-tools',
1814 b'merge-tools',
1805 br'.*\.premerge$',
1815 br'.*\.premerge$',
1806 default=dynamicdefault,
1816 default=dynamicdefault,
1807 generic=True,
1817 generic=True,
1808 priority=-1,
1818 priority=-1,
1809 )
1819 )
1810 coreconfigitem(
1820 coreconfigitem(
1811 b'merge-tools',
1821 b'merge-tools',
1812 br'.*\.symlink$',
1822 br'.*\.symlink$',
1813 default=False,
1823 default=False,
1814 generic=True,
1824 generic=True,
1815 priority=-1,
1825 priority=-1,
1816 )
1826 )
1817 coreconfigitem(
1827 coreconfigitem(
1818 b'pager',
1828 b'pager',
1819 b'attend-.*',
1829 b'attend-.*',
1820 default=dynamicdefault,
1830 default=dynamicdefault,
1821 generic=True,
1831 generic=True,
1822 )
1832 )
1823 coreconfigitem(
1833 coreconfigitem(
1824 b'pager',
1834 b'pager',
1825 b'ignore',
1835 b'ignore',
1826 default=list,
1836 default=list,
1827 )
1837 )
1828 coreconfigitem(
1838 coreconfigitem(
1829 b'pager',
1839 b'pager',
1830 b'pager',
1840 b'pager',
1831 default=dynamicdefault,
1841 default=dynamicdefault,
1832 )
1842 )
1833 coreconfigitem(
1843 coreconfigitem(
1834 b'patch',
1844 b'patch',
1835 b'eol',
1845 b'eol',
1836 default=b'strict',
1846 default=b'strict',
1837 )
1847 )
1838 coreconfigitem(
1848 coreconfigitem(
1839 b'patch',
1849 b'patch',
1840 b'fuzz',
1850 b'fuzz',
1841 default=2,
1851 default=2,
1842 )
1852 )
1843 coreconfigitem(
1853 coreconfigitem(
1844 b'paths',
1854 b'paths',
1845 b'default',
1855 b'default',
1846 default=None,
1856 default=None,
1847 )
1857 )
1848 coreconfigitem(
1858 coreconfigitem(
1849 b'paths',
1859 b'paths',
1850 b'default-push',
1860 b'default-push',
1851 default=None,
1861 default=None,
1852 )
1862 )
1853 coreconfigitem(
1863 coreconfigitem(
1854 b'paths',
1864 b'paths',
1855 b'.*',
1865 b'.*',
1856 default=None,
1866 default=None,
1857 generic=True,
1867 generic=True,
1858 )
1868 )
1859 coreconfigitem(
1869 coreconfigitem(
1860 b'paths',
1870 b'paths',
1861 b'.*:bookmarks.mode',
1871 b'.*:bookmarks.mode',
1862 default='default',
1872 default='default',
1863 generic=True,
1873 generic=True,
1864 )
1874 )
1865 coreconfigitem(
1875 coreconfigitem(
1866 b'paths',
1876 b'paths',
1867 b'.*:multi-urls',
1877 b'.*:multi-urls',
1868 default=False,
1878 default=False,
1869 generic=True,
1879 generic=True,
1870 )
1880 )
1871 coreconfigitem(
1881 coreconfigitem(
1872 b'paths',
1882 b'paths',
1873 b'.*:pushrev',
1883 b'.*:pushrev',
1874 default=None,
1884 default=None,
1875 generic=True,
1885 generic=True,
1876 )
1886 )
1877 coreconfigitem(
1887 coreconfigitem(
1878 b'paths',
1888 b'paths',
1879 b'.*:pushurl',
1889 b'.*:pushurl',
1880 default=None,
1890 default=None,
1881 generic=True,
1891 generic=True,
1882 )
1892 )
1883 coreconfigitem(
1893 coreconfigitem(
1884 b'phases',
1894 b'phases',
1885 b'checksubrepos',
1895 b'checksubrepos',
1886 default=b'follow',
1896 default=b'follow',
1887 )
1897 )
1888 coreconfigitem(
1898 coreconfigitem(
1889 b'phases',
1899 b'phases',
1890 b'new-commit',
1900 b'new-commit',
1891 default=b'draft',
1901 default=b'draft',
1892 )
1902 )
1893 coreconfigitem(
1903 coreconfigitem(
1894 b'phases',
1904 b'phases',
1895 b'publish',
1905 b'publish',
1896 default=True,
1906 default=True,
1897 )
1907 )
1898 coreconfigitem(
1908 coreconfigitem(
1899 b'profiling',
1909 b'profiling',
1900 b'enabled',
1910 b'enabled',
1901 default=False,
1911 default=False,
1902 )
1912 )
1903 coreconfigitem(
1913 coreconfigitem(
1904 b'profiling',
1914 b'profiling',
1905 b'format',
1915 b'format',
1906 default=b'text',
1916 default=b'text',
1907 )
1917 )
1908 coreconfigitem(
1918 coreconfigitem(
1909 b'profiling',
1919 b'profiling',
1910 b'freq',
1920 b'freq',
1911 default=1000,
1921 default=1000,
1912 )
1922 )
1913 coreconfigitem(
1923 coreconfigitem(
1914 b'profiling',
1924 b'profiling',
1915 b'limit',
1925 b'limit',
1916 default=30,
1926 default=30,
1917 )
1927 )
1918 coreconfigitem(
1928 coreconfigitem(
1919 b'profiling',
1929 b'profiling',
1920 b'nested',
1930 b'nested',
1921 default=0,
1931 default=0,
1922 )
1932 )
1923 coreconfigitem(
1933 coreconfigitem(
1924 b'profiling',
1934 b'profiling',
1925 b'output',
1935 b'output',
1926 default=None,
1936 default=None,
1927 )
1937 )
1928 coreconfigitem(
1938 coreconfigitem(
1929 b'profiling',
1939 b'profiling',
1930 b'showmax',
1940 b'showmax',
1931 default=0.999,
1941 default=0.999,
1932 )
1942 )
1933 coreconfigitem(
1943 coreconfigitem(
1934 b'profiling',
1944 b'profiling',
1935 b'showmin',
1945 b'showmin',
1936 default=dynamicdefault,
1946 default=dynamicdefault,
1937 )
1947 )
1938 coreconfigitem(
1948 coreconfigitem(
1939 b'profiling',
1949 b'profiling',
1940 b'showtime',
1950 b'showtime',
1941 default=True,
1951 default=True,
1942 )
1952 )
1943 coreconfigitem(
1953 coreconfigitem(
1944 b'profiling',
1954 b'profiling',
1945 b'sort',
1955 b'sort',
1946 default=b'inlinetime',
1956 default=b'inlinetime',
1947 )
1957 )
1948 coreconfigitem(
1958 coreconfigitem(
1949 b'profiling',
1959 b'profiling',
1950 b'statformat',
1960 b'statformat',
1951 default=b'hotpath',
1961 default=b'hotpath',
1952 )
1962 )
1953 coreconfigitem(
1963 coreconfigitem(
1954 b'profiling',
1964 b'profiling',
1955 b'time-track',
1965 b'time-track',
1956 default=dynamicdefault,
1966 default=dynamicdefault,
1957 )
1967 )
1958 coreconfigitem(
1968 coreconfigitem(
1959 b'profiling',
1969 b'profiling',
1960 b'type',
1970 b'type',
1961 default=b'stat',
1971 default=b'stat',
1962 )
1972 )
1963 coreconfigitem(
1973 coreconfigitem(
1964 b'progress',
1974 b'progress',
1965 b'assume-tty',
1975 b'assume-tty',
1966 default=False,
1976 default=False,
1967 )
1977 )
1968 coreconfigitem(
1978 coreconfigitem(
1969 b'progress',
1979 b'progress',
1970 b'changedelay',
1980 b'changedelay',
1971 default=1,
1981 default=1,
1972 )
1982 )
1973 coreconfigitem(
1983 coreconfigitem(
1974 b'progress',
1984 b'progress',
1975 b'clear-complete',
1985 b'clear-complete',
1976 default=True,
1986 default=True,
1977 )
1987 )
1978 coreconfigitem(
1988 coreconfigitem(
1979 b'progress',
1989 b'progress',
1980 b'debug',
1990 b'debug',
1981 default=False,
1991 default=False,
1982 )
1992 )
1983 coreconfigitem(
1993 coreconfigitem(
1984 b'progress',
1994 b'progress',
1985 b'delay',
1995 b'delay',
1986 default=3,
1996 default=3,
1987 )
1997 )
1988 coreconfigitem(
1998 coreconfigitem(
1989 b'progress',
1999 b'progress',
1990 b'disable',
2000 b'disable',
1991 default=False,
2001 default=False,
1992 )
2002 )
1993 coreconfigitem(
2003 coreconfigitem(
1994 b'progress',
2004 b'progress',
1995 b'estimateinterval',
2005 b'estimateinterval',
1996 default=60.0,
2006 default=60.0,
1997 )
2007 )
1998 coreconfigitem(
2008 coreconfigitem(
1999 b'progress',
2009 b'progress',
2000 b'format',
2010 b'format',
2001 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2011 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2002 )
2012 )
2003 coreconfigitem(
2013 coreconfigitem(
2004 b'progress',
2014 b'progress',
2005 b'refresh',
2015 b'refresh',
2006 default=0.1,
2016 default=0.1,
2007 )
2017 )
2008 coreconfigitem(
2018 coreconfigitem(
2009 b'progress',
2019 b'progress',
2010 b'width',
2020 b'width',
2011 default=dynamicdefault,
2021 default=dynamicdefault,
2012 )
2022 )
2013 coreconfigitem(
2023 coreconfigitem(
2014 b'pull',
2024 b'pull',
2015 b'confirm',
2025 b'confirm',
2016 default=False,
2026 default=False,
2017 )
2027 )
2018 coreconfigitem(
2028 coreconfigitem(
2019 b'push',
2029 b'push',
2020 b'pushvars.server',
2030 b'pushvars.server',
2021 default=False,
2031 default=False,
2022 )
2032 )
2023 coreconfigitem(
2033 coreconfigitem(
2024 b'rewrite',
2034 b'rewrite',
2025 b'backup-bundle',
2035 b'backup-bundle',
2026 default=True,
2036 default=True,
2027 alias=[(b'ui', b'history-editing-backup')],
2037 alias=[(b'ui', b'history-editing-backup')],
2028 )
2038 )
2029 coreconfigitem(
2039 coreconfigitem(
2030 b'rewrite',
2040 b'rewrite',
2031 b'update-timestamp',
2041 b'update-timestamp',
2032 default=False,
2042 default=False,
2033 )
2043 )
2034 coreconfigitem(
2044 coreconfigitem(
2035 b'rewrite',
2045 b'rewrite',
2036 b'empty-successor',
2046 b'empty-successor',
2037 default=b'skip',
2047 default=b'skip',
2038 experimental=True,
2048 experimental=True,
2039 )
2049 )
2040 # experimental as long as format.use-dirstate-v2 is.
2050 # experimental as long as format.use-dirstate-v2 is.
2041 coreconfigitem(
2051 coreconfigitem(
2042 b'storage',
2052 b'storage',
2043 b'dirstate-v2.slow-path',
2053 b'dirstate-v2.slow-path',
2044 default=b"abort",
2054 default=b"abort",
2045 experimental=True,
2055 experimental=True,
2046 )
2056 )
2047 coreconfigitem(
2057 coreconfigitem(
2048 b'storage',
2058 b'storage',
2049 b'new-repo-backend',
2059 b'new-repo-backend',
2050 default=b'revlogv1',
2060 default=b'revlogv1',
2051 experimental=True,
2061 experimental=True,
2052 )
2062 )
2053 coreconfigitem(
2063 coreconfigitem(
2054 b'storage',
2064 b'storage',
2055 b'revlog.optimize-delta-parent-choice',
2065 b'revlog.optimize-delta-parent-choice',
2056 default=True,
2066 default=True,
2057 alias=[(b'format', b'aggressivemergedeltas')],
2067 alias=[(b'format', b'aggressivemergedeltas')],
2058 )
2068 )
2059 coreconfigitem(
2069 coreconfigitem(
2060 b'storage',
2070 b'storage',
2061 b'revlog.issue6528.fix-incoming',
2071 b'revlog.issue6528.fix-incoming',
2062 default=True,
2072 default=True,
2063 )
2073 )
2064 # experimental as long as rust is experimental (or a C version is implemented)
2074 # experimental as long as rust is experimental (or a C version is implemented)
2065 coreconfigitem(
2075 coreconfigitem(
2066 b'storage',
2076 b'storage',
2067 b'revlog.persistent-nodemap.mmap',
2077 b'revlog.persistent-nodemap.mmap',
2068 default=True,
2078 default=True,
2069 )
2079 )
2070 # experimental as long as format.use-persistent-nodemap is.
2080 # experimental as long as format.use-persistent-nodemap is.
2071 coreconfigitem(
2081 coreconfigitem(
2072 b'storage',
2082 b'storage',
2073 b'revlog.persistent-nodemap.slow-path',
2083 b'revlog.persistent-nodemap.slow-path',
2074 default=b"abort",
2084 default=b"abort",
2075 )
2085 )
2076
2086
2077 coreconfigitem(
2087 coreconfigitem(
2078 b'storage',
2088 b'storage',
2079 b'revlog.reuse-external-delta',
2089 b'revlog.reuse-external-delta',
2080 default=True,
2090 default=True,
2081 )
2091 )
2082 coreconfigitem(
2092 coreconfigitem(
2083 b'storage',
2093 b'storage',
2084 b'revlog.reuse-external-delta-parent',
2094 b'revlog.reuse-external-delta-parent',
2085 default=None,
2095 default=None,
2086 )
2096 )
2087 coreconfigitem(
2097 coreconfigitem(
2088 b'storage',
2098 b'storage',
2089 b'revlog.zlib.level',
2099 b'revlog.zlib.level',
2090 default=None,
2100 default=None,
2091 )
2101 )
2092 coreconfigitem(
2102 coreconfigitem(
2093 b'storage',
2103 b'storage',
2094 b'revlog.zstd.level',
2104 b'revlog.zstd.level',
2095 default=None,
2105 default=None,
2096 )
2106 )
2097 coreconfigitem(
2107 coreconfigitem(
2098 b'server',
2108 b'server',
2099 b'bookmarks-pushkey-compat',
2109 b'bookmarks-pushkey-compat',
2100 default=True,
2110 default=True,
2101 )
2111 )
2102 coreconfigitem(
2112 coreconfigitem(
2103 b'server',
2113 b'server',
2104 b'bundle1',
2114 b'bundle1',
2105 default=True,
2115 default=True,
2106 )
2116 )
2107 coreconfigitem(
2117 coreconfigitem(
2108 b'server',
2118 b'server',
2109 b'bundle1gd',
2119 b'bundle1gd',
2110 default=None,
2120 default=None,
2111 )
2121 )
2112 coreconfigitem(
2122 coreconfigitem(
2113 b'server',
2123 b'server',
2114 b'bundle1.pull',
2124 b'bundle1.pull',
2115 default=None,
2125 default=None,
2116 )
2126 )
2117 coreconfigitem(
2127 coreconfigitem(
2118 b'server',
2128 b'server',
2119 b'bundle1gd.pull',
2129 b'bundle1gd.pull',
2120 default=None,
2130 default=None,
2121 )
2131 )
2122 coreconfigitem(
2132 coreconfigitem(
2123 b'server',
2133 b'server',
2124 b'bundle1.push',
2134 b'bundle1.push',
2125 default=None,
2135 default=None,
2126 )
2136 )
2127 coreconfigitem(
2137 coreconfigitem(
2128 b'server',
2138 b'server',
2129 b'bundle1gd.push',
2139 b'bundle1gd.push',
2130 default=None,
2140 default=None,
2131 )
2141 )
2132 coreconfigitem(
2142 coreconfigitem(
2133 b'server',
2143 b'server',
2134 b'bundle2.stream',
2144 b'bundle2.stream',
2135 default=True,
2145 default=True,
2136 alias=[(b'experimental', b'bundle2.stream')],
2146 alias=[(b'experimental', b'bundle2.stream')],
2137 )
2147 )
2138 coreconfigitem(
2148 coreconfigitem(
2139 b'server',
2149 b'server',
2140 b'compressionengines',
2150 b'compressionengines',
2141 default=list,
2151 default=list,
2142 )
2152 )
2143 coreconfigitem(
2153 coreconfigitem(
2144 b'server',
2154 b'server',
2145 b'concurrent-push-mode',
2155 b'concurrent-push-mode',
2146 default=b'check-related',
2156 default=b'check-related',
2147 )
2157 )
2148 coreconfigitem(
2158 coreconfigitem(
2149 b'server',
2159 b'server',
2150 b'disablefullbundle',
2160 b'disablefullbundle',
2151 default=False,
2161 default=False,
2152 )
2162 )
2153 coreconfigitem(
2163 coreconfigitem(
2154 b'server',
2164 b'server',
2155 b'maxhttpheaderlen',
2165 b'maxhttpheaderlen',
2156 default=1024,
2166 default=1024,
2157 )
2167 )
2158 coreconfigitem(
2168 coreconfigitem(
2159 b'server',
2169 b'server',
2160 b'pullbundle',
2170 b'pullbundle',
2161 default=False,
2171 default=False,
2162 )
2172 )
2163 coreconfigitem(
2173 coreconfigitem(
2164 b'server',
2174 b'server',
2165 b'preferuncompressed',
2175 b'preferuncompressed',
2166 default=False,
2176 default=False,
2167 )
2177 )
2168 coreconfigitem(
2178 coreconfigitem(
2169 b'server',
2179 b'server',
2170 b'streamunbundle',
2180 b'streamunbundle',
2171 default=False,
2181 default=False,
2172 )
2182 )
2173 coreconfigitem(
2183 coreconfigitem(
2174 b'server',
2184 b'server',
2175 b'uncompressed',
2185 b'uncompressed',
2176 default=True,
2186 default=True,
2177 )
2187 )
2178 coreconfigitem(
2188 coreconfigitem(
2179 b'server',
2189 b'server',
2180 b'uncompressedallowsecret',
2190 b'uncompressedallowsecret',
2181 default=False,
2191 default=False,
2182 )
2192 )
2183 coreconfigitem(
2193 coreconfigitem(
2184 b'server',
2194 b'server',
2185 b'view',
2195 b'view',
2186 default=b'served',
2196 default=b'served',
2187 )
2197 )
2188 coreconfigitem(
2198 coreconfigitem(
2189 b'server',
2199 b'server',
2190 b'validate',
2200 b'validate',
2191 default=False,
2201 default=False,
2192 )
2202 )
2193 coreconfigitem(
2203 coreconfigitem(
2194 b'server',
2204 b'server',
2195 b'zliblevel',
2205 b'zliblevel',
2196 default=-1,
2206 default=-1,
2197 )
2207 )
2198 coreconfigitem(
2208 coreconfigitem(
2199 b'server',
2209 b'server',
2200 b'zstdlevel',
2210 b'zstdlevel',
2201 default=3,
2211 default=3,
2202 )
2212 )
2203 coreconfigitem(
2213 coreconfigitem(
2204 b'share',
2214 b'share',
2205 b'pool',
2215 b'pool',
2206 default=None,
2216 default=None,
2207 )
2217 )
2208 coreconfigitem(
2218 coreconfigitem(
2209 b'share',
2219 b'share',
2210 b'poolnaming',
2220 b'poolnaming',
2211 default=b'identity',
2221 default=b'identity',
2212 )
2222 )
2213 coreconfigitem(
2223 coreconfigitem(
2214 b'share',
2224 b'share',
2215 b'safe-mismatch.source-not-safe',
2225 b'safe-mismatch.source-not-safe',
2216 default=b'abort',
2226 default=b'abort',
2217 )
2227 )
2218 coreconfigitem(
2228 coreconfigitem(
2219 b'share',
2229 b'share',
2220 b'safe-mismatch.source-safe',
2230 b'safe-mismatch.source-safe',
2221 default=b'abort',
2231 default=b'abort',
2222 )
2232 )
2223 coreconfigitem(
2233 coreconfigitem(
2224 b'share',
2234 b'share',
2225 b'safe-mismatch.source-not-safe.warn',
2235 b'safe-mismatch.source-not-safe.warn',
2226 default=True,
2236 default=True,
2227 )
2237 )
2228 coreconfigitem(
2238 coreconfigitem(
2229 b'share',
2239 b'share',
2230 b'safe-mismatch.source-safe.warn',
2240 b'safe-mismatch.source-safe.warn',
2231 default=True,
2241 default=True,
2232 )
2242 )
2233 coreconfigitem(
2243 coreconfigitem(
2234 b'share',
2244 b'share',
2235 b'safe-mismatch.source-not-safe:verbose-upgrade',
2245 b'safe-mismatch.source-not-safe:verbose-upgrade',
2236 default=True,
2246 default=True,
2237 )
2247 )
2238 coreconfigitem(
2248 coreconfigitem(
2239 b'share',
2249 b'share',
2240 b'safe-mismatch.source-safe:verbose-upgrade',
2250 b'safe-mismatch.source-safe:verbose-upgrade',
2241 default=True,
2251 default=True,
2242 )
2252 )
2243 coreconfigitem(
2253 coreconfigitem(
2244 b'shelve',
2254 b'shelve',
2245 b'maxbackups',
2255 b'maxbackups',
2246 default=10,
2256 default=10,
2247 )
2257 )
2248 coreconfigitem(
2258 coreconfigitem(
2249 b'smtp',
2259 b'smtp',
2250 b'host',
2260 b'host',
2251 default=None,
2261 default=None,
2252 )
2262 )
2253 coreconfigitem(
2263 coreconfigitem(
2254 b'smtp',
2264 b'smtp',
2255 b'local_hostname',
2265 b'local_hostname',
2256 default=None,
2266 default=None,
2257 )
2267 )
2258 coreconfigitem(
2268 coreconfigitem(
2259 b'smtp',
2269 b'smtp',
2260 b'password',
2270 b'password',
2261 default=None,
2271 default=None,
2262 )
2272 )
2263 coreconfigitem(
2273 coreconfigitem(
2264 b'smtp',
2274 b'smtp',
2265 b'port',
2275 b'port',
2266 default=dynamicdefault,
2276 default=dynamicdefault,
2267 )
2277 )
2268 coreconfigitem(
2278 coreconfigitem(
2269 b'smtp',
2279 b'smtp',
2270 b'tls',
2280 b'tls',
2271 default=b'none',
2281 default=b'none',
2272 )
2282 )
2273 coreconfigitem(
2283 coreconfigitem(
2274 b'smtp',
2284 b'smtp',
2275 b'username',
2285 b'username',
2276 default=None,
2286 default=None,
2277 )
2287 )
2278 coreconfigitem(
2288 coreconfigitem(
2279 b'sparse',
2289 b'sparse',
2280 b'missingwarning',
2290 b'missingwarning',
2281 default=True,
2291 default=True,
2282 experimental=True,
2292 experimental=True,
2283 )
2293 )
2284 coreconfigitem(
2294 coreconfigitem(
2285 b'subrepos',
2295 b'subrepos',
2286 b'allowed',
2296 b'allowed',
2287 default=dynamicdefault, # to make backporting simpler
2297 default=dynamicdefault, # to make backporting simpler
2288 )
2298 )
2289 coreconfigitem(
2299 coreconfigitem(
2290 b'subrepos',
2300 b'subrepos',
2291 b'hg:allowed',
2301 b'hg:allowed',
2292 default=dynamicdefault,
2302 default=dynamicdefault,
2293 )
2303 )
2294 coreconfigitem(
2304 coreconfigitem(
2295 b'subrepos',
2305 b'subrepos',
2296 b'git:allowed',
2306 b'git:allowed',
2297 default=dynamicdefault,
2307 default=dynamicdefault,
2298 )
2308 )
2299 coreconfigitem(
2309 coreconfigitem(
2300 b'subrepos',
2310 b'subrepos',
2301 b'svn:allowed',
2311 b'svn:allowed',
2302 default=dynamicdefault,
2312 default=dynamicdefault,
2303 )
2313 )
2304 coreconfigitem(
2314 coreconfigitem(
2305 b'templates',
2315 b'templates',
2306 b'.*',
2316 b'.*',
2307 default=None,
2317 default=None,
2308 generic=True,
2318 generic=True,
2309 )
2319 )
2310 coreconfigitem(
2320 coreconfigitem(
2311 b'templateconfig',
2321 b'templateconfig',
2312 b'.*',
2322 b'.*',
2313 default=dynamicdefault,
2323 default=dynamicdefault,
2314 generic=True,
2324 generic=True,
2315 )
2325 )
2316 coreconfigitem(
2326 coreconfigitem(
2317 b'trusted',
2327 b'trusted',
2318 b'groups',
2328 b'groups',
2319 default=list,
2329 default=list,
2320 )
2330 )
2321 coreconfigitem(
2331 coreconfigitem(
2322 b'trusted',
2332 b'trusted',
2323 b'users',
2333 b'users',
2324 default=list,
2334 default=list,
2325 )
2335 )
2326 coreconfigitem(
2336 coreconfigitem(
2327 b'ui',
2337 b'ui',
2328 b'_usedassubrepo',
2338 b'_usedassubrepo',
2329 default=False,
2339 default=False,
2330 )
2340 )
2331 coreconfigitem(
2341 coreconfigitem(
2332 b'ui',
2342 b'ui',
2333 b'allowemptycommit',
2343 b'allowemptycommit',
2334 default=False,
2344 default=False,
2335 )
2345 )
2336 coreconfigitem(
2346 coreconfigitem(
2337 b'ui',
2347 b'ui',
2338 b'archivemeta',
2348 b'archivemeta',
2339 default=True,
2349 default=True,
2340 )
2350 )
2341 coreconfigitem(
2351 coreconfigitem(
2342 b'ui',
2352 b'ui',
2343 b'askusername',
2353 b'askusername',
2344 default=False,
2354 default=False,
2345 )
2355 )
2346 coreconfigitem(
2356 coreconfigitem(
2347 b'ui',
2357 b'ui',
2348 b'available-memory',
2358 b'available-memory',
2349 default=None,
2359 default=None,
2350 )
2360 )
2351
2361
2352 coreconfigitem(
2362 coreconfigitem(
2353 b'ui',
2363 b'ui',
2354 b'clonebundlefallback',
2364 b'clonebundlefallback',
2355 default=False,
2365 default=False,
2356 )
2366 )
2357 coreconfigitem(
2367 coreconfigitem(
2358 b'ui',
2368 b'ui',
2359 b'clonebundleprefers',
2369 b'clonebundleprefers',
2360 default=list,
2370 default=list,
2361 )
2371 )
2362 coreconfigitem(
2372 coreconfigitem(
2363 b'ui',
2373 b'ui',
2364 b'clonebundles',
2374 b'clonebundles',
2365 default=True,
2375 default=True,
2366 )
2376 )
2367 coreconfigitem(
2377 coreconfigitem(
2368 b'ui',
2378 b'ui',
2369 b'color',
2379 b'color',
2370 default=b'auto',
2380 default=b'auto',
2371 )
2381 )
2372 coreconfigitem(
2382 coreconfigitem(
2373 b'ui',
2383 b'ui',
2374 b'commitsubrepos',
2384 b'commitsubrepos',
2375 default=False,
2385 default=False,
2376 )
2386 )
2377 coreconfigitem(
2387 coreconfigitem(
2378 b'ui',
2388 b'ui',
2379 b'debug',
2389 b'debug',
2380 default=False,
2390 default=False,
2381 )
2391 )
2382 coreconfigitem(
2392 coreconfigitem(
2383 b'ui',
2393 b'ui',
2384 b'debugger',
2394 b'debugger',
2385 default=None,
2395 default=None,
2386 )
2396 )
2387 coreconfigitem(
2397 coreconfigitem(
2388 b'ui',
2398 b'ui',
2389 b'editor',
2399 b'editor',
2390 default=dynamicdefault,
2400 default=dynamicdefault,
2391 )
2401 )
2392 coreconfigitem(
2402 coreconfigitem(
2393 b'ui',
2403 b'ui',
2394 b'detailed-exit-code',
2404 b'detailed-exit-code',
2395 default=False,
2405 default=False,
2396 experimental=True,
2406 experimental=True,
2397 )
2407 )
2398 coreconfigitem(
2408 coreconfigitem(
2399 b'ui',
2409 b'ui',
2400 b'fallbackencoding',
2410 b'fallbackencoding',
2401 default=None,
2411 default=None,
2402 )
2412 )
2403 coreconfigitem(
2413 coreconfigitem(
2404 b'ui',
2414 b'ui',
2405 b'forcecwd',
2415 b'forcecwd',
2406 default=None,
2416 default=None,
2407 )
2417 )
2408 coreconfigitem(
2418 coreconfigitem(
2409 b'ui',
2419 b'ui',
2410 b'forcemerge',
2420 b'forcemerge',
2411 default=None,
2421 default=None,
2412 )
2422 )
2413 coreconfigitem(
2423 coreconfigitem(
2414 b'ui',
2424 b'ui',
2415 b'formatdebug',
2425 b'formatdebug',
2416 default=False,
2426 default=False,
2417 )
2427 )
2418 coreconfigitem(
2428 coreconfigitem(
2419 b'ui',
2429 b'ui',
2420 b'formatjson',
2430 b'formatjson',
2421 default=False,
2431 default=False,
2422 )
2432 )
2423 coreconfigitem(
2433 coreconfigitem(
2424 b'ui',
2434 b'ui',
2425 b'formatted',
2435 b'formatted',
2426 default=None,
2436 default=None,
2427 )
2437 )
2428 coreconfigitem(
2438 coreconfigitem(
2429 b'ui',
2439 b'ui',
2430 b'interactive',
2440 b'interactive',
2431 default=None,
2441 default=None,
2432 )
2442 )
2433 coreconfigitem(
2443 coreconfigitem(
2434 b'ui',
2444 b'ui',
2435 b'interface',
2445 b'interface',
2436 default=None,
2446 default=None,
2437 )
2447 )
2438 coreconfigitem(
2448 coreconfigitem(
2439 b'ui',
2449 b'ui',
2440 b'interface.chunkselector',
2450 b'interface.chunkselector',
2441 default=None,
2451 default=None,
2442 )
2452 )
2443 coreconfigitem(
2453 coreconfigitem(
2444 b'ui',
2454 b'ui',
2445 b'large-file-limit',
2455 b'large-file-limit',
2446 default=10 * (2 ** 20),
2456 default=10 * (2 ** 20),
2447 )
2457 )
2448 coreconfigitem(
2458 coreconfigitem(
2449 b'ui',
2459 b'ui',
2450 b'logblockedtimes',
2460 b'logblockedtimes',
2451 default=False,
2461 default=False,
2452 )
2462 )
2453 coreconfigitem(
2463 coreconfigitem(
2454 b'ui',
2464 b'ui',
2455 b'merge',
2465 b'merge',
2456 default=None,
2466 default=None,
2457 )
2467 )
2458 coreconfigitem(
2468 coreconfigitem(
2459 b'ui',
2469 b'ui',
2460 b'mergemarkers',
2470 b'mergemarkers',
2461 default=b'basic',
2471 default=b'basic',
2462 )
2472 )
2463 coreconfigitem(
2473 coreconfigitem(
2464 b'ui',
2474 b'ui',
2465 b'message-output',
2475 b'message-output',
2466 default=b'stdio',
2476 default=b'stdio',
2467 )
2477 )
2468 coreconfigitem(
2478 coreconfigitem(
2469 b'ui',
2479 b'ui',
2470 b'nontty',
2480 b'nontty',
2471 default=False,
2481 default=False,
2472 )
2482 )
2473 coreconfigitem(
2483 coreconfigitem(
2474 b'ui',
2484 b'ui',
2475 b'origbackuppath',
2485 b'origbackuppath',
2476 default=None,
2486 default=None,
2477 )
2487 )
2478 coreconfigitem(
2488 coreconfigitem(
2479 b'ui',
2489 b'ui',
2480 b'paginate',
2490 b'paginate',
2481 default=True,
2491 default=True,
2482 )
2492 )
2483 coreconfigitem(
2493 coreconfigitem(
2484 b'ui',
2494 b'ui',
2485 b'patch',
2495 b'patch',
2486 default=None,
2496 default=None,
2487 )
2497 )
2488 coreconfigitem(
2498 coreconfigitem(
2489 b'ui',
2499 b'ui',
2490 b'portablefilenames',
2500 b'portablefilenames',
2491 default=b'warn',
2501 default=b'warn',
2492 )
2502 )
2493 coreconfigitem(
2503 coreconfigitem(
2494 b'ui',
2504 b'ui',
2495 b'promptecho',
2505 b'promptecho',
2496 default=False,
2506 default=False,
2497 )
2507 )
2498 coreconfigitem(
2508 coreconfigitem(
2499 b'ui',
2509 b'ui',
2500 b'quiet',
2510 b'quiet',
2501 default=False,
2511 default=False,
2502 )
2512 )
2503 coreconfigitem(
2513 coreconfigitem(
2504 b'ui',
2514 b'ui',
2505 b'quietbookmarkmove',
2515 b'quietbookmarkmove',
2506 default=False,
2516 default=False,
2507 )
2517 )
2508 coreconfigitem(
2518 coreconfigitem(
2509 b'ui',
2519 b'ui',
2510 b'relative-paths',
2520 b'relative-paths',
2511 default=b'legacy',
2521 default=b'legacy',
2512 )
2522 )
2513 coreconfigitem(
2523 coreconfigitem(
2514 b'ui',
2524 b'ui',
2515 b'remotecmd',
2525 b'remotecmd',
2516 default=b'hg',
2526 default=b'hg',
2517 )
2527 )
2518 coreconfigitem(
2528 coreconfigitem(
2519 b'ui',
2529 b'ui',
2520 b'report_untrusted',
2530 b'report_untrusted',
2521 default=True,
2531 default=True,
2522 )
2532 )
2523 coreconfigitem(
2533 coreconfigitem(
2524 b'ui',
2534 b'ui',
2525 b'rollback',
2535 b'rollback',
2526 default=True,
2536 default=True,
2527 )
2537 )
2528 coreconfigitem(
2538 coreconfigitem(
2529 b'ui',
2539 b'ui',
2530 b'signal-safe-lock',
2540 b'signal-safe-lock',
2531 default=True,
2541 default=True,
2532 )
2542 )
2533 coreconfigitem(
2543 coreconfigitem(
2534 b'ui',
2544 b'ui',
2535 b'slash',
2545 b'slash',
2536 default=False,
2546 default=False,
2537 )
2547 )
2538 coreconfigitem(
2548 coreconfigitem(
2539 b'ui',
2549 b'ui',
2540 b'ssh',
2550 b'ssh',
2541 default=b'ssh',
2551 default=b'ssh',
2542 )
2552 )
2543 coreconfigitem(
2553 coreconfigitem(
2544 b'ui',
2554 b'ui',
2545 b'ssherrorhint',
2555 b'ssherrorhint',
2546 default=None,
2556 default=None,
2547 )
2557 )
2548 coreconfigitem(
2558 coreconfigitem(
2549 b'ui',
2559 b'ui',
2550 b'statuscopies',
2560 b'statuscopies',
2551 default=False,
2561 default=False,
2552 )
2562 )
2553 coreconfigitem(
2563 coreconfigitem(
2554 b'ui',
2564 b'ui',
2555 b'strict',
2565 b'strict',
2556 default=False,
2566 default=False,
2557 )
2567 )
2558 coreconfigitem(
2568 coreconfigitem(
2559 b'ui',
2569 b'ui',
2560 b'style',
2570 b'style',
2561 default=b'',
2571 default=b'',
2562 )
2572 )
2563 coreconfigitem(
2573 coreconfigitem(
2564 b'ui',
2574 b'ui',
2565 b'supportcontact',
2575 b'supportcontact',
2566 default=None,
2576 default=None,
2567 )
2577 )
2568 coreconfigitem(
2578 coreconfigitem(
2569 b'ui',
2579 b'ui',
2570 b'textwidth',
2580 b'textwidth',
2571 default=78,
2581 default=78,
2572 )
2582 )
2573 coreconfigitem(
2583 coreconfigitem(
2574 b'ui',
2584 b'ui',
2575 b'timeout',
2585 b'timeout',
2576 default=b'600',
2586 default=b'600',
2577 )
2587 )
2578 coreconfigitem(
2588 coreconfigitem(
2579 b'ui',
2589 b'ui',
2580 b'timeout.warn',
2590 b'timeout.warn',
2581 default=0,
2591 default=0,
2582 )
2592 )
2583 coreconfigitem(
2593 coreconfigitem(
2584 b'ui',
2594 b'ui',
2585 b'timestamp-output',
2595 b'timestamp-output',
2586 default=False,
2596 default=False,
2587 )
2597 )
2588 coreconfigitem(
2598 coreconfigitem(
2589 b'ui',
2599 b'ui',
2590 b'traceback',
2600 b'traceback',
2591 default=False,
2601 default=False,
2592 )
2602 )
2593 coreconfigitem(
2603 coreconfigitem(
2594 b'ui',
2604 b'ui',
2595 b'tweakdefaults',
2605 b'tweakdefaults',
2596 default=False,
2606 default=False,
2597 )
2607 )
2598 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2608 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2599 coreconfigitem(
2609 coreconfigitem(
2600 b'ui',
2610 b'ui',
2601 b'verbose',
2611 b'verbose',
2602 default=False,
2612 default=False,
2603 )
2613 )
2604 coreconfigitem(
2614 coreconfigitem(
2605 b'verify',
2615 b'verify',
2606 b'skipflags',
2616 b'skipflags',
2607 default=0,
2617 default=0,
2608 )
2618 )
2609 coreconfigitem(
2619 coreconfigitem(
2610 b'web',
2620 b'web',
2611 b'allowbz2',
2621 b'allowbz2',
2612 default=False,
2622 default=False,
2613 )
2623 )
2614 coreconfigitem(
2624 coreconfigitem(
2615 b'web',
2625 b'web',
2616 b'allowgz',
2626 b'allowgz',
2617 default=False,
2627 default=False,
2618 )
2628 )
2619 coreconfigitem(
2629 coreconfigitem(
2620 b'web',
2630 b'web',
2621 b'allow-pull',
2631 b'allow-pull',
2622 alias=[(b'web', b'allowpull')],
2632 alias=[(b'web', b'allowpull')],
2623 default=True,
2633 default=True,
2624 )
2634 )
2625 coreconfigitem(
2635 coreconfigitem(
2626 b'web',
2636 b'web',
2627 b'allow-push',
2637 b'allow-push',
2628 alias=[(b'web', b'allow_push')],
2638 alias=[(b'web', b'allow_push')],
2629 default=list,
2639 default=list,
2630 )
2640 )
2631 coreconfigitem(
2641 coreconfigitem(
2632 b'web',
2642 b'web',
2633 b'allowzip',
2643 b'allowzip',
2634 default=False,
2644 default=False,
2635 )
2645 )
2636 coreconfigitem(
2646 coreconfigitem(
2637 b'web',
2647 b'web',
2638 b'archivesubrepos',
2648 b'archivesubrepos',
2639 default=False,
2649 default=False,
2640 )
2650 )
2641 coreconfigitem(
2651 coreconfigitem(
2642 b'web',
2652 b'web',
2643 b'cache',
2653 b'cache',
2644 default=True,
2654 default=True,
2645 )
2655 )
2646 coreconfigitem(
2656 coreconfigitem(
2647 b'web',
2657 b'web',
2648 b'comparisoncontext',
2658 b'comparisoncontext',
2649 default=5,
2659 default=5,
2650 )
2660 )
2651 coreconfigitem(
2661 coreconfigitem(
2652 b'web',
2662 b'web',
2653 b'contact',
2663 b'contact',
2654 default=None,
2664 default=None,
2655 )
2665 )
2656 coreconfigitem(
2666 coreconfigitem(
2657 b'web',
2667 b'web',
2658 b'deny_push',
2668 b'deny_push',
2659 default=list,
2669 default=list,
2660 )
2670 )
2661 coreconfigitem(
2671 coreconfigitem(
2662 b'web',
2672 b'web',
2663 b'guessmime',
2673 b'guessmime',
2664 default=False,
2674 default=False,
2665 )
2675 )
2666 coreconfigitem(
2676 coreconfigitem(
2667 b'web',
2677 b'web',
2668 b'hidden',
2678 b'hidden',
2669 default=False,
2679 default=False,
2670 )
2680 )
2671 coreconfigitem(
2681 coreconfigitem(
2672 b'web',
2682 b'web',
2673 b'labels',
2683 b'labels',
2674 default=list,
2684 default=list,
2675 )
2685 )
2676 coreconfigitem(
2686 coreconfigitem(
2677 b'web',
2687 b'web',
2678 b'logoimg',
2688 b'logoimg',
2679 default=b'hglogo.png',
2689 default=b'hglogo.png',
2680 )
2690 )
2681 coreconfigitem(
2691 coreconfigitem(
2682 b'web',
2692 b'web',
2683 b'logourl',
2693 b'logourl',
2684 default=b'https://mercurial-scm.org/',
2694 default=b'https://mercurial-scm.org/',
2685 )
2695 )
2686 coreconfigitem(
2696 coreconfigitem(
2687 b'web',
2697 b'web',
2688 b'accesslog',
2698 b'accesslog',
2689 default=b'-',
2699 default=b'-',
2690 )
2700 )
2691 coreconfigitem(
2701 coreconfigitem(
2692 b'web',
2702 b'web',
2693 b'address',
2703 b'address',
2694 default=b'',
2704 default=b'',
2695 )
2705 )
2696 coreconfigitem(
2706 coreconfigitem(
2697 b'web',
2707 b'web',
2698 b'allow-archive',
2708 b'allow-archive',
2699 alias=[(b'web', b'allow_archive')],
2709 alias=[(b'web', b'allow_archive')],
2700 default=list,
2710 default=list,
2701 )
2711 )
2702 coreconfigitem(
2712 coreconfigitem(
2703 b'web',
2713 b'web',
2704 b'allow_read',
2714 b'allow_read',
2705 default=list,
2715 default=list,
2706 )
2716 )
2707 coreconfigitem(
2717 coreconfigitem(
2708 b'web',
2718 b'web',
2709 b'baseurl',
2719 b'baseurl',
2710 default=None,
2720 default=None,
2711 )
2721 )
2712 coreconfigitem(
2722 coreconfigitem(
2713 b'web',
2723 b'web',
2714 b'cacerts',
2724 b'cacerts',
2715 default=None,
2725 default=None,
2716 )
2726 )
2717 coreconfigitem(
2727 coreconfigitem(
2718 b'web',
2728 b'web',
2719 b'certificate',
2729 b'certificate',
2720 default=None,
2730 default=None,
2721 )
2731 )
2722 coreconfigitem(
2732 coreconfigitem(
2723 b'web',
2733 b'web',
2724 b'collapse',
2734 b'collapse',
2725 default=False,
2735 default=False,
2726 )
2736 )
2727 coreconfigitem(
2737 coreconfigitem(
2728 b'web',
2738 b'web',
2729 b'csp',
2739 b'csp',
2730 default=None,
2740 default=None,
2731 )
2741 )
2732 coreconfigitem(
2742 coreconfigitem(
2733 b'web',
2743 b'web',
2734 b'deny_read',
2744 b'deny_read',
2735 default=list,
2745 default=list,
2736 )
2746 )
2737 coreconfigitem(
2747 coreconfigitem(
2738 b'web',
2748 b'web',
2739 b'descend',
2749 b'descend',
2740 default=True,
2750 default=True,
2741 )
2751 )
2742 coreconfigitem(
2752 coreconfigitem(
2743 b'web',
2753 b'web',
2744 b'description',
2754 b'description',
2745 default=b"",
2755 default=b"",
2746 )
2756 )
2747 coreconfigitem(
2757 coreconfigitem(
2748 b'web',
2758 b'web',
2749 b'encoding',
2759 b'encoding',
2750 default=lambda: encoding.encoding,
2760 default=lambda: encoding.encoding,
2751 )
2761 )
2752 coreconfigitem(
2762 coreconfigitem(
2753 b'web',
2763 b'web',
2754 b'errorlog',
2764 b'errorlog',
2755 default=b'-',
2765 default=b'-',
2756 )
2766 )
2757 coreconfigitem(
2767 coreconfigitem(
2758 b'web',
2768 b'web',
2759 b'ipv6',
2769 b'ipv6',
2760 default=False,
2770 default=False,
2761 )
2771 )
2762 coreconfigitem(
2772 coreconfigitem(
2763 b'web',
2773 b'web',
2764 b'maxchanges',
2774 b'maxchanges',
2765 default=10,
2775 default=10,
2766 )
2776 )
2767 coreconfigitem(
2777 coreconfigitem(
2768 b'web',
2778 b'web',
2769 b'maxfiles',
2779 b'maxfiles',
2770 default=10,
2780 default=10,
2771 )
2781 )
2772 coreconfigitem(
2782 coreconfigitem(
2773 b'web',
2783 b'web',
2774 b'maxshortchanges',
2784 b'maxshortchanges',
2775 default=60,
2785 default=60,
2776 )
2786 )
2777 coreconfigitem(
2787 coreconfigitem(
2778 b'web',
2788 b'web',
2779 b'motd',
2789 b'motd',
2780 default=b'',
2790 default=b'',
2781 )
2791 )
2782 coreconfigitem(
2792 coreconfigitem(
2783 b'web',
2793 b'web',
2784 b'name',
2794 b'name',
2785 default=dynamicdefault,
2795 default=dynamicdefault,
2786 )
2796 )
2787 coreconfigitem(
2797 coreconfigitem(
2788 b'web',
2798 b'web',
2789 b'port',
2799 b'port',
2790 default=8000,
2800 default=8000,
2791 )
2801 )
2792 coreconfigitem(
2802 coreconfigitem(
2793 b'web',
2803 b'web',
2794 b'prefix',
2804 b'prefix',
2795 default=b'',
2805 default=b'',
2796 )
2806 )
2797 coreconfigitem(
2807 coreconfigitem(
2798 b'web',
2808 b'web',
2799 b'push_ssl',
2809 b'push_ssl',
2800 default=True,
2810 default=True,
2801 )
2811 )
2802 coreconfigitem(
2812 coreconfigitem(
2803 b'web',
2813 b'web',
2804 b'refreshinterval',
2814 b'refreshinterval',
2805 default=20,
2815 default=20,
2806 )
2816 )
2807 coreconfigitem(
2817 coreconfigitem(
2808 b'web',
2818 b'web',
2809 b'server-header',
2819 b'server-header',
2810 default=None,
2820 default=None,
2811 )
2821 )
2812 coreconfigitem(
2822 coreconfigitem(
2813 b'web',
2823 b'web',
2814 b'static',
2824 b'static',
2815 default=None,
2825 default=None,
2816 )
2826 )
2817 coreconfigitem(
2827 coreconfigitem(
2818 b'web',
2828 b'web',
2819 b'staticurl',
2829 b'staticurl',
2820 default=None,
2830 default=None,
2821 )
2831 )
2822 coreconfigitem(
2832 coreconfigitem(
2823 b'web',
2833 b'web',
2824 b'stripes',
2834 b'stripes',
2825 default=1,
2835 default=1,
2826 )
2836 )
2827 coreconfigitem(
2837 coreconfigitem(
2828 b'web',
2838 b'web',
2829 b'style',
2839 b'style',
2830 default=b'paper',
2840 default=b'paper',
2831 )
2841 )
2832 coreconfigitem(
2842 coreconfigitem(
2833 b'web',
2843 b'web',
2834 b'templates',
2844 b'templates',
2835 default=None,
2845 default=None,
2836 )
2846 )
2837 coreconfigitem(
2847 coreconfigitem(
2838 b'web',
2848 b'web',
2839 b'view',
2849 b'view',
2840 default=b'served',
2850 default=b'served',
2841 experimental=True,
2851 experimental=True,
2842 )
2852 )
2843 coreconfigitem(
2853 coreconfigitem(
2844 b'worker',
2854 b'worker',
2845 b'backgroundclose',
2855 b'backgroundclose',
2846 default=dynamicdefault,
2856 default=dynamicdefault,
2847 )
2857 )
2848 # Windows defaults to a limit of 512 open files. A buffer of 128
2858 # Windows defaults to a limit of 512 open files. A buffer of 128
2849 # should give us enough headway.
2859 # should give us enough headway.
2850 coreconfigitem(
2860 coreconfigitem(
2851 b'worker',
2861 b'worker',
2852 b'backgroundclosemaxqueue',
2862 b'backgroundclosemaxqueue',
2853 default=384,
2863 default=384,
2854 )
2864 )
2855 coreconfigitem(
2865 coreconfigitem(
2856 b'worker',
2866 b'worker',
2857 b'backgroundcloseminfilecount',
2867 b'backgroundcloseminfilecount',
2858 default=2048,
2868 default=2048,
2859 )
2869 )
2860 coreconfigitem(
2870 coreconfigitem(
2861 b'worker',
2871 b'worker',
2862 b'backgroundclosethreadcount',
2872 b'backgroundclosethreadcount',
2863 default=4,
2873 default=4,
2864 )
2874 )
2865 coreconfigitem(
2875 coreconfigitem(
2866 b'worker',
2876 b'worker',
2867 b'enabled',
2877 b'enabled',
2868 default=True,
2878 default=True,
2869 )
2879 )
2870 coreconfigitem(
2880 coreconfigitem(
2871 b'worker',
2881 b'worker',
2872 b'numcpus',
2882 b'numcpus',
2873 default=None,
2883 default=None,
2874 )
2884 )
2875
2885
2876 # Rebase related configuration moved to core because other extension are doing
2886 # Rebase related configuration moved to core because other extension are doing
2877 # strange things. For example, shelve import the extensions to reuse some bit
2887 # strange things. For example, shelve import the extensions to reuse some bit
2878 # without formally loading it.
2888 # without formally loading it.
2879 coreconfigitem(
2889 coreconfigitem(
2880 b'commands',
2890 b'commands',
2881 b'rebase.requiredest',
2891 b'rebase.requiredest',
2882 default=False,
2892 default=False,
2883 )
2893 )
2884 coreconfigitem(
2894 coreconfigitem(
2885 b'experimental',
2895 b'experimental',
2886 b'rebaseskipobsolete',
2896 b'rebaseskipobsolete',
2887 default=True,
2897 default=True,
2888 )
2898 )
2889 coreconfigitem(
2899 coreconfigitem(
2890 b'rebase',
2900 b'rebase',
2891 b'singletransaction',
2901 b'singletransaction',
2892 default=False,
2902 default=False,
2893 )
2903 )
2894 coreconfigitem(
2904 coreconfigitem(
2895 b'rebase',
2905 b'rebase',
2896 b'experimental.inmemory',
2906 b'experimental.inmemory',
2897 default=False,
2907 default=False,
2898 )
2908 )
2899
2909
2900 # This setting controls creation of a rebase_source extra field
2910 # This setting controls creation of a rebase_source extra field
2901 # during rebase. When False, no such field is created. This is
2911 # during rebase. When False, no such field is created. This is
2902 # useful eg for incrementally converting changesets and then
2912 # useful eg for incrementally converting changesets and then
2903 # rebasing them onto an existing repo.
2913 # rebasing them onto an existing repo.
2904 # WARNING: this is an advanced setting reserved for people who know
2914 # WARNING: this is an advanced setting reserved for people who know
2905 # exactly what they are doing. Misuse of this setting can easily
2915 # exactly what they are doing. Misuse of this setting can easily
2906 # result in obsmarker cycles and a vivid headache.
2916 # result in obsmarker cycles and a vivid headache.
2907 coreconfigitem(
2917 coreconfigitem(
2908 b'rebase',
2918 b'rebase',
2909 b'store-source',
2919 b'store-source',
2910 default=True,
2920 default=True,
2911 experimental=True,
2921 experimental=True,
2912 )
2922 )
@@ -1,708 +1,712
1 # dirstatemap.py
1 # dirstatemap.py
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6
6
7 from .i18n import _
7 from .i18n import _
8
8
9 from . import (
9 from . import (
10 error,
10 error,
11 pathutil,
11 pathutil,
12 policy,
12 policy,
13 testing,
13 testing,
14 txnutil,
14 txnutil,
15 util,
15 util,
16 )
16 )
17
17
18 from .dirstateutils import (
18 from .dirstateutils import (
19 docket as docketmod,
19 docket as docketmod,
20 v2,
20 v2,
21 )
21 )
22
22
23 parsers = policy.importmod('parsers')
23 parsers = policy.importmod('parsers')
24 rustmod = policy.importrust('dirstate')
24 rustmod = policy.importrust('dirstate')
25
25
26 propertycache = util.propertycache
26 propertycache = util.propertycache
27
27
28 if rustmod is None:
28 if rustmod is None:
29 DirstateItem = parsers.DirstateItem
29 DirstateItem = parsers.DirstateItem
30 else:
30 else:
31 DirstateItem = rustmod.DirstateItem
31 DirstateItem = rustmod.DirstateItem
32
32
33 rangemask = 0x7FFFFFFF
33 rangemask = 0x7FFFFFFF
34
34
35 WRITE_MODE_AUTO = 0
35 WRITE_MODE_AUTO = 0
36 WRITE_MODE_FORCE_NEW = 1
36 WRITE_MODE_FORCE_NEW = 1
37 WRITE_MODE_FORCE_APPEND = 2
37 WRITE_MODE_FORCE_APPEND = 2
38
38
39
39
40 class _dirstatemapcommon:
40 class _dirstatemapcommon:
41 """
41 """
42 Methods that are identical for both implementations of the dirstatemap
42 Methods that are identical for both implementations of the dirstatemap
43 class, with and without Rust extensions enabled.
43 class, with and without Rust extensions enabled.
44 """
44 """
45
45
46 # please pytype
46 # please pytype
47
47
48 _map = None
48 _map = None
49 copymap = None
49 copymap = None
50
50
51 def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2):
51 def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2):
52 self._use_dirstate_v2 = use_dirstate_v2
52 self._use_dirstate_v2 = use_dirstate_v2
53 self._nodeconstants = nodeconstants
53 self._nodeconstants = nodeconstants
54 self._ui = ui
54 self._ui = ui
55 self._opener = opener
55 self._opener = opener
56 self._root = root
56 self._root = root
57 self._filename = b'dirstate'
57 self._filename = b'dirstate'
58 self._nodelen = 20 # Also update Rust code when changing this!
58 self._nodelen = 20 # Also update Rust code when changing this!
59 self._parents = None
59 self._parents = None
60 self._dirtyparents = False
60 self._dirtyparents = False
61 self._docket = None
61 self._docket = None
62 write_mode = ui.config(b"devel", b"dirstate.v2.data_update_mode")
62 write_mode = ui.config(b"devel", b"dirstate.v2.data_update_mode")
63 if write_mode == b"auto":
63 if write_mode == b"auto":
64 self._write_mode = WRITE_MODE_AUTO
64 self._write_mode = WRITE_MODE_AUTO
65 elif write_mode == b"force-append":
65 elif write_mode == b"force-append":
66 self._write_mode = WRITE_MODE_FORCE_APPEND
66 self._write_mode = WRITE_MODE_FORCE_APPEND
67 elif write_mode == b"force-new":
67 elif write_mode == b"force-new":
68 self._write_mode = WRITE_MODE_FORCE_NEW
68 self._write_mode = WRITE_MODE_FORCE_NEW
69 else:
69 else:
70 # unknown value, fallback to default
70 # unknown value, fallback to default
71 self._write_mode = WRITE_MODE_AUTO
71 self._write_mode = WRITE_MODE_AUTO
72
72
73 # for consistent view between _pl() and _read() invocations
73 # for consistent view between _pl() and _read() invocations
74 self._pendingmode = None
74 self._pendingmode = None
75
75
76 def preload(self):
76 def preload(self):
77 """Loads the underlying data, if it's not already loaded"""
77 """Loads the underlying data, if it's not already loaded"""
78 self._map
78 self._map
79
79
80 def get(self, key, default=None):
80 def get(self, key, default=None):
81 return self._map.get(key, default)
81 return self._map.get(key, default)
82
82
83 def __len__(self):
83 def __len__(self):
84 return len(self._map)
84 return len(self._map)
85
85
86 def __iter__(self):
86 def __iter__(self):
87 return iter(self._map)
87 return iter(self._map)
88
88
89 def __contains__(self, key):
89 def __contains__(self, key):
90 return key in self._map
90 return key in self._map
91
91
92 def __getitem__(self, item):
92 def __getitem__(self, item):
93 return self._map[item]
93 return self._map[item]
94
94
95 ### disk interaction
95 ### disk interaction
96
96
97 def _opendirstatefile(self):
97 def _opendirstatefile(self):
98 fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
98 fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
99 if self._pendingmode is not None and self._pendingmode != mode:
99 if self._pendingmode is not None and self._pendingmode != mode:
100 fp.close()
100 fp.close()
101 raise error.Abort(
101 raise error.Abort(
102 _(b'working directory state may be changed parallelly')
102 _(b'working directory state may be changed parallelly')
103 )
103 )
104 self._pendingmode = mode
104 self._pendingmode = mode
105 return fp
105 return fp
106
106
107 def _readdirstatefile(self, size=-1):
107 def _readdirstatefile(self, size=-1):
108 try:
108 try:
109 with self._opendirstatefile() as fp:
109 with self._opendirstatefile() as fp:
110 return fp.read(size)
110 return fp.read(size)
111 except FileNotFoundError:
111 except FileNotFoundError:
112 # File doesn't exist, so the current state is empty
112 # File doesn't exist, so the current state is empty
113 return b''
113 return b''
114
114
115 @property
115 @property
116 def docket(self):
116 def docket(self):
117 if not self._docket:
117 if not self._docket:
118 if not self._use_dirstate_v2:
118 if not self._use_dirstate_v2:
119 raise error.ProgrammingError(
119 raise error.ProgrammingError(
120 b'dirstate only has a docket in v2 format'
120 b'dirstate only has a docket in v2 format'
121 )
121 )
122 self._docket = docketmod.DirstateDocket.parse(
122 self._docket = docketmod.DirstateDocket.parse(
123 self._readdirstatefile(), self._nodeconstants
123 self._readdirstatefile(), self._nodeconstants
124 )
124 )
125 return self._docket
125 return self._docket
126
126
127 def write_v2_no_append(self, tr, st, meta, packed):
127 def write_v2_no_append(self, tr, st, meta, packed):
128 old_docket = self.docket
128 old_docket = self.docket
129 new_docket = docketmod.DirstateDocket.with_new_uuid(
129 new_docket = docketmod.DirstateDocket.with_new_uuid(
130 self.parents(), len(packed), meta
130 self.parents(), len(packed), meta
131 )
131 )
132 if old_docket.uuid == new_docket.uuid:
132 if old_docket.uuid == new_docket.uuid:
133 raise error.ProgrammingError(b'dirstate docket name collision')
133 raise error.ProgrammingError(b'dirstate docket name collision')
134 data_filename = new_docket.data_filename()
134 data_filename = new_docket.data_filename()
135 self._opener.write(data_filename, packed)
135 self._opener.write(data_filename, packed)
136 # Write the new docket after the new data file has been
136 # Write the new docket after the new data file has been
137 # written. Because `st` was opened with `atomictemp=True`,
137 # written. Because `st` was opened with `atomictemp=True`,
138 # the actual `.hg/dirstate` file is only affected on close.
138 # the actual `.hg/dirstate` file is only affected on close.
139 st.write(new_docket.serialize())
139 st.write(new_docket.serialize())
140 st.close()
140 st.close()
141 # Remove the old data file after the new docket pointing to
141 # Remove the old data file after the new docket pointing to
142 # the new data file was written.
142 # the new data file was written.
143 if old_docket.uuid:
143 if old_docket.uuid:
144 data_filename = old_docket.data_filename()
144 data_filename = old_docket.data_filename()
145 unlink = lambda _tr=None: self._opener.unlink(data_filename)
145 unlink = lambda _tr=None: self._opener.unlink(data_filename)
146 if tr:
146 if tr:
147 category = b"dirstate-v2-clean-" + old_docket.uuid
147 category = b"dirstate-v2-clean-" + old_docket.uuid
148 tr.addpostclose(category, unlink)
148 tr.addpostclose(category, unlink)
149 else:
149 else:
150 unlink()
150 unlink()
151 self._docket = new_docket
151 self._docket = new_docket
152
152
153 ### reading/setting parents
153 ### reading/setting parents
154
154
155 def parents(self):
155 def parents(self):
156 if not self._parents:
156 if not self._parents:
157 if self._use_dirstate_v2:
157 if self._use_dirstate_v2:
158 self._parents = self.docket.parents
158 self._parents = self.docket.parents
159 else:
159 else:
160 read_len = self._nodelen * 2
160 read_len = self._nodelen * 2
161 st = self._readdirstatefile(read_len)
161 st = self._readdirstatefile(read_len)
162 l = len(st)
162 l = len(st)
163 if l == read_len:
163 if l == read_len:
164 self._parents = (
164 self._parents = (
165 st[: self._nodelen],
165 st[: self._nodelen],
166 st[self._nodelen : 2 * self._nodelen],
166 st[self._nodelen : 2 * self._nodelen],
167 )
167 )
168 elif l == 0:
168 elif l == 0:
169 self._parents = (
169 self._parents = (
170 self._nodeconstants.nullid,
170 self._nodeconstants.nullid,
171 self._nodeconstants.nullid,
171 self._nodeconstants.nullid,
172 )
172 )
173 else:
173 else:
174 raise error.Abort(
174 raise error.Abort(
175 _(b'working directory state appears damaged!')
175 _(b'working directory state appears damaged!')
176 )
176 )
177
177
178 return self._parents
178 return self._parents
179
179
180
180
181 class dirstatemap(_dirstatemapcommon):
181 class dirstatemap(_dirstatemapcommon):
182 """Map encapsulating the dirstate's contents.
182 """Map encapsulating the dirstate's contents.
183
183
184 The dirstate contains the following state:
184 The dirstate contains the following state:
185
185
186 - `identity` is the identity of the dirstate file, which can be used to
186 - `identity` is the identity of the dirstate file, which can be used to
187 detect when changes have occurred to the dirstate file.
187 detect when changes have occurred to the dirstate file.
188
188
189 - `parents` is a pair containing the parents of the working copy. The
189 - `parents` is a pair containing the parents of the working copy. The
190 parents are updated by calling `setparents`.
190 parents are updated by calling `setparents`.
191
191
192 - the state map maps filenames to tuples of (state, mode, size, mtime),
192 - the state map maps filenames to tuples of (state, mode, size, mtime),
193 where state is a single character representing 'normal', 'added',
193 where state is a single character representing 'normal', 'added',
194 'removed', or 'merged'. It is read by treating the dirstate as a
194 'removed', or 'merged'. It is read by treating the dirstate as a
195 dict. File state is updated by calling various methods (see each
195 dict. File state is updated by calling various methods (see each
196 documentation for details):
196 documentation for details):
197
197
198 - `reset_state`,
198 - `reset_state`,
199 - `set_tracked`
199 - `set_tracked`
200 - `set_untracked`
200 - `set_untracked`
201 - `set_clean`
201 - `set_clean`
202 - `set_possibly_dirty`
202 - `set_possibly_dirty`
203
203
204 - `copymap` maps destination filenames to their source filename.
204 - `copymap` maps destination filenames to their source filename.
205
205
206 The dirstate also provides the following views onto the state:
206 The dirstate also provides the following views onto the state:
207
207
208 - `filefoldmap` is a dict mapping normalized filenames to the denormalized
208 - `filefoldmap` is a dict mapping normalized filenames to the denormalized
209 form that they appear as in the dirstate.
209 form that they appear as in the dirstate.
210
210
211 - `dirfoldmap` is a dict mapping normalized directory names to the
211 - `dirfoldmap` is a dict mapping normalized directory names to the
212 denormalized form that they appear as in the dirstate.
212 denormalized form that they appear as in the dirstate.
213 """
213 """
214
214
215 ### Core data storage and access
215 ### Core data storage and access
216
216
217 @propertycache
217 @propertycache
218 def _map(self):
218 def _map(self):
219 self._map = {}
219 self._map = {}
220 self.read()
220 self.read()
221 return self._map
221 return self._map
222
222
223 @propertycache
223 @propertycache
224 def copymap(self):
224 def copymap(self):
225 self.copymap = {}
225 self.copymap = {}
226 self._map
226 self._map
227 return self.copymap
227 return self.copymap
228
228
229 def clear(self):
229 def clear(self):
230 self._map.clear()
230 self._map.clear()
231 self.copymap.clear()
231 self.copymap.clear()
232 self.setparents(self._nodeconstants.nullid, self._nodeconstants.nullid)
232 self.setparents(self._nodeconstants.nullid, self._nodeconstants.nullid)
233 util.clearcachedproperty(self, b"_dirs")
233 util.clearcachedproperty(self, b"_dirs")
234 util.clearcachedproperty(self, b"_alldirs")
234 util.clearcachedproperty(self, b"_alldirs")
235 util.clearcachedproperty(self, b"filefoldmap")
235 util.clearcachedproperty(self, b"filefoldmap")
236 util.clearcachedproperty(self, b"dirfoldmap")
236 util.clearcachedproperty(self, b"dirfoldmap")
237
237
238 def items(self):
238 def items(self):
239 return self._map.items()
239 return self._map.items()
240
240
241 # forward for python2,3 compat
241 # forward for python2,3 compat
242 iteritems = items
242 iteritems = items
243
243
244 def debug_iter(self, all):
244 def debug_iter(self, all):
245 """
245 """
246 Return an iterator of (filename, state, mode, size, mtime) tuples
246 Return an iterator of (filename, state, mode, size, mtime) tuples
247
247
248 `all` is unused when Rust is not enabled
248 `all` is unused when Rust is not enabled
249 """
249 """
250 for (filename, item) in self.items():
250 for (filename, item) in self.items():
251 yield (filename, item.state, item.mode, item.size, item.mtime)
251 yield (filename, item.state, item.mode, item.size, item.mtime)
252
252
253 def keys(self):
253 def keys(self):
254 return self._map.keys()
254 return self._map.keys()
255
255
256 ### reading/setting parents
256 ### reading/setting parents
257
257
258 def setparents(self, p1, p2, fold_p2=False):
258 def setparents(self, p1, p2, fold_p2=False):
259 self._parents = (p1, p2)
259 self._parents = (p1, p2)
260 self._dirtyparents = True
260 self._dirtyparents = True
261 copies = {}
261 copies = {}
262 if fold_p2:
262 if fold_p2:
263 for f, s in self._map.items():
263 for f, s in self._map.items():
264 # Discard "merged" markers when moving away from a merge state
264 # Discard "merged" markers when moving away from a merge state
265 if s.p2_info:
265 if s.p2_info:
266 source = self.copymap.pop(f, None)
266 source = self.copymap.pop(f, None)
267 if source:
267 if source:
268 copies[f] = source
268 copies[f] = source
269 s.drop_merge_data()
269 s.drop_merge_data()
270 return copies
270 return copies
271
271
272 ### disk interaction
272 ### disk interaction
273
273
274 def read(self):
274 def read(self):
275 # ignore HG_PENDING because identity is used only for writing
275 # ignore HG_PENDING because identity is used only for writing
276 self.identity = util.filestat.frompath(
276 self.identity = util.filestat.frompath(
277 self._opener.join(self._filename)
277 self._opener.join(self._filename)
278 )
278 )
279
279
280 testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
280 testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
281 if self._use_dirstate_v2:
281 if self._use_dirstate_v2:
282
282
283 if not self.docket.uuid:
283 if not self.docket.uuid:
284 return
284 return
285 testing.wait_on_cfg(self._ui, b'dirstate.post-docket-read-file')
285 st = self._opener.read(self.docket.data_filename())
286 st = self._opener.read(self.docket.data_filename())
286 else:
287 else:
287 st = self._readdirstatefile()
288 st = self._readdirstatefile()
288
289
289 if not st:
290 if not st:
290 return
291 return
291
292
292 # TODO: adjust this estimate for dirstate-v2
293 # TODO: adjust this estimate for dirstate-v2
293 if util.safehasattr(parsers, b'dict_new_presized'):
294 if util.safehasattr(parsers, b'dict_new_presized'):
294 # Make an estimate of the number of files in the dirstate based on
295 # Make an estimate of the number of files in the dirstate based on
295 # its size. This trades wasting some memory for avoiding costly
296 # its size. This trades wasting some memory for avoiding costly
296 # resizes. Each entry have a prefix of 17 bytes followed by one or
297 # resizes. Each entry have a prefix of 17 bytes followed by one or
297 # two path names. Studies on various large-scale real-world repositories
298 # two path names. Studies on various large-scale real-world repositories
298 # found 54 bytes a reasonable upper limit for the average path names.
299 # found 54 bytes a reasonable upper limit for the average path names.
299 # Copy entries are ignored for the sake of this estimate.
300 # Copy entries are ignored for the sake of this estimate.
300 self._map = parsers.dict_new_presized(len(st) // 71)
301 self._map = parsers.dict_new_presized(len(st) // 71)
301
302
302 # Python's garbage collector triggers a GC each time a certain number
303 # Python's garbage collector triggers a GC each time a certain number
303 # of container objects (the number being defined by
304 # of container objects (the number being defined by
304 # gc.get_threshold()) are allocated. parse_dirstate creates a tuple
305 # gc.get_threshold()) are allocated. parse_dirstate creates a tuple
305 # for each file in the dirstate. The C version then immediately marks
306 # for each file in the dirstate. The C version then immediately marks
306 # them as not to be tracked by the collector. However, this has no
307 # them as not to be tracked by the collector. However, this has no
307 # effect on when GCs are triggered, only on what objects the GC looks
308 # effect on when GCs are triggered, only on what objects the GC looks
308 # into. This means that O(number of files) GCs are unavoidable.
309 # into. This means that O(number of files) GCs are unavoidable.
309 # Depending on when in the process's lifetime the dirstate is parsed,
310 # Depending on when in the process's lifetime the dirstate is parsed,
310 # this can get very expensive. As a workaround, disable GC while
311 # this can get very expensive. As a workaround, disable GC while
311 # parsing the dirstate.
312 # parsing the dirstate.
312 #
313 #
313 # (we cannot decorate the function directly since it is in a C module)
314 # (we cannot decorate the function directly since it is in a C module)
314 if self._use_dirstate_v2:
315 if self._use_dirstate_v2:
315 p = self.docket.parents
316 p = self.docket.parents
316 meta = self.docket.tree_metadata
317 meta = self.docket.tree_metadata
317 parse_dirstate = util.nogc(v2.parse_dirstate)
318 parse_dirstate = util.nogc(v2.parse_dirstate)
318 parse_dirstate(self._map, self.copymap, st, meta)
319 parse_dirstate(self._map, self.copymap, st, meta)
319 else:
320 else:
320 parse_dirstate = util.nogc(parsers.parse_dirstate)
321 parse_dirstate = util.nogc(parsers.parse_dirstate)
321 p = parse_dirstate(self._map, self.copymap, st)
322 p = parse_dirstate(self._map, self.copymap, st)
322 if not self._dirtyparents:
323 if not self._dirtyparents:
323 self.setparents(*p)
324 self.setparents(*p)
324
325
325 # Avoid excess attribute lookups by fast pathing certain checks
326 # Avoid excess attribute lookups by fast pathing certain checks
326 self.__contains__ = self._map.__contains__
327 self.__contains__ = self._map.__contains__
327 self.__getitem__ = self._map.__getitem__
328 self.__getitem__ = self._map.__getitem__
328 self.get = self._map.get
329 self.get = self._map.get
329
330
330 def write(self, tr, st):
331 def write(self, tr, st):
331 if self._use_dirstate_v2:
332 if self._use_dirstate_v2:
332 packed, meta = v2.pack_dirstate(self._map, self.copymap)
333 packed, meta = v2.pack_dirstate(self._map, self.copymap)
333 self.write_v2_no_append(tr, st, meta, packed)
334 self.write_v2_no_append(tr, st, meta, packed)
334 else:
335 else:
335 packed = parsers.pack_dirstate(
336 packed = parsers.pack_dirstate(
336 self._map, self.copymap, self.parents()
337 self._map, self.copymap, self.parents()
337 )
338 )
338 st.write(packed)
339 st.write(packed)
339 st.close()
340 st.close()
340 self._dirtyparents = False
341 self._dirtyparents = False
341
342
342 @propertycache
343 @propertycache
343 def identity(self):
344 def identity(self):
344 self._map
345 self._map
345 return self.identity
346 return self.identity
346
347
347 ### code related to maintaining and accessing "extra" property
348 ### code related to maintaining and accessing "extra" property
348 # (e.g. "has_dir")
349 # (e.g. "has_dir")
349
350
350 def _dirs_incr(self, filename, old_entry=None):
351 def _dirs_incr(self, filename, old_entry=None):
351 """increment the dirstate counter if applicable"""
352 """increment the dirstate counter if applicable"""
352 if (
353 if (
353 old_entry is None or old_entry.removed
354 old_entry is None or old_entry.removed
354 ) and "_dirs" in self.__dict__:
355 ) and "_dirs" in self.__dict__:
355 self._dirs.addpath(filename)
356 self._dirs.addpath(filename)
356 if old_entry is None and "_alldirs" in self.__dict__:
357 if old_entry is None and "_alldirs" in self.__dict__:
357 self._alldirs.addpath(filename)
358 self._alldirs.addpath(filename)
358
359
359 def _dirs_decr(self, filename, old_entry=None, remove_variant=False):
360 def _dirs_decr(self, filename, old_entry=None, remove_variant=False):
360 """decrement the dirstate counter if applicable"""
361 """decrement the dirstate counter if applicable"""
361 if old_entry is not None:
362 if old_entry is not None:
362 if "_dirs" in self.__dict__ and not old_entry.removed:
363 if "_dirs" in self.__dict__ and not old_entry.removed:
363 self._dirs.delpath(filename)
364 self._dirs.delpath(filename)
364 if "_alldirs" in self.__dict__ and not remove_variant:
365 if "_alldirs" in self.__dict__ and not remove_variant:
365 self._alldirs.delpath(filename)
366 self._alldirs.delpath(filename)
366 elif remove_variant and "_alldirs" in self.__dict__:
367 elif remove_variant and "_alldirs" in self.__dict__:
367 self._alldirs.addpath(filename)
368 self._alldirs.addpath(filename)
368 if "filefoldmap" in self.__dict__:
369 if "filefoldmap" in self.__dict__:
369 normed = util.normcase(filename)
370 normed = util.normcase(filename)
370 self.filefoldmap.pop(normed, None)
371 self.filefoldmap.pop(normed, None)
371
372
372 @propertycache
373 @propertycache
373 def filefoldmap(self):
374 def filefoldmap(self):
374 """Returns a dictionary mapping normalized case paths to their
375 """Returns a dictionary mapping normalized case paths to their
375 non-normalized versions.
376 non-normalized versions.
376 """
377 """
377 try:
378 try:
378 makefilefoldmap = parsers.make_file_foldmap
379 makefilefoldmap = parsers.make_file_foldmap
379 except AttributeError:
380 except AttributeError:
380 pass
381 pass
381 else:
382 else:
382 return makefilefoldmap(
383 return makefilefoldmap(
383 self._map, util.normcasespec, util.normcasefallback
384 self._map, util.normcasespec, util.normcasefallback
384 )
385 )
385
386
386 f = {}
387 f = {}
387 normcase = util.normcase
388 normcase = util.normcase
388 for name, s in self._map.items():
389 for name, s in self._map.items():
389 if not s.removed:
390 if not s.removed:
390 f[normcase(name)] = name
391 f[normcase(name)] = name
391 f[b'.'] = b'.' # prevents useless util.fspath() invocation
392 f[b'.'] = b'.' # prevents useless util.fspath() invocation
392 return f
393 return f
393
394
394 @propertycache
395 @propertycache
395 def dirfoldmap(self):
396 def dirfoldmap(self):
396 f = {}
397 f = {}
397 normcase = util.normcase
398 normcase = util.normcase
398 for name in self._dirs:
399 for name in self._dirs:
399 f[normcase(name)] = name
400 f[normcase(name)] = name
400 return f
401 return f
401
402
402 def hastrackeddir(self, d):
403 def hastrackeddir(self, d):
403 """
404 """
404 Returns True if the dirstate contains a tracked (not removed) file
405 Returns True if the dirstate contains a tracked (not removed) file
405 in this directory.
406 in this directory.
406 """
407 """
407 return d in self._dirs
408 return d in self._dirs
408
409
409 def hasdir(self, d):
410 def hasdir(self, d):
410 """
411 """
411 Returns True if the dirstate contains a file (tracked or removed)
412 Returns True if the dirstate contains a file (tracked or removed)
412 in this directory.
413 in this directory.
413 """
414 """
414 return d in self._alldirs
415 return d in self._alldirs
415
416
416 @propertycache
417 @propertycache
417 def _dirs(self):
418 def _dirs(self):
418 return pathutil.dirs(self._map, only_tracked=True)
419 return pathutil.dirs(self._map, only_tracked=True)
419
420
420 @propertycache
421 @propertycache
421 def _alldirs(self):
422 def _alldirs(self):
422 return pathutil.dirs(self._map)
423 return pathutil.dirs(self._map)
423
424
424 ### code related to manipulation of entries and copy-sources
425 ### code related to manipulation of entries and copy-sources
425
426
426 def reset_state(
427 def reset_state(
427 self,
428 self,
428 filename,
429 filename,
429 wc_tracked=False,
430 wc_tracked=False,
430 p1_tracked=False,
431 p1_tracked=False,
431 p2_info=False,
432 p2_info=False,
432 has_meaningful_mtime=True,
433 has_meaningful_mtime=True,
433 parentfiledata=None,
434 parentfiledata=None,
434 ):
435 ):
435 """Set a entry to a given state, diregarding all previous state
436 """Set a entry to a given state, diregarding all previous state
436
437
437 This is to be used by the part of the dirstate API dedicated to
438 This is to be used by the part of the dirstate API dedicated to
438 adjusting the dirstate after a update/merge.
439 adjusting the dirstate after a update/merge.
439
440
440 note: calling this might result to no entry existing at all if the
441 note: calling this might result to no entry existing at all if the
441 dirstate map does not see any point at having one for this file
442 dirstate map does not see any point at having one for this file
442 anymore.
443 anymore.
443 """
444 """
444 # copy information are now outdated
445 # copy information are now outdated
445 # (maybe new information should be in directly passed to this function)
446 # (maybe new information should be in directly passed to this function)
446 self.copymap.pop(filename, None)
447 self.copymap.pop(filename, None)
447
448
448 if not (p1_tracked or p2_info or wc_tracked):
449 if not (p1_tracked or p2_info or wc_tracked):
449 old_entry = self._map.get(filename)
450 old_entry = self._map.get(filename)
450 self._drop_entry(filename)
451 self._drop_entry(filename)
451 self._dirs_decr(filename, old_entry=old_entry)
452 self._dirs_decr(filename, old_entry=old_entry)
452 return
453 return
453
454
454 old_entry = self._map.get(filename)
455 old_entry = self._map.get(filename)
455 self._dirs_incr(filename, old_entry)
456 self._dirs_incr(filename, old_entry)
456 entry = DirstateItem(
457 entry = DirstateItem(
457 wc_tracked=wc_tracked,
458 wc_tracked=wc_tracked,
458 p1_tracked=p1_tracked,
459 p1_tracked=p1_tracked,
459 p2_info=p2_info,
460 p2_info=p2_info,
460 has_meaningful_mtime=has_meaningful_mtime,
461 has_meaningful_mtime=has_meaningful_mtime,
461 parentfiledata=parentfiledata,
462 parentfiledata=parentfiledata,
462 )
463 )
463 self._map[filename] = entry
464 self._map[filename] = entry
464
465
465 def set_tracked(self, filename):
466 def set_tracked(self, filename):
466 new = False
467 new = False
467 entry = self.get(filename)
468 entry = self.get(filename)
468 if entry is None:
469 if entry is None:
469 self._dirs_incr(filename)
470 self._dirs_incr(filename)
470 entry = DirstateItem(
471 entry = DirstateItem(
471 wc_tracked=True,
472 wc_tracked=True,
472 )
473 )
473
474
474 self._map[filename] = entry
475 self._map[filename] = entry
475 new = True
476 new = True
476 elif not entry.tracked:
477 elif not entry.tracked:
477 self._dirs_incr(filename, entry)
478 self._dirs_incr(filename, entry)
478 entry.set_tracked()
479 entry.set_tracked()
479 self._refresh_entry(filename, entry)
480 self._refresh_entry(filename, entry)
480 new = True
481 new = True
481 else:
482 else:
482 # XXX This is probably overkill for more case, but we need this to
483 # XXX This is probably overkill for more case, but we need this to
483 # fully replace the `normallookup` call with `set_tracked` one.
484 # fully replace the `normallookup` call with `set_tracked` one.
484 # Consider smoothing this in the future.
485 # Consider smoothing this in the future.
485 entry.set_possibly_dirty()
486 entry.set_possibly_dirty()
486 self._refresh_entry(filename, entry)
487 self._refresh_entry(filename, entry)
487 return new
488 return new
488
489
489 def set_untracked(self, f):
490 def set_untracked(self, f):
490 """Mark a file as no longer tracked in the dirstate map"""
491 """Mark a file as no longer tracked in the dirstate map"""
491 entry = self.get(f)
492 entry = self.get(f)
492 if entry is None:
493 if entry is None:
493 return False
494 return False
494 else:
495 else:
495 self._dirs_decr(f, old_entry=entry, remove_variant=not entry.added)
496 self._dirs_decr(f, old_entry=entry, remove_variant=not entry.added)
496 if not entry.p2_info:
497 if not entry.p2_info:
497 self.copymap.pop(f, None)
498 self.copymap.pop(f, None)
498 entry.set_untracked()
499 entry.set_untracked()
499 self._refresh_entry(f, entry)
500 self._refresh_entry(f, entry)
500 return True
501 return True
501
502
502 def set_clean(self, filename, mode, size, mtime):
503 def set_clean(self, filename, mode, size, mtime):
503 """mark a file as back to a clean state"""
504 """mark a file as back to a clean state"""
504 entry = self[filename]
505 entry = self[filename]
505 size = size & rangemask
506 size = size & rangemask
506 entry.set_clean(mode, size, mtime)
507 entry.set_clean(mode, size, mtime)
507 self._refresh_entry(filename, entry)
508 self._refresh_entry(filename, entry)
508 self.copymap.pop(filename, None)
509 self.copymap.pop(filename, None)
509
510
510 def set_possibly_dirty(self, filename):
511 def set_possibly_dirty(self, filename):
511 """record that the current state of the file on disk is unknown"""
512 """record that the current state of the file on disk is unknown"""
512 entry = self[filename]
513 entry = self[filename]
513 entry.set_possibly_dirty()
514 entry.set_possibly_dirty()
514 self._refresh_entry(filename, entry)
515 self._refresh_entry(filename, entry)
515
516
516 def _refresh_entry(self, f, entry):
517 def _refresh_entry(self, f, entry):
517 """record updated state of an entry"""
518 """record updated state of an entry"""
518 if not entry.any_tracked:
519 if not entry.any_tracked:
519 self._map.pop(f, None)
520 self._map.pop(f, None)
520
521
521 def _drop_entry(self, f):
522 def _drop_entry(self, f):
522 """remove any entry for file f
523 """remove any entry for file f
523
524
524 This should also drop associated copy information
525 This should also drop associated copy information
525
526
526 The fact we actually need to drop it is the responsability of the caller"""
527 The fact we actually need to drop it is the responsability of the caller"""
527 self._map.pop(f, None)
528 self._map.pop(f, None)
528 self.copymap.pop(f, None)
529 self.copymap.pop(f, None)
529
530
530
531
531 if rustmod is not None:
532 if rustmod is not None:
532
533
533 class dirstatemap(_dirstatemapcommon):
534 class dirstatemap(_dirstatemapcommon):
534
535
535 ### Core data storage and access
536 ### Core data storage and access
536
537
537 @propertycache
538 @propertycache
538 def _map(self):
539 def _map(self):
539 """
540 """
540 Fills the Dirstatemap when called.
541 Fills the Dirstatemap when called.
541 """
542 """
542 # ignore HG_PENDING because identity is used only for writing
543 # ignore HG_PENDING because identity is used only for writing
543 self.identity = util.filestat.frompath(
544 self.identity = util.filestat.frompath(
544 self._opener.join(self._filename)
545 self._opener.join(self._filename)
545 )
546 )
546
547
547 testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
548 testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
548 if self._use_dirstate_v2:
549 if self._use_dirstate_v2:
549 if self.docket.uuid:
550 if self.docket.uuid:
551 testing.wait_on_cfg(
552 self._ui, b'dirstate.post-docket-read-file'
553 )
550 # TODO: use mmap when possible
554 # TODO: use mmap when possible
551 data = self._opener.read(self.docket.data_filename())
555 data = self._opener.read(self.docket.data_filename())
552 else:
556 else:
553 data = b''
557 data = b''
554 self._map = rustmod.DirstateMap.new_v2(
558 self._map = rustmod.DirstateMap.new_v2(
555 data, self.docket.data_size, self.docket.tree_metadata
559 data, self.docket.data_size, self.docket.tree_metadata
556 )
560 )
557 parents = self.docket.parents
561 parents = self.docket.parents
558 else:
562 else:
559 self._map, parents = rustmod.DirstateMap.new_v1(
563 self._map, parents = rustmod.DirstateMap.new_v1(
560 self._readdirstatefile()
564 self._readdirstatefile()
561 )
565 )
562
566
563 if parents and not self._dirtyparents:
567 if parents and not self._dirtyparents:
564 self.setparents(*parents)
568 self.setparents(*parents)
565
569
566 self.__contains__ = self._map.__contains__
570 self.__contains__ = self._map.__contains__
567 self.__getitem__ = self._map.__getitem__
571 self.__getitem__ = self._map.__getitem__
568 self.get = self._map.get
572 self.get = self._map.get
569 return self._map
573 return self._map
570
574
571 @property
575 @property
572 def copymap(self):
576 def copymap(self):
573 return self._map.copymap()
577 return self._map.copymap()
574
578
575 def debug_iter(self, all):
579 def debug_iter(self, all):
576 """
580 """
577 Return an iterator of (filename, state, mode, size, mtime) tuples
581 Return an iterator of (filename, state, mode, size, mtime) tuples
578
582
579 `all`: also include with `state == b' '` dirstate tree nodes that
583 `all`: also include with `state == b' '` dirstate tree nodes that
580 don't have an associated `DirstateItem`.
584 don't have an associated `DirstateItem`.
581
585
582 """
586 """
583 return self._map.debug_iter(all)
587 return self._map.debug_iter(all)
584
588
585 def clear(self):
589 def clear(self):
586 self._map.clear()
590 self._map.clear()
587 self.setparents(
591 self.setparents(
588 self._nodeconstants.nullid, self._nodeconstants.nullid
592 self._nodeconstants.nullid, self._nodeconstants.nullid
589 )
593 )
590 util.clearcachedproperty(self, b"_dirs")
594 util.clearcachedproperty(self, b"_dirs")
591 util.clearcachedproperty(self, b"_alldirs")
595 util.clearcachedproperty(self, b"_alldirs")
592 util.clearcachedproperty(self, b"dirfoldmap")
596 util.clearcachedproperty(self, b"dirfoldmap")
593
597
594 def items(self):
598 def items(self):
595 return self._map.items()
599 return self._map.items()
596
600
597 # forward for python2,3 compat
601 # forward for python2,3 compat
598 iteritems = items
602 iteritems = items
599
603
600 def keys(self):
604 def keys(self):
601 return iter(self._map)
605 return iter(self._map)
602
606
603 ### reading/setting parents
607 ### reading/setting parents
604
608
605 def setparents(self, p1, p2, fold_p2=False):
609 def setparents(self, p1, p2, fold_p2=False):
606 self._parents = (p1, p2)
610 self._parents = (p1, p2)
607 self._dirtyparents = True
611 self._dirtyparents = True
608 copies = {}
612 copies = {}
609 if fold_p2:
613 if fold_p2:
610 copies = self._map.setparents_fixup()
614 copies = self._map.setparents_fixup()
611 return copies
615 return copies
612
616
613 ### disk interaction
617 ### disk interaction
614
618
615 @propertycache
619 @propertycache
616 def identity(self):
620 def identity(self):
617 self._map
621 self._map
618 return self.identity
622 return self.identity
619
623
620 def write(self, tr, st):
624 def write(self, tr, st):
621 if not self._use_dirstate_v2:
625 if not self._use_dirstate_v2:
622 p1, p2 = self.parents()
626 p1, p2 = self.parents()
623 packed = self._map.write_v1(p1, p2)
627 packed = self._map.write_v1(p1, p2)
624 st.write(packed)
628 st.write(packed)
625 st.close()
629 st.close()
626 self._dirtyparents = False
630 self._dirtyparents = False
627 return
631 return
628
632
629 # We can only append to an existing data file if there is one
633 # We can only append to an existing data file if there is one
630 write_mode = self._write_mode
634 write_mode = self._write_mode
631 if self.docket.uuid is None:
635 if self.docket.uuid is None:
632 write_mode = WRITE_MODE_FORCE_NEW
636 write_mode = WRITE_MODE_FORCE_NEW
633 packed, meta, append = self._map.write_v2(write_mode)
637 packed, meta, append = self._map.write_v2(write_mode)
634 if append:
638 if append:
635 docket = self.docket
639 docket = self.docket
636 data_filename = docket.data_filename()
640 data_filename = docket.data_filename()
637 with self._opener(data_filename, b'r+b') as fp:
641 with self._opener(data_filename, b'r+b') as fp:
638 fp.seek(docket.data_size)
642 fp.seek(docket.data_size)
639 assert fp.tell() == docket.data_size
643 assert fp.tell() == docket.data_size
640 written = fp.write(packed)
644 written = fp.write(packed)
641 if written is not None: # py2 may return None
645 if written is not None: # py2 may return None
642 assert written == len(packed), (written, len(packed))
646 assert written == len(packed), (written, len(packed))
643 docket.data_size += len(packed)
647 docket.data_size += len(packed)
644 docket.parents = self.parents()
648 docket.parents = self.parents()
645 docket.tree_metadata = meta
649 docket.tree_metadata = meta
646 st.write(docket.serialize())
650 st.write(docket.serialize())
647 st.close()
651 st.close()
648 else:
652 else:
649 self.write_v2_no_append(tr, st, meta, packed)
653 self.write_v2_no_append(tr, st, meta, packed)
650 # Reload from the newly-written file
654 # Reload from the newly-written file
651 util.clearcachedproperty(self, b"_map")
655 util.clearcachedproperty(self, b"_map")
652 self._dirtyparents = False
656 self._dirtyparents = False
653
657
654 ### code related to maintaining and accessing "extra" property
658 ### code related to maintaining and accessing "extra" property
655 # (e.g. "has_dir")
659 # (e.g. "has_dir")
656
660
657 @propertycache
661 @propertycache
658 def filefoldmap(self):
662 def filefoldmap(self):
659 """Returns a dictionary mapping normalized case paths to their
663 """Returns a dictionary mapping normalized case paths to their
660 non-normalized versions.
664 non-normalized versions.
661 """
665 """
662 return self._map.filefoldmapasdict()
666 return self._map.filefoldmapasdict()
663
667
664 def hastrackeddir(self, d):
668 def hastrackeddir(self, d):
665 return self._map.hastrackeddir(d)
669 return self._map.hastrackeddir(d)
666
670
667 def hasdir(self, d):
671 def hasdir(self, d):
668 return self._map.hasdir(d)
672 return self._map.hasdir(d)
669
673
670 @propertycache
674 @propertycache
671 def dirfoldmap(self):
675 def dirfoldmap(self):
672 f = {}
676 f = {}
673 normcase = util.normcase
677 normcase = util.normcase
674 for name in self._map.tracked_dirs():
678 for name in self._map.tracked_dirs():
675 f[normcase(name)] = name
679 f[normcase(name)] = name
676 return f
680 return f
677
681
678 ### code related to manipulation of entries and copy-sources
682 ### code related to manipulation of entries and copy-sources
679
683
680 def set_tracked(self, f):
684 def set_tracked(self, f):
681 return self._map.set_tracked(f)
685 return self._map.set_tracked(f)
682
686
683 def set_untracked(self, f):
687 def set_untracked(self, f):
684 return self._map.set_untracked(f)
688 return self._map.set_untracked(f)
685
689
686 def set_clean(self, filename, mode, size, mtime):
690 def set_clean(self, filename, mode, size, mtime):
687 self._map.set_clean(filename, mode, size, mtime)
691 self._map.set_clean(filename, mode, size, mtime)
688
692
689 def set_possibly_dirty(self, f):
693 def set_possibly_dirty(self, f):
690 self._map.set_possibly_dirty(f)
694 self._map.set_possibly_dirty(f)
691
695
692 def reset_state(
696 def reset_state(
693 self,
697 self,
694 filename,
698 filename,
695 wc_tracked=False,
699 wc_tracked=False,
696 p1_tracked=False,
700 p1_tracked=False,
697 p2_info=False,
701 p2_info=False,
698 has_meaningful_mtime=True,
702 has_meaningful_mtime=True,
699 parentfiledata=None,
703 parentfiledata=None,
700 ):
704 ):
701 return self._map.reset_state(
705 return self._map.reset_state(
702 filename,
706 filename,
703 wc_tracked,
707 wc_tracked,
704 p1_tracked,
708 p1_tracked,
705 p2_info,
709 p2_info,
706 has_meaningful_mtime,
710 has_meaningful_mtime,
707 parentfiledata,
711 parentfiledata,
708 )
712 )
@@ -1,615 +1,619
1 use crate::changelog::Changelog;
1 use crate::changelog::Changelog;
2 use crate::config::{Config, ConfigError, ConfigParseError};
2 use crate::config::{Config, ConfigError, ConfigParseError};
3 use crate::dirstate::DirstateParents;
3 use crate::dirstate::DirstateParents;
4 use crate::dirstate_tree::dirstate_map::DirstateMapWriteMode;
4 use crate::dirstate_tree::dirstate_map::DirstateMapWriteMode;
5 use crate::dirstate_tree::on_disk::Docket as DirstateDocket;
5 use crate::dirstate_tree::on_disk::Docket as DirstateDocket;
6 use crate::dirstate_tree::owning::OwningDirstateMap;
6 use crate::dirstate_tree::owning::OwningDirstateMap;
7 use crate::errors::HgResultExt;
7 use crate::errors::HgResultExt;
8 use crate::errors::{HgError, IoResultExt};
8 use crate::errors::{HgError, IoResultExt};
9 use crate::lock::{try_with_lock_no_wait, LockError};
9 use crate::lock::{try_with_lock_no_wait, LockError};
10 use crate::manifest::{Manifest, Manifestlog};
10 use crate::manifest::{Manifest, Manifestlog};
11 use crate::revlog::filelog::Filelog;
11 use crate::revlog::filelog::Filelog;
12 use crate::revlog::revlog::RevlogError;
12 use crate::revlog::revlog::RevlogError;
13 use crate::utils::debug::debug_wait_for_file_or_print;
13 use crate::utils::debug::debug_wait_for_file_or_print;
14 use crate::utils::files::get_path_from_bytes;
14 use crate::utils::files::get_path_from_bytes;
15 use crate::utils::hg_path::HgPath;
15 use crate::utils::hg_path::HgPath;
16 use crate::utils::SliceExt;
16 use crate::utils::SliceExt;
17 use crate::vfs::{is_dir, is_file, Vfs};
17 use crate::vfs::{is_dir, is_file, Vfs};
18 use crate::{requirements, NodePrefix};
18 use crate::{requirements, NodePrefix};
19 use crate::{DirstateError, Revision};
19 use crate::{DirstateError, Revision};
20 use std::cell::{Ref, RefCell, RefMut};
20 use std::cell::{Ref, RefCell, RefMut};
21 use std::collections::HashSet;
21 use std::collections::HashSet;
22 use std::io::Seek;
22 use std::io::Seek;
23 use std::io::SeekFrom;
23 use std::io::SeekFrom;
24 use std::io::Write as IoWrite;
24 use std::io::Write as IoWrite;
25 use std::path::{Path, PathBuf};
25 use std::path::{Path, PathBuf};
26
26
27 /// A repository on disk
27 /// A repository on disk
28 pub struct Repo {
28 pub struct Repo {
29 working_directory: PathBuf,
29 working_directory: PathBuf,
30 dot_hg: PathBuf,
30 dot_hg: PathBuf,
31 store: PathBuf,
31 store: PathBuf,
32 requirements: HashSet<String>,
32 requirements: HashSet<String>,
33 config: Config,
33 config: Config,
34 dirstate_parents: LazyCell<DirstateParents>,
34 dirstate_parents: LazyCell<DirstateParents>,
35 dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>>,
35 dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>>,
36 dirstate_map: LazyCell<OwningDirstateMap>,
36 dirstate_map: LazyCell<OwningDirstateMap>,
37 changelog: LazyCell<Changelog>,
37 changelog: LazyCell<Changelog>,
38 manifestlog: LazyCell<Manifestlog>,
38 manifestlog: LazyCell<Manifestlog>,
39 }
39 }
40
40
41 #[derive(Debug, derive_more::From)]
41 #[derive(Debug, derive_more::From)]
42 pub enum RepoError {
42 pub enum RepoError {
43 NotFound {
43 NotFound {
44 at: PathBuf,
44 at: PathBuf,
45 },
45 },
46 #[from]
46 #[from]
47 ConfigParseError(ConfigParseError),
47 ConfigParseError(ConfigParseError),
48 #[from]
48 #[from]
49 Other(HgError),
49 Other(HgError),
50 }
50 }
51
51
52 impl From<ConfigError> for RepoError {
52 impl From<ConfigError> for RepoError {
53 fn from(error: ConfigError) -> Self {
53 fn from(error: ConfigError) -> Self {
54 match error {
54 match error {
55 ConfigError::Parse(error) => error.into(),
55 ConfigError::Parse(error) => error.into(),
56 ConfigError::Other(error) => error.into(),
56 ConfigError::Other(error) => error.into(),
57 }
57 }
58 }
58 }
59 }
59 }
60
60
61 impl Repo {
61 impl Repo {
62 /// tries to find nearest repository root in current working directory or
62 /// tries to find nearest repository root in current working directory or
63 /// its ancestors
63 /// its ancestors
64 pub fn find_repo_root() -> Result<PathBuf, RepoError> {
64 pub fn find_repo_root() -> Result<PathBuf, RepoError> {
65 let current_directory = crate::utils::current_dir()?;
65 let current_directory = crate::utils::current_dir()?;
66 // ancestors() is inclusive: it first yields `current_directory`
66 // ancestors() is inclusive: it first yields `current_directory`
67 // as-is.
67 // as-is.
68 for ancestor in current_directory.ancestors() {
68 for ancestor in current_directory.ancestors() {
69 if is_dir(ancestor.join(".hg"))? {
69 if is_dir(ancestor.join(".hg"))? {
70 return Ok(ancestor.to_path_buf());
70 return Ok(ancestor.to_path_buf());
71 }
71 }
72 }
72 }
73 return Err(RepoError::NotFound {
73 return Err(RepoError::NotFound {
74 at: current_directory,
74 at: current_directory,
75 });
75 });
76 }
76 }
77
77
78 /// Find a repository, either at the given path (which must contain a `.hg`
78 /// Find a repository, either at the given path (which must contain a `.hg`
79 /// sub-directory) or by searching the current directory and its
79 /// sub-directory) or by searching the current directory and its
80 /// ancestors.
80 /// ancestors.
81 ///
81 ///
82 /// A method with two very different "modes" like this usually a code smell
82 /// A method with two very different "modes" like this usually a code smell
83 /// to make two methods instead, but in this case an `Option` is what rhg
83 /// to make two methods instead, but in this case an `Option` is what rhg
84 /// sub-commands get from Clap for the `-R` / `--repository` CLI argument.
84 /// sub-commands get from Clap for the `-R` / `--repository` CLI argument.
85 /// Having two methods would just move that `if` to almost all callers.
85 /// Having two methods would just move that `if` to almost all callers.
86 pub fn find(
86 pub fn find(
87 config: &Config,
87 config: &Config,
88 explicit_path: Option<PathBuf>,
88 explicit_path: Option<PathBuf>,
89 ) -> Result<Self, RepoError> {
89 ) -> Result<Self, RepoError> {
90 if let Some(root) = explicit_path {
90 if let Some(root) = explicit_path {
91 if is_dir(root.join(".hg"))? {
91 if is_dir(root.join(".hg"))? {
92 Self::new_at_path(root.to_owned(), config)
92 Self::new_at_path(root.to_owned(), config)
93 } else if is_file(&root)? {
93 } else if is_file(&root)? {
94 Err(HgError::unsupported("bundle repository").into())
94 Err(HgError::unsupported("bundle repository").into())
95 } else {
95 } else {
96 Err(RepoError::NotFound {
96 Err(RepoError::NotFound {
97 at: root.to_owned(),
97 at: root.to_owned(),
98 })
98 })
99 }
99 }
100 } else {
100 } else {
101 let root = Self::find_repo_root()?;
101 let root = Self::find_repo_root()?;
102 Self::new_at_path(root, config)
102 Self::new_at_path(root, config)
103 }
103 }
104 }
104 }
105
105
106 /// To be called after checking that `.hg` is a sub-directory
106 /// To be called after checking that `.hg` is a sub-directory
107 fn new_at_path(
107 fn new_at_path(
108 working_directory: PathBuf,
108 working_directory: PathBuf,
109 config: &Config,
109 config: &Config,
110 ) -> Result<Self, RepoError> {
110 ) -> Result<Self, RepoError> {
111 let dot_hg = working_directory.join(".hg");
111 let dot_hg = working_directory.join(".hg");
112
112
113 let mut repo_config_files = Vec::new();
113 let mut repo_config_files = Vec::new();
114 repo_config_files.push(dot_hg.join("hgrc"));
114 repo_config_files.push(dot_hg.join("hgrc"));
115 repo_config_files.push(dot_hg.join("hgrc-not-shared"));
115 repo_config_files.push(dot_hg.join("hgrc-not-shared"));
116
116
117 let hg_vfs = Vfs { base: &dot_hg };
117 let hg_vfs = Vfs { base: &dot_hg };
118 let mut reqs = requirements::load_if_exists(hg_vfs)?;
118 let mut reqs = requirements::load_if_exists(hg_vfs)?;
119 let relative =
119 let relative =
120 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
120 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
121 let shared =
121 let shared =
122 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
122 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
123
123
124 // From `mercurial/localrepo.py`:
124 // From `mercurial/localrepo.py`:
125 //
125 //
126 // if .hg/requires contains the sharesafe requirement, it means
126 // if .hg/requires contains the sharesafe requirement, it means
127 // there exists a `.hg/store/requires` too and we should read it
127 // there exists a `.hg/store/requires` too and we should read it
128 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
128 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
129 // is present. We never write SHARESAFE_REQUIREMENT for a repo if store
129 // is present. We never write SHARESAFE_REQUIREMENT for a repo if store
130 // is not present, refer checkrequirementscompat() for that
130 // is not present, refer checkrequirementscompat() for that
131 //
131 //
132 // However, if SHARESAFE_REQUIREMENT is not present, it means that the
132 // However, if SHARESAFE_REQUIREMENT is not present, it means that the
133 // repository was shared the old way. We check the share source
133 // repository was shared the old way. We check the share source
134 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
134 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
135 // current repository needs to be reshared
135 // current repository needs to be reshared
136 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
136 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
137
137
138 let store_path;
138 let store_path;
139 if !shared {
139 if !shared {
140 store_path = dot_hg.join("store");
140 store_path = dot_hg.join("store");
141 } else {
141 } else {
142 let bytes = hg_vfs.read("sharedpath")?;
142 let bytes = hg_vfs.read("sharedpath")?;
143 let mut shared_path =
143 let mut shared_path =
144 get_path_from_bytes(bytes.trim_end_matches(|b| b == b'\n'))
144 get_path_from_bytes(bytes.trim_end_matches(|b| b == b'\n'))
145 .to_owned();
145 .to_owned();
146 if relative {
146 if relative {
147 shared_path = dot_hg.join(shared_path)
147 shared_path = dot_hg.join(shared_path)
148 }
148 }
149 if !is_dir(&shared_path)? {
149 if !is_dir(&shared_path)? {
150 return Err(HgError::corrupted(format!(
150 return Err(HgError::corrupted(format!(
151 ".hg/sharedpath points to nonexistent directory {}",
151 ".hg/sharedpath points to nonexistent directory {}",
152 shared_path.display()
152 shared_path.display()
153 ))
153 ))
154 .into());
154 .into());
155 }
155 }
156
156
157 store_path = shared_path.join("store");
157 store_path = shared_path.join("store");
158
158
159 let source_is_share_safe =
159 let source_is_share_safe =
160 requirements::load(Vfs { base: &shared_path })?
160 requirements::load(Vfs { base: &shared_path })?
161 .contains(requirements::SHARESAFE_REQUIREMENT);
161 .contains(requirements::SHARESAFE_REQUIREMENT);
162
162
163 if share_safe != source_is_share_safe {
163 if share_safe != source_is_share_safe {
164 return Err(HgError::unsupported("share-safe mismatch").into());
164 return Err(HgError::unsupported("share-safe mismatch").into());
165 }
165 }
166
166
167 if share_safe {
167 if share_safe {
168 repo_config_files.insert(0, shared_path.join("hgrc"))
168 repo_config_files.insert(0, shared_path.join("hgrc"))
169 }
169 }
170 }
170 }
171 if share_safe {
171 if share_safe {
172 reqs.extend(requirements::load(Vfs { base: &store_path })?);
172 reqs.extend(requirements::load(Vfs { base: &store_path })?);
173 }
173 }
174
174
175 let repo_config = if std::env::var_os("HGRCSKIPREPO").is_none() {
175 let repo_config = if std::env::var_os("HGRCSKIPREPO").is_none() {
176 config.combine_with_repo(&repo_config_files)?
176 config.combine_with_repo(&repo_config_files)?
177 } else {
177 } else {
178 config.clone()
178 config.clone()
179 };
179 };
180
180
181 let repo = Self {
181 let repo = Self {
182 requirements: reqs,
182 requirements: reqs,
183 working_directory,
183 working_directory,
184 store: store_path,
184 store: store_path,
185 dot_hg,
185 dot_hg,
186 config: repo_config,
186 config: repo_config,
187 dirstate_parents: LazyCell::new(),
187 dirstate_parents: LazyCell::new(),
188 dirstate_data_file_uuid: LazyCell::new(),
188 dirstate_data_file_uuid: LazyCell::new(),
189 dirstate_map: LazyCell::new(),
189 dirstate_map: LazyCell::new(),
190 changelog: LazyCell::new(),
190 changelog: LazyCell::new(),
191 manifestlog: LazyCell::new(),
191 manifestlog: LazyCell::new(),
192 };
192 };
193
193
194 requirements::check(&repo)?;
194 requirements::check(&repo)?;
195
195
196 Ok(repo)
196 Ok(repo)
197 }
197 }
198
198
199 pub fn working_directory_path(&self) -> &Path {
199 pub fn working_directory_path(&self) -> &Path {
200 &self.working_directory
200 &self.working_directory
201 }
201 }
202
202
203 pub fn requirements(&self) -> &HashSet<String> {
203 pub fn requirements(&self) -> &HashSet<String> {
204 &self.requirements
204 &self.requirements
205 }
205 }
206
206
207 pub fn config(&self) -> &Config {
207 pub fn config(&self) -> &Config {
208 &self.config
208 &self.config
209 }
209 }
210
210
211 /// For accessing repository files (in `.hg`), except for the store
211 /// For accessing repository files (in `.hg`), except for the store
212 /// (`.hg/store`).
212 /// (`.hg/store`).
213 pub fn hg_vfs(&self) -> Vfs<'_> {
213 pub fn hg_vfs(&self) -> Vfs<'_> {
214 Vfs { base: &self.dot_hg }
214 Vfs { base: &self.dot_hg }
215 }
215 }
216
216
217 /// For accessing repository store files (in `.hg/store`)
217 /// For accessing repository store files (in `.hg/store`)
218 pub fn store_vfs(&self) -> Vfs<'_> {
218 pub fn store_vfs(&self) -> Vfs<'_> {
219 Vfs { base: &self.store }
219 Vfs { base: &self.store }
220 }
220 }
221
221
222 /// For accessing the working copy
222 /// For accessing the working copy
223 pub fn working_directory_vfs(&self) -> Vfs<'_> {
223 pub fn working_directory_vfs(&self) -> Vfs<'_> {
224 Vfs {
224 Vfs {
225 base: &self.working_directory,
225 base: &self.working_directory,
226 }
226 }
227 }
227 }
228
228
229 pub fn try_with_wlock_no_wait<R>(
229 pub fn try_with_wlock_no_wait<R>(
230 &self,
230 &self,
231 f: impl FnOnce() -> R,
231 f: impl FnOnce() -> R,
232 ) -> Result<R, LockError> {
232 ) -> Result<R, LockError> {
233 try_with_lock_no_wait(self.hg_vfs(), "wlock", f)
233 try_with_lock_no_wait(self.hg_vfs(), "wlock", f)
234 }
234 }
235
235
236 pub fn has_dirstate_v2(&self) -> bool {
236 pub fn has_dirstate_v2(&self) -> bool {
237 self.requirements
237 self.requirements
238 .contains(requirements::DIRSTATE_V2_REQUIREMENT)
238 .contains(requirements::DIRSTATE_V2_REQUIREMENT)
239 }
239 }
240
240
241 pub fn has_sparse(&self) -> bool {
241 pub fn has_sparse(&self) -> bool {
242 self.requirements.contains(requirements::SPARSE_REQUIREMENT)
242 self.requirements.contains(requirements::SPARSE_REQUIREMENT)
243 }
243 }
244
244
245 pub fn has_narrow(&self) -> bool {
245 pub fn has_narrow(&self) -> bool {
246 self.requirements.contains(requirements::NARROW_REQUIREMENT)
246 self.requirements.contains(requirements::NARROW_REQUIREMENT)
247 }
247 }
248
248
249 pub fn has_nodemap(&self) -> bool {
249 pub fn has_nodemap(&self) -> bool {
250 self.requirements
250 self.requirements
251 .contains(requirements::NODEMAP_REQUIREMENT)
251 .contains(requirements::NODEMAP_REQUIREMENT)
252 }
252 }
253
253
254 fn dirstate_file_contents(&self) -> Result<Vec<u8>, HgError> {
254 fn dirstate_file_contents(&self) -> Result<Vec<u8>, HgError> {
255 Ok(self
255 Ok(self
256 .hg_vfs()
256 .hg_vfs()
257 .read("dirstate")
257 .read("dirstate")
258 .io_not_found_as_none()?
258 .io_not_found_as_none()?
259 .unwrap_or(Vec::new()))
259 .unwrap_or(Vec::new()))
260 }
260 }
261
261
262 pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> {
262 pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> {
263 Ok(*self
263 Ok(*self
264 .dirstate_parents
264 .dirstate_parents
265 .get_or_init(|| self.read_dirstate_parents())?)
265 .get_or_init(|| self.read_dirstate_parents())?)
266 }
266 }
267
267
268 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
268 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
269 let dirstate = self.dirstate_file_contents()?;
269 let dirstate = self.dirstate_file_contents()?;
270 let parents = if dirstate.is_empty() {
270 let parents = if dirstate.is_empty() {
271 if self.has_dirstate_v2() {
271 if self.has_dirstate_v2() {
272 self.dirstate_data_file_uuid.set(None);
272 self.dirstate_data_file_uuid.set(None);
273 }
273 }
274 DirstateParents::NULL
274 DirstateParents::NULL
275 } else if self.has_dirstate_v2() {
275 } else if self.has_dirstate_v2() {
276 let docket =
276 let docket =
277 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
277 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
278 self.dirstate_data_file_uuid
278 self.dirstate_data_file_uuid
279 .set(Some(docket.uuid.to_owned()));
279 .set(Some(docket.uuid.to_owned()));
280 docket.parents()
280 docket.parents()
281 } else {
281 } else {
282 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
282 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
283 .clone()
283 .clone()
284 };
284 };
285 self.dirstate_parents.set(parents);
285 self.dirstate_parents.set(parents);
286 Ok(parents)
286 Ok(parents)
287 }
287 }
288
288
289 fn read_dirstate_data_file_uuid(
289 fn read_dirstate_data_file_uuid(
290 &self,
290 &self,
291 ) -> Result<Option<Vec<u8>>, HgError> {
291 ) -> Result<Option<Vec<u8>>, HgError> {
292 assert!(
292 assert!(
293 self.has_dirstate_v2(),
293 self.has_dirstate_v2(),
294 "accessing dirstate data file ID without dirstate-v2"
294 "accessing dirstate data file ID without dirstate-v2"
295 );
295 );
296 let dirstate = self.dirstate_file_contents()?;
296 let dirstate = self.dirstate_file_contents()?;
297 if dirstate.is_empty() {
297 if dirstate.is_empty() {
298 self.dirstate_parents.set(DirstateParents::NULL);
298 self.dirstate_parents.set(DirstateParents::NULL);
299 Ok(None)
299 Ok(None)
300 } else {
300 } else {
301 let docket =
301 let docket =
302 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
302 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
303 self.dirstate_parents.set(docket.parents());
303 self.dirstate_parents.set(docket.parents());
304 Ok(Some(docket.uuid.to_owned()))
304 Ok(Some(docket.uuid.to_owned()))
305 }
305 }
306 }
306 }
307
307
308 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> {
308 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> {
309 if self.has_dirstate_v2() {
309 if self.has_dirstate_v2() {
310 self.read_docket_and_data_file()
310 self.read_docket_and_data_file()
311 } else {
311 } else {
312 debug_wait_for_file_or_print(
312 debug_wait_for_file_or_print(
313 self.config(),
313 self.config(),
314 "dirstate.pre-read-file",
314 "dirstate.pre-read-file",
315 );
315 );
316 let dirstate_file_contents = self.dirstate_file_contents()?;
316 let dirstate_file_contents = self.dirstate_file_contents()?;
317 if dirstate_file_contents.is_empty() {
317 if dirstate_file_contents.is_empty() {
318 self.dirstate_parents.set(DirstateParents::NULL);
318 self.dirstate_parents.set(DirstateParents::NULL);
319 Ok(OwningDirstateMap::new_empty(Vec::new()))
319 Ok(OwningDirstateMap::new_empty(Vec::new()))
320 } else {
320 } else {
321 let (map, parents) =
321 let (map, parents) =
322 OwningDirstateMap::new_v1(dirstate_file_contents)?;
322 OwningDirstateMap::new_v1(dirstate_file_contents)?;
323 self.dirstate_parents.set(parents);
323 self.dirstate_parents.set(parents);
324 Ok(map)
324 Ok(map)
325 }
325 }
326 }
326 }
327 }
327 }
328
328
329 fn read_docket_and_data_file(
329 fn read_docket_and_data_file(
330 &self,
330 &self,
331 ) -> Result<OwningDirstateMap, DirstateError> {
331 ) -> Result<OwningDirstateMap, DirstateError> {
332 debug_wait_for_file_or_print(self.config(), "dirstate.pre-read-file");
332 debug_wait_for_file_or_print(self.config(), "dirstate.pre-read-file");
333 let dirstate_file_contents = self.dirstate_file_contents()?;
333 let dirstate_file_contents = self.dirstate_file_contents()?;
334 if dirstate_file_contents.is_empty() {
334 if dirstate_file_contents.is_empty() {
335 self.dirstate_parents.set(DirstateParents::NULL);
335 self.dirstate_parents.set(DirstateParents::NULL);
336 self.dirstate_data_file_uuid.set(None);
336 self.dirstate_data_file_uuid.set(None);
337 return Ok(OwningDirstateMap::new_empty(Vec::new()));
337 return Ok(OwningDirstateMap::new_empty(Vec::new()));
338 }
338 }
339 let docket = crate::dirstate_tree::on_disk::read_docket(
339 let docket = crate::dirstate_tree::on_disk::read_docket(
340 &dirstate_file_contents,
340 &dirstate_file_contents,
341 )?;
341 )?;
342 debug_wait_for_file_or_print(
343 self.config(),
344 "dirstate.post-docket-read-file",
345 );
342 self.dirstate_parents.set(docket.parents());
346 self.dirstate_parents.set(docket.parents());
343 self.dirstate_data_file_uuid
347 self.dirstate_data_file_uuid
344 .set(Some(docket.uuid.to_owned()));
348 .set(Some(docket.uuid.to_owned()));
345 let data_size = docket.data_size();
349 let data_size = docket.data_size();
346 let metadata = docket.tree_metadata();
350 let metadata = docket.tree_metadata();
347 let mut map = if crate::vfs::is_on_nfs_mount(docket.data_filename()) {
351 let mut map = if crate::vfs::is_on_nfs_mount(docket.data_filename()) {
348 // Don't mmap on NFS to prevent `SIGBUS` error on deletion
352 // Don't mmap on NFS to prevent `SIGBUS` error on deletion
349 OwningDirstateMap::new_v2(
353 OwningDirstateMap::new_v2(
350 self.hg_vfs().read(docket.data_filename())?,
354 self.hg_vfs().read(docket.data_filename())?,
351 data_size,
355 data_size,
352 metadata,
356 metadata,
353 )
357 )
354 } else if let Some(data_mmap) = self
358 } else if let Some(data_mmap) = self
355 .hg_vfs()
359 .hg_vfs()
356 .mmap_open(docket.data_filename())
360 .mmap_open(docket.data_filename())
357 .io_not_found_as_none()?
361 .io_not_found_as_none()?
358 {
362 {
359 OwningDirstateMap::new_v2(data_mmap, data_size, metadata)
363 OwningDirstateMap::new_v2(data_mmap, data_size, metadata)
360 } else {
364 } else {
361 OwningDirstateMap::new_v2(Vec::new(), data_size, metadata)
365 OwningDirstateMap::new_v2(Vec::new(), data_size, metadata)
362 }?;
366 }?;
363
367
364 let write_mode_config = self
368 let write_mode_config = self
365 .config()
369 .config()
366 .get_str(b"devel", b"dirstate.v2.data_update_mode")
370 .get_str(b"devel", b"dirstate.v2.data_update_mode")
367 .unwrap_or(Some("auto"))
371 .unwrap_or(Some("auto"))
368 .unwrap_or("auto"); // don't bother for devel options
372 .unwrap_or("auto"); // don't bother for devel options
369 let write_mode = match write_mode_config {
373 let write_mode = match write_mode_config {
370 "auto" => DirstateMapWriteMode::Auto,
374 "auto" => DirstateMapWriteMode::Auto,
371 "force-new" => DirstateMapWriteMode::ForceNewDataFile,
375 "force-new" => DirstateMapWriteMode::ForceNewDataFile,
372 "force-append" => DirstateMapWriteMode::ForceAppend,
376 "force-append" => DirstateMapWriteMode::ForceAppend,
373 _ => DirstateMapWriteMode::Auto,
377 _ => DirstateMapWriteMode::Auto,
374 };
378 };
375
379
376 map.with_dmap_mut(|m| m.set_write_mode(write_mode));
380 map.with_dmap_mut(|m| m.set_write_mode(write_mode));
377
381
378 Ok(map)
382 Ok(map)
379 }
383 }
380
384
381 pub fn dirstate_map(
385 pub fn dirstate_map(
382 &self,
386 &self,
383 ) -> Result<Ref<OwningDirstateMap>, DirstateError> {
387 ) -> Result<Ref<OwningDirstateMap>, DirstateError> {
384 self.dirstate_map.get_or_init(|| self.new_dirstate_map())
388 self.dirstate_map.get_or_init(|| self.new_dirstate_map())
385 }
389 }
386
390
387 pub fn dirstate_map_mut(
391 pub fn dirstate_map_mut(
388 &self,
392 &self,
389 ) -> Result<RefMut<OwningDirstateMap>, DirstateError> {
393 ) -> Result<RefMut<OwningDirstateMap>, DirstateError> {
390 self.dirstate_map
394 self.dirstate_map
391 .get_mut_or_init(|| self.new_dirstate_map())
395 .get_mut_or_init(|| self.new_dirstate_map())
392 }
396 }
393
397
394 fn new_changelog(&self) -> Result<Changelog, HgError> {
398 fn new_changelog(&self) -> Result<Changelog, HgError> {
395 Changelog::open(&self.store_vfs(), self.has_nodemap())
399 Changelog::open(&self.store_vfs(), self.has_nodemap())
396 }
400 }
397
401
398 pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> {
402 pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> {
399 self.changelog.get_or_init(|| self.new_changelog())
403 self.changelog.get_or_init(|| self.new_changelog())
400 }
404 }
401
405
402 pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> {
406 pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> {
403 self.changelog.get_mut_or_init(|| self.new_changelog())
407 self.changelog.get_mut_or_init(|| self.new_changelog())
404 }
408 }
405
409
406 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> {
410 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> {
407 Manifestlog::open(&self.store_vfs(), self.has_nodemap())
411 Manifestlog::open(&self.store_vfs(), self.has_nodemap())
408 }
412 }
409
413
410 pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> {
414 pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> {
411 self.manifestlog.get_or_init(|| self.new_manifestlog())
415 self.manifestlog.get_or_init(|| self.new_manifestlog())
412 }
416 }
413
417
414 pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, HgError> {
418 pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, HgError> {
415 self.manifestlog.get_mut_or_init(|| self.new_manifestlog())
419 self.manifestlog.get_mut_or_init(|| self.new_manifestlog())
416 }
420 }
417
421
418 /// Returns the manifest of the *changeset* with the given node ID
422 /// Returns the manifest of the *changeset* with the given node ID
419 pub fn manifest_for_node(
423 pub fn manifest_for_node(
420 &self,
424 &self,
421 node: impl Into<NodePrefix>,
425 node: impl Into<NodePrefix>,
422 ) -> Result<Manifest, RevlogError> {
426 ) -> Result<Manifest, RevlogError> {
423 self.manifestlog()?.data_for_node(
427 self.manifestlog()?.data_for_node(
424 self.changelog()?
428 self.changelog()?
425 .data_for_node(node.into())?
429 .data_for_node(node.into())?
426 .manifest_node()?
430 .manifest_node()?
427 .into(),
431 .into(),
428 )
432 )
429 }
433 }
430
434
431 /// Returns the manifest of the *changeset* with the given revision number
435 /// Returns the manifest of the *changeset* with the given revision number
432 pub fn manifest_for_rev(
436 pub fn manifest_for_rev(
433 &self,
437 &self,
434 revision: Revision,
438 revision: Revision,
435 ) -> Result<Manifest, RevlogError> {
439 ) -> Result<Manifest, RevlogError> {
436 self.manifestlog()?.data_for_node(
440 self.manifestlog()?.data_for_node(
437 self.changelog()?
441 self.changelog()?
438 .data_for_rev(revision)?
442 .data_for_rev(revision)?
439 .manifest_node()?
443 .manifest_node()?
440 .into(),
444 .into(),
441 )
445 )
442 }
446 }
443
447
444 pub fn has_subrepos(&self) -> Result<bool, DirstateError> {
448 pub fn has_subrepos(&self) -> Result<bool, DirstateError> {
445 if let Some(entry) = self.dirstate_map()?.get(HgPath::new(".hgsub"))? {
449 if let Some(entry) = self.dirstate_map()?.get(HgPath::new(".hgsub"))? {
446 Ok(entry.tracked())
450 Ok(entry.tracked())
447 } else {
451 } else {
448 Ok(false)
452 Ok(false)
449 }
453 }
450 }
454 }
451
455
452 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> {
456 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> {
453 Filelog::open(self, path)
457 Filelog::open(self, path)
454 }
458 }
455
459
456 /// Write to disk any updates that were made through `dirstate_map_mut`.
460 /// Write to disk any updates that were made through `dirstate_map_mut`.
457 ///
461 ///
458 /// The "wlock" must be held while calling this.
462 /// The "wlock" must be held while calling this.
459 /// See for example `try_with_wlock_no_wait`.
463 /// See for example `try_with_wlock_no_wait`.
460 ///
464 ///
461 /// TODO: have a `WritableRepo` type only accessible while holding the
465 /// TODO: have a `WritableRepo` type only accessible while holding the
462 /// lock?
466 /// lock?
463 pub fn write_dirstate(&self) -> Result<(), DirstateError> {
467 pub fn write_dirstate(&self) -> Result<(), DirstateError> {
464 let map = self.dirstate_map()?;
468 let map = self.dirstate_map()?;
465 // TODO: Maintain a `DirstateMap::dirty` flag, and return early here if
469 // TODO: Maintain a `DirstateMap::dirty` flag, and return early here if
466 // it’s unset
470 // it’s unset
467 let parents = self.dirstate_parents()?;
471 let parents = self.dirstate_parents()?;
468 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
472 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
469 let uuid_opt = self
473 let uuid_opt = self
470 .dirstate_data_file_uuid
474 .dirstate_data_file_uuid
471 .get_or_init(|| self.read_dirstate_data_file_uuid())?;
475 .get_or_init(|| self.read_dirstate_data_file_uuid())?;
472 let uuid_opt = uuid_opt.as_ref();
476 let uuid_opt = uuid_opt.as_ref();
473 let write_mode = if uuid_opt.is_some() {
477 let write_mode = if uuid_opt.is_some() {
474 DirstateMapWriteMode::Auto
478 DirstateMapWriteMode::Auto
475 } else {
479 } else {
476 DirstateMapWriteMode::ForceNewDataFile
480 DirstateMapWriteMode::ForceNewDataFile
477 };
481 };
478 let (data, tree_metadata, append, old_data_size) =
482 let (data, tree_metadata, append, old_data_size) =
479 map.pack_v2(write_mode)?;
483 map.pack_v2(write_mode)?;
480
484
481 // Reuse the uuid, or generate a new one, keeping the old for
485 // Reuse the uuid, or generate a new one, keeping the old for
482 // deletion.
486 // deletion.
483 let (uuid, old_uuid) = match uuid_opt {
487 let (uuid, old_uuid) = match uuid_opt {
484 Some(uuid) => {
488 Some(uuid) => {
485 let as_str = std::str::from_utf8(uuid)
489 let as_str = std::str::from_utf8(uuid)
486 .map_err(|_| {
490 .map_err(|_| {
487 HgError::corrupted(
491 HgError::corrupted(
488 "non-UTF-8 dirstate data file ID",
492 "non-UTF-8 dirstate data file ID",
489 )
493 )
490 })?
494 })?
491 .to_owned();
495 .to_owned();
492 if append {
496 if append {
493 (as_str, None)
497 (as_str, None)
494 } else {
498 } else {
495 (DirstateDocket::new_uid(), Some(as_str))
499 (DirstateDocket::new_uid(), Some(as_str))
496 }
500 }
497 }
501 }
498 None => (DirstateDocket::new_uid(), None),
502 None => (DirstateDocket::new_uid(), None),
499 };
503 };
500
504
501 let data_filename = format!("dirstate.{}", uuid);
505 let data_filename = format!("dirstate.{}", uuid);
502 let data_filename = self.hg_vfs().join(data_filename);
506 let data_filename = self.hg_vfs().join(data_filename);
503 let mut options = std::fs::OpenOptions::new();
507 let mut options = std::fs::OpenOptions::new();
504 options.write(true);
508 options.write(true);
505
509
506 // Why are we not using the O_APPEND flag when appending?
510 // Why are we not using the O_APPEND flag when appending?
507 //
511 //
508 // - O_APPEND makes it trickier to deal with garbage at the end of
512 // - O_APPEND makes it trickier to deal with garbage at the end of
509 // the file, left by a previous uncommitted transaction. By
513 // the file, left by a previous uncommitted transaction. By
510 // starting the write at [old_data_size] we make sure we erase
514 // starting the write at [old_data_size] we make sure we erase
511 // all such garbage.
515 // all such garbage.
512 //
516 //
513 // - O_APPEND requires to special-case 0-byte writes, whereas we
517 // - O_APPEND requires to special-case 0-byte writes, whereas we
514 // don't need that.
518 // don't need that.
515 //
519 //
516 // - Some OSes have bugs in implementation O_APPEND:
520 // - Some OSes have bugs in implementation O_APPEND:
517 // revlog.py talks about a Solaris bug, but we also saw some ZFS
521 // revlog.py talks about a Solaris bug, but we also saw some ZFS
518 // bug: https://github.com/openzfs/zfs/pull/3124,
522 // bug: https://github.com/openzfs/zfs/pull/3124,
519 // https://github.com/openzfs/zfs/issues/13370
523 // https://github.com/openzfs/zfs/issues/13370
520 //
524 //
521 if !append {
525 if !append {
522 log::trace!("creating a new dirstate data file");
526 log::trace!("creating a new dirstate data file");
523 options.create_new(true);
527 options.create_new(true);
524 } else {
528 } else {
525 log::trace!("appending to the dirstate data file");
529 log::trace!("appending to the dirstate data file");
526 }
530 }
527
531
528 let data_size = (|| {
532 let data_size = (|| {
529 // TODO: loop and try another random ID if !append and this
533 // TODO: loop and try another random ID if !append and this
530 // returns `ErrorKind::AlreadyExists`? Collision chance of two
534 // returns `ErrorKind::AlreadyExists`? Collision chance of two
531 // random IDs is one in 2**32
535 // random IDs is one in 2**32
532 let mut file = options.open(&data_filename)?;
536 let mut file = options.open(&data_filename)?;
533 if append {
537 if append {
534 file.seek(SeekFrom::Start(old_data_size as u64))?;
538 file.seek(SeekFrom::Start(old_data_size as u64))?;
535 }
539 }
536 file.write_all(&data)?;
540 file.write_all(&data)?;
537 file.flush()?;
541 file.flush()?;
538 file.seek(SeekFrom::Current(0))
542 file.seek(SeekFrom::Current(0))
539 })()
543 })()
540 .when_writing_file(&data_filename)?;
544 .when_writing_file(&data_filename)?;
541
545
542 let packed_dirstate = DirstateDocket::serialize(
546 let packed_dirstate = DirstateDocket::serialize(
543 parents,
547 parents,
544 tree_metadata,
548 tree_metadata,
545 data_size,
549 data_size,
546 uuid.as_bytes(),
550 uuid.as_bytes(),
547 )
551 )
548 .map_err(|_: std::num::TryFromIntError| {
552 .map_err(|_: std::num::TryFromIntError| {
549 HgError::corrupted("overflow in dirstate docket serialization")
553 HgError::corrupted("overflow in dirstate docket serialization")
550 })?;
554 })?;
551
555
552 (packed_dirstate, old_uuid)
556 (packed_dirstate, old_uuid)
553 } else {
557 } else {
554 (map.pack_v1(parents)?, None)
558 (map.pack_v1(parents)?, None)
555 };
559 };
556
560
557 let vfs = self.hg_vfs();
561 let vfs = self.hg_vfs();
558 vfs.atomic_write("dirstate", &packed_dirstate)?;
562 vfs.atomic_write("dirstate", &packed_dirstate)?;
559 if let Some(uuid) = old_uuid_to_remove {
563 if let Some(uuid) = old_uuid_to_remove {
560 // Remove the old data file after the new docket pointing to the
564 // Remove the old data file after the new docket pointing to the
561 // new data file was written.
565 // new data file was written.
562 vfs.remove_file(format!("dirstate.{}", uuid))?;
566 vfs.remove_file(format!("dirstate.{}", uuid))?;
563 }
567 }
564 Ok(())
568 Ok(())
565 }
569 }
566 }
570 }
567
571
568 /// Lazily-initialized component of `Repo` with interior mutability
572 /// Lazily-initialized component of `Repo` with interior mutability
569 ///
573 ///
570 /// This differs from `OnceCell` in that the value can still be "deinitialized"
574 /// This differs from `OnceCell` in that the value can still be "deinitialized"
571 /// later by setting its inner `Option` to `None`. It also takes the
575 /// later by setting its inner `Option` to `None`. It also takes the
572 /// initialization function as an argument when the value is requested, not
576 /// initialization function as an argument when the value is requested, not
573 /// when the instance is created.
577 /// when the instance is created.
574 struct LazyCell<T> {
578 struct LazyCell<T> {
575 value: RefCell<Option<T>>,
579 value: RefCell<Option<T>>,
576 }
580 }
577
581
578 impl<T> LazyCell<T> {
582 impl<T> LazyCell<T> {
579 fn new() -> Self {
583 fn new() -> Self {
580 Self {
584 Self {
581 value: RefCell::new(None),
585 value: RefCell::new(None),
582 }
586 }
583 }
587 }
584
588
585 fn set(&self, value: T) {
589 fn set(&self, value: T) {
586 *self.value.borrow_mut() = Some(value)
590 *self.value.borrow_mut() = Some(value)
587 }
591 }
588
592
589 fn get_or_init<E>(
593 fn get_or_init<E>(
590 &self,
594 &self,
591 init: impl Fn() -> Result<T, E>,
595 init: impl Fn() -> Result<T, E>,
592 ) -> Result<Ref<T>, E> {
596 ) -> Result<Ref<T>, E> {
593 let mut borrowed = self.value.borrow();
597 let mut borrowed = self.value.borrow();
594 if borrowed.is_none() {
598 if borrowed.is_none() {
595 drop(borrowed);
599 drop(borrowed);
596 // Only use `borrow_mut` if it is really needed to avoid panic in
600 // Only use `borrow_mut` if it is really needed to avoid panic in
597 // case there is another outstanding borrow but mutation is not
601 // case there is another outstanding borrow but mutation is not
598 // needed.
602 // needed.
599 *self.value.borrow_mut() = Some(init()?);
603 *self.value.borrow_mut() = Some(init()?);
600 borrowed = self.value.borrow()
604 borrowed = self.value.borrow()
601 }
605 }
602 Ok(Ref::map(borrowed, |option| option.as_ref().unwrap()))
606 Ok(Ref::map(borrowed, |option| option.as_ref().unwrap()))
603 }
607 }
604
608
605 fn get_mut_or_init<E>(
609 fn get_mut_or_init<E>(
606 &self,
610 &self,
607 init: impl Fn() -> Result<T, E>,
611 init: impl Fn() -> Result<T, E>,
608 ) -> Result<RefMut<T>, E> {
612 ) -> Result<RefMut<T>, E> {
609 let mut borrowed = self.value.borrow_mut();
613 let mut borrowed = self.value.borrow_mut();
610 if borrowed.is_none() {
614 if borrowed.is_none() {
611 *borrowed = Some(init()?);
615 *borrowed = Some(init()?);
612 }
616 }
613 Ok(RefMut::map(borrowed, |option| option.as_mut().unwrap()))
617 Ok(RefMut::map(borrowed, |option| option.as_mut().unwrap()))
614 }
618 }
615 }
619 }
General Comments 0
You need to be logged in to leave comments. Login now