##// END OF EJS Templates
persistent-nodemap: add a "abort" option to the slow-path config...
marmoute -
r46937:38d41346 default draft
parent child Browse files
Show More
@@ -1,2595 +1,2595 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18
18
19 def loadconfigtable(ui, extname, configtable):
19 def loadconfigtable(ui, extname, configtable):
20 """update config item known to the ui with the extension ones"""
20 """update config item known to the ui with the extension ones"""
21 for section, items in sorted(configtable.items()):
21 for section, items in sorted(configtable.items()):
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
23 knownkeys = set(knownitems)
23 knownkeys = set(knownitems)
24 newkeys = set(items)
24 newkeys = set(items)
25 for key in sorted(knownkeys & newkeys):
25 for key in sorted(knownkeys & newkeys):
26 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg = b"extension '%s' overwrite config item '%s.%s'"
27 msg %= (extname, section, key)
27 msg %= (extname, section, key)
28 ui.develwarn(msg, config=b'warn-config')
28 ui.develwarn(msg, config=b'warn-config')
29
29
30 knownitems.update(items)
30 knownitems.update(items)
31
31
32
32
33 class configitem(object):
33 class configitem(object):
34 """represent a known config item
34 """represent a known config item
35
35
36 :section: the official config section where to find this item,
36 :section: the official config section where to find this item,
37 :name: the official name within the section,
37 :name: the official name within the section,
38 :default: default value for this item,
38 :default: default value for this item,
39 :alias: optional list of tuples as alternatives,
39 :alias: optional list of tuples as alternatives,
40 :generic: this is a generic definition, match name using regular expression.
40 :generic: this is a generic definition, match name using regular expression.
41 """
41 """
42
42
43 def __init__(
43 def __init__(
44 self,
44 self,
45 section,
45 section,
46 name,
46 name,
47 default=None,
47 default=None,
48 alias=(),
48 alias=(),
49 generic=False,
49 generic=False,
50 priority=0,
50 priority=0,
51 experimental=False,
51 experimental=False,
52 ):
52 ):
53 self.section = section
53 self.section = section
54 self.name = name
54 self.name = name
55 self.default = default
55 self.default = default
56 self.alias = list(alias)
56 self.alias = list(alias)
57 self.generic = generic
57 self.generic = generic
58 self.priority = priority
58 self.priority = priority
59 self.experimental = experimental
59 self.experimental = experimental
60 self._re = None
60 self._re = None
61 if generic:
61 if generic:
62 self._re = re.compile(self.name)
62 self._re = re.compile(self.name)
63
63
64
64
65 class itemregister(dict):
65 class itemregister(dict):
66 """A specialized dictionary that can handle wild-card selection"""
66 """A specialized dictionary that can handle wild-card selection"""
67
67
68 def __init__(self):
68 def __init__(self):
69 super(itemregister, self).__init__()
69 super(itemregister, self).__init__()
70 self._generics = set()
70 self._generics = set()
71
71
72 def update(self, other):
72 def update(self, other):
73 super(itemregister, self).update(other)
73 super(itemregister, self).update(other)
74 self._generics.update(other._generics)
74 self._generics.update(other._generics)
75
75
76 def __setitem__(self, key, item):
76 def __setitem__(self, key, item):
77 super(itemregister, self).__setitem__(key, item)
77 super(itemregister, self).__setitem__(key, item)
78 if item.generic:
78 if item.generic:
79 self._generics.add(item)
79 self._generics.add(item)
80
80
81 def get(self, key):
81 def get(self, key):
82 baseitem = super(itemregister, self).get(key)
82 baseitem = super(itemregister, self).get(key)
83 if baseitem is not None and not baseitem.generic:
83 if baseitem is not None and not baseitem.generic:
84 return baseitem
84 return baseitem
85
85
86 # search for a matching generic item
86 # search for a matching generic item
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
88 for item in generics:
88 for item in generics:
89 # we use 'match' instead of 'search' to make the matching simpler
89 # we use 'match' instead of 'search' to make the matching simpler
90 # for people unfamiliar with regular expression. Having the match
90 # for people unfamiliar with regular expression. Having the match
91 # rooted to the start of the string will produce less surprising
91 # rooted to the start of the string will produce less surprising
92 # result for user writing simple regex for sub-attribute.
92 # result for user writing simple regex for sub-attribute.
93 #
93 #
94 # For example using "color\..*" match produces an unsurprising
94 # For example using "color\..*" match produces an unsurprising
95 # result, while using search could suddenly match apparently
95 # result, while using search could suddenly match apparently
96 # unrelated configuration that happens to contains "color."
96 # unrelated configuration that happens to contains "color."
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
98 # some match to avoid the need to prefix most pattern with "^".
98 # some match to avoid the need to prefix most pattern with "^".
99 # The "^" seems more error prone.
99 # The "^" seems more error prone.
100 if item._re.match(key):
100 if item._re.match(key):
101 return item
101 return item
102
102
103 return None
103 return None
104
104
105
105
106 coreitems = {}
106 coreitems = {}
107
107
108
108
109 def _register(configtable, *args, **kwargs):
109 def _register(configtable, *args, **kwargs):
110 item = configitem(*args, **kwargs)
110 item = configitem(*args, **kwargs)
111 section = configtable.setdefault(item.section, itemregister())
111 section = configtable.setdefault(item.section, itemregister())
112 if item.name in section:
112 if item.name in section:
113 msg = b"duplicated config item registration for '%s.%s'"
113 msg = b"duplicated config item registration for '%s.%s'"
114 raise error.ProgrammingError(msg % (item.section, item.name))
114 raise error.ProgrammingError(msg % (item.section, item.name))
115 section[item.name] = item
115 section[item.name] = item
116
116
117
117
118 # special value for case where the default is derived from other values
118 # special value for case where the default is derived from other values
119 dynamicdefault = object()
119 dynamicdefault = object()
120
120
121 # Registering actual config items
121 # Registering actual config items
122
122
123
123
124 def getitemregister(configtable):
124 def getitemregister(configtable):
125 f = functools.partial(_register, configtable)
125 f = functools.partial(_register, configtable)
126 # export pseudo enum as configitem.*
126 # export pseudo enum as configitem.*
127 f.dynamicdefault = dynamicdefault
127 f.dynamicdefault = dynamicdefault
128 return f
128 return f
129
129
130
130
131 coreconfigitem = getitemregister(coreitems)
131 coreconfigitem = getitemregister(coreitems)
132
132
133
133
134 def _registerdiffopts(section, configprefix=b''):
134 def _registerdiffopts(section, configprefix=b''):
135 coreconfigitem(
135 coreconfigitem(
136 section,
136 section,
137 configprefix + b'nodates',
137 configprefix + b'nodates',
138 default=False,
138 default=False,
139 )
139 )
140 coreconfigitem(
140 coreconfigitem(
141 section,
141 section,
142 configprefix + b'showfunc',
142 configprefix + b'showfunc',
143 default=False,
143 default=False,
144 )
144 )
145 coreconfigitem(
145 coreconfigitem(
146 section,
146 section,
147 configprefix + b'unified',
147 configprefix + b'unified',
148 default=None,
148 default=None,
149 )
149 )
150 coreconfigitem(
150 coreconfigitem(
151 section,
151 section,
152 configprefix + b'git',
152 configprefix + b'git',
153 default=False,
153 default=False,
154 )
154 )
155 coreconfigitem(
155 coreconfigitem(
156 section,
156 section,
157 configprefix + b'ignorews',
157 configprefix + b'ignorews',
158 default=False,
158 default=False,
159 )
159 )
160 coreconfigitem(
160 coreconfigitem(
161 section,
161 section,
162 configprefix + b'ignorewsamount',
162 configprefix + b'ignorewsamount',
163 default=False,
163 default=False,
164 )
164 )
165 coreconfigitem(
165 coreconfigitem(
166 section,
166 section,
167 configprefix + b'ignoreblanklines',
167 configprefix + b'ignoreblanklines',
168 default=False,
168 default=False,
169 )
169 )
170 coreconfigitem(
170 coreconfigitem(
171 section,
171 section,
172 configprefix + b'ignorewseol',
172 configprefix + b'ignorewseol',
173 default=False,
173 default=False,
174 )
174 )
175 coreconfigitem(
175 coreconfigitem(
176 section,
176 section,
177 configprefix + b'nobinary',
177 configprefix + b'nobinary',
178 default=False,
178 default=False,
179 )
179 )
180 coreconfigitem(
180 coreconfigitem(
181 section,
181 section,
182 configprefix + b'noprefix',
182 configprefix + b'noprefix',
183 default=False,
183 default=False,
184 )
184 )
185 coreconfigitem(
185 coreconfigitem(
186 section,
186 section,
187 configprefix + b'word-diff',
187 configprefix + b'word-diff',
188 default=False,
188 default=False,
189 )
189 )
190
190
191
191
192 coreconfigitem(
192 coreconfigitem(
193 b'alias',
193 b'alias',
194 b'.*',
194 b'.*',
195 default=dynamicdefault,
195 default=dynamicdefault,
196 generic=True,
196 generic=True,
197 )
197 )
198 coreconfigitem(
198 coreconfigitem(
199 b'auth',
199 b'auth',
200 b'cookiefile',
200 b'cookiefile',
201 default=None,
201 default=None,
202 )
202 )
203 _registerdiffopts(section=b'annotate')
203 _registerdiffopts(section=b'annotate')
204 # bookmarks.pushing: internal hack for discovery
204 # bookmarks.pushing: internal hack for discovery
205 coreconfigitem(
205 coreconfigitem(
206 b'bookmarks',
206 b'bookmarks',
207 b'pushing',
207 b'pushing',
208 default=list,
208 default=list,
209 )
209 )
210 # bundle.mainreporoot: internal hack for bundlerepo
210 # bundle.mainreporoot: internal hack for bundlerepo
211 coreconfigitem(
211 coreconfigitem(
212 b'bundle',
212 b'bundle',
213 b'mainreporoot',
213 b'mainreporoot',
214 default=b'',
214 default=b'',
215 )
215 )
216 coreconfigitem(
216 coreconfigitem(
217 b'censor',
217 b'censor',
218 b'policy',
218 b'policy',
219 default=b'abort',
219 default=b'abort',
220 experimental=True,
220 experimental=True,
221 )
221 )
222 coreconfigitem(
222 coreconfigitem(
223 b'chgserver',
223 b'chgserver',
224 b'idletimeout',
224 b'idletimeout',
225 default=3600,
225 default=3600,
226 )
226 )
227 coreconfigitem(
227 coreconfigitem(
228 b'chgserver',
228 b'chgserver',
229 b'skiphash',
229 b'skiphash',
230 default=False,
230 default=False,
231 )
231 )
232 coreconfigitem(
232 coreconfigitem(
233 b'cmdserver',
233 b'cmdserver',
234 b'log',
234 b'log',
235 default=None,
235 default=None,
236 )
236 )
237 coreconfigitem(
237 coreconfigitem(
238 b'cmdserver',
238 b'cmdserver',
239 b'max-log-files',
239 b'max-log-files',
240 default=7,
240 default=7,
241 )
241 )
242 coreconfigitem(
242 coreconfigitem(
243 b'cmdserver',
243 b'cmdserver',
244 b'max-log-size',
244 b'max-log-size',
245 default=b'1 MB',
245 default=b'1 MB',
246 )
246 )
247 coreconfigitem(
247 coreconfigitem(
248 b'cmdserver',
248 b'cmdserver',
249 b'max-repo-cache',
249 b'max-repo-cache',
250 default=0,
250 default=0,
251 experimental=True,
251 experimental=True,
252 )
252 )
253 coreconfigitem(
253 coreconfigitem(
254 b'cmdserver',
254 b'cmdserver',
255 b'message-encodings',
255 b'message-encodings',
256 default=list,
256 default=list,
257 )
257 )
258 coreconfigitem(
258 coreconfigitem(
259 b'cmdserver',
259 b'cmdserver',
260 b'track-log',
260 b'track-log',
261 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
262 )
262 )
263 coreconfigitem(
263 coreconfigitem(
264 b'cmdserver',
264 b'cmdserver',
265 b'shutdown-on-interrupt',
265 b'shutdown-on-interrupt',
266 default=True,
266 default=True,
267 )
267 )
268 coreconfigitem(
268 coreconfigitem(
269 b'color',
269 b'color',
270 b'.*',
270 b'.*',
271 default=None,
271 default=None,
272 generic=True,
272 generic=True,
273 )
273 )
274 coreconfigitem(
274 coreconfigitem(
275 b'color',
275 b'color',
276 b'mode',
276 b'mode',
277 default=b'auto',
277 default=b'auto',
278 )
278 )
279 coreconfigitem(
279 coreconfigitem(
280 b'color',
280 b'color',
281 b'pagermode',
281 b'pagermode',
282 default=dynamicdefault,
282 default=dynamicdefault,
283 )
283 )
284 coreconfigitem(
284 coreconfigitem(
285 b'command-templates',
285 b'command-templates',
286 b'graphnode',
286 b'graphnode',
287 default=None,
287 default=None,
288 alias=[(b'ui', b'graphnodetemplate')],
288 alias=[(b'ui', b'graphnodetemplate')],
289 )
289 )
290 coreconfigitem(
290 coreconfigitem(
291 b'command-templates',
291 b'command-templates',
292 b'log',
292 b'log',
293 default=None,
293 default=None,
294 alias=[(b'ui', b'logtemplate')],
294 alias=[(b'ui', b'logtemplate')],
295 )
295 )
296 coreconfigitem(
296 coreconfigitem(
297 b'command-templates',
297 b'command-templates',
298 b'mergemarker',
298 b'mergemarker',
299 default=(
299 default=(
300 b'{node|short} '
300 b'{node|short} '
301 b'{ifeq(tags, "tip", "", '
301 b'{ifeq(tags, "tip", "", '
302 b'ifeq(tags, "", "", "{tags} "))}'
302 b'ifeq(tags, "", "", "{tags} "))}'
303 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{if(bookmarks, "{bookmarks} ")}'
304 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'{ifeq(branch, "default", "", "{branch} ")}'
305 b'- {author|user}: {desc|firstline}'
305 b'- {author|user}: {desc|firstline}'
306 ),
306 ),
307 alias=[(b'ui', b'mergemarkertemplate')],
307 alias=[(b'ui', b'mergemarkertemplate')],
308 )
308 )
309 coreconfigitem(
309 coreconfigitem(
310 b'command-templates',
310 b'command-templates',
311 b'pre-merge-tool-output',
311 b'pre-merge-tool-output',
312 default=None,
312 default=None,
313 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 alias=[(b'ui', b'pre-merge-tool-output-template')],
314 )
314 )
315 coreconfigitem(
315 coreconfigitem(
316 b'command-templates',
316 b'command-templates',
317 b'oneline-summary',
317 b'oneline-summary',
318 default=None,
318 default=None,
319 )
319 )
320 coreconfigitem(
320 coreconfigitem(
321 b'command-templates',
321 b'command-templates',
322 b'oneline-summary.*',
322 b'oneline-summary.*',
323 default=dynamicdefault,
323 default=dynamicdefault,
324 generic=True,
324 generic=True,
325 )
325 )
326 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
327 coreconfigitem(
327 coreconfigitem(
328 b'commands',
328 b'commands',
329 b'commit.post-status',
329 b'commit.post-status',
330 default=False,
330 default=False,
331 )
331 )
332 coreconfigitem(
332 coreconfigitem(
333 b'commands',
333 b'commands',
334 b'grep.all-files',
334 b'grep.all-files',
335 default=False,
335 default=False,
336 experimental=True,
336 experimental=True,
337 )
337 )
338 coreconfigitem(
338 coreconfigitem(
339 b'commands',
339 b'commands',
340 b'merge.require-rev',
340 b'merge.require-rev',
341 default=False,
341 default=False,
342 )
342 )
343 coreconfigitem(
343 coreconfigitem(
344 b'commands',
344 b'commands',
345 b'push.require-revs',
345 b'push.require-revs',
346 default=False,
346 default=False,
347 )
347 )
348 coreconfigitem(
348 coreconfigitem(
349 b'commands',
349 b'commands',
350 b'resolve.confirm',
350 b'resolve.confirm',
351 default=False,
351 default=False,
352 )
352 )
353 coreconfigitem(
353 coreconfigitem(
354 b'commands',
354 b'commands',
355 b'resolve.explicit-re-merge',
355 b'resolve.explicit-re-merge',
356 default=False,
356 default=False,
357 )
357 )
358 coreconfigitem(
358 coreconfigitem(
359 b'commands',
359 b'commands',
360 b'resolve.mark-check',
360 b'resolve.mark-check',
361 default=b'none',
361 default=b'none',
362 )
362 )
363 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
364 coreconfigitem(
364 coreconfigitem(
365 b'commands',
365 b'commands',
366 b'show.aliasprefix',
366 b'show.aliasprefix',
367 default=list,
367 default=list,
368 )
368 )
369 coreconfigitem(
369 coreconfigitem(
370 b'commands',
370 b'commands',
371 b'status.relative',
371 b'status.relative',
372 default=False,
372 default=False,
373 )
373 )
374 coreconfigitem(
374 coreconfigitem(
375 b'commands',
375 b'commands',
376 b'status.skipstates',
376 b'status.skipstates',
377 default=[],
377 default=[],
378 experimental=True,
378 experimental=True,
379 )
379 )
380 coreconfigitem(
380 coreconfigitem(
381 b'commands',
381 b'commands',
382 b'status.terse',
382 b'status.terse',
383 default=b'',
383 default=b'',
384 )
384 )
385 coreconfigitem(
385 coreconfigitem(
386 b'commands',
386 b'commands',
387 b'status.verbose',
387 b'status.verbose',
388 default=False,
388 default=False,
389 )
389 )
390 coreconfigitem(
390 coreconfigitem(
391 b'commands',
391 b'commands',
392 b'update.check',
392 b'update.check',
393 default=None,
393 default=None,
394 )
394 )
395 coreconfigitem(
395 coreconfigitem(
396 b'commands',
396 b'commands',
397 b'update.requiredest',
397 b'update.requiredest',
398 default=False,
398 default=False,
399 )
399 )
400 coreconfigitem(
400 coreconfigitem(
401 b'committemplate',
401 b'committemplate',
402 b'.*',
402 b'.*',
403 default=None,
403 default=None,
404 generic=True,
404 generic=True,
405 )
405 )
406 coreconfigitem(
406 coreconfigitem(
407 b'convert',
407 b'convert',
408 b'bzr.saverev',
408 b'bzr.saverev',
409 default=True,
409 default=True,
410 )
410 )
411 coreconfigitem(
411 coreconfigitem(
412 b'convert',
412 b'convert',
413 b'cvsps.cache',
413 b'cvsps.cache',
414 default=True,
414 default=True,
415 )
415 )
416 coreconfigitem(
416 coreconfigitem(
417 b'convert',
417 b'convert',
418 b'cvsps.fuzz',
418 b'cvsps.fuzz',
419 default=60,
419 default=60,
420 )
420 )
421 coreconfigitem(
421 coreconfigitem(
422 b'convert',
422 b'convert',
423 b'cvsps.logencoding',
423 b'cvsps.logencoding',
424 default=None,
424 default=None,
425 )
425 )
426 coreconfigitem(
426 coreconfigitem(
427 b'convert',
427 b'convert',
428 b'cvsps.mergefrom',
428 b'cvsps.mergefrom',
429 default=None,
429 default=None,
430 )
430 )
431 coreconfigitem(
431 coreconfigitem(
432 b'convert',
432 b'convert',
433 b'cvsps.mergeto',
433 b'cvsps.mergeto',
434 default=None,
434 default=None,
435 )
435 )
436 coreconfigitem(
436 coreconfigitem(
437 b'convert',
437 b'convert',
438 b'git.committeractions',
438 b'git.committeractions',
439 default=lambda: [b'messagedifferent'],
439 default=lambda: [b'messagedifferent'],
440 )
440 )
441 coreconfigitem(
441 coreconfigitem(
442 b'convert',
442 b'convert',
443 b'git.extrakeys',
443 b'git.extrakeys',
444 default=list,
444 default=list,
445 )
445 )
446 coreconfigitem(
446 coreconfigitem(
447 b'convert',
447 b'convert',
448 b'git.findcopiesharder',
448 b'git.findcopiesharder',
449 default=False,
449 default=False,
450 )
450 )
451 coreconfigitem(
451 coreconfigitem(
452 b'convert',
452 b'convert',
453 b'git.remoteprefix',
453 b'git.remoteprefix',
454 default=b'remote',
454 default=b'remote',
455 )
455 )
456 coreconfigitem(
456 coreconfigitem(
457 b'convert',
457 b'convert',
458 b'git.renamelimit',
458 b'git.renamelimit',
459 default=400,
459 default=400,
460 )
460 )
461 coreconfigitem(
461 coreconfigitem(
462 b'convert',
462 b'convert',
463 b'git.saverev',
463 b'git.saverev',
464 default=True,
464 default=True,
465 )
465 )
466 coreconfigitem(
466 coreconfigitem(
467 b'convert',
467 b'convert',
468 b'git.similarity',
468 b'git.similarity',
469 default=50,
469 default=50,
470 )
470 )
471 coreconfigitem(
471 coreconfigitem(
472 b'convert',
472 b'convert',
473 b'git.skipsubmodules',
473 b'git.skipsubmodules',
474 default=False,
474 default=False,
475 )
475 )
476 coreconfigitem(
476 coreconfigitem(
477 b'convert',
477 b'convert',
478 b'hg.clonebranches',
478 b'hg.clonebranches',
479 default=False,
479 default=False,
480 )
480 )
481 coreconfigitem(
481 coreconfigitem(
482 b'convert',
482 b'convert',
483 b'hg.ignoreerrors',
483 b'hg.ignoreerrors',
484 default=False,
484 default=False,
485 )
485 )
486 coreconfigitem(
486 coreconfigitem(
487 b'convert',
487 b'convert',
488 b'hg.preserve-hash',
488 b'hg.preserve-hash',
489 default=False,
489 default=False,
490 )
490 )
491 coreconfigitem(
491 coreconfigitem(
492 b'convert',
492 b'convert',
493 b'hg.revs',
493 b'hg.revs',
494 default=None,
494 default=None,
495 )
495 )
496 coreconfigitem(
496 coreconfigitem(
497 b'convert',
497 b'convert',
498 b'hg.saverev',
498 b'hg.saverev',
499 default=False,
499 default=False,
500 )
500 )
501 coreconfigitem(
501 coreconfigitem(
502 b'convert',
502 b'convert',
503 b'hg.sourcename',
503 b'hg.sourcename',
504 default=None,
504 default=None,
505 )
505 )
506 coreconfigitem(
506 coreconfigitem(
507 b'convert',
507 b'convert',
508 b'hg.startrev',
508 b'hg.startrev',
509 default=None,
509 default=None,
510 )
510 )
511 coreconfigitem(
511 coreconfigitem(
512 b'convert',
512 b'convert',
513 b'hg.tagsbranch',
513 b'hg.tagsbranch',
514 default=b'default',
514 default=b'default',
515 )
515 )
516 coreconfigitem(
516 coreconfigitem(
517 b'convert',
517 b'convert',
518 b'hg.usebranchnames',
518 b'hg.usebranchnames',
519 default=True,
519 default=True,
520 )
520 )
521 coreconfigitem(
521 coreconfigitem(
522 b'convert',
522 b'convert',
523 b'ignoreancestorcheck',
523 b'ignoreancestorcheck',
524 default=False,
524 default=False,
525 experimental=True,
525 experimental=True,
526 )
526 )
527 coreconfigitem(
527 coreconfigitem(
528 b'convert',
528 b'convert',
529 b'localtimezone',
529 b'localtimezone',
530 default=False,
530 default=False,
531 )
531 )
532 coreconfigitem(
532 coreconfigitem(
533 b'convert',
533 b'convert',
534 b'p4.encoding',
534 b'p4.encoding',
535 default=dynamicdefault,
535 default=dynamicdefault,
536 )
536 )
537 coreconfigitem(
537 coreconfigitem(
538 b'convert',
538 b'convert',
539 b'p4.startrev',
539 b'p4.startrev',
540 default=0,
540 default=0,
541 )
541 )
542 coreconfigitem(
542 coreconfigitem(
543 b'convert',
543 b'convert',
544 b'skiptags',
544 b'skiptags',
545 default=False,
545 default=False,
546 )
546 )
547 coreconfigitem(
547 coreconfigitem(
548 b'convert',
548 b'convert',
549 b'svn.debugsvnlog',
549 b'svn.debugsvnlog',
550 default=True,
550 default=True,
551 )
551 )
552 coreconfigitem(
552 coreconfigitem(
553 b'convert',
553 b'convert',
554 b'svn.trunk',
554 b'svn.trunk',
555 default=None,
555 default=None,
556 )
556 )
557 coreconfigitem(
557 coreconfigitem(
558 b'convert',
558 b'convert',
559 b'svn.tags',
559 b'svn.tags',
560 default=None,
560 default=None,
561 )
561 )
562 coreconfigitem(
562 coreconfigitem(
563 b'convert',
563 b'convert',
564 b'svn.branches',
564 b'svn.branches',
565 default=None,
565 default=None,
566 )
566 )
567 coreconfigitem(
567 coreconfigitem(
568 b'convert',
568 b'convert',
569 b'svn.startrev',
569 b'svn.startrev',
570 default=0,
570 default=0,
571 )
571 )
572 coreconfigitem(
572 coreconfigitem(
573 b'debug',
573 b'debug',
574 b'dirstate.delaywrite',
574 b'dirstate.delaywrite',
575 default=0,
575 default=0,
576 )
576 )
577 coreconfigitem(
577 coreconfigitem(
578 b'defaults',
578 b'defaults',
579 b'.*',
579 b'.*',
580 default=None,
580 default=None,
581 generic=True,
581 generic=True,
582 )
582 )
583 coreconfigitem(
583 coreconfigitem(
584 b'devel',
584 b'devel',
585 b'all-warnings',
585 b'all-warnings',
586 default=False,
586 default=False,
587 )
587 )
588 coreconfigitem(
588 coreconfigitem(
589 b'devel',
589 b'devel',
590 b'bundle2.debug',
590 b'bundle2.debug',
591 default=False,
591 default=False,
592 )
592 )
593 coreconfigitem(
593 coreconfigitem(
594 b'devel',
594 b'devel',
595 b'bundle.delta',
595 b'bundle.delta',
596 default=b'',
596 default=b'',
597 )
597 )
598 coreconfigitem(
598 coreconfigitem(
599 b'devel',
599 b'devel',
600 b'cache-vfs',
600 b'cache-vfs',
601 default=None,
601 default=None,
602 )
602 )
603 coreconfigitem(
603 coreconfigitem(
604 b'devel',
604 b'devel',
605 b'check-locks',
605 b'check-locks',
606 default=False,
606 default=False,
607 )
607 )
608 coreconfigitem(
608 coreconfigitem(
609 b'devel',
609 b'devel',
610 b'check-relroot',
610 b'check-relroot',
611 default=False,
611 default=False,
612 )
612 )
613 coreconfigitem(
613 coreconfigitem(
614 b'devel',
614 b'devel',
615 b'default-date',
615 b'default-date',
616 default=None,
616 default=None,
617 )
617 )
618 coreconfigitem(
618 coreconfigitem(
619 b'devel',
619 b'devel',
620 b'deprec-warn',
620 b'deprec-warn',
621 default=False,
621 default=False,
622 )
622 )
623 coreconfigitem(
623 coreconfigitem(
624 b'devel',
624 b'devel',
625 b'disableloaddefaultcerts',
625 b'disableloaddefaultcerts',
626 default=False,
626 default=False,
627 )
627 )
628 coreconfigitem(
628 coreconfigitem(
629 b'devel',
629 b'devel',
630 b'warn-empty-changegroup',
630 b'warn-empty-changegroup',
631 default=False,
631 default=False,
632 )
632 )
633 coreconfigitem(
633 coreconfigitem(
634 b'devel',
634 b'devel',
635 b'legacy.exchange',
635 b'legacy.exchange',
636 default=list,
636 default=list,
637 )
637 )
638 # When True, revlogs use a special reference version of the nodemap, that is not
638 # When True, revlogs use a special reference version of the nodemap, that is not
639 # performant but is "known" to behave properly.
639 # performant but is "known" to behave properly.
640 coreconfigitem(
640 coreconfigitem(
641 b'devel',
641 b'devel',
642 b'persistent-nodemap',
642 b'persistent-nodemap',
643 default=False,
643 default=False,
644 )
644 )
645 coreconfigitem(
645 coreconfigitem(
646 b'devel',
646 b'devel',
647 b'servercafile',
647 b'servercafile',
648 default=b'',
648 default=b'',
649 )
649 )
650 coreconfigitem(
650 coreconfigitem(
651 b'devel',
651 b'devel',
652 b'serverexactprotocol',
652 b'serverexactprotocol',
653 default=b'',
653 default=b'',
654 )
654 )
655 coreconfigitem(
655 coreconfigitem(
656 b'devel',
656 b'devel',
657 b'serverrequirecert',
657 b'serverrequirecert',
658 default=False,
658 default=False,
659 )
659 )
660 coreconfigitem(
660 coreconfigitem(
661 b'devel',
661 b'devel',
662 b'strip-obsmarkers',
662 b'strip-obsmarkers',
663 default=True,
663 default=True,
664 )
664 )
665 coreconfigitem(
665 coreconfigitem(
666 b'devel',
666 b'devel',
667 b'warn-config',
667 b'warn-config',
668 default=None,
668 default=None,
669 )
669 )
670 coreconfigitem(
670 coreconfigitem(
671 b'devel',
671 b'devel',
672 b'warn-config-default',
672 b'warn-config-default',
673 default=None,
673 default=None,
674 )
674 )
675 coreconfigitem(
675 coreconfigitem(
676 b'devel',
676 b'devel',
677 b'user.obsmarker',
677 b'user.obsmarker',
678 default=None,
678 default=None,
679 )
679 )
680 coreconfigitem(
680 coreconfigitem(
681 b'devel',
681 b'devel',
682 b'warn-config-unknown',
682 b'warn-config-unknown',
683 default=None,
683 default=None,
684 )
684 )
685 coreconfigitem(
685 coreconfigitem(
686 b'devel',
686 b'devel',
687 b'debug.copies',
687 b'debug.copies',
688 default=False,
688 default=False,
689 )
689 )
690 coreconfigitem(
690 coreconfigitem(
691 b'devel',
691 b'devel',
692 b'debug.extensions',
692 b'debug.extensions',
693 default=False,
693 default=False,
694 )
694 )
695 coreconfigitem(
695 coreconfigitem(
696 b'devel',
696 b'devel',
697 b'debug.repo-filters',
697 b'debug.repo-filters',
698 default=False,
698 default=False,
699 )
699 )
700 coreconfigitem(
700 coreconfigitem(
701 b'devel',
701 b'devel',
702 b'debug.peer-request',
702 b'debug.peer-request',
703 default=False,
703 default=False,
704 )
704 )
705 # If discovery.grow-sample is False, the sample size used in set discovery will
705 # If discovery.grow-sample is False, the sample size used in set discovery will
706 # not be increased through the process
706 # not be increased through the process
707 coreconfigitem(
707 coreconfigitem(
708 b'devel',
708 b'devel',
709 b'discovery.grow-sample',
709 b'discovery.grow-sample',
710 default=True,
710 default=True,
711 )
711 )
712 # discovery.grow-sample.rate control the rate at which the sample grow
712 # discovery.grow-sample.rate control the rate at which the sample grow
713 coreconfigitem(
713 coreconfigitem(
714 b'devel',
714 b'devel',
715 b'discovery.grow-sample.rate',
715 b'discovery.grow-sample.rate',
716 default=1.05,
716 default=1.05,
717 )
717 )
718 # If discovery.randomize is False, random sampling during discovery are
718 # If discovery.randomize is False, random sampling during discovery are
719 # deterministic. It is meant for integration tests.
719 # deterministic. It is meant for integration tests.
720 coreconfigitem(
720 coreconfigitem(
721 b'devel',
721 b'devel',
722 b'discovery.randomize',
722 b'discovery.randomize',
723 default=True,
723 default=True,
724 )
724 )
725 _registerdiffopts(section=b'diff')
725 _registerdiffopts(section=b'diff')
726 coreconfigitem(
726 coreconfigitem(
727 b'email',
727 b'email',
728 b'bcc',
728 b'bcc',
729 default=None,
729 default=None,
730 )
730 )
731 coreconfigitem(
731 coreconfigitem(
732 b'email',
732 b'email',
733 b'cc',
733 b'cc',
734 default=None,
734 default=None,
735 )
735 )
736 coreconfigitem(
736 coreconfigitem(
737 b'email',
737 b'email',
738 b'charsets',
738 b'charsets',
739 default=list,
739 default=list,
740 )
740 )
741 coreconfigitem(
741 coreconfigitem(
742 b'email',
742 b'email',
743 b'from',
743 b'from',
744 default=None,
744 default=None,
745 )
745 )
746 coreconfigitem(
746 coreconfigitem(
747 b'email',
747 b'email',
748 b'method',
748 b'method',
749 default=b'smtp',
749 default=b'smtp',
750 )
750 )
751 coreconfigitem(
751 coreconfigitem(
752 b'email',
752 b'email',
753 b'reply-to',
753 b'reply-to',
754 default=None,
754 default=None,
755 )
755 )
756 coreconfigitem(
756 coreconfigitem(
757 b'email',
757 b'email',
758 b'to',
758 b'to',
759 default=None,
759 default=None,
760 )
760 )
761 coreconfigitem(
761 coreconfigitem(
762 b'experimental',
762 b'experimental',
763 b'archivemetatemplate',
763 b'archivemetatemplate',
764 default=dynamicdefault,
764 default=dynamicdefault,
765 )
765 )
766 coreconfigitem(
766 coreconfigitem(
767 b'experimental',
767 b'experimental',
768 b'auto-publish',
768 b'auto-publish',
769 default=b'publish',
769 default=b'publish',
770 )
770 )
771 coreconfigitem(
771 coreconfigitem(
772 b'experimental',
772 b'experimental',
773 b'bundle-phases',
773 b'bundle-phases',
774 default=False,
774 default=False,
775 )
775 )
776 coreconfigitem(
776 coreconfigitem(
777 b'experimental',
777 b'experimental',
778 b'bundle2-advertise',
778 b'bundle2-advertise',
779 default=True,
779 default=True,
780 )
780 )
781 coreconfigitem(
781 coreconfigitem(
782 b'experimental',
782 b'experimental',
783 b'bundle2-output-capture',
783 b'bundle2-output-capture',
784 default=False,
784 default=False,
785 )
785 )
786 coreconfigitem(
786 coreconfigitem(
787 b'experimental',
787 b'experimental',
788 b'bundle2.pushback',
788 b'bundle2.pushback',
789 default=False,
789 default=False,
790 )
790 )
791 coreconfigitem(
791 coreconfigitem(
792 b'experimental',
792 b'experimental',
793 b'bundle2lazylocking',
793 b'bundle2lazylocking',
794 default=False,
794 default=False,
795 )
795 )
796 coreconfigitem(
796 coreconfigitem(
797 b'experimental',
797 b'experimental',
798 b'bundlecomplevel',
798 b'bundlecomplevel',
799 default=None,
799 default=None,
800 )
800 )
801 coreconfigitem(
801 coreconfigitem(
802 b'experimental',
802 b'experimental',
803 b'bundlecomplevel.bzip2',
803 b'bundlecomplevel.bzip2',
804 default=None,
804 default=None,
805 )
805 )
806 coreconfigitem(
806 coreconfigitem(
807 b'experimental',
807 b'experimental',
808 b'bundlecomplevel.gzip',
808 b'bundlecomplevel.gzip',
809 default=None,
809 default=None,
810 )
810 )
811 coreconfigitem(
811 coreconfigitem(
812 b'experimental',
812 b'experimental',
813 b'bundlecomplevel.none',
813 b'bundlecomplevel.none',
814 default=None,
814 default=None,
815 )
815 )
816 coreconfigitem(
816 coreconfigitem(
817 b'experimental',
817 b'experimental',
818 b'bundlecomplevel.zstd',
818 b'bundlecomplevel.zstd',
819 default=None,
819 default=None,
820 )
820 )
821 coreconfigitem(
821 coreconfigitem(
822 b'experimental',
822 b'experimental',
823 b'changegroup3',
823 b'changegroup3',
824 default=False,
824 default=False,
825 )
825 )
826 coreconfigitem(
826 coreconfigitem(
827 b'experimental',
827 b'experimental',
828 b'cleanup-as-archived',
828 b'cleanup-as-archived',
829 default=False,
829 default=False,
830 )
830 )
831 coreconfigitem(
831 coreconfigitem(
832 b'experimental',
832 b'experimental',
833 b'clientcompressionengines',
833 b'clientcompressionengines',
834 default=list,
834 default=list,
835 )
835 )
836 coreconfigitem(
836 coreconfigitem(
837 b'experimental',
837 b'experimental',
838 b'copytrace',
838 b'copytrace',
839 default=b'on',
839 default=b'on',
840 )
840 )
841 coreconfigitem(
841 coreconfigitem(
842 b'experimental',
842 b'experimental',
843 b'copytrace.movecandidateslimit',
843 b'copytrace.movecandidateslimit',
844 default=100,
844 default=100,
845 )
845 )
846 coreconfigitem(
846 coreconfigitem(
847 b'experimental',
847 b'experimental',
848 b'copytrace.sourcecommitlimit',
848 b'copytrace.sourcecommitlimit',
849 default=100,
849 default=100,
850 )
850 )
851 coreconfigitem(
851 coreconfigitem(
852 b'experimental',
852 b'experimental',
853 b'copies.read-from',
853 b'copies.read-from',
854 default=b"filelog-only",
854 default=b"filelog-only",
855 )
855 )
856 coreconfigitem(
856 coreconfigitem(
857 b'experimental',
857 b'experimental',
858 b'copies.write-to',
858 b'copies.write-to',
859 default=b'filelog-only',
859 default=b'filelog-only',
860 )
860 )
861 coreconfigitem(
861 coreconfigitem(
862 b'experimental',
862 b'experimental',
863 b'crecordtest',
863 b'crecordtest',
864 default=None,
864 default=None,
865 )
865 )
866 coreconfigitem(
866 coreconfigitem(
867 b'experimental',
867 b'experimental',
868 b'directaccess',
868 b'directaccess',
869 default=False,
869 default=False,
870 )
870 )
871 coreconfigitem(
871 coreconfigitem(
872 b'experimental',
872 b'experimental',
873 b'directaccess.revnums',
873 b'directaccess.revnums',
874 default=False,
874 default=False,
875 )
875 )
876 coreconfigitem(
876 coreconfigitem(
877 b'experimental',
877 b'experimental',
878 b'editortmpinhg',
878 b'editortmpinhg',
879 default=False,
879 default=False,
880 )
880 )
881 coreconfigitem(
881 coreconfigitem(
882 b'experimental',
882 b'experimental',
883 b'evolution',
883 b'evolution',
884 default=list,
884 default=list,
885 )
885 )
886 coreconfigitem(
886 coreconfigitem(
887 b'experimental',
887 b'experimental',
888 b'evolution.allowdivergence',
888 b'evolution.allowdivergence',
889 default=False,
889 default=False,
890 alias=[(b'experimental', b'allowdivergence')],
890 alias=[(b'experimental', b'allowdivergence')],
891 )
891 )
892 coreconfigitem(
892 coreconfigitem(
893 b'experimental',
893 b'experimental',
894 b'evolution.allowunstable',
894 b'evolution.allowunstable',
895 default=None,
895 default=None,
896 )
896 )
897 coreconfigitem(
897 coreconfigitem(
898 b'experimental',
898 b'experimental',
899 b'evolution.createmarkers',
899 b'evolution.createmarkers',
900 default=None,
900 default=None,
901 )
901 )
902 coreconfigitem(
902 coreconfigitem(
903 b'experimental',
903 b'experimental',
904 b'evolution.effect-flags',
904 b'evolution.effect-flags',
905 default=True,
905 default=True,
906 alias=[(b'experimental', b'effect-flags')],
906 alias=[(b'experimental', b'effect-flags')],
907 )
907 )
908 coreconfigitem(
908 coreconfigitem(
909 b'experimental',
909 b'experimental',
910 b'evolution.exchange',
910 b'evolution.exchange',
911 default=None,
911 default=None,
912 )
912 )
913 coreconfigitem(
913 coreconfigitem(
914 b'experimental',
914 b'experimental',
915 b'evolution.bundle-obsmarker',
915 b'evolution.bundle-obsmarker',
916 default=False,
916 default=False,
917 )
917 )
918 coreconfigitem(
918 coreconfigitem(
919 b'experimental',
919 b'experimental',
920 b'evolution.bundle-obsmarker:mandatory',
920 b'evolution.bundle-obsmarker:mandatory',
921 default=True,
921 default=True,
922 )
922 )
923 coreconfigitem(
923 coreconfigitem(
924 b'experimental',
924 b'experimental',
925 b'log.topo',
925 b'log.topo',
926 default=False,
926 default=False,
927 )
927 )
928 coreconfigitem(
928 coreconfigitem(
929 b'experimental',
929 b'experimental',
930 b'evolution.report-instabilities',
930 b'evolution.report-instabilities',
931 default=True,
931 default=True,
932 )
932 )
933 coreconfigitem(
933 coreconfigitem(
934 b'experimental',
934 b'experimental',
935 b'evolution.track-operation',
935 b'evolution.track-operation',
936 default=True,
936 default=True,
937 )
937 )
938 # repo-level config to exclude a revset visibility
938 # repo-level config to exclude a revset visibility
939 #
939 #
940 # The target use case is to use `share` to expose different subset of the same
940 # The target use case is to use `share` to expose different subset of the same
941 # repository, especially server side. See also `server.view`.
941 # repository, especially server side. See also `server.view`.
942 coreconfigitem(
942 coreconfigitem(
943 b'experimental',
943 b'experimental',
944 b'extra-filter-revs',
944 b'extra-filter-revs',
945 default=None,
945 default=None,
946 )
946 )
947 coreconfigitem(
947 coreconfigitem(
948 b'experimental',
948 b'experimental',
949 b'maxdeltachainspan',
949 b'maxdeltachainspan',
950 default=-1,
950 default=-1,
951 )
951 )
952 # tracks files which were undeleted (merge might delete them but we explicitly
952 # tracks files which were undeleted (merge might delete them but we explicitly
953 # kept/undeleted them) and creates new filenodes for them
953 # kept/undeleted them) and creates new filenodes for them
954 coreconfigitem(
954 coreconfigitem(
955 b'experimental',
955 b'experimental',
956 b'merge-track-salvaged',
956 b'merge-track-salvaged',
957 default=False,
957 default=False,
958 )
958 )
959 coreconfigitem(
959 coreconfigitem(
960 b'experimental',
960 b'experimental',
961 b'mergetempdirprefix',
961 b'mergetempdirprefix',
962 default=None,
962 default=None,
963 )
963 )
964 coreconfigitem(
964 coreconfigitem(
965 b'experimental',
965 b'experimental',
966 b'mmapindexthreshold',
966 b'mmapindexthreshold',
967 default=None,
967 default=None,
968 )
968 )
969 coreconfigitem(
969 coreconfigitem(
970 b'experimental',
970 b'experimental',
971 b'narrow',
971 b'narrow',
972 default=False,
972 default=False,
973 )
973 )
974 coreconfigitem(
974 coreconfigitem(
975 b'experimental',
975 b'experimental',
976 b'nonnormalparanoidcheck',
976 b'nonnormalparanoidcheck',
977 default=False,
977 default=False,
978 )
978 )
979 coreconfigitem(
979 coreconfigitem(
980 b'experimental',
980 b'experimental',
981 b'exportableenviron',
981 b'exportableenviron',
982 default=list,
982 default=list,
983 )
983 )
984 coreconfigitem(
984 coreconfigitem(
985 b'experimental',
985 b'experimental',
986 b'extendedheader.index',
986 b'extendedheader.index',
987 default=None,
987 default=None,
988 )
988 )
989 coreconfigitem(
989 coreconfigitem(
990 b'experimental',
990 b'experimental',
991 b'extendedheader.similarity',
991 b'extendedheader.similarity',
992 default=False,
992 default=False,
993 )
993 )
994 coreconfigitem(
994 coreconfigitem(
995 b'experimental',
995 b'experimental',
996 b'graphshorten',
996 b'graphshorten',
997 default=False,
997 default=False,
998 )
998 )
999 coreconfigitem(
999 coreconfigitem(
1000 b'experimental',
1000 b'experimental',
1001 b'graphstyle.parent',
1001 b'graphstyle.parent',
1002 default=dynamicdefault,
1002 default=dynamicdefault,
1003 )
1003 )
1004 coreconfigitem(
1004 coreconfigitem(
1005 b'experimental',
1005 b'experimental',
1006 b'graphstyle.missing',
1006 b'graphstyle.missing',
1007 default=dynamicdefault,
1007 default=dynamicdefault,
1008 )
1008 )
1009 coreconfigitem(
1009 coreconfigitem(
1010 b'experimental',
1010 b'experimental',
1011 b'graphstyle.grandparent',
1011 b'graphstyle.grandparent',
1012 default=dynamicdefault,
1012 default=dynamicdefault,
1013 )
1013 )
1014 coreconfigitem(
1014 coreconfigitem(
1015 b'experimental',
1015 b'experimental',
1016 b'hook-track-tags',
1016 b'hook-track-tags',
1017 default=False,
1017 default=False,
1018 )
1018 )
1019 coreconfigitem(
1019 coreconfigitem(
1020 b'experimental',
1020 b'experimental',
1021 b'httppeer.advertise-v2',
1021 b'httppeer.advertise-v2',
1022 default=False,
1022 default=False,
1023 )
1023 )
1024 coreconfigitem(
1024 coreconfigitem(
1025 b'experimental',
1025 b'experimental',
1026 b'httppeer.v2-encoder-order',
1026 b'httppeer.v2-encoder-order',
1027 default=None,
1027 default=None,
1028 )
1028 )
1029 coreconfigitem(
1029 coreconfigitem(
1030 b'experimental',
1030 b'experimental',
1031 b'httppostargs',
1031 b'httppostargs',
1032 default=False,
1032 default=False,
1033 )
1033 )
1034 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1034 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1035 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1035 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1036
1036
1037 coreconfigitem(
1037 coreconfigitem(
1038 b'experimental',
1038 b'experimental',
1039 b'obsmarkers-exchange-debug',
1039 b'obsmarkers-exchange-debug',
1040 default=False,
1040 default=False,
1041 )
1041 )
1042 coreconfigitem(
1042 coreconfigitem(
1043 b'experimental',
1043 b'experimental',
1044 b'remotenames',
1044 b'remotenames',
1045 default=False,
1045 default=False,
1046 )
1046 )
1047 coreconfigitem(
1047 coreconfigitem(
1048 b'experimental',
1048 b'experimental',
1049 b'removeemptydirs',
1049 b'removeemptydirs',
1050 default=True,
1050 default=True,
1051 )
1051 )
1052 coreconfigitem(
1052 coreconfigitem(
1053 b'experimental',
1053 b'experimental',
1054 b'revert.interactive.select-to-keep',
1054 b'revert.interactive.select-to-keep',
1055 default=False,
1055 default=False,
1056 )
1056 )
1057 coreconfigitem(
1057 coreconfigitem(
1058 b'experimental',
1058 b'experimental',
1059 b'revisions.prefixhexnode',
1059 b'revisions.prefixhexnode',
1060 default=False,
1060 default=False,
1061 )
1061 )
1062 coreconfigitem(
1062 coreconfigitem(
1063 b'experimental',
1063 b'experimental',
1064 b'revlogv2',
1064 b'revlogv2',
1065 default=None,
1065 default=None,
1066 )
1066 )
1067 coreconfigitem(
1067 coreconfigitem(
1068 b'experimental',
1068 b'experimental',
1069 b'revisions.disambiguatewithin',
1069 b'revisions.disambiguatewithin',
1070 default=None,
1070 default=None,
1071 )
1071 )
1072 coreconfigitem(
1072 coreconfigitem(
1073 b'experimental',
1073 b'experimental',
1074 b'rust.index',
1074 b'rust.index',
1075 default=False,
1075 default=False,
1076 )
1076 )
1077 coreconfigitem(
1077 coreconfigitem(
1078 b'experimental',
1078 b'experimental',
1079 b'server.filesdata.recommended-batch-size',
1079 b'server.filesdata.recommended-batch-size',
1080 default=50000,
1080 default=50000,
1081 )
1081 )
1082 coreconfigitem(
1082 coreconfigitem(
1083 b'experimental',
1083 b'experimental',
1084 b'server.manifestdata.recommended-batch-size',
1084 b'server.manifestdata.recommended-batch-size',
1085 default=100000,
1085 default=100000,
1086 )
1086 )
1087 coreconfigitem(
1087 coreconfigitem(
1088 b'experimental',
1088 b'experimental',
1089 b'server.stream-narrow-clones',
1089 b'server.stream-narrow-clones',
1090 default=False,
1090 default=False,
1091 )
1091 )
1092 coreconfigitem(
1092 coreconfigitem(
1093 b'experimental',
1093 b'experimental',
1094 b'sharesafe-auto-downgrade-shares',
1094 b'sharesafe-auto-downgrade-shares',
1095 default=False,
1095 default=False,
1096 )
1096 )
1097 coreconfigitem(
1097 coreconfigitem(
1098 b'experimental',
1098 b'experimental',
1099 b'sharesafe-auto-upgrade-shares',
1099 b'sharesafe-auto-upgrade-shares',
1100 default=False,
1100 default=False,
1101 )
1101 )
1102 coreconfigitem(
1102 coreconfigitem(
1103 b'experimental',
1103 b'experimental',
1104 b'sharesafe-auto-upgrade-fail-error',
1104 b'sharesafe-auto-upgrade-fail-error',
1105 default=False,
1105 default=False,
1106 )
1106 )
1107 coreconfigitem(
1107 coreconfigitem(
1108 b'experimental',
1108 b'experimental',
1109 b'sharesafe-warn-outdated-shares',
1109 b'sharesafe-warn-outdated-shares',
1110 default=True,
1110 default=True,
1111 )
1111 )
1112 coreconfigitem(
1112 coreconfigitem(
1113 b'experimental',
1113 b'experimental',
1114 b'single-head-per-branch',
1114 b'single-head-per-branch',
1115 default=False,
1115 default=False,
1116 )
1116 )
1117 coreconfigitem(
1117 coreconfigitem(
1118 b'experimental',
1118 b'experimental',
1119 b'single-head-per-branch:account-closed-heads',
1119 b'single-head-per-branch:account-closed-heads',
1120 default=False,
1120 default=False,
1121 )
1121 )
1122 coreconfigitem(
1122 coreconfigitem(
1123 b'experimental',
1123 b'experimental',
1124 b'single-head-per-branch:public-changes-only',
1124 b'single-head-per-branch:public-changes-only',
1125 default=False,
1125 default=False,
1126 )
1126 )
1127 coreconfigitem(
1127 coreconfigitem(
1128 b'experimental',
1128 b'experimental',
1129 b'sshserver.support-v2',
1129 b'sshserver.support-v2',
1130 default=False,
1130 default=False,
1131 )
1131 )
1132 coreconfigitem(
1132 coreconfigitem(
1133 b'experimental',
1133 b'experimental',
1134 b'sparse-read',
1134 b'sparse-read',
1135 default=False,
1135 default=False,
1136 )
1136 )
1137 coreconfigitem(
1137 coreconfigitem(
1138 b'experimental',
1138 b'experimental',
1139 b'sparse-read.density-threshold',
1139 b'sparse-read.density-threshold',
1140 default=0.50,
1140 default=0.50,
1141 )
1141 )
1142 coreconfigitem(
1142 coreconfigitem(
1143 b'experimental',
1143 b'experimental',
1144 b'sparse-read.min-gap-size',
1144 b'sparse-read.min-gap-size',
1145 default=b'65K',
1145 default=b'65K',
1146 )
1146 )
1147 coreconfigitem(
1147 coreconfigitem(
1148 b'experimental',
1148 b'experimental',
1149 b'treemanifest',
1149 b'treemanifest',
1150 default=False,
1150 default=False,
1151 )
1151 )
1152 coreconfigitem(
1152 coreconfigitem(
1153 b'experimental',
1153 b'experimental',
1154 b'update.atomic-file',
1154 b'update.atomic-file',
1155 default=False,
1155 default=False,
1156 )
1156 )
1157 coreconfigitem(
1157 coreconfigitem(
1158 b'experimental',
1158 b'experimental',
1159 b'sshpeer.advertise-v2',
1159 b'sshpeer.advertise-v2',
1160 default=False,
1160 default=False,
1161 )
1161 )
1162 coreconfigitem(
1162 coreconfigitem(
1163 b'experimental',
1163 b'experimental',
1164 b'web.apiserver',
1164 b'web.apiserver',
1165 default=False,
1165 default=False,
1166 )
1166 )
1167 coreconfigitem(
1167 coreconfigitem(
1168 b'experimental',
1168 b'experimental',
1169 b'web.api.http-v2',
1169 b'web.api.http-v2',
1170 default=False,
1170 default=False,
1171 )
1171 )
1172 coreconfigitem(
1172 coreconfigitem(
1173 b'experimental',
1173 b'experimental',
1174 b'web.api.debugreflect',
1174 b'web.api.debugreflect',
1175 default=False,
1175 default=False,
1176 )
1176 )
1177 coreconfigitem(
1177 coreconfigitem(
1178 b'experimental',
1178 b'experimental',
1179 b'worker.wdir-get-thread-safe',
1179 b'worker.wdir-get-thread-safe',
1180 default=False,
1180 default=False,
1181 )
1181 )
1182 coreconfigitem(
1182 coreconfigitem(
1183 b'experimental',
1183 b'experimental',
1184 b'worker.repository-upgrade',
1184 b'worker.repository-upgrade',
1185 default=False,
1185 default=False,
1186 )
1186 )
1187 coreconfigitem(
1187 coreconfigitem(
1188 b'experimental',
1188 b'experimental',
1189 b'xdiff',
1189 b'xdiff',
1190 default=False,
1190 default=False,
1191 )
1191 )
1192 coreconfigitem(
1192 coreconfigitem(
1193 b'extensions',
1193 b'extensions',
1194 b'.*',
1194 b'.*',
1195 default=None,
1195 default=None,
1196 generic=True,
1196 generic=True,
1197 )
1197 )
1198 coreconfigitem(
1198 coreconfigitem(
1199 b'extdata',
1199 b'extdata',
1200 b'.*',
1200 b'.*',
1201 default=None,
1201 default=None,
1202 generic=True,
1202 generic=True,
1203 )
1203 )
1204 coreconfigitem(
1204 coreconfigitem(
1205 b'format',
1205 b'format',
1206 b'bookmarks-in-store',
1206 b'bookmarks-in-store',
1207 default=False,
1207 default=False,
1208 )
1208 )
1209 coreconfigitem(
1209 coreconfigitem(
1210 b'format',
1210 b'format',
1211 b'chunkcachesize',
1211 b'chunkcachesize',
1212 default=None,
1212 default=None,
1213 experimental=True,
1213 experimental=True,
1214 )
1214 )
1215 coreconfigitem(
1215 coreconfigitem(
1216 b'format',
1216 b'format',
1217 b'dotencode',
1217 b'dotencode',
1218 default=True,
1218 default=True,
1219 )
1219 )
1220 coreconfigitem(
1220 coreconfigitem(
1221 b'format',
1221 b'format',
1222 b'generaldelta',
1222 b'generaldelta',
1223 default=False,
1223 default=False,
1224 experimental=True,
1224 experimental=True,
1225 )
1225 )
1226 coreconfigitem(
1226 coreconfigitem(
1227 b'format',
1227 b'format',
1228 b'manifestcachesize',
1228 b'manifestcachesize',
1229 default=None,
1229 default=None,
1230 experimental=True,
1230 experimental=True,
1231 )
1231 )
1232 coreconfigitem(
1232 coreconfigitem(
1233 b'format',
1233 b'format',
1234 b'maxchainlen',
1234 b'maxchainlen',
1235 default=dynamicdefault,
1235 default=dynamicdefault,
1236 experimental=True,
1236 experimental=True,
1237 )
1237 )
1238 coreconfigitem(
1238 coreconfigitem(
1239 b'format',
1239 b'format',
1240 b'obsstore-version',
1240 b'obsstore-version',
1241 default=None,
1241 default=None,
1242 )
1242 )
1243 coreconfigitem(
1243 coreconfigitem(
1244 b'format',
1244 b'format',
1245 b'sparse-revlog',
1245 b'sparse-revlog',
1246 default=True,
1246 default=True,
1247 )
1247 )
1248 coreconfigitem(
1248 coreconfigitem(
1249 b'format',
1249 b'format',
1250 b'revlog-compression',
1250 b'revlog-compression',
1251 default=lambda: [b'zlib'],
1251 default=lambda: [b'zlib'],
1252 alias=[(b'experimental', b'format.compression')],
1252 alias=[(b'experimental', b'format.compression')],
1253 )
1253 )
1254 coreconfigitem(
1254 coreconfigitem(
1255 b'format',
1255 b'format',
1256 b'usefncache',
1256 b'usefncache',
1257 default=True,
1257 default=True,
1258 )
1258 )
1259 coreconfigitem(
1259 coreconfigitem(
1260 b'format',
1260 b'format',
1261 b'usegeneraldelta',
1261 b'usegeneraldelta',
1262 default=True,
1262 default=True,
1263 )
1263 )
1264 coreconfigitem(
1264 coreconfigitem(
1265 b'format',
1265 b'format',
1266 b'usestore',
1266 b'usestore',
1267 default=True,
1267 default=True,
1268 )
1268 )
1269 # Right now, the only efficient implement of the nodemap logic is in Rust,
1269 # Right now, the only efficient implement of the nodemap logic is in Rust,
1270 #
1270 #
1271 # The case was discussed that the 5.6 sprint and the following was decided for
1271 # The case was discussed that the 5.6 sprint and the following was decided for
1272 # feature that have an optional fast implementation (and are a performance
1272 # feature that have an optional fast implementation (and are a performance
1273 # regression in the others)
1273 # regression in the others)
1274 #
1274 #
1275 # * If the fast implementation is not available, Mercurial will refuse to
1275 # * If the fast implementation is not available, Mercurial will refuse to
1276 # access repository that requires it. Pointing to proper documentation
1276 # access repository that requires it. Pointing to proper documentation
1277 #
1277 #
1278 # * An option exist to lift that limitation and allow repository access.
1278 # * An option exist to lift that limitation and allow repository access.
1279 #
1279 #
1280 # Such access will emit a warning unless configured not to.
1280 # Such access will emit a warning unless configured not to.
1281 #
1281 #
1282 # * When sufficiently mature, the feature can be enabled by default only for
1282 # * When sufficiently mature, the feature can be enabled by default only for
1283 # installation that supports it.
1283 # installation that supports it.
1284 coreconfigitem(
1284 coreconfigitem(
1285 b'format', b'use-persistent-nodemap', default=False, experimental=True
1285 b'format', b'use-persistent-nodemap', default=False, experimental=True
1286 )
1286 )
1287 coreconfigitem(
1287 coreconfigitem(
1288 b'format',
1288 b'format',
1289 b'exp-use-copies-side-data-changeset',
1289 b'exp-use-copies-side-data-changeset',
1290 default=False,
1290 default=False,
1291 experimental=True,
1291 experimental=True,
1292 )
1292 )
1293 coreconfigitem(
1293 coreconfigitem(
1294 b'format',
1294 b'format',
1295 b'exp-use-side-data',
1295 b'exp-use-side-data',
1296 default=False,
1296 default=False,
1297 experimental=True,
1297 experimental=True,
1298 )
1298 )
1299 coreconfigitem(
1299 coreconfigitem(
1300 b'format',
1300 b'format',
1301 b'exp-share-safe',
1301 b'exp-share-safe',
1302 default=False,
1302 default=False,
1303 experimental=True,
1303 experimental=True,
1304 )
1304 )
1305 coreconfigitem(
1305 coreconfigitem(
1306 b'format',
1306 b'format',
1307 b'internal-phase',
1307 b'internal-phase',
1308 default=False,
1308 default=False,
1309 experimental=True,
1309 experimental=True,
1310 )
1310 )
1311 coreconfigitem(
1311 coreconfigitem(
1312 b'fsmonitor',
1312 b'fsmonitor',
1313 b'warn_when_unused',
1313 b'warn_when_unused',
1314 default=True,
1314 default=True,
1315 )
1315 )
1316 coreconfigitem(
1316 coreconfigitem(
1317 b'fsmonitor',
1317 b'fsmonitor',
1318 b'warn_update_file_count',
1318 b'warn_update_file_count',
1319 default=50000,
1319 default=50000,
1320 )
1320 )
1321 coreconfigitem(
1321 coreconfigitem(
1322 b'fsmonitor',
1322 b'fsmonitor',
1323 b'warn_update_file_count_rust',
1323 b'warn_update_file_count_rust',
1324 default=400000,
1324 default=400000,
1325 )
1325 )
1326 coreconfigitem(
1326 coreconfigitem(
1327 b'help',
1327 b'help',
1328 br'hidden-command\..*',
1328 br'hidden-command\..*',
1329 default=False,
1329 default=False,
1330 generic=True,
1330 generic=True,
1331 )
1331 )
1332 coreconfigitem(
1332 coreconfigitem(
1333 b'help',
1333 b'help',
1334 br'hidden-topic\..*',
1334 br'hidden-topic\..*',
1335 default=False,
1335 default=False,
1336 generic=True,
1336 generic=True,
1337 )
1337 )
1338 coreconfigitem(
1338 coreconfigitem(
1339 b'hooks',
1339 b'hooks',
1340 b'.*',
1340 b'.*',
1341 default=dynamicdefault,
1341 default=dynamicdefault,
1342 generic=True,
1342 generic=True,
1343 )
1343 )
1344 coreconfigitem(
1344 coreconfigitem(
1345 b'hgweb-paths',
1345 b'hgweb-paths',
1346 b'.*',
1346 b'.*',
1347 default=list,
1347 default=list,
1348 generic=True,
1348 generic=True,
1349 )
1349 )
1350 coreconfigitem(
1350 coreconfigitem(
1351 b'hostfingerprints',
1351 b'hostfingerprints',
1352 b'.*',
1352 b'.*',
1353 default=list,
1353 default=list,
1354 generic=True,
1354 generic=True,
1355 )
1355 )
1356 coreconfigitem(
1356 coreconfigitem(
1357 b'hostsecurity',
1357 b'hostsecurity',
1358 b'ciphers',
1358 b'ciphers',
1359 default=None,
1359 default=None,
1360 )
1360 )
1361 coreconfigitem(
1361 coreconfigitem(
1362 b'hostsecurity',
1362 b'hostsecurity',
1363 b'minimumprotocol',
1363 b'minimumprotocol',
1364 default=dynamicdefault,
1364 default=dynamicdefault,
1365 )
1365 )
1366 coreconfigitem(
1366 coreconfigitem(
1367 b'hostsecurity',
1367 b'hostsecurity',
1368 b'.*:minimumprotocol$',
1368 b'.*:minimumprotocol$',
1369 default=dynamicdefault,
1369 default=dynamicdefault,
1370 generic=True,
1370 generic=True,
1371 )
1371 )
1372 coreconfigitem(
1372 coreconfigitem(
1373 b'hostsecurity',
1373 b'hostsecurity',
1374 b'.*:ciphers$',
1374 b'.*:ciphers$',
1375 default=dynamicdefault,
1375 default=dynamicdefault,
1376 generic=True,
1376 generic=True,
1377 )
1377 )
1378 coreconfigitem(
1378 coreconfigitem(
1379 b'hostsecurity',
1379 b'hostsecurity',
1380 b'.*:fingerprints$',
1380 b'.*:fingerprints$',
1381 default=list,
1381 default=list,
1382 generic=True,
1382 generic=True,
1383 )
1383 )
1384 coreconfigitem(
1384 coreconfigitem(
1385 b'hostsecurity',
1385 b'hostsecurity',
1386 b'.*:verifycertsfile$',
1386 b'.*:verifycertsfile$',
1387 default=None,
1387 default=None,
1388 generic=True,
1388 generic=True,
1389 )
1389 )
1390
1390
1391 coreconfigitem(
1391 coreconfigitem(
1392 b'http_proxy',
1392 b'http_proxy',
1393 b'always',
1393 b'always',
1394 default=False,
1394 default=False,
1395 )
1395 )
1396 coreconfigitem(
1396 coreconfigitem(
1397 b'http_proxy',
1397 b'http_proxy',
1398 b'host',
1398 b'host',
1399 default=None,
1399 default=None,
1400 )
1400 )
1401 coreconfigitem(
1401 coreconfigitem(
1402 b'http_proxy',
1402 b'http_proxy',
1403 b'no',
1403 b'no',
1404 default=list,
1404 default=list,
1405 )
1405 )
1406 coreconfigitem(
1406 coreconfigitem(
1407 b'http_proxy',
1407 b'http_proxy',
1408 b'passwd',
1408 b'passwd',
1409 default=None,
1409 default=None,
1410 )
1410 )
1411 coreconfigitem(
1411 coreconfigitem(
1412 b'http_proxy',
1412 b'http_proxy',
1413 b'user',
1413 b'user',
1414 default=None,
1414 default=None,
1415 )
1415 )
1416
1416
1417 coreconfigitem(
1417 coreconfigitem(
1418 b'http',
1418 b'http',
1419 b'timeout',
1419 b'timeout',
1420 default=None,
1420 default=None,
1421 )
1421 )
1422
1422
1423 coreconfigitem(
1423 coreconfigitem(
1424 b'logtoprocess',
1424 b'logtoprocess',
1425 b'commandexception',
1425 b'commandexception',
1426 default=None,
1426 default=None,
1427 )
1427 )
1428 coreconfigitem(
1428 coreconfigitem(
1429 b'logtoprocess',
1429 b'logtoprocess',
1430 b'commandfinish',
1430 b'commandfinish',
1431 default=None,
1431 default=None,
1432 )
1432 )
1433 coreconfigitem(
1433 coreconfigitem(
1434 b'logtoprocess',
1434 b'logtoprocess',
1435 b'command',
1435 b'command',
1436 default=None,
1436 default=None,
1437 )
1437 )
1438 coreconfigitem(
1438 coreconfigitem(
1439 b'logtoprocess',
1439 b'logtoprocess',
1440 b'develwarn',
1440 b'develwarn',
1441 default=None,
1441 default=None,
1442 )
1442 )
1443 coreconfigitem(
1443 coreconfigitem(
1444 b'logtoprocess',
1444 b'logtoprocess',
1445 b'uiblocked',
1445 b'uiblocked',
1446 default=None,
1446 default=None,
1447 )
1447 )
1448 coreconfigitem(
1448 coreconfigitem(
1449 b'merge',
1449 b'merge',
1450 b'checkunknown',
1450 b'checkunknown',
1451 default=b'abort',
1451 default=b'abort',
1452 )
1452 )
1453 coreconfigitem(
1453 coreconfigitem(
1454 b'merge',
1454 b'merge',
1455 b'checkignored',
1455 b'checkignored',
1456 default=b'abort',
1456 default=b'abort',
1457 )
1457 )
1458 coreconfigitem(
1458 coreconfigitem(
1459 b'experimental',
1459 b'experimental',
1460 b'merge.checkpathconflicts',
1460 b'merge.checkpathconflicts',
1461 default=False,
1461 default=False,
1462 )
1462 )
1463 coreconfigitem(
1463 coreconfigitem(
1464 b'merge',
1464 b'merge',
1465 b'followcopies',
1465 b'followcopies',
1466 default=True,
1466 default=True,
1467 )
1467 )
1468 coreconfigitem(
1468 coreconfigitem(
1469 b'merge',
1469 b'merge',
1470 b'on-failure',
1470 b'on-failure',
1471 default=b'continue',
1471 default=b'continue',
1472 )
1472 )
1473 coreconfigitem(
1473 coreconfigitem(
1474 b'merge',
1474 b'merge',
1475 b'preferancestor',
1475 b'preferancestor',
1476 default=lambda: [b'*'],
1476 default=lambda: [b'*'],
1477 experimental=True,
1477 experimental=True,
1478 )
1478 )
1479 coreconfigitem(
1479 coreconfigitem(
1480 b'merge',
1480 b'merge',
1481 b'strict-capability-check',
1481 b'strict-capability-check',
1482 default=False,
1482 default=False,
1483 )
1483 )
1484 coreconfigitem(
1484 coreconfigitem(
1485 b'merge-tools',
1485 b'merge-tools',
1486 b'.*',
1486 b'.*',
1487 default=None,
1487 default=None,
1488 generic=True,
1488 generic=True,
1489 )
1489 )
1490 coreconfigitem(
1490 coreconfigitem(
1491 b'merge-tools',
1491 b'merge-tools',
1492 br'.*\.args$',
1492 br'.*\.args$',
1493 default=b"$local $base $other",
1493 default=b"$local $base $other",
1494 generic=True,
1494 generic=True,
1495 priority=-1,
1495 priority=-1,
1496 )
1496 )
1497 coreconfigitem(
1497 coreconfigitem(
1498 b'merge-tools',
1498 b'merge-tools',
1499 br'.*\.binary$',
1499 br'.*\.binary$',
1500 default=False,
1500 default=False,
1501 generic=True,
1501 generic=True,
1502 priority=-1,
1502 priority=-1,
1503 )
1503 )
1504 coreconfigitem(
1504 coreconfigitem(
1505 b'merge-tools',
1505 b'merge-tools',
1506 br'.*\.check$',
1506 br'.*\.check$',
1507 default=list,
1507 default=list,
1508 generic=True,
1508 generic=True,
1509 priority=-1,
1509 priority=-1,
1510 )
1510 )
1511 coreconfigitem(
1511 coreconfigitem(
1512 b'merge-tools',
1512 b'merge-tools',
1513 br'.*\.checkchanged$',
1513 br'.*\.checkchanged$',
1514 default=False,
1514 default=False,
1515 generic=True,
1515 generic=True,
1516 priority=-1,
1516 priority=-1,
1517 )
1517 )
1518 coreconfigitem(
1518 coreconfigitem(
1519 b'merge-tools',
1519 b'merge-tools',
1520 br'.*\.executable$',
1520 br'.*\.executable$',
1521 default=dynamicdefault,
1521 default=dynamicdefault,
1522 generic=True,
1522 generic=True,
1523 priority=-1,
1523 priority=-1,
1524 )
1524 )
1525 coreconfigitem(
1525 coreconfigitem(
1526 b'merge-tools',
1526 b'merge-tools',
1527 br'.*\.fixeol$',
1527 br'.*\.fixeol$',
1528 default=False,
1528 default=False,
1529 generic=True,
1529 generic=True,
1530 priority=-1,
1530 priority=-1,
1531 )
1531 )
1532 coreconfigitem(
1532 coreconfigitem(
1533 b'merge-tools',
1533 b'merge-tools',
1534 br'.*\.gui$',
1534 br'.*\.gui$',
1535 default=False,
1535 default=False,
1536 generic=True,
1536 generic=True,
1537 priority=-1,
1537 priority=-1,
1538 )
1538 )
1539 coreconfigitem(
1539 coreconfigitem(
1540 b'merge-tools',
1540 b'merge-tools',
1541 br'.*\.mergemarkers$',
1541 br'.*\.mergemarkers$',
1542 default=b'basic',
1542 default=b'basic',
1543 generic=True,
1543 generic=True,
1544 priority=-1,
1544 priority=-1,
1545 )
1545 )
1546 coreconfigitem(
1546 coreconfigitem(
1547 b'merge-tools',
1547 b'merge-tools',
1548 br'.*\.mergemarkertemplate$',
1548 br'.*\.mergemarkertemplate$',
1549 default=dynamicdefault, # take from command-templates.mergemarker
1549 default=dynamicdefault, # take from command-templates.mergemarker
1550 generic=True,
1550 generic=True,
1551 priority=-1,
1551 priority=-1,
1552 )
1552 )
1553 coreconfigitem(
1553 coreconfigitem(
1554 b'merge-tools',
1554 b'merge-tools',
1555 br'.*\.priority$',
1555 br'.*\.priority$',
1556 default=0,
1556 default=0,
1557 generic=True,
1557 generic=True,
1558 priority=-1,
1558 priority=-1,
1559 )
1559 )
1560 coreconfigitem(
1560 coreconfigitem(
1561 b'merge-tools',
1561 b'merge-tools',
1562 br'.*\.premerge$',
1562 br'.*\.premerge$',
1563 default=dynamicdefault,
1563 default=dynamicdefault,
1564 generic=True,
1564 generic=True,
1565 priority=-1,
1565 priority=-1,
1566 )
1566 )
1567 coreconfigitem(
1567 coreconfigitem(
1568 b'merge-tools',
1568 b'merge-tools',
1569 br'.*\.symlink$',
1569 br'.*\.symlink$',
1570 default=False,
1570 default=False,
1571 generic=True,
1571 generic=True,
1572 priority=-1,
1572 priority=-1,
1573 )
1573 )
1574 coreconfigitem(
1574 coreconfigitem(
1575 b'pager',
1575 b'pager',
1576 b'attend-.*',
1576 b'attend-.*',
1577 default=dynamicdefault,
1577 default=dynamicdefault,
1578 generic=True,
1578 generic=True,
1579 )
1579 )
1580 coreconfigitem(
1580 coreconfigitem(
1581 b'pager',
1581 b'pager',
1582 b'ignore',
1582 b'ignore',
1583 default=list,
1583 default=list,
1584 )
1584 )
1585 coreconfigitem(
1585 coreconfigitem(
1586 b'pager',
1586 b'pager',
1587 b'pager',
1587 b'pager',
1588 default=dynamicdefault,
1588 default=dynamicdefault,
1589 )
1589 )
1590 coreconfigitem(
1590 coreconfigitem(
1591 b'patch',
1591 b'patch',
1592 b'eol',
1592 b'eol',
1593 default=b'strict',
1593 default=b'strict',
1594 )
1594 )
1595 coreconfigitem(
1595 coreconfigitem(
1596 b'patch',
1596 b'patch',
1597 b'fuzz',
1597 b'fuzz',
1598 default=2,
1598 default=2,
1599 )
1599 )
1600 coreconfigitem(
1600 coreconfigitem(
1601 b'paths',
1601 b'paths',
1602 b'default',
1602 b'default',
1603 default=None,
1603 default=None,
1604 )
1604 )
1605 coreconfigitem(
1605 coreconfigitem(
1606 b'paths',
1606 b'paths',
1607 b'default-push',
1607 b'default-push',
1608 default=None,
1608 default=None,
1609 )
1609 )
1610 coreconfigitem(
1610 coreconfigitem(
1611 b'paths',
1611 b'paths',
1612 b'.*',
1612 b'.*',
1613 default=None,
1613 default=None,
1614 generic=True,
1614 generic=True,
1615 )
1615 )
1616 coreconfigitem(
1616 coreconfigitem(
1617 b'phases',
1617 b'phases',
1618 b'checksubrepos',
1618 b'checksubrepos',
1619 default=b'follow',
1619 default=b'follow',
1620 )
1620 )
1621 coreconfigitem(
1621 coreconfigitem(
1622 b'phases',
1622 b'phases',
1623 b'new-commit',
1623 b'new-commit',
1624 default=b'draft',
1624 default=b'draft',
1625 )
1625 )
1626 coreconfigitem(
1626 coreconfigitem(
1627 b'phases',
1627 b'phases',
1628 b'publish',
1628 b'publish',
1629 default=True,
1629 default=True,
1630 )
1630 )
1631 coreconfigitem(
1631 coreconfigitem(
1632 b'profiling',
1632 b'profiling',
1633 b'enabled',
1633 b'enabled',
1634 default=False,
1634 default=False,
1635 )
1635 )
1636 coreconfigitem(
1636 coreconfigitem(
1637 b'profiling',
1637 b'profiling',
1638 b'format',
1638 b'format',
1639 default=b'text',
1639 default=b'text',
1640 )
1640 )
1641 coreconfigitem(
1641 coreconfigitem(
1642 b'profiling',
1642 b'profiling',
1643 b'freq',
1643 b'freq',
1644 default=1000,
1644 default=1000,
1645 )
1645 )
1646 coreconfigitem(
1646 coreconfigitem(
1647 b'profiling',
1647 b'profiling',
1648 b'limit',
1648 b'limit',
1649 default=30,
1649 default=30,
1650 )
1650 )
1651 coreconfigitem(
1651 coreconfigitem(
1652 b'profiling',
1652 b'profiling',
1653 b'nested',
1653 b'nested',
1654 default=0,
1654 default=0,
1655 )
1655 )
1656 coreconfigitem(
1656 coreconfigitem(
1657 b'profiling',
1657 b'profiling',
1658 b'output',
1658 b'output',
1659 default=None,
1659 default=None,
1660 )
1660 )
1661 coreconfigitem(
1661 coreconfigitem(
1662 b'profiling',
1662 b'profiling',
1663 b'showmax',
1663 b'showmax',
1664 default=0.999,
1664 default=0.999,
1665 )
1665 )
1666 coreconfigitem(
1666 coreconfigitem(
1667 b'profiling',
1667 b'profiling',
1668 b'showmin',
1668 b'showmin',
1669 default=dynamicdefault,
1669 default=dynamicdefault,
1670 )
1670 )
1671 coreconfigitem(
1671 coreconfigitem(
1672 b'profiling',
1672 b'profiling',
1673 b'showtime',
1673 b'showtime',
1674 default=True,
1674 default=True,
1675 )
1675 )
1676 coreconfigitem(
1676 coreconfigitem(
1677 b'profiling',
1677 b'profiling',
1678 b'sort',
1678 b'sort',
1679 default=b'inlinetime',
1679 default=b'inlinetime',
1680 )
1680 )
1681 coreconfigitem(
1681 coreconfigitem(
1682 b'profiling',
1682 b'profiling',
1683 b'statformat',
1683 b'statformat',
1684 default=b'hotpath',
1684 default=b'hotpath',
1685 )
1685 )
1686 coreconfigitem(
1686 coreconfigitem(
1687 b'profiling',
1687 b'profiling',
1688 b'time-track',
1688 b'time-track',
1689 default=dynamicdefault,
1689 default=dynamicdefault,
1690 )
1690 )
1691 coreconfigitem(
1691 coreconfigitem(
1692 b'profiling',
1692 b'profiling',
1693 b'type',
1693 b'type',
1694 default=b'stat',
1694 default=b'stat',
1695 )
1695 )
1696 coreconfigitem(
1696 coreconfigitem(
1697 b'progress',
1697 b'progress',
1698 b'assume-tty',
1698 b'assume-tty',
1699 default=False,
1699 default=False,
1700 )
1700 )
1701 coreconfigitem(
1701 coreconfigitem(
1702 b'progress',
1702 b'progress',
1703 b'changedelay',
1703 b'changedelay',
1704 default=1,
1704 default=1,
1705 )
1705 )
1706 coreconfigitem(
1706 coreconfigitem(
1707 b'progress',
1707 b'progress',
1708 b'clear-complete',
1708 b'clear-complete',
1709 default=True,
1709 default=True,
1710 )
1710 )
1711 coreconfigitem(
1711 coreconfigitem(
1712 b'progress',
1712 b'progress',
1713 b'debug',
1713 b'debug',
1714 default=False,
1714 default=False,
1715 )
1715 )
1716 coreconfigitem(
1716 coreconfigitem(
1717 b'progress',
1717 b'progress',
1718 b'delay',
1718 b'delay',
1719 default=3,
1719 default=3,
1720 )
1720 )
1721 coreconfigitem(
1721 coreconfigitem(
1722 b'progress',
1722 b'progress',
1723 b'disable',
1723 b'disable',
1724 default=False,
1724 default=False,
1725 )
1725 )
1726 coreconfigitem(
1726 coreconfigitem(
1727 b'progress',
1727 b'progress',
1728 b'estimateinterval',
1728 b'estimateinterval',
1729 default=60.0,
1729 default=60.0,
1730 )
1730 )
1731 coreconfigitem(
1731 coreconfigitem(
1732 b'progress',
1732 b'progress',
1733 b'format',
1733 b'format',
1734 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1734 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1735 )
1735 )
1736 coreconfigitem(
1736 coreconfigitem(
1737 b'progress',
1737 b'progress',
1738 b'refresh',
1738 b'refresh',
1739 default=0.1,
1739 default=0.1,
1740 )
1740 )
1741 coreconfigitem(
1741 coreconfigitem(
1742 b'progress',
1742 b'progress',
1743 b'width',
1743 b'width',
1744 default=dynamicdefault,
1744 default=dynamicdefault,
1745 )
1745 )
1746 coreconfigitem(
1746 coreconfigitem(
1747 b'pull',
1747 b'pull',
1748 b'confirm',
1748 b'confirm',
1749 default=False,
1749 default=False,
1750 )
1750 )
1751 coreconfigitem(
1751 coreconfigitem(
1752 b'push',
1752 b'push',
1753 b'pushvars.server',
1753 b'pushvars.server',
1754 default=False,
1754 default=False,
1755 )
1755 )
1756 coreconfigitem(
1756 coreconfigitem(
1757 b'rewrite',
1757 b'rewrite',
1758 b'backup-bundle',
1758 b'backup-bundle',
1759 default=True,
1759 default=True,
1760 alias=[(b'ui', b'history-editing-backup')],
1760 alias=[(b'ui', b'history-editing-backup')],
1761 )
1761 )
1762 coreconfigitem(
1762 coreconfigitem(
1763 b'rewrite',
1763 b'rewrite',
1764 b'update-timestamp',
1764 b'update-timestamp',
1765 default=False,
1765 default=False,
1766 )
1766 )
1767 coreconfigitem(
1767 coreconfigitem(
1768 b'rewrite',
1768 b'rewrite',
1769 b'empty-successor',
1769 b'empty-successor',
1770 default=b'skip',
1770 default=b'skip',
1771 experimental=True,
1771 experimental=True,
1772 )
1772 )
1773 coreconfigitem(
1773 coreconfigitem(
1774 b'storage',
1774 b'storage',
1775 b'new-repo-backend',
1775 b'new-repo-backend',
1776 default=b'revlogv1',
1776 default=b'revlogv1',
1777 experimental=True,
1777 experimental=True,
1778 )
1778 )
1779 coreconfigitem(
1779 coreconfigitem(
1780 b'storage',
1780 b'storage',
1781 b'revlog.optimize-delta-parent-choice',
1781 b'revlog.optimize-delta-parent-choice',
1782 default=True,
1782 default=True,
1783 alias=[(b'format', b'aggressivemergedeltas')],
1783 alias=[(b'format', b'aggressivemergedeltas')],
1784 )
1784 )
1785 # experimental as long as rust is experimental (or a C version is implemented)
1785 # experimental as long as rust is experimental (or a C version is implemented)
1786 coreconfigitem(
1786 coreconfigitem(
1787 b'storage',
1787 b'storage',
1788 b'revlog.persistent-nodemap.mmap',
1788 b'revlog.persistent-nodemap.mmap',
1789 default=True,
1789 default=True,
1790 experimental=True,
1790 experimental=True,
1791 )
1791 )
1792 # experimental as long as format.use-persistent-nodemap is.
1792 # experimental as long as format.use-persistent-nodemap is.
1793 coreconfigitem(
1793 coreconfigitem(
1794 b'storage', b'revlog.nodemap.mode', default=b'compat', experimental=True
1794 b'storage', b'revlog.nodemap.mode', default=b'compat', experimental=True
1795 )
1795 )
1796 # experimental as long as format.use-persistent-nodemap is.
1796 # experimental as long as format.use-persistent-nodemap is.
1797 coreconfigitem(
1797 coreconfigitem(
1798 b'storage',
1798 b'storage',
1799 b'revlog.persistent-nodemap.slow-path',
1799 b'revlog.persistent-nodemap.slow-path',
1800 default=b"warn",
1800 default=b"abort",
1801 experimental=True,
1801 experimental=True,
1802 )
1802 )
1803
1803
1804 coreconfigitem(
1804 coreconfigitem(
1805 b'storage',
1805 b'storage',
1806 b'revlog.reuse-external-delta',
1806 b'revlog.reuse-external-delta',
1807 default=True,
1807 default=True,
1808 )
1808 )
1809 coreconfigitem(
1809 coreconfigitem(
1810 b'storage',
1810 b'storage',
1811 b'revlog.reuse-external-delta-parent',
1811 b'revlog.reuse-external-delta-parent',
1812 default=None,
1812 default=None,
1813 )
1813 )
1814 coreconfigitem(
1814 coreconfigitem(
1815 b'storage',
1815 b'storage',
1816 b'revlog.zlib.level',
1816 b'revlog.zlib.level',
1817 default=None,
1817 default=None,
1818 )
1818 )
1819 coreconfigitem(
1819 coreconfigitem(
1820 b'storage',
1820 b'storage',
1821 b'revlog.zstd.level',
1821 b'revlog.zstd.level',
1822 default=None,
1822 default=None,
1823 )
1823 )
1824 coreconfigitem(
1824 coreconfigitem(
1825 b'server',
1825 b'server',
1826 b'bookmarks-pushkey-compat',
1826 b'bookmarks-pushkey-compat',
1827 default=True,
1827 default=True,
1828 )
1828 )
1829 coreconfigitem(
1829 coreconfigitem(
1830 b'server',
1830 b'server',
1831 b'bundle1',
1831 b'bundle1',
1832 default=True,
1832 default=True,
1833 )
1833 )
1834 coreconfigitem(
1834 coreconfigitem(
1835 b'server',
1835 b'server',
1836 b'bundle1gd',
1836 b'bundle1gd',
1837 default=None,
1837 default=None,
1838 )
1838 )
1839 coreconfigitem(
1839 coreconfigitem(
1840 b'server',
1840 b'server',
1841 b'bundle1.pull',
1841 b'bundle1.pull',
1842 default=None,
1842 default=None,
1843 )
1843 )
1844 coreconfigitem(
1844 coreconfigitem(
1845 b'server',
1845 b'server',
1846 b'bundle1gd.pull',
1846 b'bundle1gd.pull',
1847 default=None,
1847 default=None,
1848 )
1848 )
1849 coreconfigitem(
1849 coreconfigitem(
1850 b'server',
1850 b'server',
1851 b'bundle1.push',
1851 b'bundle1.push',
1852 default=None,
1852 default=None,
1853 )
1853 )
1854 coreconfigitem(
1854 coreconfigitem(
1855 b'server',
1855 b'server',
1856 b'bundle1gd.push',
1856 b'bundle1gd.push',
1857 default=None,
1857 default=None,
1858 )
1858 )
1859 coreconfigitem(
1859 coreconfigitem(
1860 b'server',
1860 b'server',
1861 b'bundle2.stream',
1861 b'bundle2.stream',
1862 default=True,
1862 default=True,
1863 alias=[(b'experimental', b'bundle2.stream')],
1863 alias=[(b'experimental', b'bundle2.stream')],
1864 )
1864 )
1865 coreconfigitem(
1865 coreconfigitem(
1866 b'server',
1866 b'server',
1867 b'compressionengines',
1867 b'compressionengines',
1868 default=list,
1868 default=list,
1869 )
1869 )
1870 coreconfigitem(
1870 coreconfigitem(
1871 b'server',
1871 b'server',
1872 b'concurrent-push-mode',
1872 b'concurrent-push-mode',
1873 default=b'check-related',
1873 default=b'check-related',
1874 )
1874 )
1875 coreconfigitem(
1875 coreconfigitem(
1876 b'server',
1876 b'server',
1877 b'disablefullbundle',
1877 b'disablefullbundle',
1878 default=False,
1878 default=False,
1879 )
1879 )
1880 coreconfigitem(
1880 coreconfigitem(
1881 b'server',
1881 b'server',
1882 b'maxhttpheaderlen',
1882 b'maxhttpheaderlen',
1883 default=1024,
1883 default=1024,
1884 )
1884 )
1885 coreconfigitem(
1885 coreconfigitem(
1886 b'server',
1886 b'server',
1887 b'pullbundle',
1887 b'pullbundle',
1888 default=False,
1888 default=False,
1889 )
1889 )
1890 coreconfigitem(
1890 coreconfigitem(
1891 b'server',
1891 b'server',
1892 b'preferuncompressed',
1892 b'preferuncompressed',
1893 default=False,
1893 default=False,
1894 )
1894 )
1895 coreconfigitem(
1895 coreconfigitem(
1896 b'server',
1896 b'server',
1897 b'streamunbundle',
1897 b'streamunbundle',
1898 default=False,
1898 default=False,
1899 )
1899 )
1900 coreconfigitem(
1900 coreconfigitem(
1901 b'server',
1901 b'server',
1902 b'uncompressed',
1902 b'uncompressed',
1903 default=True,
1903 default=True,
1904 )
1904 )
1905 coreconfigitem(
1905 coreconfigitem(
1906 b'server',
1906 b'server',
1907 b'uncompressedallowsecret',
1907 b'uncompressedallowsecret',
1908 default=False,
1908 default=False,
1909 )
1909 )
1910 coreconfigitem(
1910 coreconfigitem(
1911 b'server',
1911 b'server',
1912 b'view',
1912 b'view',
1913 default=b'served',
1913 default=b'served',
1914 )
1914 )
1915 coreconfigitem(
1915 coreconfigitem(
1916 b'server',
1916 b'server',
1917 b'validate',
1917 b'validate',
1918 default=False,
1918 default=False,
1919 )
1919 )
1920 coreconfigitem(
1920 coreconfigitem(
1921 b'server',
1921 b'server',
1922 b'zliblevel',
1922 b'zliblevel',
1923 default=-1,
1923 default=-1,
1924 )
1924 )
1925 coreconfigitem(
1925 coreconfigitem(
1926 b'server',
1926 b'server',
1927 b'zstdlevel',
1927 b'zstdlevel',
1928 default=3,
1928 default=3,
1929 )
1929 )
1930 coreconfigitem(
1930 coreconfigitem(
1931 b'share',
1931 b'share',
1932 b'pool',
1932 b'pool',
1933 default=None,
1933 default=None,
1934 )
1934 )
1935 coreconfigitem(
1935 coreconfigitem(
1936 b'share',
1936 b'share',
1937 b'poolnaming',
1937 b'poolnaming',
1938 default=b'identity',
1938 default=b'identity',
1939 )
1939 )
1940 coreconfigitem(
1940 coreconfigitem(
1941 b'shelve',
1941 b'shelve',
1942 b'maxbackups',
1942 b'maxbackups',
1943 default=10,
1943 default=10,
1944 )
1944 )
1945 coreconfigitem(
1945 coreconfigitem(
1946 b'smtp',
1946 b'smtp',
1947 b'host',
1947 b'host',
1948 default=None,
1948 default=None,
1949 )
1949 )
1950 coreconfigitem(
1950 coreconfigitem(
1951 b'smtp',
1951 b'smtp',
1952 b'local_hostname',
1952 b'local_hostname',
1953 default=None,
1953 default=None,
1954 )
1954 )
1955 coreconfigitem(
1955 coreconfigitem(
1956 b'smtp',
1956 b'smtp',
1957 b'password',
1957 b'password',
1958 default=None,
1958 default=None,
1959 )
1959 )
1960 coreconfigitem(
1960 coreconfigitem(
1961 b'smtp',
1961 b'smtp',
1962 b'port',
1962 b'port',
1963 default=dynamicdefault,
1963 default=dynamicdefault,
1964 )
1964 )
1965 coreconfigitem(
1965 coreconfigitem(
1966 b'smtp',
1966 b'smtp',
1967 b'tls',
1967 b'tls',
1968 default=b'none',
1968 default=b'none',
1969 )
1969 )
1970 coreconfigitem(
1970 coreconfigitem(
1971 b'smtp',
1971 b'smtp',
1972 b'username',
1972 b'username',
1973 default=None,
1973 default=None,
1974 )
1974 )
1975 coreconfigitem(
1975 coreconfigitem(
1976 b'sparse',
1976 b'sparse',
1977 b'missingwarning',
1977 b'missingwarning',
1978 default=True,
1978 default=True,
1979 experimental=True,
1979 experimental=True,
1980 )
1980 )
1981 coreconfigitem(
1981 coreconfigitem(
1982 b'subrepos',
1982 b'subrepos',
1983 b'allowed',
1983 b'allowed',
1984 default=dynamicdefault, # to make backporting simpler
1984 default=dynamicdefault, # to make backporting simpler
1985 )
1985 )
1986 coreconfigitem(
1986 coreconfigitem(
1987 b'subrepos',
1987 b'subrepos',
1988 b'hg:allowed',
1988 b'hg:allowed',
1989 default=dynamicdefault,
1989 default=dynamicdefault,
1990 )
1990 )
1991 coreconfigitem(
1991 coreconfigitem(
1992 b'subrepos',
1992 b'subrepos',
1993 b'git:allowed',
1993 b'git:allowed',
1994 default=dynamicdefault,
1994 default=dynamicdefault,
1995 )
1995 )
1996 coreconfigitem(
1996 coreconfigitem(
1997 b'subrepos',
1997 b'subrepos',
1998 b'svn:allowed',
1998 b'svn:allowed',
1999 default=dynamicdefault,
1999 default=dynamicdefault,
2000 )
2000 )
2001 coreconfigitem(
2001 coreconfigitem(
2002 b'templates',
2002 b'templates',
2003 b'.*',
2003 b'.*',
2004 default=None,
2004 default=None,
2005 generic=True,
2005 generic=True,
2006 )
2006 )
2007 coreconfigitem(
2007 coreconfigitem(
2008 b'templateconfig',
2008 b'templateconfig',
2009 b'.*',
2009 b'.*',
2010 default=dynamicdefault,
2010 default=dynamicdefault,
2011 generic=True,
2011 generic=True,
2012 )
2012 )
2013 coreconfigitem(
2013 coreconfigitem(
2014 b'trusted',
2014 b'trusted',
2015 b'groups',
2015 b'groups',
2016 default=list,
2016 default=list,
2017 )
2017 )
2018 coreconfigitem(
2018 coreconfigitem(
2019 b'trusted',
2019 b'trusted',
2020 b'users',
2020 b'users',
2021 default=list,
2021 default=list,
2022 )
2022 )
2023 coreconfigitem(
2023 coreconfigitem(
2024 b'ui',
2024 b'ui',
2025 b'_usedassubrepo',
2025 b'_usedassubrepo',
2026 default=False,
2026 default=False,
2027 )
2027 )
2028 coreconfigitem(
2028 coreconfigitem(
2029 b'ui',
2029 b'ui',
2030 b'allowemptycommit',
2030 b'allowemptycommit',
2031 default=False,
2031 default=False,
2032 )
2032 )
2033 coreconfigitem(
2033 coreconfigitem(
2034 b'ui',
2034 b'ui',
2035 b'archivemeta',
2035 b'archivemeta',
2036 default=True,
2036 default=True,
2037 )
2037 )
2038 coreconfigitem(
2038 coreconfigitem(
2039 b'ui',
2039 b'ui',
2040 b'askusername',
2040 b'askusername',
2041 default=False,
2041 default=False,
2042 )
2042 )
2043 coreconfigitem(
2043 coreconfigitem(
2044 b'ui',
2044 b'ui',
2045 b'available-memory',
2045 b'available-memory',
2046 default=None,
2046 default=None,
2047 )
2047 )
2048
2048
2049 coreconfigitem(
2049 coreconfigitem(
2050 b'ui',
2050 b'ui',
2051 b'clonebundlefallback',
2051 b'clonebundlefallback',
2052 default=False,
2052 default=False,
2053 )
2053 )
2054 coreconfigitem(
2054 coreconfigitem(
2055 b'ui',
2055 b'ui',
2056 b'clonebundleprefers',
2056 b'clonebundleprefers',
2057 default=list,
2057 default=list,
2058 )
2058 )
2059 coreconfigitem(
2059 coreconfigitem(
2060 b'ui',
2060 b'ui',
2061 b'clonebundles',
2061 b'clonebundles',
2062 default=True,
2062 default=True,
2063 )
2063 )
2064 coreconfigitem(
2064 coreconfigitem(
2065 b'ui',
2065 b'ui',
2066 b'color',
2066 b'color',
2067 default=b'auto',
2067 default=b'auto',
2068 )
2068 )
2069 coreconfigitem(
2069 coreconfigitem(
2070 b'ui',
2070 b'ui',
2071 b'commitsubrepos',
2071 b'commitsubrepos',
2072 default=False,
2072 default=False,
2073 )
2073 )
2074 coreconfigitem(
2074 coreconfigitem(
2075 b'ui',
2075 b'ui',
2076 b'debug',
2076 b'debug',
2077 default=False,
2077 default=False,
2078 )
2078 )
2079 coreconfigitem(
2079 coreconfigitem(
2080 b'ui',
2080 b'ui',
2081 b'debugger',
2081 b'debugger',
2082 default=None,
2082 default=None,
2083 )
2083 )
2084 coreconfigitem(
2084 coreconfigitem(
2085 b'ui',
2085 b'ui',
2086 b'editor',
2086 b'editor',
2087 default=dynamicdefault,
2087 default=dynamicdefault,
2088 )
2088 )
2089 coreconfigitem(
2089 coreconfigitem(
2090 b'ui',
2090 b'ui',
2091 b'detailed-exit-code',
2091 b'detailed-exit-code',
2092 default=False,
2092 default=False,
2093 experimental=True,
2093 experimental=True,
2094 )
2094 )
2095 coreconfigitem(
2095 coreconfigitem(
2096 b'ui',
2096 b'ui',
2097 b'fallbackencoding',
2097 b'fallbackencoding',
2098 default=None,
2098 default=None,
2099 )
2099 )
2100 coreconfigitem(
2100 coreconfigitem(
2101 b'ui',
2101 b'ui',
2102 b'forcecwd',
2102 b'forcecwd',
2103 default=None,
2103 default=None,
2104 )
2104 )
2105 coreconfigitem(
2105 coreconfigitem(
2106 b'ui',
2106 b'ui',
2107 b'forcemerge',
2107 b'forcemerge',
2108 default=None,
2108 default=None,
2109 )
2109 )
2110 coreconfigitem(
2110 coreconfigitem(
2111 b'ui',
2111 b'ui',
2112 b'formatdebug',
2112 b'formatdebug',
2113 default=False,
2113 default=False,
2114 )
2114 )
2115 coreconfigitem(
2115 coreconfigitem(
2116 b'ui',
2116 b'ui',
2117 b'formatjson',
2117 b'formatjson',
2118 default=False,
2118 default=False,
2119 )
2119 )
2120 coreconfigitem(
2120 coreconfigitem(
2121 b'ui',
2121 b'ui',
2122 b'formatted',
2122 b'formatted',
2123 default=None,
2123 default=None,
2124 )
2124 )
2125 coreconfigitem(
2125 coreconfigitem(
2126 b'ui',
2126 b'ui',
2127 b'interactive',
2127 b'interactive',
2128 default=None,
2128 default=None,
2129 )
2129 )
2130 coreconfigitem(
2130 coreconfigitem(
2131 b'ui',
2131 b'ui',
2132 b'interface',
2132 b'interface',
2133 default=None,
2133 default=None,
2134 )
2134 )
2135 coreconfigitem(
2135 coreconfigitem(
2136 b'ui',
2136 b'ui',
2137 b'interface.chunkselector',
2137 b'interface.chunkselector',
2138 default=None,
2138 default=None,
2139 )
2139 )
2140 coreconfigitem(
2140 coreconfigitem(
2141 b'ui',
2141 b'ui',
2142 b'large-file-limit',
2142 b'large-file-limit',
2143 default=10000000,
2143 default=10000000,
2144 )
2144 )
2145 coreconfigitem(
2145 coreconfigitem(
2146 b'ui',
2146 b'ui',
2147 b'logblockedtimes',
2147 b'logblockedtimes',
2148 default=False,
2148 default=False,
2149 )
2149 )
2150 coreconfigitem(
2150 coreconfigitem(
2151 b'ui',
2151 b'ui',
2152 b'merge',
2152 b'merge',
2153 default=None,
2153 default=None,
2154 )
2154 )
2155 coreconfigitem(
2155 coreconfigitem(
2156 b'ui',
2156 b'ui',
2157 b'mergemarkers',
2157 b'mergemarkers',
2158 default=b'basic',
2158 default=b'basic',
2159 )
2159 )
2160 coreconfigitem(
2160 coreconfigitem(
2161 b'ui',
2161 b'ui',
2162 b'message-output',
2162 b'message-output',
2163 default=b'stdio',
2163 default=b'stdio',
2164 )
2164 )
2165 coreconfigitem(
2165 coreconfigitem(
2166 b'ui',
2166 b'ui',
2167 b'nontty',
2167 b'nontty',
2168 default=False,
2168 default=False,
2169 )
2169 )
2170 coreconfigitem(
2170 coreconfigitem(
2171 b'ui',
2171 b'ui',
2172 b'origbackuppath',
2172 b'origbackuppath',
2173 default=None,
2173 default=None,
2174 )
2174 )
2175 coreconfigitem(
2175 coreconfigitem(
2176 b'ui',
2176 b'ui',
2177 b'paginate',
2177 b'paginate',
2178 default=True,
2178 default=True,
2179 )
2179 )
2180 coreconfigitem(
2180 coreconfigitem(
2181 b'ui',
2181 b'ui',
2182 b'patch',
2182 b'patch',
2183 default=None,
2183 default=None,
2184 )
2184 )
2185 coreconfigitem(
2185 coreconfigitem(
2186 b'ui',
2186 b'ui',
2187 b'portablefilenames',
2187 b'portablefilenames',
2188 default=b'warn',
2188 default=b'warn',
2189 )
2189 )
2190 coreconfigitem(
2190 coreconfigitem(
2191 b'ui',
2191 b'ui',
2192 b'promptecho',
2192 b'promptecho',
2193 default=False,
2193 default=False,
2194 )
2194 )
2195 coreconfigitem(
2195 coreconfigitem(
2196 b'ui',
2196 b'ui',
2197 b'quiet',
2197 b'quiet',
2198 default=False,
2198 default=False,
2199 )
2199 )
2200 coreconfigitem(
2200 coreconfigitem(
2201 b'ui',
2201 b'ui',
2202 b'quietbookmarkmove',
2202 b'quietbookmarkmove',
2203 default=False,
2203 default=False,
2204 )
2204 )
2205 coreconfigitem(
2205 coreconfigitem(
2206 b'ui',
2206 b'ui',
2207 b'relative-paths',
2207 b'relative-paths',
2208 default=b'legacy',
2208 default=b'legacy',
2209 )
2209 )
2210 coreconfigitem(
2210 coreconfigitem(
2211 b'ui',
2211 b'ui',
2212 b'remotecmd',
2212 b'remotecmd',
2213 default=b'hg',
2213 default=b'hg',
2214 )
2214 )
2215 coreconfigitem(
2215 coreconfigitem(
2216 b'ui',
2216 b'ui',
2217 b'report_untrusted',
2217 b'report_untrusted',
2218 default=True,
2218 default=True,
2219 )
2219 )
2220 coreconfigitem(
2220 coreconfigitem(
2221 b'ui',
2221 b'ui',
2222 b'rollback',
2222 b'rollback',
2223 default=True,
2223 default=True,
2224 )
2224 )
2225 coreconfigitem(
2225 coreconfigitem(
2226 b'ui',
2226 b'ui',
2227 b'signal-safe-lock',
2227 b'signal-safe-lock',
2228 default=True,
2228 default=True,
2229 )
2229 )
2230 coreconfigitem(
2230 coreconfigitem(
2231 b'ui',
2231 b'ui',
2232 b'slash',
2232 b'slash',
2233 default=False,
2233 default=False,
2234 )
2234 )
2235 coreconfigitem(
2235 coreconfigitem(
2236 b'ui',
2236 b'ui',
2237 b'ssh',
2237 b'ssh',
2238 default=b'ssh',
2238 default=b'ssh',
2239 )
2239 )
2240 coreconfigitem(
2240 coreconfigitem(
2241 b'ui',
2241 b'ui',
2242 b'ssherrorhint',
2242 b'ssherrorhint',
2243 default=None,
2243 default=None,
2244 )
2244 )
2245 coreconfigitem(
2245 coreconfigitem(
2246 b'ui',
2246 b'ui',
2247 b'statuscopies',
2247 b'statuscopies',
2248 default=False,
2248 default=False,
2249 )
2249 )
2250 coreconfigitem(
2250 coreconfigitem(
2251 b'ui',
2251 b'ui',
2252 b'strict',
2252 b'strict',
2253 default=False,
2253 default=False,
2254 )
2254 )
2255 coreconfigitem(
2255 coreconfigitem(
2256 b'ui',
2256 b'ui',
2257 b'style',
2257 b'style',
2258 default=b'',
2258 default=b'',
2259 )
2259 )
2260 coreconfigitem(
2260 coreconfigitem(
2261 b'ui',
2261 b'ui',
2262 b'supportcontact',
2262 b'supportcontact',
2263 default=None,
2263 default=None,
2264 )
2264 )
2265 coreconfigitem(
2265 coreconfigitem(
2266 b'ui',
2266 b'ui',
2267 b'textwidth',
2267 b'textwidth',
2268 default=78,
2268 default=78,
2269 )
2269 )
2270 coreconfigitem(
2270 coreconfigitem(
2271 b'ui',
2271 b'ui',
2272 b'timeout',
2272 b'timeout',
2273 default=b'600',
2273 default=b'600',
2274 )
2274 )
2275 coreconfigitem(
2275 coreconfigitem(
2276 b'ui',
2276 b'ui',
2277 b'timeout.warn',
2277 b'timeout.warn',
2278 default=0,
2278 default=0,
2279 )
2279 )
2280 coreconfigitem(
2280 coreconfigitem(
2281 b'ui',
2281 b'ui',
2282 b'timestamp-output',
2282 b'timestamp-output',
2283 default=False,
2283 default=False,
2284 )
2284 )
2285 coreconfigitem(
2285 coreconfigitem(
2286 b'ui',
2286 b'ui',
2287 b'traceback',
2287 b'traceback',
2288 default=False,
2288 default=False,
2289 )
2289 )
2290 coreconfigitem(
2290 coreconfigitem(
2291 b'ui',
2291 b'ui',
2292 b'tweakdefaults',
2292 b'tweakdefaults',
2293 default=False,
2293 default=False,
2294 )
2294 )
2295 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2295 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2296 coreconfigitem(
2296 coreconfigitem(
2297 b'ui',
2297 b'ui',
2298 b'verbose',
2298 b'verbose',
2299 default=False,
2299 default=False,
2300 )
2300 )
2301 coreconfigitem(
2301 coreconfigitem(
2302 b'verify',
2302 b'verify',
2303 b'skipflags',
2303 b'skipflags',
2304 default=None,
2304 default=None,
2305 )
2305 )
2306 coreconfigitem(
2306 coreconfigitem(
2307 b'web',
2307 b'web',
2308 b'allowbz2',
2308 b'allowbz2',
2309 default=False,
2309 default=False,
2310 )
2310 )
2311 coreconfigitem(
2311 coreconfigitem(
2312 b'web',
2312 b'web',
2313 b'allowgz',
2313 b'allowgz',
2314 default=False,
2314 default=False,
2315 )
2315 )
2316 coreconfigitem(
2316 coreconfigitem(
2317 b'web',
2317 b'web',
2318 b'allow-pull',
2318 b'allow-pull',
2319 alias=[(b'web', b'allowpull')],
2319 alias=[(b'web', b'allowpull')],
2320 default=True,
2320 default=True,
2321 )
2321 )
2322 coreconfigitem(
2322 coreconfigitem(
2323 b'web',
2323 b'web',
2324 b'allow-push',
2324 b'allow-push',
2325 alias=[(b'web', b'allow_push')],
2325 alias=[(b'web', b'allow_push')],
2326 default=list,
2326 default=list,
2327 )
2327 )
2328 coreconfigitem(
2328 coreconfigitem(
2329 b'web',
2329 b'web',
2330 b'allowzip',
2330 b'allowzip',
2331 default=False,
2331 default=False,
2332 )
2332 )
2333 coreconfigitem(
2333 coreconfigitem(
2334 b'web',
2334 b'web',
2335 b'archivesubrepos',
2335 b'archivesubrepos',
2336 default=False,
2336 default=False,
2337 )
2337 )
2338 coreconfigitem(
2338 coreconfigitem(
2339 b'web',
2339 b'web',
2340 b'cache',
2340 b'cache',
2341 default=True,
2341 default=True,
2342 )
2342 )
2343 coreconfigitem(
2343 coreconfigitem(
2344 b'web',
2344 b'web',
2345 b'comparisoncontext',
2345 b'comparisoncontext',
2346 default=5,
2346 default=5,
2347 )
2347 )
2348 coreconfigitem(
2348 coreconfigitem(
2349 b'web',
2349 b'web',
2350 b'contact',
2350 b'contact',
2351 default=None,
2351 default=None,
2352 )
2352 )
2353 coreconfigitem(
2353 coreconfigitem(
2354 b'web',
2354 b'web',
2355 b'deny_push',
2355 b'deny_push',
2356 default=list,
2356 default=list,
2357 )
2357 )
2358 coreconfigitem(
2358 coreconfigitem(
2359 b'web',
2359 b'web',
2360 b'guessmime',
2360 b'guessmime',
2361 default=False,
2361 default=False,
2362 )
2362 )
2363 coreconfigitem(
2363 coreconfigitem(
2364 b'web',
2364 b'web',
2365 b'hidden',
2365 b'hidden',
2366 default=False,
2366 default=False,
2367 )
2367 )
2368 coreconfigitem(
2368 coreconfigitem(
2369 b'web',
2369 b'web',
2370 b'labels',
2370 b'labels',
2371 default=list,
2371 default=list,
2372 )
2372 )
2373 coreconfigitem(
2373 coreconfigitem(
2374 b'web',
2374 b'web',
2375 b'logoimg',
2375 b'logoimg',
2376 default=b'hglogo.png',
2376 default=b'hglogo.png',
2377 )
2377 )
2378 coreconfigitem(
2378 coreconfigitem(
2379 b'web',
2379 b'web',
2380 b'logourl',
2380 b'logourl',
2381 default=b'https://mercurial-scm.org/',
2381 default=b'https://mercurial-scm.org/',
2382 )
2382 )
2383 coreconfigitem(
2383 coreconfigitem(
2384 b'web',
2384 b'web',
2385 b'accesslog',
2385 b'accesslog',
2386 default=b'-',
2386 default=b'-',
2387 )
2387 )
2388 coreconfigitem(
2388 coreconfigitem(
2389 b'web',
2389 b'web',
2390 b'address',
2390 b'address',
2391 default=b'',
2391 default=b'',
2392 )
2392 )
2393 coreconfigitem(
2393 coreconfigitem(
2394 b'web',
2394 b'web',
2395 b'allow-archive',
2395 b'allow-archive',
2396 alias=[(b'web', b'allow_archive')],
2396 alias=[(b'web', b'allow_archive')],
2397 default=list,
2397 default=list,
2398 )
2398 )
2399 coreconfigitem(
2399 coreconfigitem(
2400 b'web',
2400 b'web',
2401 b'allow_read',
2401 b'allow_read',
2402 default=list,
2402 default=list,
2403 )
2403 )
2404 coreconfigitem(
2404 coreconfigitem(
2405 b'web',
2405 b'web',
2406 b'baseurl',
2406 b'baseurl',
2407 default=None,
2407 default=None,
2408 )
2408 )
2409 coreconfigitem(
2409 coreconfigitem(
2410 b'web',
2410 b'web',
2411 b'cacerts',
2411 b'cacerts',
2412 default=None,
2412 default=None,
2413 )
2413 )
2414 coreconfigitem(
2414 coreconfigitem(
2415 b'web',
2415 b'web',
2416 b'certificate',
2416 b'certificate',
2417 default=None,
2417 default=None,
2418 )
2418 )
2419 coreconfigitem(
2419 coreconfigitem(
2420 b'web',
2420 b'web',
2421 b'collapse',
2421 b'collapse',
2422 default=False,
2422 default=False,
2423 )
2423 )
2424 coreconfigitem(
2424 coreconfigitem(
2425 b'web',
2425 b'web',
2426 b'csp',
2426 b'csp',
2427 default=None,
2427 default=None,
2428 )
2428 )
2429 coreconfigitem(
2429 coreconfigitem(
2430 b'web',
2430 b'web',
2431 b'deny_read',
2431 b'deny_read',
2432 default=list,
2432 default=list,
2433 )
2433 )
2434 coreconfigitem(
2434 coreconfigitem(
2435 b'web',
2435 b'web',
2436 b'descend',
2436 b'descend',
2437 default=True,
2437 default=True,
2438 )
2438 )
2439 coreconfigitem(
2439 coreconfigitem(
2440 b'web',
2440 b'web',
2441 b'description',
2441 b'description',
2442 default=b"",
2442 default=b"",
2443 )
2443 )
2444 coreconfigitem(
2444 coreconfigitem(
2445 b'web',
2445 b'web',
2446 b'encoding',
2446 b'encoding',
2447 default=lambda: encoding.encoding,
2447 default=lambda: encoding.encoding,
2448 )
2448 )
2449 coreconfigitem(
2449 coreconfigitem(
2450 b'web',
2450 b'web',
2451 b'errorlog',
2451 b'errorlog',
2452 default=b'-',
2452 default=b'-',
2453 )
2453 )
2454 coreconfigitem(
2454 coreconfigitem(
2455 b'web',
2455 b'web',
2456 b'ipv6',
2456 b'ipv6',
2457 default=False,
2457 default=False,
2458 )
2458 )
2459 coreconfigitem(
2459 coreconfigitem(
2460 b'web',
2460 b'web',
2461 b'maxchanges',
2461 b'maxchanges',
2462 default=10,
2462 default=10,
2463 )
2463 )
2464 coreconfigitem(
2464 coreconfigitem(
2465 b'web',
2465 b'web',
2466 b'maxfiles',
2466 b'maxfiles',
2467 default=10,
2467 default=10,
2468 )
2468 )
2469 coreconfigitem(
2469 coreconfigitem(
2470 b'web',
2470 b'web',
2471 b'maxshortchanges',
2471 b'maxshortchanges',
2472 default=60,
2472 default=60,
2473 )
2473 )
2474 coreconfigitem(
2474 coreconfigitem(
2475 b'web',
2475 b'web',
2476 b'motd',
2476 b'motd',
2477 default=b'',
2477 default=b'',
2478 )
2478 )
2479 coreconfigitem(
2479 coreconfigitem(
2480 b'web',
2480 b'web',
2481 b'name',
2481 b'name',
2482 default=dynamicdefault,
2482 default=dynamicdefault,
2483 )
2483 )
2484 coreconfigitem(
2484 coreconfigitem(
2485 b'web',
2485 b'web',
2486 b'port',
2486 b'port',
2487 default=8000,
2487 default=8000,
2488 )
2488 )
2489 coreconfigitem(
2489 coreconfigitem(
2490 b'web',
2490 b'web',
2491 b'prefix',
2491 b'prefix',
2492 default=b'',
2492 default=b'',
2493 )
2493 )
2494 coreconfigitem(
2494 coreconfigitem(
2495 b'web',
2495 b'web',
2496 b'push_ssl',
2496 b'push_ssl',
2497 default=True,
2497 default=True,
2498 )
2498 )
2499 coreconfigitem(
2499 coreconfigitem(
2500 b'web',
2500 b'web',
2501 b'refreshinterval',
2501 b'refreshinterval',
2502 default=20,
2502 default=20,
2503 )
2503 )
2504 coreconfigitem(
2504 coreconfigitem(
2505 b'web',
2505 b'web',
2506 b'server-header',
2506 b'server-header',
2507 default=None,
2507 default=None,
2508 )
2508 )
2509 coreconfigitem(
2509 coreconfigitem(
2510 b'web',
2510 b'web',
2511 b'static',
2511 b'static',
2512 default=None,
2512 default=None,
2513 )
2513 )
2514 coreconfigitem(
2514 coreconfigitem(
2515 b'web',
2515 b'web',
2516 b'staticurl',
2516 b'staticurl',
2517 default=None,
2517 default=None,
2518 )
2518 )
2519 coreconfigitem(
2519 coreconfigitem(
2520 b'web',
2520 b'web',
2521 b'stripes',
2521 b'stripes',
2522 default=1,
2522 default=1,
2523 )
2523 )
2524 coreconfigitem(
2524 coreconfigitem(
2525 b'web',
2525 b'web',
2526 b'style',
2526 b'style',
2527 default=b'paper',
2527 default=b'paper',
2528 )
2528 )
2529 coreconfigitem(
2529 coreconfigitem(
2530 b'web',
2530 b'web',
2531 b'templates',
2531 b'templates',
2532 default=None,
2532 default=None,
2533 )
2533 )
2534 coreconfigitem(
2534 coreconfigitem(
2535 b'web',
2535 b'web',
2536 b'view',
2536 b'view',
2537 default=b'served',
2537 default=b'served',
2538 experimental=True,
2538 experimental=True,
2539 )
2539 )
2540 coreconfigitem(
2540 coreconfigitem(
2541 b'worker',
2541 b'worker',
2542 b'backgroundclose',
2542 b'backgroundclose',
2543 default=dynamicdefault,
2543 default=dynamicdefault,
2544 )
2544 )
2545 # Windows defaults to a limit of 512 open files. A buffer of 128
2545 # Windows defaults to a limit of 512 open files. A buffer of 128
2546 # should give us enough headway.
2546 # should give us enough headway.
2547 coreconfigitem(
2547 coreconfigitem(
2548 b'worker',
2548 b'worker',
2549 b'backgroundclosemaxqueue',
2549 b'backgroundclosemaxqueue',
2550 default=384,
2550 default=384,
2551 )
2551 )
2552 coreconfigitem(
2552 coreconfigitem(
2553 b'worker',
2553 b'worker',
2554 b'backgroundcloseminfilecount',
2554 b'backgroundcloseminfilecount',
2555 default=2048,
2555 default=2048,
2556 )
2556 )
2557 coreconfigitem(
2557 coreconfigitem(
2558 b'worker',
2558 b'worker',
2559 b'backgroundclosethreadcount',
2559 b'backgroundclosethreadcount',
2560 default=4,
2560 default=4,
2561 )
2561 )
2562 coreconfigitem(
2562 coreconfigitem(
2563 b'worker',
2563 b'worker',
2564 b'enabled',
2564 b'enabled',
2565 default=True,
2565 default=True,
2566 )
2566 )
2567 coreconfigitem(
2567 coreconfigitem(
2568 b'worker',
2568 b'worker',
2569 b'numcpus',
2569 b'numcpus',
2570 default=None,
2570 default=None,
2571 )
2571 )
2572
2572
2573 # Rebase related configuration moved to core because other extension are doing
2573 # Rebase related configuration moved to core because other extension are doing
2574 # strange things. For example, shelve import the extensions to reuse some bit
2574 # strange things. For example, shelve import the extensions to reuse some bit
2575 # without formally loading it.
2575 # without formally loading it.
2576 coreconfigitem(
2576 coreconfigitem(
2577 b'commands',
2577 b'commands',
2578 b'rebase.requiredest',
2578 b'rebase.requiredest',
2579 default=False,
2579 default=False,
2580 )
2580 )
2581 coreconfigitem(
2581 coreconfigitem(
2582 b'experimental',
2582 b'experimental',
2583 b'rebaseskipobsolete',
2583 b'rebaseskipobsolete',
2584 default=True,
2584 default=True,
2585 )
2585 )
2586 coreconfigitem(
2586 coreconfigitem(
2587 b'rebase',
2587 b'rebase',
2588 b'singletransaction',
2588 b'singletransaction',
2589 default=False,
2589 default=False,
2590 )
2590 )
2591 coreconfigitem(
2591 coreconfigitem(
2592 b'rebase',
2592 b'rebase',
2593 b'experimental.inmemory',
2593 b'experimental.inmemory',
2594 default=False,
2594 default=False,
2595 )
2595 )
@@ -1,2986 +1,2988 b''
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 Troubleshooting
4 Troubleshooting
5 ===============
5 ===============
6
6
7 If you're having problems with your configuration,
7 If you're having problems with your configuration,
8 :hg:`config --debug` can help you understand what is introducing
8 :hg:`config --debug` can help you understand what is introducing
9 a setting into your environment.
9 a setting into your environment.
10
10
11 See :hg:`help config.syntax` and :hg:`help config.files`
11 See :hg:`help config.syntax` and :hg:`help config.files`
12 for information about how and where to override things.
12 for information about how and where to override things.
13
13
14 Structure
14 Structure
15 =========
15 =========
16
16
17 The configuration files use a simple ini-file format. A configuration
17 The configuration files use a simple ini-file format. A configuration
18 file consists of sections, led by a ``[section]`` header and followed
18 file consists of sections, led by a ``[section]`` header and followed
19 by ``name = value`` entries::
19 by ``name = value`` entries::
20
20
21 [ui]
21 [ui]
22 username = Firstname Lastname <firstname.lastname@example.net>
22 username = Firstname Lastname <firstname.lastname@example.net>
23 verbose = True
23 verbose = True
24
24
25 The above entries will be referred to as ``ui.username`` and
25 The above entries will be referred to as ``ui.username`` and
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27
27
28 Files
28 Files
29 =====
29 =====
30
30
31 Mercurial reads configuration data from several files, if they exist.
31 Mercurial reads configuration data from several files, if they exist.
32 These files do not exist by default and you will have to create the
32 These files do not exist by default and you will have to create the
33 appropriate configuration files yourself:
33 appropriate configuration files yourself:
34
34
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36
36
37 Global configuration like the username setting is typically put into:
37 Global configuration like the username setting is typically put into:
38
38
39 .. container:: windows
39 .. container:: windows
40
40
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42
42
43 .. container:: unix.plan9
43 .. container:: unix.plan9
44
44
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46
46
47 The names of these files depend on the system on which Mercurial is
47 The names of these files depend on the system on which Mercurial is
48 installed. ``*.rc`` files from a single directory are read in
48 installed. ``*.rc`` files from a single directory are read in
49 alphabetical order, later ones overriding earlier ones. Where multiple
49 alphabetical order, later ones overriding earlier ones. Where multiple
50 paths are given below, settings from earlier paths override later
50 paths are given below, settings from earlier paths override later
51 ones.
51 ones.
52
52
53 .. container:: verbose.unix
53 .. container:: verbose.unix
54
54
55 On Unix, the following files are consulted:
55 On Unix, the following files are consulted:
56
56
57 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
57 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
58 - ``<repo>/.hg/hgrc`` (per-repository)
58 - ``<repo>/.hg/hgrc`` (per-repository)
59 - ``$HOME/.hgrc`` (per-user)
59 - ``$HOME/.hgrc`` (per-user)
60 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
61 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
62 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
63 - ``/etc/mercurial/hgrc`` (per-system)
63 - ``/etc/mercurial/hgrc`` (per-system)
64 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
65 - ``<internal>/*.rc`` (defaults)
65 - ``<internal>/*.rc`` (defaults)
66
66
67 .. container:: verbose.windows
67 .. container:: verbose.windows
68
68
69 On Windows, the following files are consulted:
69 On Windows, the following files are consulted:
70
70
71 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
71 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
72 - ``<repo>/.hg/hgrc`` (per-repository)
72 - ``<repo>/.hg/hgrc`` (per-repository)
73 - ``%USERPROFILE%\.hgrc`` (per-user)
73 - ``%USERPROFILE%\.hgrc`` (per-user)
74 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
74 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
75 - ``%HOME%\.hgrc`` (per-user)
75 - ``%HOME%\.hgrc`` (per-user)
76 - ``%HOME%\Mercurial.ini`` (per-user)
76 - ``%HOME%\Mercurial.ini`` (per-user)
77 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-system)
77 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-system)
78 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
78 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
79 - ``<install-dir>\Mercurial.ini`` (per-installation)
79 - ``<install-dir>\Mercurial.ini`` (per-installation)
80 - ``%PROGRAMDATA%\Mercurial\hgrc`` (per-system)
80 - ``%PROGRAMDATA%\Mercurial\hgrc`` (per-system)
81 - ``%PROGRAMDATA%\Mercurial\Mercurial.ini`` (per-system)
81 - ``%PROGRAMDATA%\Mercurial\Mercurial.ini`` (per-system)
82 - ``%PROGRAMDATA%\Mercurial\hgrc.d\*.rc`` (per-system)
82 - ``%PROGRAMDATA%\Mercurial\hgrc.d\*.rc`` (per-system)
83 - ``<internal>/*.rc`` (defaults)
83 - ``<internal>/*.rc`` (defaults)
84
84
85 .. note::
85 .. note::
86
86
87 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
87 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
88 is used when running 32-bit Python on 64-bit Windows.
88 is used when running 32-bit Python on 64-bit Windows.
89
89
90 .. container:: verbose.plan9
90 .. container:: verbose.plan9
91
91
92 On Plan9, the following files are consulted:
92 On Plan9, the following files are consulted:
93
93
94 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
94 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
95 - ``<repo>/.hg/hgrc`` (per-repository)
95 - ``<repo>/.hg/hgrc`` (per-repository)
96 - ``$home/lib/hgrc`` (per-user)
96 - ``$home/lib/hgrc`` (per-user)
97 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
97 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
98 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
98 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
99 - ``/lib/mercurial/hgrc`` (per-system)
99 - ``/lib/mercurial/hgrc`` (per-system)
100 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
100 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
101 - ``<internal>/*.rc`` (defaults)
101 - ``<internal>/*.rc`` (defaults)
102
102
103 Per-repository configuration options only apply in a
103 Per-repository configuration options only apply in a
104 particular repository. This file is not version-controlled, and
104 particular repository. This file is not version-controlled, and
105 will not get transferred during a "clone" operation. Options in
105 will not get transferred during a "clone" operation. Options in
106 this file override options in all other configuration files.
106 this file override options in all other configuration files.
107
107
108 .. container:: unix.plan9
108 .. container:: unix.plan9
109
109
110 On Plan 9 and Unix, most of this file will be ignored if it doesn't
110 On Plan 9 and Unix, most of this file will be ignored if it doesn't
111 belong to a trusted user or to a trusted group. See
111 belong to a trusted user or to a trusted group. See
112 :hg:`help config.trusted` for more details.
112 :hg:`help config.trusted` for more details.
113
113
114 Per-user configuration file(s) are for the user running Mercurial. Options
114 Per-user configuration file(s) are for the user running Mercurial. Options
115 in these files apply to all Mercurial commands executed by this user in any
115 in these files apply to all Mercurial commands executed by this user in any
116 directory. Options in these files override per-system and per-installation
116 directory. Options in these files override per-system and per-installation
117 options.
117 options.
118
118
119 Per-installation configuration files are searched for in the
119 Per-installation configuration files are searched for in the
120 directory where Mercurial is installed. ``<install-root>`` is the
120 directory where Mercurial is installed. ``<install-root>`` is the
121 parent directory of the **hg** executable (or symlink) being run.
121 parent directory of the **hg** executable (or symlink) being run.
122
122
123 .. container:: unix.plan9
123 .. container:: unix.plan9
124
124
125 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
125 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
126 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
126 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
127 files apply to all Mercurial commands executed by any user in any
127 files apply to all Mercurial commands executed by any user in any
128 directory.
128 directory.
129
129
130 Per-installation configuration files are for the system on
130 Per-installation configuration files are for the system on
131 which Mercurial is running. Options in these files apply to all
131 which Mercurial is running. Options in these files apply to all
132 Mercurial commands executed by any user in any directory. Registry
132 Mercurial commands executed by any user in any directory. Registry
133 keys contain PATH-like strings, every part of which must reference
133 keys contain PATH-like strings, every part of which must reference
134 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
134 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
135 be read. Mercurial checks each of these locations in the specified
135 be read. Mercurial checks each of these locations in the specified
136 order until one or more configuration files are detected.
136 order until one or more configuration files are detected.
137
137
138 Per-system configuration files are for the system on which Mercurial
138 Per-system configuration files are for the system on which Mercurial
139 is running. Options in these files apply to all Mercurial commands
139 is running. Options in these files apply to all Mercurial commands
140 executed by any user in any directory. Options in these files
140 executed by any user in any directory. Options in these files
141 override per-installation options.
141 override per-installation options.
142
142
143 Mercurial comes with some default configuration. The default configuration
143 Mercurial comes with some default configuration. The default configuration
144 files are installed with Mercurial and will be overwritten on upgrades. Default
144 files are installed with Mercurial and will be overwritten on upgrades. Default
145 configuration files should never be edited by users or administrators but can
145 configuration files should never be edited by users or administrators but can
146 be overridden in other configuration files. So far the directory only contains
146 be overridden in other configuration files. So far the directory only contains
147 merge tool configuration but packagers can also put other default configuration
147 merge tool configuration but packagers can also put other default configuration
148 there.
148 there.
149
149
150 .. container:: verbose
150 .. container:: verbose
151
151
152 On versions 5.7 and later, if share-safe functionality is enabled,
152 On versions 5.7 and later, if share-safe functionality is enabled,
153 shares will read config file of share source too.
153 shares will read config file of share source too.
154 `<share-source/.hg/hgrc>` is read before reading `<repo/.hg/hgrc>`.
154 `<share-source/.hg/hgrc>` is read before reading `<repo/.hg/hgrc>`.
155
155
156 For configs which should not be shared, `<repo/.hg/hgrc-not-shared>`
156 For configs which should not be shared, `<repo/.hg/hgrc-not-shared>`
157 should be used.
157 should be used.
158
158
159 Syntax
159 Syntax
160 ======
160 ======
161
161
162 A configuration file consists of sections, led by a ``[section]`` header
162 A configuration file consists of sections, led by a ``[section]`` header
163 and followed by ``name = value`` entries (sometimes called
163 and followed by ``name = value`` entries (sometimes called
164 ``configuration keys``)::
164 ``configuration keys``)::
165
165
166 [spam]
166 [spam]
167 eggs=ham
167 eggs=ham
168 green=
168 green=
169 eggs
169 eggs
170
170
171 Each line contains one entry. If the lines that follow are indented,
171 Each line contains one entry. If the lines that follow are indented,
172 they are treated as continuations of that entry. Leading whitespace is
172 they are treated as continuations of that entry. Leading whitespace is
173 removed from values. Empty lines are skipped. Lines beginning with
173 removed from values. Empty lines are skipped. Lines beginning with
174 ``#`` or ``;`` are ignored and may be used to provide comments.
174 ``#`` or ``;`` are ignored and may be used to provide comments.
175
175
176 Configuration keys can be set multiple times, in which case Mercurial
176 Configuration keys can be set multiple times, in which case Mercurial
177 will use the value that was configured last. As an example::
177 will use the value that was configured last. As an example::
178
178
179 [spam]
179 [spam]
180 eggs=large
180 eggs=large
181 ham=serrano
181 ham=serrano
182 eggs=small
182 eggs=small
183
183
184 This would set the configuration key named ``eggs`` to ``small``.
184 This would set the configuration key named ``eggs`` to ``small``.
185
185
186 It is also possible to define a section multiple times. A section can
186 It is also possible to define a section multiple times. A section can
187 be redefined on the same and/or on different configuration files. For
187 be redefined on the same and/or on different configuration files. For
188 example::
188 example::
189
189
190 [foo]
190 [foo]
191 eggs=large
191 eggs=large
192 ham=serrano
192 ham=serrano
193 eggs=small
193 eggs=small
194
194
195 [bar]
195 [bar]
196 eggs=ham
196 eggs=ham
197 green=
197 green=
198 eggs
198 eggs
199
199
200 [foo]
200 [foo]
201 ham=prosciutto
201 ham=prosciutto
202 eggs=medium
202 eggs=medium
203 bread=toasted
203 bread=toasted
204
204
205 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
205 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
206 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
206 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
207 respectively. As you can see there only thing that matters is the last
207 respectively. As you can see there only thing that matters is the last
208 value that was set for each of the configuration keys.
208 value that was set for each of the configuration keys.
209
209
210 If a configuration key is set multiple times in different
210 If a configuration key is set multiple times in different
211 configuration files the final value will depend on the order in which
211 configuration files the final value will depend on the order in which
212 the different configuration files are read, with settings from earlier
212 the different configuration files are read, with settings from earlier
213 paths overriding later ones as described on the ``Files`` section
213 paths overriding later ones as described on the ``Files`` section
214 above.
214 above.
215
215
216 A line of the form ``%include file`` will include ``file`` into the
216 A line of the form ``%include file`` will include ``file`` into the
217 current configuration file. The inclusion is recursive, which means
217 current configuration file. The inclusion is recursive, which means
218 that included files can include other files. Filenames are relative to
218 that included files can include other files. Filenames are relative to
219 the configuration file in which the ``%include`` directive is found.
219 the configuration file in which the ``%include`` directive is found.
220 Environment variables and ``~user`` constructs are expanded in
220 Environment variables and ``~user`` constructs are expanded in
221 ``file``. This lets you do something like::
221 ``file``. This lets you do something like::
222
222
223 %include ~/.hgrc.d/$HOST.rc
223 %include ~/.hgrc.d/$HOST.rc
224
224
225 to include a different configuration file on each computer you use.
225 to include a different configuration file on each computer you use.
226
226
227 A line with ``%unset name`` will remove ``name`` from the current
227 A line with ``%unset name`` will remove ``name`` from the current
228 section, if it has been set previously.
228 section, if it has been set previously.
229
229
230 The values are either free-form text strings, lists of text strings,
230 The values are either free-form text strings, lists of text strings,
231 or Boolean values. Boolean values can be set to true using any of "1",
231 or Boolean values. Boolean values can be set to true using any of "1",
232 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
232 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
233 (all case insensitive).
233 (all case insensitive).
234
234
235 List values are separated by whitespace or comma, except when values are
235 List values are separated by whitespace or comma, except when values are
236 placed in double quotation marks::
236 placed in double quotation marks::
237
237
238 allow_read = "John Doe, PhD", brian, betty
238 allow_read = "John Doe, PhD", brian, betty
239
239
240 Quotation marks can be escaped by prefixing them with a backslash. Only
240 Quotation marks can be escaped by prefixing them with a backslash. Only
241 quotation marks at the beginning of a word is counted as a quotation
241 quotation marks at the beginning of a word is counted as a quotation
242 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
242 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
243
243
244 Sections
244 Sections
245 ========
245 ========
246
246
247 This section describes the different sections that may appear in a
247 This section describes the different sections that may appear in a
248 Mercurial configuration file, the purpose of each section, its possible
248 Mercurial configuration file, the purpose of each section, its possible
249 keys, and their possible values.
249 keys, and their possible values.
250
250
251 ``alias``
251 ``alias``
252 ---------
252 ---------
253
253
254 Defines command aliases.
254 Defines command aliases.
255
255
256 Aliases allow you to define your own commands in terms of other
256 Aliases allow you to define your own commands in terms of other
257 commands (or aliases), optionally including arguments. Positional
257 commands (or aliases), optionally including arguments. Positional
258 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
258 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
259 are expanded by Mercurial before execution. Positional arguments not
259 are expanded by Mercurial before execution. Positional arguments not
260 already used by ``$N`` in the definition are put at the end of the
260 already used by ``$N`` in the definition are put at the end of the
261 command to be executed.
261 command to be executed.
262
262
263 Alias definitions consist of lines of the form::
263 Alias definitions consist of lines of the form::
264
264
265 <alias> = <command> [<argument>]...
265 <alias> = <command> [<argument>]...
266
266
267 For example, this definition::
267 For example, this definition::
268
268
269 latest = log --limit 5
269 latest = log --limit 5
270
270
271 creates a new command ``latest`` that shows only the five most recent
271 creates a new command ``latest`` that shows only the five most recent
272 changesets. You can define subsequent aliases using earlier ones::
272 changesets. You can define subsequent aliases using earlier ones::
273
273
274 stable5 = latest -b stable
274 stable5 = latest -b stable
275
275
276 .. note::
276 .. note::
277
277
278 It is possible to create aliases with the same names as
278 It is possible to create aliases with the same names as
279 existing commands, which will then override the original
279 existing commands, which will then override the original
280 definitions. This is almost always a bad idea!
280 definitions. This is almost always a bad idea!
281
281
282 An alias can start with an exclamation point (``!``) to make it a
282 An alias can start with an exclamation point (``!``) to make it a
283 shell alias. A shell alias is executed with the shell and will let you
283 shell alias. A shell alias is executed with the shell and will let you
284 run arbitrary commands. As an example, ::
284 run arbitrary commands. As an example, ::
285
285
286 echo = !echo $@
286 echo = !echo $@
287
287
288 will let you do ``hg echo foo`` to have ``foo`` printed in your
288 will let you do ``hg echo foo`` to have ``foo`` printed in your
289 terminal. A better example might be::
289 terminal. A better example might be::
290
290
291 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
291 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
292
292
293 which will make ``hg purge`` delete all unknown files in the
293 which will make ``hg purge`` delete all unknown files in the
294 repository in the same manner as the purge extension.
294 repository in the same manner as the purge extension.
295
295
296 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
296 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
297 expand to the command arguments. Unmatched arguments are
297 expand to the command arguments. Unmatched arguments are
298 removed. ``$0`` expands to the alias name and ``$@`` expands to all
298 removed. ``$0`` expands to the alias name and ``$@`` expands to all
299 arguments separated by a space. ``"$@"`` (with quotes) expands to all
299 arguments separated by a space. ``"$@"`` (with quotes) expands to all
300 arguments quoted individually and separated by a space. These expansions
300 arguments quoted individually and separated by a space. These expansions
301 happen before the command is passed to the shell.
301 happen before the command is passed to the shell.
302
302
303 Shell aliases are executed in an environment where ``$HG`` expands to
303 Shell aliases are executed in an environment where ``$HG`` expands to
304 the path of the Mercurial that was used to execute the alias. This is
304 the path of the Mercurial that was used to execute the alias. This is
305 useful when you want to call further Mercurial commands in a shell
305 useful when you want to call further Mercurial commands in a shell
306 alias, as was done above for the purge alias. In addition,
306 alias, as was done above for the purge alias. In addition,
307 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
307 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
308 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
308 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
309
309
310 .. note::
310 .. note::
311
311
312 Some global configuration options such as ``-R`` are
312 Some global configuration options such as ``-R`` are
313 processed before shell aliases and will thus not be passed to
313 processed before shell aliases and will thus not be passed to
314 aliases.
314 aliases.
315
315
316
316
317 ``annotate``
317 ``annotate``
318 ------------
318 ------------
319
319
320 Settings used when displaying file annotations. All values are
320 Settings used when displaying file annotations. All values are
321 Booleans and default to False. See :hg:`help config.diff` for
321 Booleans and default to False. See :hg:`help config.diff` for
322 related options for the diff command.
322 related options for the diff command.
323
323
324 ``ignorews``
324 ``ignorews``
325 Ignore white space when comparing lines.
325 Ignore white space when comparing lines.
326
326
327 ``ignorewseol``
327 ``ignorewseol``
328 Ignore white space at the end of a line when comparing lines.
328 Ignore white space at the end of a line when comparing lines.
329
329
330 ``ignorewsamount``
330 ``ignorewsamount``
331 Ignore changes in the amount of white space.
331 Ignore changes in the amount of white space.
332
332
333 ``ignoreblanklines``
333 ``ignoreblanklines``
334 Ignore changes whose lines are all blank.
334 Ignore changes whose lines are all blank.
335
335
336
336
337 ``auth``
337 ``auth``
338 --------
338 --------
339
339
340 Authentication credentials and other authentication-like configuration
340 Authentication credentials and other authentication-like configuration
341 for HTTP connections. This section allows you to store usernames and
341 for HTTP connections. This section allows you to store usernames and
342 passwords for use when logging *into* HTTP servers. See
342 passwords for use when logging *into* HTTP servers. See
343 :hg:`help config.web` if you want to configure *who* can login to
343 :hg:`help config.web` if you want to configure *who* can login to
344 your HTTP server.
344 your HTTP server.
345
345
346 The following options apply to all hosts.
346 The following options apply to all hosts.
347
347
348 ``cookiefile``
348 ``cookiefile``
349 Path to a file containing HTTP cookie lines. Cookies matching a
349 Path to a file containing HTTP cookie lines. Cookies matching a
350 host will be sent automatically.
350 host will be sent automatically.
351
351
352 The file format uses the Mozilla cookies.txt format, which defines cookies
352 The file format uses the Mozilla cookies.txt format, which defines cookies
353 on their own lines. Each line contains 7 fields delimited by the tab
353 on their own lines. Each line contains 7 fields delimited by the tab
354 character (domain, is_domain_cookie, path, is_secure, expires, name,
354 character (domain, is_domain_cookie, path, is_secure, expires, name,
355 value). For more info, do an Internet search for "Netscape cookies.txt
355 value). For more info, do an Internet search for "Netscape cookies.txt
356 format."
356 format."
357
357
358 Note: the cookies parser does not handle port numbers on domains. You
358 Note: the cookies parser does not handle port numbers on domains. You
359 will need to remove ports from the domain for the cookie to be recognized.
359 will need to remove ports from the domain for the cookie to be recognized.
360 This could result in a cookie being disclosed to an unwanted server.
360 This could result in a cookie being disclosed to an unwanted server.
361
361
362 The cookies file is read-only.
362 The cookies file is read-only.
363
363
364 Other options in this section are grouped by name and have the following
364 Other options in this section are grouped by name and have the following
365 format::
365 format::
366
366
367 <name>.<argument> = <value>
367 <name>.<argument> = <value>
368
368
369 where ``<name>`` is used to group arguments into authentication
369 where ``<name>`` is used to group arguments into authentication
370 entries. Example::
370 entries. Example::
371
371
372 foo.prefix = hg.intevation.de/mercurial
372 foo.prefix = hg.intevation.de/mercurial
373 foo.username = foo
373 foo.username = foo
374 foo.password = bar
374 foo.password = bar
375 foo.schemes = http https
375 foo.schemes = http https
376
376
377 bar.prefix = secure.example.org
377 bar.prefix = secure.example.org
378 bar.key = path/to/file.key
378 bar.key = path/to/file.key
379 bar.cert = path/to/file.cert
379 bar.cert = path/to/file.cert
380 bar.schemes = https
380 bar.schemes = https
381
381
382 Supported arguments:
382 Supported arguments:
383
383
384 ``prefix``
384 ``prefix``
385 Either ``*`` or a URI prefix with or without the scheme part.
385 Either ``*`` or a URI prefix with or without the scheme part.
386 The authentication entry with the longest matching prefix is used
386 The authentication entry with the longest matching prefix is used
387 (where ``*`` matches everything and counts as a match of length
387 (where ``*`` matches everything and counts as a match of length
388 1). If the prefix doesn't include a scheme, the match is performed
388 1). If the prefix doesn't include a scheme, the match is performed
389 against the URI with its scheme stripped as well, and the schemes
389 against the URI with its scheme stripped as well, and the schemes
390 argument, q.v., is then subsequently consulted.
390 argument, q.v., is then subsequently consulted.
391
391
392 ``username``
392 ``username``
393 Optional. Username to authenticate with. If not given, and the
393 Optional. Username to authenticate with. If not given, and the
394 remote site requires basic or digest authentication, the user will
394 remote site requires basic or digest authentication, the user will
395 be prompted for it. Environment variables are expanded in the
395 be prompted for it. Environment variables are expanded in the
396 username letting you do ``foo.username = $USER``. If the URI
396 username letting you do ``foo.username = $USER``. If the URI
397 includes a username, only ``[auth]`` entries with a matching
397 includes a username, only ``[auth]`` entries with a matching
398 username or without a username will be considered.
398 username or without a username will be considered.
399
399
400 ``password``
400 ``password``
401 Optional. Password to authenticate with. If not given, and the
401 Optional. Password to authenticate with. If not given, and the
402 remote site requires basic or digest authentication, the user
402 remote site requires basic or digest authentication, the user
403 will be prompted for it.
403 will be prompted for it.
404
404
405 ``key``
405 ``key``
406 Optional. PEM encoded client certificate key file. Environment
406 Optional. PEM encoded client certificate key file. Environment
407 variables are expanded in the filename.
407 variables are expanded in the filename.
408
408
409 ``cert``
409 ``cert``
410 Optional. PEM encoded client certificate chain file. Environment
410 Optional. PEM encoded client certificate chain file. Environment
411 variables are expanded in the filename.
411 variables are expanded in the filename.
412
412
413 ``schemes``
413 ``schemes``
414 Optional. Space separated list of URI schemes to use this
414 Optional. Space separated list of URI schemes to use this
415 authentication entry with. Only used if the prefix doesn't include
415 authentication entry with. Only used if the prefix doesn't include
416 a scheme. Supported schemes are http and https. They will match
416 a scheme. Supported schemes are http and https. They will match
417 static-http and static-https respectively, as well.
417 static-http and static-https respectively, as well.
418 (default: https)
418 (default: https)
419
419
420 If no suitable authentication entry is found, the user is prompted
420 If no suitable authentication entry is found, the user is prompted
421 for credentials as usual if required by the remote.
421 for credentials as usual if required by the remote.
422
422
423 ``cmdserver``
423 ``cmdserver``
424 -------------
424 -------------
425
425
426 Controls command server settings. (ADVANCED)
426 Controls command server settings. (ADVANCED)
427
427
428 ``message-encodings``
428 ``message-encodings``
429 List of encodings for the ``m`` (message) channel. The first encoding
429 List of encodings for the ``m`` (message) channel. The first encoding
430 supported by the server will be selected and advertised in the hello
430 supported by the server will be selected and advertised in the hello
431 message. This is useful only when ``ui.message-output`` is set to
431 message. This is useful only when ``ui.message-output`` is set to
432 ``channel``. Supported encodings are ``cbor``.
432 ``channel``. Supported encodings are ``cbor``.
433
433
434 ``shutdown-on-interrupt``
434 ``shutdown-on-interrupt``
435 If set to false, the server's main loop will continue running after
435 If set to false, the server's main loop will continue running after
436 SIGINT received. ``runcommand`` requests can still be interrupted by
436 SIGINT received. ``runcommand`` requests can still be interrupted by
437 SIGINT. Close the write end of the pipe to shut down the server
437 SIGINT. Close the write end of the pipe to shut down the server
438 process gracefully.
438 process gracefully.
439 (default: True)
439 (default: True)
440
440
441 ``color``
441 ``color``
442 ---------
442 ---------
443
443
444 Configure the Mercurial color mode. For details about how to define your custom
444 Configure the Mercurial color mode. For details about how to define your custom
445 effect and style see :hg:`help color`.
445 effect and style see :hg:`help color`.
446
446
447 ``mode``
447 ``mode``
448 String: control the method used to output color. One of ``auto``, ``ansi``,
448 String: control the method used to output color. One of ``auto``, ``ansi``,
449 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
449 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
450 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
450 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
451 terminal. Any invalid value will disable color.
451 terminal. Any invalid value will disable color.
452
452
453 ``pagermode``
453 ``pagermode``
454 String: optional override of ``color.mode`` used with pager.
454 String: optional override of ``color.mode`` used with pager.
455
455
456 On some systems, terminfo mode may cause problems when using
456 On some systems, terminfo mode may cause problems when using
457 color with ``less -R`` as a pager program. less with the -R option
457 color with ``less -R`` as a pager program. less with the -R option
458 will only display ECMA-48 color codes, and terminfo mode may sometimes
458 will only display ECMA-48 color codes, and terminfo mode may sometimes
459 emit codes that less doesn't understand. You can work around this by
459 emit codes that less doesn't understand. You can work around this by
460 either using ansi mode (or auto mode), or by using less -r (which will
460 either using ansi mode (or auto mode), or by using less -r (which will
461 pass through all terminal control codes, not just color control
461 pass through all terminal control codes, not just color control
462 codes).
462 codes).
463
463
464 On some systems (such as MSYS in Windows), the terminal may support
464 On some systems (such as MSYS in Windows), the terminal may support
465 a different color mode than the pager program.
465 a different color mode than the pager program.
466
466
467 ``commands``
467 ``commands``
468 ------------
468 ------------
469
469
470 ``commit.post-status``
470 ``commit.post-status``
471 Show status of files in the working directory after successful commit.
471 Show status of files in the working directory after successful commit.
472 (default: False)
472 (default: False)
473
473
474 ``merge.require-rev``
474 ``merge.require-rev``
475 Require that the revision to merge the current commit with be specified on
475 Require that the revision to merge the current commit with be specified on
476 the command line. If this is enabled and a revision is not specified, the
476 the command line. If this is enabled and a revision is not specified, the
477 command aborts.
477 command aborts.
478 (default: False)
478 (default: False)
479
479
480 ``push.require-revs``
480 ``push.require-revs``
481 Require revisions to push be specified using one or more mechanisms such as
481 Require revisions to push be specified using one or more mechanisms such as
482 specifying them positionally on the command line, using ``-r``, ``-b``,
482 specifying them positionally on the command line, using ``-r``, ``-b``,
483 and/or ``-B`` on the command line, or using ``paths.<path>:pushrev`` in the
483 and/or ``-B`` on the command line, or using ``paths.<path>:pushrev`` in the
484 configuration. If this is enabled and revisions are not specified, the
484 configuration. If this is enabled and revisions are not specified, the
485 command aborts.
485 command aborts.
486 (default: False)
486 (default: False)
487
487
488 ``resolve.confirm``
488 ``resolve.confirm``
489 Confirm before performing action if no filename is passed.
489 Confirm before performing action if no filename is passed.
490 (default: False)
490 (default: False)
491
491
492 ``resolve.explicit-re-merge``
492 ``resolve.explicit-re-merge``
493 Require uses of ``hg resolve`` to specify which action it should perform,
493 Require uses of ``hg resolve`` to specify which action it should perform,
494 instead of re-merging files by default.
494 instead of re-merging files by default.
495 (default: False)
495 (default: False)
496
496
497 ``resolve.mark-check``
497 ``resolve.mark-check``
498 Determines what level of checking :hg:`resolve --mark` will perform before
498 Determines what level of checking :hg:`resolve --mark` will perform before
499 marking files as resolved. Valid values are ``none`, ``warn``, and
499 marking files as resolved. Valid values are ``none`, ``warn``, and
500 ``abort``. ``warn`` will output a warning listing the file(s) that still
500 ``abort``. ``warn`` will output a warning listing the file(s) that still
501 have conflict markers in them, but will still mark everything resolved.
501 have conflict markers in them, but will still mark everything resolved.
502 ``abort`` will output the same warning but will not mark things as resolved.
502 ``abort`` will output the same warning but will not mark things as resolved.
503 If --all is passed and this is set to ``abort``, only a warning will be
503 If --all is passed and this is set to ``abort``, only a warning will be
504 shown (an error will not be raised).
504 shown (an error will not be raised).
505 (default: ``none``)
505 (default: ``none``)
506
506
507 ``status.relative``
507 ``status.relative``
508 Make paths in :hg:`status` output relative to the current directory.
508 Make paths in :hg:`status` output relative to the current directory.
509 (default: False)
509 (default: False)
510
510
511 ``status.terse``
511 ``status.terse``
512 Default value for the --terse flag, which condenses status output.
512 Default value for the --terse flag, which condenses status output.
513 (default: empty)
513 (default: empty)
514
514
515 ``update.check``
515 ``update.check``
516 Determines what level of checking :hg:`update` will perform before moving
516 Determines what level of checking :hg:`update` will perform before moving
517 to a destination revision. Valid values are ``abort``, ``none``,
517 to a destination revision. Valid values are ``abort``, ``none``,
518 ``linear``, and ``noconflict``. ``abort`` always fails if the working
518 ``linear``, and ``noconflict``. ``abort`` always fails if the working
519 directory has uncommitted changes. ``none`` performs no checking, and may
519 directory has uncommitted changes. ``none`` performs no checking, and may
520 result in a merge with uncommitted changes. ``linear`` allows any update
520 result in a merge with uncommitted changes. ``linear`` allows any update
521 as long as it follows a straight line in the revision history, and may
521 as long as it follows a straight line in the revision history, and may
522 trigger a merge with uncommitted changes. ``noconflict`` will allow any
522 trigger a merge with uncommitted changes. ``noconflict`` will allow any
523 update which would not trigger a merge with uncommitted changes, if any
523 update which would not trigger a merge with uncommitted changes, if any
524 are present.
524 are present.
525 (default: ``linear``)
525 (default: ``linear``)
526
526
527 ``update.requiredest``
527 ``update.requiredest``
528 Require that the user pass a destination when running :hg:`update`.
528 Require that the user pass a destination when running :hg:`update`.
529 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
529 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
530 will be disallowed.
530 will be disallowed.
531 (default: False)
531 (default: False)
532
532
533 ``committemplate``
533 ``committemplate``
534 ------------------
534 ------------------
535
535
536 ``changeset``
536 ``changeset``
537 String: configuration in this section is used as the template to
537 String: configuration in this section is used as the template to
538 customize the text shown in the editor when committing.
538 customize the text shown in the editor when committing.
539
539
540 In addition to pre-defined template keywords, commit log specific one
540 In addition to pre-defined template keywords, commit log specific one
541 below can be used for customization:
541 below can be used for customization:
542
542
543 ``extramsg``
543 ``extramsg``
544 String: Extra message (typically 'Leave message empty to abort
544 String: Extra message (typically 'Leave message empty to abort
545 commit.'). This may be changed by some commands or extensions.
545 commit.'). This may be changed by some commands or extensions.
546
546
547 For example, the template configuration below shows as same text as
547 For example, the template configuration below shows as same text as
548 one shown by default::
548 one shown by default::
549
549
550 [committemplate]
550 [committemplate]
551 changeset = {desc}\n\n
551 changeset = {desc}\n\n
552 HG: Enter commit message. Lines beginning with 'HG:' are removed.
552 HG: Enter commit message. Lines beginning with 'HG:' are removed.
553 HG: {extramsg}
553 HG: {extramsg}
554 HG: --
554 HG: --
555 HG: user: {author}\n{ifeq(p2rev, "-1", "",
555 HG: user: {author}\n{ifeq(p2rev, "-1", "",
556 "HG: branch merge\n")
556 "HG: branch merge\n")
557 }HG: branch '{branch}'\n{if(activebookmark,
557 }HG: branch '{branch}'\n{if(activebookmark,
558 "HG: bookmark '{activebookmark}'\n") }{subrepos %
558 "HG: bookmark '{activebookmark}'\n") }{subrepos %
559 "HG: subrepo {subrepo}\n" }{file_adds %
559 "HG: subrepo {subrepo}\n" }{file_adds %
560 "HG: added {file}\n" }{file_mods %
560 "HG: added {file}\n" }{file_mods %
561 "HG: changed {file}\n" }{file_dels %
561 "HG: changed {file}\n" }{file_dels %
562 "HG: removed {file}\n" }{if(files, "",
562 "HG: removed {file}\n" }{if(files, "",
563 "HG: no files changed\n")}
563 "HG: no files changed\n")}
564
564
565 ``diff()``
565 ``diff()``
566 String: show the diff (see :hg:`help templates` for detail)
566 String: show the diff (see :hg:`help templates` for detail)
567
567
568 Sometimes it is helpful to show the diff of the changeset in the editor without
568 Sometimes it is helpful to show the diff of the changeset in the editor without
569 having to prefix 'HG: ' to each line so that highlighting works correctly. For
569 having to prefix 'HG: ' to each line so that highlighting works correctly. For
570 this, Mercurial provides a special string which will ignore everything below
570 this, Mercurial provides a special string which will ignore everything below
571 it::
571 it::
572
572
573 HG: ------------------------ >8 ------------------------
573 HG: ------------------------ >8 ------------------------
574
574
575 For example, the template configuration below will show the diff below the
575 For example, the template configuration below will show the diff below the
576 extra message::
576 extra message::
577
577
578 [committemplate]
578 [committemplate]
579 changeset = {desc}\n\n
579 changeset = {desc}\n\n
580 HG: Enter commit message. Lines beginning with 'HG:' are removed.
580 HG: Enter commit message. Lines beginning with 'HG:' are removed.
581 HG: {extramsg}
581 HG: {extramsg}
582 HG: ------------------------ >8 ------------------------
582 HG: ------------------------ >8 ------------------------
583 HG: Do not touch the line above.
583 HG: Do not touch the line above.
584 HG: Everything below will be removed.
584 HG: Everything below will be removed.
585 {diff()}
585 {diff()}
586
586
587 .. note::
587 .. note::
588
588
589 For some problematic encodings (see :hg:`help win32mbcs` for
589 For some problematic encodings (see :hg:`help win32mbcs` for
590 detail), this customization should be configured carefully, to
590 detail), this customization should be configured carefully, to
591 avoid showing broken characters.
591 avoid showing broken characters.
592
592
593 For example, if a multibyte character ending with backslash (0x5c) is
593 For example, if a multibyte character ending with backslash (0x5c) is
594 followed by the ASCII character 'n' in the customized template,
594 followed by the ASCII character 'n' in the customized template,
595 the sequence of backslash and 'n' is treated as line-feed unexpectedly
595 the sequence of backslash and 'n' is treated as line-feed unexpectedly
596 (and the multibyte character is broken, too).
596 (and the multibyte character is broken, too).
597
597
598 Customized template is used for commands below (``--edit`` may be
598 Customized template is used for commands below (``--edit`` may be
599 required):
599 required):
600
600
601 - :hg:`backout`
601 - :hg:`backout`
602 - :hg:`commit`
602 - :hg:`commit`
603 - :hg:`fetch` (for merge commit only)
603 - :hg:`fetch` (for merge commit only)
604 - :hg:`graft`
604 - :hg:`graft`
605 - :hg:`histedit`
605 - :hg:`histedit`
606 - :hg:`import`
606 - :hg:`import`
607 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
607 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
608 - :hg:`rebase`
608 - :hg:`rebase`
609 - :hg:`shelve`
609 - :hg:`shelve`
610 - :hg:`sign`
610 - :hg:`sign`
611 - :hg:`tag`
611 - :hg:`tag`
612 - :hg:`transplant`
612 - :hg:`transplant`
613
613
614 Configuring items below instead of ``changeset`` allows showing
614 Configuring items below instead of ``changeset`` allows showing
615 customized message only for specific actions, or showing different
615 customized message only for specific actions, or showing different
616 messages for each action.
616 messages for each action.
617
617
618 - ``changeset.backout`` for :hg:`backout`
618 - ``changeset.backout`` for :hg:`backout`
619 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
619 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
620 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
620 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
621 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
621 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
622 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
622 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
623 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
623 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
624 - ``changeset.gpg.sign`` for :hg:`sign`
624 - ``changeset.gpg.sign`` for :hg:`sign`
625 - ``changeset.graft`` for :hg:`graft`
625 - ``changeset.graft`` for :hg:`graft`
626 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
626 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
627 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
627 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
628 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
628 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
629 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
629 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
630 - ``changeset.import.bypass`` for :hg:`import --bypass`
630 - ``changeset.import.bypass`` for :hg:`import --bypass`
631 - ``changeset.import.normal.merge`` for :hg:`import` on merges
631 - ``changeset.import.normal.merge`` for :hg:`import` on merges
632 - ``changeset.import.normal.normal`` for :hg:`import` on other
632 - ``changeset.import.normal.normal`` for :hg:`import` on other
633 - ``changeset.mq.qnew`` for :hg:`qnew`
633 - ``changeset.mq.qnew`` for :hg:`qnew`
634 - ``changeset.mq.qfold`` for :hg:`qfold`
634 - ``changeset.mq.qfold`` for :hg:`qfold`
635 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
635 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
636 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
636 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
637 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
637 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
638 - ``changeset.rebase.normal`` for :hg:`rebase` on other
638 - ``changeset.rebase.normal`` for :hg:`rebase` on other
639 - ``changeset.shelve.shelve`` for :hg:`shelve`
639 - ``changeset.shelve.shelve`` for :hg:`shelve`
640 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
640 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
641 - ``changeset.tag.remove`` for :hg:`tag --remove`
641 - ``changeset.tag.remove`` for :hg:`tag --remove`
642 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
642 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
643 - ``changeset.transplant.normal`` for :hg:`transplant` on other
643 - ``changeset.transplant.normal`` for :hg:`transplant` on other
644
644
645 These dot-separated lists of names are treated as hierarchical ones.
645 These dot-separated lists of names are treated as hierarchical ones.
646 For example, ``changeset.tag.remove`` customizes the commit message
646 For example, ``changeset.tag.remove`` customizes the commit message
647 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
647 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
648 commit message for :hg:`tag` regardless of ``--remove`` option.
648 commit message for :hg:`tag` regardless of ``--remove`` option.
649
649
650 When the external editor is invoked for a commit, the corresponding
650 When the external editor is invoked for a commit, the corresponding
651 dot-separated list of names without the ``changeset.`` prefix
651 dot-separated list of names without the ``changeset.`` prefix
652 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
652 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
653 variable.
653 variable.
654
654
655 In this section, items other than ``changeset`` can be referred from
655 In this section, items other than ``changeset`` can be referred from
656 others. For example, the configuration to list committed files up
656 others. For example, the configuration to list committed files up
657 below can be referred as ``{listupfiles}``::
657 below can be referred as ``{listupfiles}``::
658
658
659 [committemplate]
659 [committemplate]
660 listupfiles = {file_adds %
660 listupfiles = {file_adds %
661 "HG: added {file}\n" }{file_mods %
661 "HG: added {file}\n" }{file_mods %
662 "HG: changed {file}\n" }{file_dels %
662 "HG: changed {file}\n" }{file_dels %
663 "HG: removed {file}\n" }{if(files, "",
663 "HG: removed {file}\n" }{if(files, "",
664 "HG: no files changed\n")}
664 "HG: no files changed\n")}
665
665
666 ``decode/encode``
666 ``decode/encode``
667 -----------------
667 -----------------
668
668
669 Filters for transforming files on checkout/checkin. This would
669 Filters for transforming files on checkout/checkin. This would
670 typically be used for newline processing or other
670 typically be used for newline processing or other
671 localization/canonicalization of files.
671 localization/canonicalization of files.
672
672
673 Filters consist of a filter pattern followed by a filter command.
673 Filters consist of a filter pattern followed by a filter command.
674 Filter patterns are globs by default, rooted at the repository root.
674 Filter patterns are globs by default, rooted at the repository root.
675 For example, to match any file ending in ``.txt`` in the root
675 For example, to match any file ending in ``.txt`` in the root
676 directory only, use the pattern ``*.txt``. To match any file ending
676 directory only, use the pattern ``*.txt``. To match any file ending
677 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
677 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
678 For each file only the first matching filter applies.
678 For each file only the first matching filter applies.
679
679
680 The filter command can start with a specifier, either ``pipe:`` or
680 The filter command can start with a specifier, either ``pipe:`` or
681 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
681 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
682
682
683 A ``pipe:`` command must accept data on stdin and return the transformed
683 A ``pipe:`` command must accept data on stdin and return the transformed
684 data on stdout.
684 data on stdout.
685
685
686 Pipe example::
686 Pipe example::
687
687
688 [encode]
688 [encode]
689 # uncompress gzip files on checkin to improve delta compression
689 # uncompress gzip files on checkin to improve delta compression
690 # note: not necessarily a good idea, just an example
690 # note: not necessarily a good idea, just an example
691 *.gz = pipe: gunzip
691 *.gz = pipe: gunzip
692
692
693 [decode]
693 [decode]
694 # recompress gzip files when writing them to the working dir (we
694 # recompress gzip files when writing them to the working dir (we
695 # can safely omit "pipe:", because it's the default)
695 # can safely omit "pipe:", because it's the default)
696 *.gz = gzip
696 *.gz = gzip
697
697
698 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
698 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
699 with the name of a temporary file that contains the data to be
699 with the name of a temporary file that contains the data to be
700 filtered by the command. The string ``OUTFILE`` is replaced with the name
700 filtered by the command. The string ``OUTFILE`` is replaced with the name
701 of an empty temporary file, where the filtered data must be written by
701 of an empty temporary file, where the filtered data must be written by
702 the command.
702 the command.
703
703
704 .. container:: windows
704 .. container:: windows
705
705
706 .. note::
706 .. note::
707
707
708 The tempfile mechanism is recommended for Windows systems,
708 The tempfile mechanism is recommended for Windows systems,
709 where the standard shell I/O redirection operators often have
709 where the standard shell I/O redirection operators often have
710 strange effects and may corrupt the contents of your files.
710 strange effects and may corrupt the contents of your files.
711
711
712 This filter mechanism is used internally by the ``eol`` extension to
712 This filter mechanism is used internally by the ``eol`` extension to
713 translate line ending characters between Windows (CRLF) and Unix (LF)
713 translate line ending characters between Windows (CRLF) and Unix (LF)
714 format. We suggest you use the ``eol`` extension for convenience.
714 format. We suggest you use the ``eol`` extension for convenience.
715
715
716
716
717 ``defaults``
717 ``defaults``
718 ------------
718 ------------
719
719
720 (defaults are deprecated. Don't use them. Use aliases instead.)
720 (defaults are deprecated. Don't use them. Use aliases instead.)
721
721
722 Use the ``[defaults]`` section to define command defaults, i.e. the
722 Use the ``[defaults]`` section to define command defaults, i.e. the
723 default options/arguments to pass to the specified commands.
723 default options/arguments to pass to the specified commands.
724
724
725 The following example makes :hg:`log` run in verbose mode, and
725 The following example makes :hg:`log` run in verbose mode, and
726 :hg:`status` show only the modified files, by default::
726 :hg:`status` show only the modified files, by default::
727
727
728 [defaults]
728 [defaults]
729 log = -v
729 log = -v
730 status = -m
730 status = -m
731
731
732 The actual commands, instead of their aliases, must be used when
732 The actual commands, instead of their aliases, must be used when
733 defining command defaults. The command defaults will also be applied
733 defining command defaults. The command defaults will also be applied
734 to the aliases of the commands defined.
734 to the aliases of the commands defined.
735
735
736
736
737 ``diff``
737 ``diff``
738 --------
738 --------
739
739
740 Settings used when displaying diffs. Everything except for ``unified``
740 Settings used when displaying diffs. Everything except for ``unified``
741 is a Boolean and defaults to False. See :hg:`help config.annotate`
741 is a Boolean and defaults to False. See :hg:`help config.annotate`
742 for related options for the annotate command.
742 for related options for the annotate command.
743
743
744 ``git``
744 ``git``
745 Use git extended diff format.
745 Use git extended diff format.
746
746
747 ``nobinary``
747 ``nobinary``
748 Omit git binary patches.
748 Omit git binary patches.
749
749
750 ``nodates``
750 ``nodates``
751 Don't include dates in diff headers.
751 Don't include dates in diff headers.
752
752
753 ``noprefix``
753 ``noprefix``
754 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
754 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
755
755
756 ``showfunc``
756 ``showfunc``
757 Show which function each change is in.
757 Show which function each change is in.
758
758
759 ``ignorews``
759 ``ignorews``
760 Ignore white space when comparing lines.
760 Ignore white space when comparing lines.
761
761
762 ``ignorewsamount``
762 ``ignorewsamount``
763 Ignore changes in the amount of white space.
763 Ignore changes in the amount of white space.
764
764
765 ``ignoreblanklines``
765 ``ignoreblanklines``
766 Ignore changes whose lines are all blank.
766 Ignore changes whose lines are all blank.
767
767
768 ``unified``
768 ``unified``
769 Number of lines of context to show.
769 Number of lines of context to show.
770
770
771 ``word-diff``
771 ``word-diff``
772 Highlight changed words.
772 Highlight changed words.
773
773
774 ``email``
774 ``email``
775 ---------
775 ---------
776
776
777 Settings for extensions that send email messages.
777 Settings for extensions that send email messages.
778
778
779 ``from``
779 ``from``
780 Optional. Email address to use in "From" header and SMTP envelope
780 Optional. Email address to use in "From" header and SMTP envelope
781 of outgoing messages.
781 of outgoing messages.
782
782
783 ``to``
783 ``to``
784 Optional. Comma-separated list of recipients' email addresses.
784 Optional. Comma-separated list of recipients' email addresses.
785
785
786 ``cc``
786 ``cc``
787 Optional. Comma-separated list of carbon copy recipients'
787 Optional. Comma-separated list of carbon copy recipients'
788 email addresses.
788 email addresses.
789
789
790 ``bcc``
790 ``bcc``
791 Optional. Comma-separated list of blind carbon copy recipients'
791 Optional. Comma-separated list of blind carbon copy recipients'
792 email addresses.
792 email addresses.
793
793
794 ``method``
794 ``method``
795 Optional. Method to use to send email messages. If value is ``smtp``
795 Optional. Method to use to send email messages. If value is ``smtp``
796 (default), use SMTP (see the ``[smtp]`` section for configuration).
796 (default), use SMTP (see the ``[smtp]`` section for configuration).
797 Otherwise, use as name of program to run that acts like sendmail
797 Otherwise, use as name of program to run that acts like sendmail
798 (takes ``-f`` option for sender, list of recipients on command line,
798 (takes ``-f`` option for sender, list of recipients on command line,
799 message on stdin). Normally, setting this to ``sendmail`` or
799 message on stdin). Normally, setting this to ``sendmail`` or
800 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
800 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
801
801
802 ``charsets``
802 ``charsets``
803 Optional. Comma-separated list of character sets considered
803 Optional. Comma-separated list of character sets considered
804 convenient for recipients. Addresses, headers, and parts not
804 convenient for recipients. Addresses, headers, and parts not
805 containing patches of outgoing messages will be encoded in the
805 containing patches of outgoing messages will be encoded in the
806 first character set to which conversion from local encoding
806 first character set to which conversion from local encoding
807 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
807 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
808 conversion fails, the text in question is sent as is.
808 conversion fails, the text in question is sent as is.
809 (default: '')
809 (default: '')
810
810
811 Order of outgoing email character sets:
811 Order of outgoing email character sets:
812
812
813 1. ``us-ascii``: always first, regardless of settings
813 1. ``us-ascii``: always first, regardless of settings
814 2. ``email.charsets``: in order given by user
814 2. ``email.charsets``: in order given by user
815 3. ``ui.fallbackencoding``: if not in email.charsets
815 3. ``ui.fallbackencoding``: if not in email.charsets
816 4. ``$HGENCODING``: if not in email.charsets
816 4. ``$HGENCODING``: if not in email.charsets
817 5. ``utf-8``: always last, regardless of settings
817 5. ``utf-8``: always last, regardless of settings
818
818
819 Email example::
819 Email example::
820
820
821 [email]
821 [email]
822 from = Joseph User <joe.user@example.com>
822 from = Joseph User <joe.user@example.com>
823 method = /usr/sbin/sendmail
823 method = /usr/sbin/sendmail
824 # charsets for western Europeans
824 # charsets for western Europeans
825 # us-ascii, utf-8 omitted, as they are tried first and last
825 # us-ascii, utf-8 omitted, as they are tried first and last
826 charsets = iso-8859-1, iso-8859-15, windows-1252
826 charsets = iso-8859-1, iso-8859-15, windows-1252
827
827
828
828
829 ``extensions``
829 ``extensions``
830 --------------
830 --------------
831
831
832 Mercurial has an extension mechanism for adding new features. To
832 Mercurial has an extension mechanism for adding new features. To
833 enable an extension, create an entry for it in this section.
833 enable an extension, create an entry for it in this section.
834
834
835 If you know that the extension is already in Python's search path,
835 If you know that the extension is already in Python's search path,
836 you can give the name of the module, followed by ``=``, with nothing
836 you can give the name of the module, followed by ``=``, with nothing
837 after the ``=``.
837 after the ``=``.
838
838
839 Otherwise, give a name that you choose, followed by ``=``, followed by
839 Otherwise, give a name that you choose, followed by ``=``, followed by
840 the path to the ``.py`` file (including the file name extension) that
840 the path to the ``.py`` file (including the file name extension) that
841 defines the extension.
841 defines the extension.
842
842
843 To explicitly disable an extension that is enabled in an hgrc of
843 To explicitly disable an extension that is enabled in an hgrc of
844 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
844 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
845 or ``foo = !`` when path is not supplied.
845 or ``foo = !`` when path is not supplied.
846
846
847 Example for ``~/.hgrc``::
847 Example for ``~/.hgrc``::
848
848
849 [extensions]
849 [extensions]
850 # (the churn extension will get loaded from Mercurial's path)
850 # (the churn extension will get loaded from Mercurial's path)
851 churn =
851 churn =
852 # (this extension will get loaded from the file specified)
852 # (this extension will get loaded from the file specified)
853 myfeature = ~/.hgext/myfeature.py
853 myfeature = ~/.hgext/myfeature.py
854
854
855
855
856 ``format``
856 ``format``
857 ----------
857 ----------
858
858
859 Configuration that controls the repository format. Newer format options are more
859 Configuration that controls the repository format. Newer format options are more
860 powerful, but incompatible with some older versions of Mercurial. Format options
860 powerful, but incompatible with some older versions of Mercurial. Format options
861 are considered at repository initialization only. You need to make a new clone
861 are considered at repository initialization only. You need to make a new clone
862 for config changes to be taken into account.
862 for config changes to be taken into account.
863
863
864 For more details about repository format and version compatibility, see
864 For more details about repository format and version compatibility, see
865 https://www.mercurial-scm.org/wiki/MissingRequirement
865 https://www.mercurial-scm.org/wiki/MissingRequirement
866
866
867 ``usegeneraldelta``
867 ``usegeneraldelta``
868 Enable or disable the "generaldelta" repository format which improves
868 Enable or disable the "generaldelta" repository format which improves
869 repository compression by allowing "revlog" to store deltas against
869 repository compression by allowing "revlog" to store deltas against
870 arbitrary revisions instead of the previously stored one. This provides
870 arbitrary revisions instead of the previously stored one. This provides
871 significant improvement for repositories with branches.
871 significant improvement for repositories with branches.
872
872
873 Repositories with this on-disk format require Mercurial version 1.9.
873 Repositories with this on-disk format require Mercurial version 1.9.
874
874
875 Enabled by default.
875 Enabled by default.
876
876
877 ``dotencode``
877 ``dotencode``
878 Enable or disable the "dotencode" repository format which enhances
878 Enable or disable the "dotencode" repository format which enhances
879 the "fncache" repository format (which has to be enabled to use
879 the "fncache" repository format (which has to be enabled to use
880 dotencode) to avoid issues with filenames starting with "._" on
880 dotencode) to avoid issues with filenames starting with "._" on
881 Mac OS X and spaces on Windows.
881 Mac OS X and spaces on Windows.
882
882
883 Repositories with this on-disk format require Mercurial version 1.7.
883 Repositories with this on-disk format require Mercurial version 1.7.
884
884
885 Enabled by default.
885 Enabled by default.
886
886
887 ``usefncache``
887 ``usefncache``
888 Enable or disable the "fncache" repository format which enhances
888 Enable or disable the "fncache" repository format which enhances
889 the "store" repository format (which has to be enabled to use
889 the "store" repository format (which has to be enabled to use
890 fncache) to allow longer filenames and avoids using Windows
890 fncache) to allow longer filenames and avoids using Windows
891 reserved names, e.g. "nul".
891 reserved names, e.g. "nul".
892
892
893 Repositories with this on-disk format require Mercurial version 1.1.
893 Repositories with this on-disk format require Mercurial version 1.1.
894
894
895 Enabled by default.
895 Enabled by default.
896
896
897 ``use-persistent-nodemap``
897 ``use-persistent-nodemap``
898 Enable or disable the "persistent-nodemap" feature which improves
898 Enable or disable the "persistent-nodemap" feature which improves
899 performance if the rust extensions are available.
899 performance if the rust extensions are available.
900
900
901 The "persistence-nodemap" persist the "node -> rev" on disk removing the
901 The "persistence-nodemap" persist the "node -> rev" on disk removing the
902 need to dynamically build that mapping for each Mercurial invocation. This
902 need to dynamically build that mapping for each Mercurial invocation. This
903 significantly reduce the startup cost of various local and server-side
903 significantly reduce the startup cost of various local and server-side
904 operation for larger repository.
904 operation for larger repository.
905
905
906 The performance improving version of this feature is currently only
906 The performance improving version of this feature is currently only
907 implemented in Rust, so people using a version of Mercurial compiled
907 implemented in Rust, so people not using a version of Mercurial compiled
908 without the Rust part might actually suffer some slowdown.
908 with the Rust part might actually suffer some slowdown. For this reason,
909 Such version will by default refuse to access such repositories. That
910 behavior can be controlled by configuration. Check
911 :hg:`help config.storage.revlog.persistent-nodemap.slowpath` for details.
909
912
910 Repository with this on-disk format require Mercurial version 5.4 or above.
913 Repository with this on-disk format require Mercurial version 5.4 or above.
911
914
912 Disabled by default.
915 Disabled by default.
913
916
914 ``usestore``
917 ``usestore``
915 Enable or disable the "store" repository format which improves
918 Enable or disable the "store" repository format which improves
916 compatibility with systems that fold case or otherwise mangle
919 compatibility with systems that fold case or otherwise mangle
917 filenames. Disabling this option will allow you to store longer filenames
920 filenames. Disabling this option will allow you to store longer filenames
918 in some situations at the expense of compatibility.
921 in some situations at the expense of compatibility.
919
922
920 Repositories with this on-disk format require Mercurial version 0.9.4.
923 Repositories with this on-disk format require Mercurial version 0.9.4.
921
924
922 Enabled by default.
925 Enabled by default.
923
926
924 ``sparse-revlog``
927 ``sparse-revlog``
925 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
928 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
926 delta re-use inside revlog. For very branchy repositories, it results in a
929 delta re-use inside revlog. For very branchy repositories, it results in a
927 smaller store. For repositories with many revisions, it also helps
930 smaller store. For repositories with many revisions, it also helps
928 performance (by using shortened delta chains.)
931 performance (by using shortened delta chains.)
929
932
930 Repositories with this on-disk format require Mercurial version 4.7
933 Repositories with this on-disk format require Mercurial version 4.7
931
934
932 Enabled by default.
935 Enabled by default.
933
936
934 ``revlog-compression``
937 ``revlog-compression``
935 Compression algorithm used by revlog. Supported values are `zlib` and
938 Compression algorithm used by revlog. Supported values are `zlib` and
936 `zstd`. The `zlib` engine is the historical default of Mercurial. `zstd` is
939 `zstd`. The `zlib` engine is the historical default of Mercurial. `zstd` is
937 a newer format that is usually a net win over `zlib`, operating faster at
940 a newer format that is usually a net win over `zlib`, operating faster at
938 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
941 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
939 can be specified, the first available one will be used.
942 can be specified, the first available one will be used.
940
943
941 On some systems, the Mercurial installation may lack `zstd` support.
944 On some systems, the Mercurial installation may lack `zstd` support.
942
945
943 Default is `zlib`.
946 Default is `zlib`.
944
947
945 ``bookmarks-in-store``
948 ``bookmarks-in-store``
946 Store bookmarks in .hg/store/. This means that bookmarks are shared when
949 Store bookmarks in .hg/store/. This means that bookmarks are shared when
947 using `hg share` regardless of the `-B` option.
950 using `hg share` regardless of the `-B` option.
948
951
949 Repositories with this on-disk format require Mercurial version 5.1.
952 Repositories with this on-disk format require Mercurial version 5.1.
950
953
951 Disabled by default.
954 Disabled by default.
952
955
953
956
954 ``graph``
957 ``graph``
955 ---------
958 ---------
956
959
957 Web graph view configuration. This section let you change graph
960 Web graph view configuration. This section let you change graph
958 elements display properties by branches, for instance to make the
961 elements display properties by branches, for instance to make the
959 ``default`` branch stand out.
962 ``default`` branch stand out.
960
963
961 Each line has the following format::
964 Each line has the following format::
962
965
963 <branch>.<argument> = <value>
966 <branch>.<argument> = <value>
964
967
965 where ``<branch>`` is the name of the branch being
968 where ``<branch>`` is the name of the branch being
966 customized. Example::
969 customized. Example::
967
970
968 [graph]
971 [graph]
969 # 2px width
972 # 2px width
970 default.width = 2
973 default.width = 2
971 # red color
974 # red color
972 default.color = FF0000
975 default.color = FF0000
973
976
974 Supported arguments:
977 Supported arguments:
975
978
976 ``width``
979 ``width``
977 Set branch edges width in pixels.
980 Set branch edges width in pixels.
978
981
979 ``color``
982 ``color``
980 Set branch edges color in hexadecimal RGB notation.
983 Set branch edges color in hexadecimal RGB notation.
981
984
982 ``hooks``
985 ``hooks``
983 ---------
986 ---------
984
987
985 Commands or Python functions that get automatically executed by
988 Commands or Python functions that get automatically executed by
986 various actions such as starting or finishing a commit. Multiple
989 various actions such as starting or finishing a commit. Multiple
987 hooks can be run for the same action by appending a suffix to the
990 hooks can be run for the same action by appending a suffix to the
988 action. Overriding a site-wide hook can be done by changing its
991 action. Overriding a site-wide hook can be done by changing its
989 value or setting it to an empty string. Hooks can be prioritized
992 value or setting it to an empty string. Hooks can be prioritized
990 by adding a prefix of ``priority.`` to the hook name on a new line
993 by adding a prefix of ``priority.`` to the hook name on a new line
991 and setting the priority. The default priority is 0.
994 and setting the priority. The default priority is 0.
992
995
993 Example ``.hg/hgrc``::
996 Example ``.hg/hgrc``::
994
997
995 [hooks]
998 [hooks]
996 # update working directory after adding changesets
999 # update working directory after adding changesets
997 changegroup.update = hg update
1000 changegroup.update = hg update
998 # do not use the site-wide hook
1001 # do not use the site-wide hook
999 incoming =
1002 incoming =
1000 incoming.email = /my/email/hook
1003 incoming.email = /my/email/hook
1001 incoming.autobuild = /my/build/hook
1004 incoming.autobuild = /my/build/hook
1002 # force autobuild hook to run before other incoming hooks
1005 # force autobuild hook to run before other incoming hooks
1003 priority.incoming.autobuild = 1
1006 priority.incoming.autobuild = 1
1004
1007
1005 Most hooks are run with environment variables set that give useful
1008 Most hooks are run with environment variables set that give useful
1006 additional information. For each hook below, the environment variables
1009 additional information. For each hook below, the environment variables
1007 it is passed are listed with names in the form ``$HG_foo``. The
1010 it is passed are listed with names in the form ``$HG_foo``. The
1008 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1011 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1009 They contain the type of hook which triggered the run and the full name
1012 They contain the type of hook which triggered the run and the full name
1010 of the hook in the config, respectively. In the example above, this will
1013 of the hook in the config, respectively. In the example above, this will
1011 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1014 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1012
1015
1013 .. container:: windows
1016 .. container:: windows
1014
1017
1015 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1018 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1016 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1019 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1017 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1020 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1018 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
1021 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
1019 slash or inside of a strong quote. Strong quotes will be replaced by
1022 slash or inside of a strong quote. Strong quotes will be replaced by
1020 double quotes after processing.
1023 double quotes after processing.
1021
1024
1022 This feature is enabled by adding a prefix of ``tonative.`` to the hook
1025 This feature is enabled by adding a prefix of ``tonative.`` to the hook
1023 name on a new line, and setting it to ``True``. For example::
1026 name on a new line, and setting it to ``True``. For example::
1024
1027
1025 [hooks]
1028 [hooks]
1026 incoming.autobuild = /my/build/hook
1029 incoming.autobuild = /my/build/hook
1027 # enable translation to cmd.exe syntax for autobuild hook
1030 # enable translation to cmd.exe syntax for autobuild hook
1028 tonative.incoming.autobuild = True
1031 tonative.incoming.autobuild = True
1029
1032
1030 ``changegroup``
1033 ``changegroup``
1031 Run after a changegroup has been added via push, pull or unbundle. The ID of
1034 Run after a changegroup has been added via push, pull or unbundle. The ID of
1032 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
1035 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
1033 The URL from which changes came is in ``$HG_URL``.
1036 The URL from which changes came is in ``$HG_URL``.
1034
1037
1035 ``commit``
1038 ``commit``
1036 Run after a changeset has been created in the local repository. The ID
1039 Run after a changeset has been created in the local repository. The ID
1037 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1040 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1038 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1041 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1039
1042
1040 ``incoming``
1043 ``incoming``
1041 Run after a changeset has been pulled, pushed, or unbundled into
1044 Run after a changeset has been pulled, pushed, or unbundled into
1042 the local repository. The ID of the newly arrived changeset is in
1045 the local repository. The ID of the newly arrived changeset is in
1043 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
1046 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
1044
1047
1045 ``outgoing``
1048 ``outgoing``
1046 Run after sending changes from the local repository to another. The ID of
1049 Run after sending changes from the local repository to another. The ID of
1047 first changeset sent is in ``$HG_NODE``. The source of operation is in
1050 first changeset sent is in ``$HG_NODE``. The source of operation is in
1048 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1051 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1049
1052
1050 ``post-<command>``
1053 ``post-<command>``
1051 Run after successful invocations of the associated command. The
1054 Run after successful invocations of the associated command. The
1052 contents of the command line are passed as ``$HG_ARGS`` and the result
1055 contents of the command line are passed as ``$HG_ARGS`` and the result
1053 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1056 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1054 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1057 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1055 the python data internally passed to <command>. ``$HG_OPTS`` is a
1058 the python data internally passed to <command>. ``$HG_OPTS`` is a
1056 dictionary of options (with unspecified options set to their defaults).
1059 dictionary of options (with unspecified options set to their defaults).
1057 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1060 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1058
1061
1059 ``fail-<command>``
1062 ``fail-<command>``
1060 Run after a failed invocation of an associated command. The contents
1063 Run after a failed invocation of an associated command. The contents
1061 of the command line are passed as ``$HG_ARGS``. Parsed command line
1064 of the command line are passed as ``$HG_ARGS``. Parsed command line
1062 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1065 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1063 string representations of the python data internally passed to
1066 string representations of the python data internally passed to
1064 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1067 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1065 options set to their defaults). ``$HG_PATS`` is a list of arguments.
1068 options set to their defaults). ``$HG_PATS`` is a list of arguments.
1066 Hook failure is ignored.
1069 Hook failure is ignored.
1067
1070
1068 ``pre-<command>``
1071 ``pre-<command>``
1069 Run before executing the associated command. The contents of the
1072 Run before executing the associated command. The contents of the
1070 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1073 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1071 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1074 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1072 representations of the data internally passed to <command>. ``$HG_OPTS``
1075 representations of the data internally passed to <command>. ``$HG_OPTS``
1073 is a dictionary of options (with unspecified options set to their
1076 is a dictionary of options (with unspecified options set to their
1074 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1077 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1075 failure, the command doesn't execute and Mercurial returns the failure
1078 failure, the command doesn't execute and Mercurial returns the failure
1076 code.
1079 code.
1077
1080
1078 ``prechangegroup``
1081 ``prechangegroup``
1079 Run before a changegroup is added via push, pull or unbundle. Exit
1082 Run before a changegroup is added via push, pull or unbundle. Exit
1080 status 0 allows the changegroup to proceed. A non-zero status will
1083 status 0 allows the changegroup to proceed. A non-zero status will
1081 cause the push, pull or unbundle to fail. The URL from which changes
1084 cause the push, pull or unbundle to fail. The URL from which changes
1082 will come is in ``$HG_URL``.
1085 will come is in ``$HG_URL``.
1083
1086
1084 ``precommit``
1087 ``precommit``
1085 Run before starting a local commit. Exit status 0 allows the
1088 Run before starting a local commit. Exit status 0 allows the
1086 commit to proceed. A non-zero status will cause the commit to fail.
1089 commit to proceed. A non-zero status will cause the commit to fail.
1087 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1090 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1088
1091
1089 ``prelistkeys``
1092 ``prelistkeys``
1090 Run before listing pushkeys (like bookmarks) in the
1093 Run before listing pushkeys (like bookmarks) in the
1091 repository. A non-zero status will cause failure. The key namespace is
1094 repository. A non-zero status will cause failure. The key namespace is
1092 in ``$HG_NAMESPACE``.
1095 in ``$HG_NAMESPACE``.
1093
1096
1094 ``preoutgoing``
1097 ``preoutgoing``
1095 Run before collecting changes to send from the local repository to
1098 Run before collecting changes to send from the local repository to
1096 another. A non-zero status will cause failure. This lets you prevent
1099 another. A non-zero status will cause failure. This lets you prevent
1097 pull over HTTP or SSH. It can also prevent propagating commits (via
1100 pull over HTTP or SSH. It can also prevent propagating commits (via
1098 local pull, push (outbound) or bundle commands), but not completely,
1101 local pull, push (outbound) or bundle commands), but not completely,
1099 since you can just copy files instead. The source of operation is in
1102 since you can just copy files instead. The source of operation is in
1100 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1103 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1101 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1104 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1102 is happening on behalf of a repository on same system.
1105 is happening on behalf of a repository on same system.
1103
1106
1104 ``prepushkey``
1107 ``prepushkey``
1105 Run before a pushkey (like a bookmark) is added to the
1108 Run before a pushkey (like a bookmark) is added to the
1106 repository. A non-zero status will cause the key to be rejected. The
1109 repository. A non-zero status will cause the key to be rejected. The
1107 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1110 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1108 the old value (if any) is in ``$HG_OLD``, and the new value is in
1111 the old value (if any) is in ``$HG_OLD``, and the new value is in
1109 ``$HG_NEW``.
1112 ``$HG_NEW``.
1110
1113
1111 ``pretag``
1114 ``pretag``
1112 Run before creating a tag. Exit status 0 allows the tag to be
1115 Run before creating a tag. Exit status 0 allows the tag to be
1113 created. A non-zero status will cause the tag to fail. The ID of the
1116 created. A non-zero status will cause the tag to fail. The ID of the
1114 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1117 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1115 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1118 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1116
1119
1117 ``pretxnopen``
1120 ``pretxnopen``
1118 Run before any new repository transaction is open. The reason for the
1121 Run before any new repository transaction is open. The reason for the
1119 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1122 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1120 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1123 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1121 transaction from being opened.
1124 transaction from being opened.
1122
1125
1123 ``pretxnclose``
1126 ``pretxnclose``
1124 Run right before the transaction is actually finalized. Any repository change
1127 Run right before the transaction is actually finalized. Any repository change
1125 will be visible to the hook program. This lets you validate the transaction
1128 will be visible to the hook program. This lets you validate the transaction
1126 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1129 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1127 status will cause the transaction to be rolled back. The reason for the
1130 status will cause the transaction to be rolled back. The reason for the
1128 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1131 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1129 the transaction will be in ``HG_TXNID``. The rest of the available data will
1132 the transaction will be in ``HG_TXNID``. The rest of the available data will
1130 vary according the transaction type. New changesets will add ``$HG_NODE``
1133 vary according the transaction type. New changesets will add ``$HG_NODE``
1131 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1134 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1132 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1135 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1133 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1136 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1134 respectively, etc.
1137 respectively, etc.
1135
1138
1136 ``pretxnclose-bookmark``
1139 ``pretxnclose-bookmark``
1137 Run right before a bookmark change is actually finalized. Any repository
1140 Run right before a bookmark change is actually finalized. Any repository
1138 change will be visible to the hook program. This lets you validate the
1141 change will be visible to the hook program. This lets you validate the
1139 transaction content or change it. Exit status 0 allows the commit to
1142 transaction content or change it. Exit status 0 allows the commit to
1140 proceed. A non-zero status will cause the transaction to be rolled back.
1143 proceed. A non-zero status will cause the transaction to be rolled back.
1141 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1144 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1142 bookmark location will be available in ``$HG_NODE`` while the previous
1145 bookmark location will be available in ``$HG_NODE`` while the previous
1143 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1146 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1144 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1147 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1145 will be empty.
1148 will be empty.
1146 In addition, the reason for the transaction opening will be in
1149 In addition, the reason for the transaction opening will be in
1147 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1150 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1148 ``HG_TXNID``.
1151 ``HG_TXNID``.
1149
1152
1150 ``pretxnclose-phase``
1153 ``pretxnclose-phase``
1151 Run right before a phase change is actually finalized. Any repository change
1154 Run right before a phase change is actually finalized. Any repository change
1152 will be visible to the hook program. This lets you validate the transaction
1155 will be visible to the hook program. This lets you validate the transaction
1153 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1156 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1154 status will cause the transaction to be rolled back. The hook is called
1157 status will cause the transaction to be rolled back. The hook is called
1155 multiple times, once for each revision affected by a phase change.
1158 multiple times, once for each revision affected by a phase change.
1156 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1159 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1157 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1160 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1158 will be empty. In addition, the reason for the transaction opening will be in
1161 will be empty. In addition, the reason for the transaction opening will be in
1159 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1162 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1160 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1163 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1161 the ``$HG_OLDPHASE`` entry will be empty.
1164 the ``$HG_OLDPHASE`` entry will be empty.
1162
1165
1163 ``txnclose``
1166 ``txnclose``
1164 Run after any repository transaction has been committed. At this
1167 Run after any repository transaction has been committed. At this
1165 point, the transaction can no longer be rolled back. The hook will run
1168 point, the transaction can no longer be rolled back. The hook will run
1166 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1169 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1167 details about available variables.
1170 details about available variables.
1168
1171
1169 ``txnclose-bookmark``
1172 ``txnclose-bookmark``
1170 Run after any bookmark change has been committed. At this point, the
1173 Run after any bookmark change has been committed. At this point, the
1171 transaction can no longer be rolled back. The hook will run after the lock
1174 transaction can no longer be rolled back. The hook will run after the lock
1172 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1175 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1173 about available variables.
1176 about available variables.
1174
1177
1175 ``txnclose-phase``
1178 ``txnclose-phase``
1176 Run after any phase change has been committed. At this point, the
1179 Run after any phase change has been committed. At this point, the
1177 transaction can no longer be rolled back. The hook will run after the lock
1180 transaction can no longer be rolled back. The hook will run after the lock
1178 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1181 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1179 available variables.
1182 available variables.
1180
1183
1181 ``txnabort``
1184 ``txnabort``
1182 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1185 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1183 for details about available variables.
1186 for details about available variables.
1184
1187
1185 ``pretxnchangegroup``
1188 ``pretxnchangegroup``
1186 Run after a changegroup has been added via push, pull or unbundle, but before
1189 Run after a changegroup has been added via push, pull or unbundle, but before
1187 the transaction has been committed. The changegroup is visible to the hook
1190 the transaction has been committed. The changegroup is visible to the hook
1188 program. This allows validation of incoming changes before accepting them.
1191 program. This allows validation of incoming changes before accepting them.
1189 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1192 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1190 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1193 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1191 status will cause the transaction to be rolled back, and the push, pull or
1194 status will cause the transaction to be rolled back, and the push, pull or
1192 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1195 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1193
1196
1194 ``pretxncommit``
1197 ``pretxncommit``
1195 Run after a changeset has been created, but before the transaction is
1198 Run after a changeset has been created, but before the transaction is
1196 committed. The changeset is visible to the hook program. This allows
1199 committed. The changeset is visible to the hook program. This allows
1197 validation of the commit message and changes. Exit status 0 allows the
1200 validation of the commit message and changes. Exit status 0 allows the
1198 commit to proceed. A non-zero status will cause the transaction to
1201 commit to proceed. A non-zero status will cause the transaction to
1199 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1202 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1200 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1203 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1201
1204
1202 ``preupdate``
1205 ``preupdate``
1203 Run before updating the working directory. Exit status 0 allows
1206 Run before updating the working directory. Exit status 0 allows
1204 the update to proceed. A non-zero status will prevent the update.
1207 the update to proceed. A non-zero status will prevent the update.
1205 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1208 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1206 merge, the ID of second new parent is in ``$HG_PARENT2``.
1209 merge, the ID of second new parent is in ``$HG_PARENT2``.
1207
1210
1208 ``listkeys``
1211 ``listkeys``
1209 Run after listing pushkeys (like bookmarks) in the repository. The
1212 Run after listing pushkeys (like bookmarks) in the repository. The
1210 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1213 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1211 dictionary containing the keys and values.
1214 dictionary containing the keys and values.
1212
1215
1213 ``pushkey``
1216 ``pushkey``
1214 Run after a pushkey (like a bookmark) is added to the
1217 Run after a pushkey (like a bookmark) is added to the
1215 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1218 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1216 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1219 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1217 value is in ``$HG_NEW``.
1220 value is in ``$HG_NEW``.
1218
1221
1219 ``tag``
1222 ``tag``
1220 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1223 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1221 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1224 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1222 the repository if ``$HG_LOCAL=0``.
1225 the repository if ``$HG_LOCAL=0``.
1223
1226
1224 ``update``
1227 ``update``
1225 Run after updating the working directory. The changeset ID of first
1228 Run after updating the working directory. The changeset ID of first
1226 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1229 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1227 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1230 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1228 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1231 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1229
1232
1230 .. note::
1233 .. note::
1231
1234
1232 It is generally better to use standard hooks rather than the
1235 It is generally better to use standard hooks rather than the
1233 generic pre- and post- command hooks, as they are guaranteed to be
1236 generic pre- and post- command hooks, as they are guaranteed to be
1234 called in the appropriate contexts for influencing transactions.
1237 called in the appropriate contexts for influencing transactions.
1235 Also, hooks like "commit" will be called in all contexts that
1238 Also, hooks like "commit" will be called in all contexts that
1236 generate a commit (e.g. tag) and not just the commit command.
1239 generate a commit (e.g. tag) and not just the commit command.
1237
1240
1238 .. note::
1241 .. note::
1239
1242
1240 Environment variables with empty values may not be passed to
1243 Environment variables with empty values may not be passed to
1241 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1244 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1242 will have an empty value under Unix-like platforms for non-merge
1245 will have an empty value under Unix-like platforms for non-merge
1243 changesets, while it will not be available at all under Windows.
1246 changesets, while it will not be available at all under Windows.
1244
1247
1245 The syntax for Python hooks is as follows::
1248 The syntax for Python hooks is as follows::
1246
1249
1247 hookname = python:modulename.submodule.callable
1250 hookname = python:modulename.submodule.callable
1248 hookname = python:/path/to/python/module.py:callable
1251 hookname = python:/path/to/python/module.py:callable
1249
1252
1250 Python hooks are run within the Mercurial process. Each hook is
1253 Python hooks are run within the Mercurial process. Each hook is
1251 called with at least three keyword arguments: a ui object (keyword
1254 called with at least three keyword arguments: a ui object (keyword
1252 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1255 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1253 keyword that tells what kind of hook is used. Arguments listed as
1256 keyword that tells what kind of hook is used. Arguments listed as
1254 environment variables above are passed as keyword arguments, with no
1257 environment variables above are passed as keyword arguments, with no
1255 ``HG_`` prefix, and names in lower case.
1258 ``HG_`` prefix, and names in lower case.
1256
1259
1257 If a Python hook returns a "true" value or raises an exception, this
1260 If a Python hook returns a "true" value or raises an exception, this
1258 is treated as a failure.
1261 is treated as a failure.
1259
1262
1260
1263
1261 ``hostfingerprints``
1264 ``hostfingerprints``
1262 --------------------
1265 --------------------
1263
1266
1264 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1267 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1265
1268
1266 Fingerprints of the certificates of known HTTPS servers.
1269 Fingerprints of the certificates of known HTTPS servers.
1267
1270
1268 A HTTPS connection to a server with a fingerprint configured here will
1271 A HTTPS connection to a server with a fingerprint configured here will
1269 only succeed if the servers certificate matches the fingerprint.
1272 only succeed if the servers certificate matches the fingerprint.
1270 This is very similar to how ssh known hosts works.
1273 This is very similar to how ssh known hosts works.
1271
1274
1272 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1275 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1273 Multiple values can be specified (separated by spaces or commas). This can
1276 Multiple values can be specified (separated by spaces or commas). This can
1274 be used to define both old and new fingerprints while a host transitions
1277 be used to define both old and new fingerprints while a host transitions
1275 to a new certificate.
1278 to a new certificate.
1276
1279
1277 The CA chain and web.cacerts is not used for servers with a fingerprint.
1280 The CA chain and web.cacerts is not used for servers with a fingerprint.
1278
1281
1279 For example::
1282 For example::
1280
1283
1281 [hostfingerprints]
1284 [hostfingerprints]
1282 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1285 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1283 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1286 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1284
1287
1285 ``hostsecurity``
1288 ``hostsecurity``
1286 ----------------
1289 ----------------
1287
1290
1288 Used to specify global and per-host security settings for connecting to
1291 Used to specify global and per-host security settings for connecting to
1289 other machines.
1292 other machines.
1290
1293
1291 The following options control default behavior for all hosts.
1294 The following options control default behavior for all hosts.
1292
1295
1293 ``ciphers``
1296 ``ciphers``
1294 Defines the cryptographic ciphers to use for connections.
1297 Defines the cryptographic ciphers to use for connections.
1295
1298
1296 Value must be a valid OpenSSL Cipher List Format as documented at
1299 Value must be a valid OpenSSL Cipher List Format as documented at
1297 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1300 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1298
1301
1299 This setting is for advanced users only. Setting to incorrect values
1302 This setting is for advanced users only. Setting to incorrect values
1300 can significantly lower connection security or decrease performance.
1303 can significantly lower connection security or decrease performance.
1301 You have been warned.
1304 You have been warned.
1302
1305
1303 This option requires Python 2.7.
1306 This option requires Python 2.7.
1304
1307
1305 ``minimumprotocol``
1308 ``minimumprotocol``
1306 Defines the minimum channel encryption protocol to use.
1309 Defines the minimum channel encryption protocol to use.
1307
1310
1308 By default, the highest version of TLS supported by both client and server
1311 By default, the highest version of TLS supported by both client and server
1309 is used.
1312 is used.
1310
1313
1311 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1314 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1312
1315
1313 When running on an old Python version, only ``tls1.0`` is allowed since
1316 When running on an old Python version, only ``tls1.0`` is allowed since
1314 old versions of Python only support up to TLS 1.0.
1317 old versions of Python only support up to TLS 1.0.
1315
1318
1316 When running a Python that supports modern TLS versions, the default is
1319 When running a Python that supports modern TLS versions, the default is
1317 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1320 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1318 weakens security and should only be used as a feature of last resort if
1321 weakens security and should only be used as a feature of last resort if
1319 a server does not support TLS 1.1+.
1322 a server does not support TLS 1.1+.
1320
1323
1321 Options in the ``[hostsecurity]`` section can have the form
1324 Options in the ``[hostsecurity]`` section can have the form
1322 ``hostname``:``setting``. This allows multiple settings to be defined on a
1325 ``hostname``:``setting``. This allows multiple settings to be defined on a
1323 per-host basis.
1326 per-host basis.
1324
1327
1325 The following per-host settings can be defined.
1328 The following per-host settings can be defined.
1326
1329
1327 ``ciphers``
1330 ``ciphers``
1328 This behaves like ``ciphers`` as described above except it only applies
1331 This behaves like ``ciphers`` as described above except it only applies
1329 to the host on which it is defined.
1332 to the host on which it is defined.
1330
1333
1331 ``fingerprints``
1334 ``fingerprints``
1332 A list of hashes of the DER encoded peer/remote certificate. Values have
1335 A list of hashes of the DER encoded peer/remote certificate. Values have
1333 the form ``algorithm``:``fingerprint``. e.g.
1336 the form ``algorithm``:``fingerprint``. e.g.
1334 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1337 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1335 In addition, colons (``:``) can appear in the fingerprint part.
1338 In addition, colons (``:``) can appear in the fingerprint part.
1336
1339
1337 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1340 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1338 ``sha512``.
1341 ``sha512``.
1339
1342
1340 Use of ``sha256`` or ``sha512`` is preferred.
1343 Use of ``sha256`` or ``sha512`` is preferred.
1341
1344
1342 If a fingerprint is specified, the CA chain is not validated for this
1345 If a fingerprint is specified, the CA chain is not validated for this
1343 host and Mercurial will require the remote certificate to match one
1346 host and Mercurial will require the remote certificate to match one
1344 of the fingerprints specified. This means if the server updates its
1347 of the fingerprints specified. This means if the server updates its
1345 certificate, Mercurial will abort until a new fingerprint is defined.
1348 certificate, Mercurial will abort until a new fingerprint is defined.
1346 This can provide stronger security than traditional CA-based validation
1349 This can provide stronger security than traditional CA-based validation
1347 at the expense of convenience.
1350 at the expense of convenience.
1348
1351
1349 This option takes precedence over ``verifycertsfile``.
1352 This option takes precedence over ``verifycertsfile``.
1350
1353
1351 ``minimumprotocol``
1354 ``minimumprotocol``
1352 This behaves like ``minimumprotocol`` as described above except it
1355 This behaves like ``minimumprotocol`` as described above except it
1353 only applies to the host on which it is defined.
1356 only applies to the host on which it is defined.
1354
1357
1355 ``verifycertsfile``
1358 ``verifycertsfile``
1356 Path to file a containing a list of PEM encoded certificates used to
1359 Path to file a containing a list of PEM encoded certificates used to
1357 verify the server certificate. Environment variables and ``~user``
1360 verify the server certificate. Environment variables and ``~user``
1358 constructs are expanded in the filename.
1361 constructs are expanded in the filename.
1359
1362
1360 The server certificate or the certificate's certificate authority (CA)
1363 The server certificate or the certificate's certificate authority (CA)
1361 must match a certificate from this file or certificate verification
1364 must match a certificate from this file or certificate verification
1362 will fail and connections to the server will be refused.
1365 will fail and connections to the server will be refused.
1363
1366
1364 If defined, only certificates provided by this file will be used:
1367 If defined, only certificates provided by this file will be used:
1365 ``web.cacerts`` and any system/default certificates will not be
1368 ``web.cacerts`` and any system/default certificates will not be
1366 used.
1369 used.
1367
1370
1368 This option has no effect if the per-host ``fingerprints`` option
1371 This option has no effect if the per-host ``fingerprints`` option
1369 is set.
1372 is set.
1370
1373
1371 The format of the file is as follows::
1374 The format of the file is as follows::
1372
1375
1373 -----BEGIN CERTIFICATE-----
1376 -----BEGIN CERTIFICATE-----
1374 ... (certificate in base64 PEM encoding) ...
1377 ... (certificate in base64 PEM encoding) ...
1375 -----END CERTIFICATE-----
1378 -----END CERTIFICATE-----
1376 -----BEGIN CERTIFICATE-----
1379 -----BEGIN CERTIFICATE-----
1377 ... (certificate in base64 PEM encoding) ...
1380 ... (certificate in base64 PEM encoding) ...
1378 -----END CERTIFICATE-----
1381 -----END CERTIFICATE-----
1379
1382
1380 For example::
1383 For example::
1381
1384
1382 [hostsecurity]
1385 [hostsecurity]
1383 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1386 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1384 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1387 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1385 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1388 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1386 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1389 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1387
1390
1388 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1391 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1389 when connecting to ``hg.example.com``::
1392 when connecting to ``hg.example.com``::
1390
1393
1391 [hostsecurity]
1394 [hostsecurity]
1392 minimumprotocol = tls1.2
1395 minimumprotocol = tls1.2
1393 hg.example.com:minimumprotocol = tls1.1
1396 hg.example.com:minimumprotocol = tls1.1
1394
1397
1395 ``http_proxy``
1398 ``http_proxy``
1396 --------------
1399 --------------
1397
1400
1398 Used to access web-based Mercurial repositories through a HTTP
1401 Used to access web-based Mercurial repositories through a HTTP
1399 proxy.
1402 proxy.
1400
1403
1401 ``host``
1404 ``host``
1402 Host name and (optional) port of the proxy server, for example
1405 Host name and (optional) port of the proxy server, for example
1403 "myproxy:8000".
1406 "myproxy:8000".
1404
1407
1405 ``no``
1408 ``no``
1406 Optional. Comma-separated list of host names that should bypass
1409 Optional. Comma-separated list of host names that should bypass
1407 the proxy.
1410 the proxy.
1408
1411
1409 ``passwd``
1412 ``passwd``
1410 Optional. Password to authenticate with at the proxy server.
1413 Optional. Password to authenticate with at the proxy server.
1411
1414
1412 ``user``
1415 ``user``
1413 Optional. User name to authenticate with at the proxy server.
1416 Optional. User name to authenticate with at the proxy server.
1414
1417
1415 ``always``
1418 ``always``
1416 Optional. Always use the proxy, even for localhost and any entries
1419 Optional. Always use the proxy, even for localhost and any entries
1417 in ``http_proxy.no``. (default: False)
1420 in ``http_proxy.no``. (default: False)
1418
1421
1419 ``http``
1422 ``http``
1420 ----------
1423 ----------
1421
1424
1422 Used to configure access to Mercurial repositories via HTTP.
1425 Used to configure access to Mercurial repositories via HTTP.
1423
1426
1424 ``timeout``
1427 ``timeout``
1425 If set, blocking operations will timeout after that many seconds.
1428 If set, blocking operations will timeout after that many seconds.
1426 (default: None)
1429 (default: None)
1427
1430
1428 ``merge``
1431 ``merge``
1429 ---------
1432 ---------
1430
1433
1431 This section specifies behavior during merges and updates.
1434 This section specifies behavior during merges and updates.
1432
1435
1433 ``checkignored``
1436 ``checkignored``
1434 Controls behavior when an ignored file on disk has the same name as a tracked
1437 Controls behavior when an ignored file on disk has the same name as a tracked
1435 file in the changeset being merged or updated to, and has different
1438 file in the changeset being merged or updated to, and has different
1436 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1439 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1437 abort on such files. With ``warn``, warn on such files and back them up as
1440 abort on such files. With ``warn``, warn on such files and back them up as
1438 ``.orig``. With ``ignore``, don't print a warning and back them up as
1441 ``.orig``. With ``ignore``, don't print a warning and back them up as
1439 ``.orig``. (default: ``abort``)
1442 ``.orig``. (default: ``abort``)
1440
1443
1441 ``checkunknown``
1444 ``checkunknown``
1442 Controls behavior when an unknown file that isn't ignored has the same name
1445 Controls behavior when an unknown file that isn't ignored has the same name
1443 as a tracked file in the changeset being merged or updated to, and has
1446 as a tracked file in the changeset being merged or updated to, and has
1444 different contents. Similar to ``merge.checkignored``, except for files that
1447 different contents. Similar to ``merge.checkignored``, except for files that
1445 are not ignored. (default: ``abort``)
1448 are not ignored. (default: ``abort``)
1446
1449
1447 ``on-failure``
1450 ``on-failure``
1448 When set to ``continue`` (the default), the merge process attempts to
1451 When set to ``continue`` (the default), the merge process attempts to
1449 merge all unresolved files using the merge chosen tool, regardless of
1452 merge all unresolved files using the merge chosen tool, regardless of
1450 whether previous file merge attempts during the process succeeded or not.
1453 whether previous file merge attempts during the process succeeded or not.
1451 Setting this to ``prompt`` will prompt after any merge failure continue
1454 Setting this to ``prompt`` will prompt after any merge failure continue
1452 or halt the merge process. Setting this to ``halt`` will automatically
1455 or halt the merge process. Setting this to ``halt`` will automatically
1453 halt the merge process on any merge tool failure. The merge process
1456 halt the merge process on any merge tool failure. The merge process
1454 can be restarted by using the ``resolve`` command. When a merge is
1457 can be restarted by using the ``resolve`` command. When a merge is
1455 halted, the repository is left in a normal ``unresolved`` merge state.
1458 halted, the repository is left in a normal ``unresolved`` merge state.
1456 (default: ``continue``)
1459 (default: ``continue``)
1457
1460
1458 ``strict-capability-check``
1461 ``strict-capability-check``
1459 Whether capabilities of internal merge tools are checked strictly
1462 Whether capabilities of internal merge tools are checked strictly
1460 or not, while examining rules to decide merge tool to be used.
1463 or not, while examining rules to decide merge tool to be used.
1461 (default: False)
1464 (default: False)
1462
1465
1463 ``merge-patterns``
1466 ``merge-patterns``
1464 ------------------
1467 ------------------
1465
1468
1466 This section specifies merge tools to associate with particular file
1469 This section specifies merge tools to associate with particular file
1467 patterns. Tools matched here will take precedence over the default
1470 patterns. Tools matched here will take precedence over the default
1468 merge tool. Patterns are globs by default, rooted at the repository
1471 merge tool. Patterns are globs by default, rooted at the repository
1469 root.
1472 root.
1470
1473
1471 Example::
1474 Example::
1472
1475
1473 [merge-patterns]
1476 [merge-patterns]
1474 **.c = kdiff3
1477 **.c = kdiff3
1475 **.jpg = myimgmerge
1478 **.jpg = myimgmerge
1476
1479
1477 ``merge-tools``
1480 ``merge-tools``
1478 ---------------
1481 ---------------
1479
1482
1480 This section configures external merge tools to use for file-level
1483 This section configures external merge tools to use for file-level
1481 merges. This section has likely been preconfigured at install time.
1484 merges. This section has likely been preconfigured at install time.
1482 Use :hg:`config merge-tools` to check the existing configuration.
1485 Use :hg:`config merge-tools` to check the existing configuration.
1483 Also see :hg:`help merge-tools` for more details.
1486 Also see :hg:`help merge-tools` for more details.
1484
1487
1485 Example ``~/.hgrc``::
1488 Example ``~/.hgrc``::
1486
1489
1487 [merge-tools]
1490 [merge-tools]
1488 # Override stock tool location
1491 # Override stock tool location
1489 kdiff3.executable = ~/bin/kdiff3
1492 kdiff3.executable = ~/bin/kdiff3
1490 # Specify command line
1493 # Specify command line
1491 kdiff3.args = $base $local $other -o $output
1494 kdiff3.args = $base $local $other -o $output
1492 # Give higher priority
1495 # Give higher priority
1493 kdiff3.priority = 1
1496 kdiff3.priority = 1
1494
1497
1495 # Changing the priority of preconfigured tool
1498 # Changing the priority of preconfigured tool
1496 meld.priority = 0
1499 meld.priority = 0
1497
1500
1498 # Disable a preconfigured tool
1501 # Disable a preconfigured tool
1499 vimdiff.disabled = yes
1502 vimdiff.disabled = yes
1500
1503
1501 # Define new tool
1504 # Define new tool
1502 myHtmlTool.args = -m $local $other $base $output
1505 myHtmlTool.args = -m $local $other $base $output
1503 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1506 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1504 myHtmlTool.priority = 1
1507 myHtmlTool.priority = 1
1505
1508
1506 Supported arguments:
1509 Supported arguments:
1507
1510
1508 ``priority``
1511 ``priority``
1509 The priority in which to evaluate this tool.
1512 The priority in which to evaluate this tool.
1510 (default: 0)
1513 (default: 0)
1511
1514
1512 ``executable``
1515 ``executable``
1513 Either just the name of the executable or its pathname.
1516 Either just the name of the executable or its pathname.
1514
1517
1515 .. container:: windows
1518 .. container:: windows
1516
1519
1517 On Windows, the path can use environment variables with ${ProgramFiles}
1520 On Windows, the path can use environment variables with ${ProgramFiles}
1518 syntax.
1521 syntax.
1519
1522
1520 (default: the tool name)
1523 (default: the tool name)
1521
1524
1522 ``args``
1525 ``args``
1523 The arguments to pass to the tool executable. You can refer to the
1526 The arguments to pass to the tool executable. You can refer to the
1524 files being merged as well as the output file through these
1527 files being merged as well as the output file through these
1525 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1528 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1526
1529
1527 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1530 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1528 being performed. During an update or merge, ``$local`` represents the original
1531 being performed. During an update or merge, ``$local`` represents the original
1529 state of the file, while ``$other`` represents the commit you are updating to or
1532 state of the file, while ``$other`` represents the commit you are updating to or
1530 the commit you are merging with. During a rebase, ``$local`` represents the
1533 the commit you are merging with. During a rebase, ``$local`` represents the
1531 destination of the rebase, and ``$other`` represents the commit being rebased.
1534 destination of the rebase, and ``$other`` represents the commit being rebased.
1532
1535
1533 Some operations define custom labels to assist with identifying the revisions,
1536 Some operations define custom labels to assist with identifying the revisions,
1534 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1537 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1535 labels are not available, these will be ``local``, ``other``, and ``base``,
1538 labels are not available, these will be ``local``, ``other``, and ``base``,
1536 respectively.
1539 respectively.
1537 (default: ``$local $base $other``)
1540 (default: ``$local $base $other``)
1538
1541
1539 ``premerge``
1542 ``premerge``
1540 Attempt to run internal non-interactive 3-way merge tool before
1543 Attempt to run internal non-interactive 3-way merge tool before
1541 launching external tool. Options are ``true``, ``false``, ``keep``,
1544 launching external tool. Options are ``true``, ``false``, ``keep``,
1542 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1545 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1543 will leave markers in the file if the premerge fails. The ``keep-merge3``
1546 will leave markers in the file if the premerge fails. The ``keep-merge3``
1544 will do the same but include information about the base of the merge in the
1547 will do the same but include information about the base of the merge in the
1545 marker (see internal :merge3 in :hg:`help merge-tools`). The
1548 marker (see internal :merge3 in :hg:`help merge-tools`). The
1546 ``keep-mergediff`` option is similar but uses a different marker style
1549 ``keep-mergediff`` option is similar but uses a different marker style
1547 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1550 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1548
1551
1549 ``binary``
1552 ``binary``
1550 This tool can merge binary files. (default: False, unless tool
1553 This tool can merge binary files. (default: False, unless tool
1551 was selected by file pattern match)
1554 was selected by file pattern match)
1552
1555
1553 ``symlink``
1556 ``symlink``
1554 This tool can merge symlinks. (default: False)
1557 This tool can merge symlinks. (default: False)
1555
1558
1556 ``check``
1559 ``check``
1557 A list of merge success-checking options:
1560 A list of merge success-checking options:
1558
1561
1559 ``changed``
1562 ``changed``
1560 Ask whether merge was successful when the merged file shows no changes.
1563 Ask whether merge was successful when the merged file shows no changes.
1561 ``conflicts``
1564 ``conflicts``
1562 Check whether there are conflicts even though the tool reported success.
1565 Check whether there are conflicts even though the tool reported success.
1563 ``prompt``
1566 ``prompt``
1564 Always prompt for merge success, regardless of success reported by tool.
1567 Always prompt for merge success, regardless of success reported by tool.
1565
1568
1566 ``fixeol``
1569 ``fixeol``
1567 Attempt to fix up EOL changes caused by the merge tool.
1570 Attempt to fix up EOL changes caused by the merge tool.
1568 (default: False)
1571 (default: False)
1569
1572
1570 ``gui``
1573 ``gui``
1571 This tool requires a graphical interface to run. (default: False)
1574 This tool requires a graphical interface to run. (default: False)
1572
1575
1573 ``mergemarkers``
1576 ``mergemarkers``
1574 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1577 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1575 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1578 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1576 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1579 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1577 markers generated during premerge will be ``detailed`` if either this option or
1580 markers generated during premerge will be ``detailed`` if either this option or
1578 the corresponding option in the ``[ui]`` section is ``detailed``.
1581 the corresponding option in the ``[ui]`` section is ``detailed``.
1579 (default: ``basic``)
1582 (default: ``basic``)
1580
1583
1581 ``mergemarkertemplate``
1584 ``mergemarkertemplate``
1582 This setting can be used to override ``mergemarker`` from the
1585 This setting can be used to override ``mergemarker`` from the
1583 ``[command-templates]`` section on a per-tool basis; this applies to the
1586 ``[command-templates]`` section on a per-tool basis; this applies to the
1584 ``$label``-prefixed variables and to the conflict markers that are generated
1587 ``$label``-prefixed variables and to the conflict markers that are generated
1585 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1588 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1586 in ``[ui]`` for more information.
1589 in ``[ui]`` for more information.
1587
1590
1588 .. container:: windows
1591 .. container:: windows
1589
1592
1590 ``regkey``
1593 ``regkey``
1591 Windows registry key which describes install location of this
1594 Windows registry key which describes install location of this
1592 tool. Mercurial will search for this key first under
1595 tool. Mercurial will search for this key first under
1593 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1596 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1594 (default: None)
1597 (default: None)
1595
1598
1596 ``regkeyalt``
1599 ``regkeyalt``
1597 An alternate Windows registry key to try if the first key is not
1600 An alternate Windows registry key to try if the first key is not
1598 found. The alternate key uses the same ``regname`` and ``regappend``
1601 found. The alternate key uses the same ``regname`` and ``regappend``
1599 semantics of the primary key. The most common use for this key
1602 semantics of the primary key. The most common use for this key
1600 is to search for 32bit applications on 64bit operating systems.
1603 is to search for 32bit applications on 64bit operating systems.
1601 (default: None)
1604 (default: None)
1602
1605
1603 ``regname``
1606 ``regname``
1604 Name of value to read from specified registry key.
1607 Name of value to read from specified registry key.
1605 (default: the unnamed (default) value)
1608 (default: the unnamed (default) value)
1606
1609
1607 ``regappend``
1610 ``regappend``
1608 String to append to the value read from the registry, typically
1611 String to append to the value read from the registry, typically
1609 the executable name of the tool.
1612 the executable name of the tool.
1610 (default: None)
1613 (default: None)
1611
1614
1612 ``pager``
1615 ``pager``
1613 ---------
1616 ---------
1614
1617
1615 Setting used to control when to paginate and with what external tool. See
1618 Setting used to control when to paginate and with what external tool. See
1616 :hg:`help pager` for details.
1619 :hg:`help pager` for details.
1617
1620
1618 ``pager``
1621 ``pager``
1619 Define the external tool used as pager.
1622 Define the external tool used as pager.
1620
1623
1621 If no pager is set, Mercurial uses the environment variable $PAGER.
1624 If no pager is set, Mercurial uses the environment variable $PAGER.
1622 If neither pager.pager, nor $PAGER is set, a default pager will be
1625 If neither pager.pager, nor $PAGER is set, a default pager will be
1623 used, typically `less` on Unix and `more` on Windows. Example::
1626 used, typically `less` on Unix and `more` on Windows. Example::
1624
1627
1625 [pager]
1628 [pager]
1626 pager = less -FRX
1629 pager = less -FRX
1627
1630
1628 ``ignore``
1631 ``ignore``
1629 List of commands to disable the pager for. Example::
1632 List of commands to disable the pager for. Example::
1630
1633
1631 [pager]
1634 [pager]
1632 ignore = version, help, update
1635 ignore = version, help, update
1633
1636
1634 ``patch``
1637 ``patch``
1635 ---------
1638 ---------
1636
1639
1637 Settings used when applying patches, for instance through the 'import'
1640 Settings used when applying patches, for instance through the 'import'
1638 command or with Mercurial Queues extension.
1641 command or with Mercurial Queues extension.
1639
1642
1640 ``eol``
1643 ``eol``
1641 When set to 'strict' patch content and patched files end of lines
1644 When set to 'strict' patch content and patched files end of lines
1642 are preserved. When set to ``lf`` or ``crlf``, both files end of
1645 are preserved. When set to ``lf`` or ``crlf``, both files end of
1643 lines are ignored when patching and the result line endings are
1646 lines are ignored when patching and the result line endings are
1644 normalized to either LF (Unix) or CRLF (Windows). When set to
1647 normalized to either LF (Unix) or CRLF (Windows). When set to
1645 ``auto``, end of lines are again ignored while patching but line
1648 ``auto``, end of lines are again ignored while patching but line
1646 endings in patched files are normalized to their original setting
1649 endings in patched files are normalized to their original setting
1647 on a per-file basis. If target file does not exist or has no end
1650 on a per-file basis. If target file does not exist or has no end
1648 of line, patch line endings are preserved.
1651 of line, patch line endings are preserved.
1649 (default: strict)
1652 (default: strict)
1650
1653
1651 ``fuzz``
1654 ``fuzz``
1652 The number of lines of 'fuzz' to allow when applying patches. This
1655 The number of lines of 'fuzz' to allow when applying patches. This
1653 controls how much context the patcher is allowed to ignore when
1656 controls how much context the patcher is allowed to ignore when
1654 trying to apply a patch.
1657 trying to apply a patch.
1655 (default: 2)
1658 (default: 2)
1656
1659
1657 ``paths``
1660 ``paths``
1658 ---------
1661 ---------
1659
1662
1660 Assigns symbolic names and behavior to repositories.
1663 Assigns symbolic names and behavior to repositories.
1661
1664
1662 Options are symbolic names defining the URL or directory that is the
1665 Options are symbolic names defining the URL or directory that is the
1663 location of the repository. Example::
1666 location of the repository. Example::
1664
1667
1665 [paths]
1668 [paths]
1666 my_server = https://example.com/my_repo
1669 my_server = https://example.com/my_repo
1667 local_path = /home/me/repo
1670 local_path = /home/me/repo
1668
1671
1669 These symbolic names can be used from the command line. To pull
1672 These symbolic names can be used from the command line. To pull
1670 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1673 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1671 :hg:`push local_path`.
1674 :hg:`push local_path`.
1672
1675
1673 Options containing colons (``:``) denote sub-options that can influence
1676 Options containing colons (``:``) denote sub-options that can influence
1674 behavior for that specific path. Example::
1677 behavior for that specific path. Example::
1675
1678
1676 [paths]
1679 [paths]
1677 my_server = https://example.com/my_path
1680 my_server = https://example.com/my_path
1678 my_server:pushurl = ssh://example.com/my_path
1681 my_server:pushurl = ssh://example.com/my_path
1679
1682
1680 The following sub-options can be defined:
1683 The following sub-options can be defined:
1681
1684
1682 ``pushurl``
1685 ``pushurl``
1683 The URL to use for push operations. If not defined, the location
1686 The URL to use for push operations. If not defined, the location
1684 defined by the path's main entry is used.
1687 defined by the path's main entry is used.
1685
1688
1686 ``pushrev``
1689 ``pushrev``
1687 A revset defining which revisions to push by default.
1690 A revset defining which revisions to push by default.
1688
1691
1689 When :hg:`push` is executed without a ``-r`` argument, the revset
1692 When :hg:`push` is executed without a ``-r`` argument, the revset
1690 defined by this sub-option is evaluated to determine what to push.
1693 defined by this sub-option is evaluated to determine what to push.
1691
1694
1692 For example, a value of ``.`` will push the working directory's
1695 For example, a value of ``.`` will push the working directory's
1693 revision by default.
1696 revision by default.
1694
1697
1695 Revsets specifying bookmarks will not result in the bookmark being
1698 Revsets specifying bookmarks will not result in the bookmark being
1696 pushed.
1699 pushed.
1697
1700
1698 The following special named paths exist:
1701 The following special named paths exist:
1699
1702
1700 ``default``
1703 ``default``
1701 The URL or directory to use when no source or remote is specified.
1704 The URL or directory to use when no source or remote is specified.
1702
1705
1703 :hg:`clone` will automatically define this path to the location the
1706 :hg:`clone` will automatically define this path to the location the
1704 repository was cloned from.
1707 repository was cloned from.
1705
1708
1706 ``default-push``
1709 ``default-push``
1707 (deprecated) The URL or directory for the default :hg:`push` location.
1710 (deprecated) The URL or directory for the default :hg:`push` location.
1708 ``default:pushurl`` should be used instead.
1711 ``default:pushurl`` should be used instead.
1709
1712
1710 ``phases``
1713 ``phases``
1711 ----------
1714 ----------
1712
1715
1713 Specifies default handling of phases. See :hg:`help phases` for more
1716 Specifies default handling of phases. See :hg:`help phases` for more
1714 information about working with phases.
1717 information about working with phases.
1715
1718
1716 ``publish``
1719 ``publish``
1717 Controls draft phase behavior when working as a server. When true,
1720 Controls draft phase behavior when working as a server. When true,
1718 pushed changesets are set to public in both client and server and
1721 pushed changesets are set to public in both client and server and
1719 pulled or cloned changesets are set to public in the client.
1722 pulled or cloned changesets are set to public in the client.
1720 (default: True)
1723 (default: True)
1721
1724
1722 ``new-commit``
1725 ``new-commit``
1723 Phase of newly-created commits.
1726 Phase of newly-created commits.
1724 (default: draft)
1727 (default: draft)
1725
1728
1726 ``checksubrepos``
1729 ``checksubrepos``
1727 Check the phase of the current revision of each subrepository. Allowed
1730 Check the phase of the current revision of each subrepository. Allowed
1728 values are "ignore", "follow" and "abort". For settings other than
1731 values are "ignore", "follow" and "abort". For settings other than
1729 "ignore", the phase of the current revision of each subrepository is
1732 "ignore", the phase of the current revision of each subrepository is
1730 checked before committing the parent repository. If any of those phases is
1733 checked before committing the parent repository. If any of those phases is
1731 greater than the phase of the parent repository (e.g. if a subrepo is in a
1734 greater than the phase of the parent repository (e.g. if a subrepo is in a
1732 "secret" phase while the parent repo is in "draft" phase), the commit is
1735 "secret" phase while the parent repo is in "draft" phase), the commit is
1733 either aborted (if checksubrepos is set to "abort") or the higher phase is
1736 either aborted (if checksubrepos is set to "abort") or the higher phase is
1734 used for the parent repository commit (if set to "follow").
1737 used for the parent repository commit (if set to "follow").
1735 (default: follow)
1738 (default: follow)
1736
1739
1737
1740
1738 ``profiling``
1741 ``profiling``
1739 -------------
1742 -------------
1740
1743
1741 Specifies profiling type, format, and file output. Two profilers are
1744 Specifies profiling type, format, and file output. Two profilers are
1742 supported: an instrumenting profiler (named ``ls``), and a sampling
1745 supported: an instrumenting profiler (named ``ls``), and a sampling
1743 profiler (named ``stat``).
1746 profiler (named ``stat``).
1744
1747
1745 In this section description, 'profiling data' stands for the raw data
1748 In this section description, 'profiling data' stands for the raw data
1746 collected during profiling, while 'profiling report' stands for a
1749 collected during profiling, while 'profiling report' stands for a
1747 statistical text report generated from the profiling data.
1750 statistical text report generated from the profiling data.
1748
1751
1749 ``enabled``
1752 ``enabled``
1750 Enable the profiler.
1753 Enable the profiler.
1751 (default: false)
1754 (default: false)
1752
1755
1753 This is equivalent to passing ``--profile`` on the command line.
1756 This is equivalent to passing ``--profile`` on the command line.
1754
1757
1755 ``type``
1758 ``type``
1756 The type of profiler to use.
1759 The type of profiler to use.
1757 (default: stat)
1760 (default: stat)
1758
1761
1759 ``ls``
1762 ``ls``
1760 Use Python's built-in instrumenting profiler. This profiler
1763 Use Python's built-in instrumenting profiler. This profiler
1761 works on all platforms, but each line number it reports is the
1764 works on all platforms, but each line number it reports is the
1762 first line of a function. This restriction makes it difficult to
1765 first line of a function. This restriction makes it difficult to
1763 identify the expensive parts of a non-trivial function.
1766 identify the expensive parts of a non-trivial function.
1764 ``stat``
1767 ``stat``
1765 Use a statistical profiler, statprof. This profiler is most
1768 Use a statistical profiler, statprof. This profiler is most
1766 useful for profiling commands that run for longer than about 0.1
1769 useful for profiling commands that run for longer than about 0.1
1767 seconds.
1770 seconds.
1768
1771
1769 ``format``
1772 ``format``
1770 Profiling format. Specific to the ``ls`` instrumenting profiler.
1773 Profiling format. Specific to the ``ls`` instrumenting profiler.
1771 (default: text)
1774 (default: text)
1772
1775
1773 ``text``
1776 ``text``
1774 Generate a profiling report. When saving to a file, it should be
1777 Generate a profiling report. When saving to a file, it should be
1775 noted that only the report is saved, and the profiling data is
1778 noted that only the report is saved, and the profiling data is
1776 not kept.
1779 not kept.
1777 ``kcachegrind``
1780 ``kcachegrind``
1778 Format profiling data for kcachegrind use: when saving to a
1781 Format profiling data for kcachegrind use: when saving to a
1779 file, the generated file can directly be loaded into
1782 file, the generated file can directly be loaded into
1780 kcachegrind.
1783 kcachegrind.
1781
1784
1782 ``statformat``
1785 ``statformat``
1783 Profiling format for the ``stat`` profiler.
1786 Profiling format for the ``stat`` profiler.
1784 (default: hotpath)
1787 (default: hotpath)
1785
1788
1786 ``hotpath``
1789 ``hotpath``
1787 Show a tree-based display containing the hot path of execution (where
1790 Show a tree-based display containing the hot path of execution (where
1788 most time was spent).
1791 most time was spent).
1789 ``bymethod``
1792 ``bymethod``
1790 Show a table of methods ordered by how frequently they are active.
1793 Show a table of methods ordered by how frequently they are active.
1791 ``byline``
1794 ``byline``
1792 Show a table of lines in files ordered by how frequently they are active.
1795 Show a table of lines in files ordered by how frequently they are active.
1793 ``json``
1796 ``json``
1794 Render profiling data as JSON.
1797 Render profiling data as JSON.
1795
1798
1796 ``frequency``
1799 ``frequency``
1797 Sampling frequency. Specific to the ``stat`` sampling profiler.
1800 Sampling frequency. Specific to the ``stat`` sampling profiler.
1798 (default: 1000)
1801 (default: 1000)
1799
1802
1800 ``output``
1803 ``output``
1801 File path where profiling data or report should be saved. If the
1804 File path where profiling data or report should be saved. If the
1802 file exists, it is replaced. (default: None, data is printed on
1805 file exists, it is replaced. (default: None, data is printed on
1803 stderr)
1806 stderr)
1804
1807
1805 ``sort``
1808 ``sort``
1806 Sort field. Specific to the ``ls`` instrumenting profiler.
1809 Sort field. Specific to the ``ls`` instrumenting profiler.
1807 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1810 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1808 ``inlinetime``.
1811 ``inlinetime``.
1809 (default: inlinetime)
1812 (default: inlinetime)
1810
1813
1811 ``time-track``
1814 ``time-track``
1812 Control if the stat profiler track ``cpu`` or ``real`` time.
1815 Control if the stat profiler track ``cpu`` or ``real`` time.
1813 (default: ``cpu`` on Windows, otherwise ``real``)
1816 (default: ``cpu`` on Windows, otherwise ``real``)
1814
1817
1815 ``limit``
1818 ``limit``
1816 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1819 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1817 (default: 30)
1820 (default: 30)
1818
1821
1819 ``nested``
1822 ``nested``
1820 Show at most this number of lines of drill-down info after each main entry.
1823 Show at most this number of lines of drill-down info after each main entry.
1821 This can help explain the difference between Total and Inline.
1824 This can help explain the difference between Total and Inline.
1822 Specific to the ``ls`` instrumenting profiler.
1825 Specific to the ``ls`` instrumenting profiler.
1823 (default: 0)
1826 (default: 0)
1824
1827
1825 ``showmin``
1828 ``showmin``
1826 Minimum fraction of samples an entry must have for it to be displayed.
1829 Minimum fraction of samples an entry must have for it to be displayed.
1827 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1830 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1828 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1831 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1829
1832
1830 Only used by the ``stat`` profiler.
1833 Only used by the ``stat`` profiler.
1831
1834
1832 For the ``hotpath`` format, default is ``0.05``.
1835 For the ``hotpath`` format, default is ``0.05``.
1833 For the ``chrome`` format, default is ``0.005``.
1836 For the ``chrome`` format, default is ``0.005``.
1834
1837
1835 The option is unused on other formats.
1838 The option is unused on other formats.
1836
1839
1837 ``showmax``
1840 ``showmax``
1838 Maximum fraction of samples an entry can have before it is ignored in
1841 Maximum fraction of samples an entry can have before it is ignored in
1839 display. Values format is the same as ``showmin``.
1842 display. Values format is the same as ``showmin``.
1840
1843
1841 Only used by the ``stat`` profiler.
1844 Only used by the ``stat`` profiler.
1842
1845
1843 For the ``chrome`` format, default is ``0.999``.
1846 For the ``chrome`` format, default is ``0.999``.
1844
1847
1845 The option is unused on other formats.
1848 The option is unused on other formats.
1846
1849
1847 ``showtime``
1850 ``showtime``
1848 Show time taken as absolute durations, in addition to percentages.
1851 Show time taken as absolute durations, in addition to percentages.
1849 Only used by the ``hotpath`` format.
1852 Only used by the ``hotpath`` format.
1850 (default: true)
1853 (default: true)
1851
1854
1852 ``progress``
1855 ``progress``
1853 ------------
1856 ------------
1854
1857
1855 Mercurial commands can draw progress bars that are as informative as
1858 Mercurial commands can draw progress bars that are as informative as
1856 possible. Some progress bars only offer indeterminate information, while others
1859 possible. Some progress bars only offer indeterminate information, while others
1857 have a definite end point.
1860 have a definite end point.
1858
1861
1859 ``debug``
1862 ``debug``
1860 Whether to print debug info when updating the progress bar. (default: False)
1863 Whether to print debug info when updating the progress bar. (default: False)
1861
1864
1862 ``delay``
1865 ``delay``
1863 Number of seconds (float) before showing the progress bar. (default: 3)
1866 Number of seconds (float) before showing the progress bar. (default: 3)
1864
1867
1865 ``changedelay``
1868 ``changedelay``
1866 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1869 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1867 that value will be used instead. (default: 1)
1870 that value will be used instead. (default: 1)
1868
1871
1869 ``estimateinterval``
1872 ``estimateinterval``
1870 Maximum sampling interval in seconds for speed and estimated time
1873 Maximum sampling interval in seconds for speed and estimated time
1871 calculation. (default: 60)
1874 calculation. (default: 60)
1872
1875
1873 ``refresh``
1876 ``refresh``
1874 Time in seconds between refreshes of the progress bar. (default: 0.1)
1877 Time in seconds between refreshes of the progress bar. (default: 0.1)
1875
1878
1876 ``format``
1879 ``format``
1877 Format of the progress bar.
1880 Format of the progress bar.
1878
1881
1879 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1882 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1880 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1883 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1881 last 20 characters of the item, but this can be changed by adding either
1884 last 20 characters of the item, but this can be changed by adding either
1882 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1885 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1883 first num characters.
1886 first num characters.
1884
1887
1885 (default: topic bar number estimate)
1888 (default: topic bar number estimate)
1886
1889
1887 ``width``
1890 ``width``
1888 If set, the maximum width of the progress information (that is, min(width,
1891 If set, the maximum width of the progress information (that is, min(width,
1889 term width) will be used).
1892 term width) will be used).
1890
1893
1891 ``clear-complete``
1894 ``clear-complete``
1892 Clear the progress bar after it's done. (default: True)
1895 Clear the progress bar after it's done. (default: True)
1893
1896
1894 ``disable``
1897 ``disable``
1895 If true, don't show a progress bar.
1898 If true, don't show a progress bar.
1896
1899
1897 ``assume-tty``
1900 ``assume-tty``
1898 If true, ALWAYS show a progress bar, unless disable is given.
1901 If true, ALWAYS show a progress bar, unless disable is given.
1899
1902
1900 ``rebase``
1903 ``rebase``
1901 ----------
1904 ----------
1902
1905
1903 ``evolution.allowdivergence``
1906 ``evolution.allowdivergence``
1904 Default to False, when True allow creating divergence when performing
1907 Default to False, when True allow creating divergence when performing
1905 rebase of obsolete changesets.
1908 rebase of obsolete changesets.
1906
1909
1907 ``revsetalias``
1910 ``revsetalias``
1908 ---------------
1911 ---------------
1909
1912
1910 Alias definitions for revsets. See :hg:`help revsets` for details.
1913 Alias definitions for revsets. See :hg:`help revsets` for details.
1911
1914
1912 ``rewrite``
1915 ``rewrite``
1913 -----------
1916 -----------
1914
1917
1915 ``backup-bundle``
1918 ``backup-bundle``
1916 Whether to save stripped changesets to a bundle file. (default: True)
1919 Whether to save stripped changesets to a bundle file. (default: True)
1917
1920
1918 ``update-timestamp``
1921 ``update-timestamp``
1919 If true, updates the date and time of the changeset to current. It is only
1922 If true, updates the date and time of the changeset to current. It is only
1920 applicable for `hg amend`, `hg commit --amend` and `hg uncommit` in the
1923 applicable for `hg amend`, `hg commit --amend` and `hg uncommit` in the
1921 current version.
1924 current version.
1922
1925
1923 ``empty-successor``
1926 ``empty-successor``
1924
1927
1925 Control what happens with empty successors that are the result of rewrite
1928 Control what happens with empty successors that are the result of rewrite
1926 operations. If set to ``skip``, the successor is not created. If set to
1929 operations. If set to ``skip``, the successor is not created. If set to
1927 ``keep``, the empty successor is created and kept.
1930 ``keep``, the empty successor is created and kept.
1928
1931
1929 Currently, only the rebase and absorb commands consider this configuration.
1932 Currently, only the rebase and absorb commands consider this configuration.
1930 (EXPERIMENTAL)
1933 (EXPERIMENTAL)
1931
1934
1932 ``storage``
1935 ``storage``
1933 -----------
1936 -----------
1934
1937
1935 Control the strategy Mercurial uses internally to store history. Options in this
1938 Control the strategy Mercurial uses internally to store history. Options in this
1936 category impact performance and repository size.
1939 category impact performance and repository size.
1937
1940
1938 ``revlog.optimize-delta-parent-choice``
1941 ``revlog.optimize-delta-parent-choice``
1939 When storing a merge revision, both parents will be equally considered as
1942 When storing a merge revision, both parents will be equally considered as
1940 a possible delta base. This results in better delta selection and improved
1943 a possible delta base. This results in better delta selection and improved
1941 revlog compression. This option is enabled by default.
1944 revlog compression. This option is enabled by default.
1942
1945
1943 Turning this option off can result in large increase of repository size for
1946 Turning this option off can result in large increase of repository size for
1944 repository with many merges.
1947 repository with many merges.
1945
1948
1946 ``revlog.persistent-nodemap.mmap``
1949 ``revlog.persistent-nodemap.mmap``
1947 Whether to use the Operating System "memory mapping" feature (when
1950 Whether to use the Operating System "memory mapping" feature (when
1948 possible) to access the persistent nodemap data. This improve performance
1951 possible) to access the persistent nodemap data. This improve performance
1949 and reduce memory pressure.
1952 and reduce memory pressure.
1950
1953
1951 Default to True.
1954 Default to True.
1952
1955
1953 For details on the "persistent-nodemap" feature, see:
1956 For details on the "persistent-nodemap" feature, see:
1954 :hg:`help config format.use-persistent-nodemap`.
1957 :hg:`help config format.use-persistent-nodemap`.
1955
1958
1956 ``revlog.persistent-nodemap.slow-path``
1959 ``revlog.persistent-nodemap.slow-path``
1957 Control the behavior of Merucrial when using a repository with "persistent"
1960 Control the behavior of Merucrial when using a repository with "persistent"
1958 nodemap with an installation of Mercurial without a fast implementation for
1961 nodemap with an installation of Mercurial without a fast implementation for
1959 the feature:
1962 the feature:
1960
1963
1961 ``allow``: Silently use the slower implementation to access the repository.
1964 ``allow``: Silently use the slower implementation to access the repository.
1962 ``warn``: Warn, but use the slower implementation to access the repository.
1965 ``warn``: Warn, but use the slower implementation to access the repository.
1963
1966 ``abort``: Prevent access to such repositories. (This is the default)
1964 Default to ``warn``
1965
1967
1966 For details on the "persistent-nodemap" feature, see:
1968 For details on the "persistent-nodemap" feature, see:
1967 :hg:`help config format.use-persistent-nodemap`.
1969 :hg:`help config format.use-persistent-nodemap`.
1968
1970
1969 ``revlog.reuse-external-delta-parent``
1971 ``revlog.reuse-external-delta-parent``
1970 Control the order in which delta parents are considered when adding new
1972 Control the order in which delta parents are considered when adding new
1971 revisions from an external source.
1973 revisions from an external source.
1972 (typically: apply bundle from `hg pull` or `hg push`).
1974 (typically: apply bundle from `hg pull` or `hg push`).
1973
1975
1974 New revisions are usually provided as a delta against other revisions. By
1976 New revisions are usually provided as a delta against other revisions. By
1975 default, Mercurial will try to reuse this delta first, therefore using the
1977 default, Mercurial will try to reuse this delta first, therefore using the
1976 same "delta parent" as the source. Directly using delta's from the source
1978 same "delta parent" as the source. Directly using delta's from the source
1977 reduces CPU usage and usually speeds up operation. However, in some case,
1979 reduces CPU usage and usually speeds up operation. However, in some case,
1978 the source might have sub-optimal delta bases and forcing their reevaluation
1980 the source might have sub-optimal delta bases and forcing their reevaluation
1979 is useful. For example, pushes from an old client could have sub-optimal
1981 is useful. For example, pushes from an old client could have sub-optimal
1980 delta's parent that the server want to optimize. (lack of general delta, bad
1982 delta's parent that the server want to optimize. (lack of general delta, bad
1981 parents, choice, lack of sparse-revlog, etc).
1983 parents, choice, lack of sparse-revlog, etc).
1982
1984
1983 This option is enabled by default. Turning it off will ensure bad delta
1985 This option is enabled by default. Turning it off will ensure bad delta
1984 parent choices from older client do not propagate to this repository, at
1986 parent choices from older client do not propagate to this repository, at
1985 the cost of a small increase in CPU consumption.
1987 the cost of a small increase in CPU consumption.
1986
1988
1987 Note: this option only control the order in which delta parents are
1989 Note: this option only control the order in which delta parents are
1988 considered. Even when disabled, the existing delta from the source will be
1990 considered. Even when disabled, the existing delta from the source will be
1989 reused if the same delta parent is selected.
1991 reused if the same delta parent is selected.
1990
1992
1991 ``revlog.reuse-external-delta``
1993 ``revlog.reuse-external-delta``
1992 Control the reuse of delta from external source.
1994 Control the reuse of delta from external source.
1993 (typically: apply bundle from `hg pull` or `hg push`).
1995 (typically: apply bundle from `hg pull` or `hg push`).
1994
1996
1995 New revisions are usually provided as a delta against another revision. By
1997 New revisions are usually provided as a delta against another revision. By
1996 default, Mercurial will not recompute the same delta again, trusting
1998 default, Mercurial will not recompute the same delta again, trusting
1997 externally provided deltas. There have been rare cases of small adjustment
1999 externally provided deltas. There have been rare cases of small adjustment
1998 to the diffing algorithm in the past. So in some rare case, recomputing
2000 to the diffing algorithm in the past. So in some rare case, recomputing
1999 delta provided by ancient clients can provides better results. Disabling
2001 delta provided by ancient clients can provides better results. Disabling
2000 this option means going through a full delta recomputation for all incoming
2002 this option means going through a full delta recomputation for all incoming
2001 revisions. It means a large increase in CPU usage and will slow operations
2003 revisions. It means a large increase in CPU usage and will slow operations
2002 down.
2004 down.
2003
2005
2004 This option is enabled by default. When disabled, it also disables the
2006 This option is enabled by default. When disabled, it also disables the
2005 related ``storage.revlog.reuse-external-delta-parent`` option.
2007 related ``storage.revlog.reuse-external-delta-parent`` option.
2006
2008
2007 ``revlog.zlib.level``
2009 ``revlog.zlib.level``
2008 Zlib compression level used when storing data into the repository. Accepted
2010 Zlib compression level used when storing data into the repository. Accepted
2009 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2011 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2010 default value is 6.
2012 default value is 6.
2011
2013
2012
2014
2013 ``revlog.zstd.level``
2015 ``revlog.zstd.level``
2014 zstd compression level used when storing data into the repository. Accepted
2016 zstd compression level used when storing data into the repository. Accepted
2015 Value range from 1 (lowest compression) to 22 (highest compression).
2017 Value range from 1 (lowest compression) to 22 (highest compression).
2016 (default 3)
2018 (default 3)
2017
2019
2018 ``server``
2020 ``server``
2019 ----------
2021 ----------
2020
2022
2021 Controls generic server settings.
2023 Controls generic server settings.
2022
2024
2023 ``bookmarks-pushkey-compat``
2025 ``bookmarks-pushkey-compat``
2024 Trigger pushkey hook when being pushed bookmark updates. This config exist
2026 Trigger pushkey hook when being pushed bookmark updates. This config exist
2025 for compatibility purpose (default to True)
2027 for compatibility purpose (default to True)
2026
2028
2027 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2029 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2028 movement we recommend you migrate them to ``txnclose-bookmark`` and
2030 movement we recommend you migrate them to ``txnclose-bookmark`` and
2029 ``pretxnclose-bookmark``.
2031 ``pretxnclose-bookmark``.
2030
2032
2031 ``compressionengines``
2033 ``compressionengines``
2032 List of compression engines and their relative priority to advertise
2034 List of compression engines and their relative priority to advertise
2033 to clients.
2035 to clients.
2034
2036
2035 The order of compression engines determines their priority, the first
2037 The order of compression engines determines their priority, the first
2036 having the highest priority. If a compression engine is not listed
2038 having the highest priority. If a compression engine is not listed
2037 here, it won't be advertised to clients.
2039 here, it won't be advertised to clients.
2038
2040
2039 If not set (the default), built-in defaults are used. Run
2041 If not set (the default), built-in defaults are used. Run
2040 :hg:`debuginstall` to list available compression engines and their
2042 :hg:`debuginstall` to list available compression engines and their
2041 default wire protocol priority.
2043 default wire protocol priority.
2042
2044
2043 Older Mercurial clients only support zlib compression and this setting
2045 Older Mercurial clients only support zlib compression and this setting
2044 has no effect for legacy clients.
2046 has no effect for legacy clients.
2045
2047
2046 ``uncompressed``
2048 ``uncompressed``
2047 Whether to allow clients to clone a repository using the
2049 Whether to allow clients to clone a repository using the
2048 uncompressed streaming protocol. This transfers about 40% more
2050 uncompressed streaming protocol. This transfers about 40% more
2049 data than a regular clone, but uses less memory and CPU on both
2051 data than a regular clone, but uses less memory and CPU on both
2050 server and client. Over a LAN (100 Mbps or better) or a very fast
2052 server and client. Over a LAN (100 Mbps or better) or a very fast
2051 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2053 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2052 regular clone. Over most WAN connections (anything slower than
2054 regular clone. Over most WAN connections (anything slower than
2053 about 6 Mbps), uncompressed streaming is slower, because of the
2055 about 6 Mbps), uncompressed streaming is slower, because of the
2054 extra data transfer overhead. This mode will also temporarily hold
2056 extra data transfer overhead. This mode will also temporarily hold
2055 the write lock while determining what data to transfer.
2057 the write lock while determining what data to transfer.
2056 (default: True)
2058 (default: True)
2057
2059
2058 ``uncompressedallowsecret``
2060 ``uncompressedallowsecret``
2059 Whether to allow stream clones when the repository contains secret
2061 Whether to allow stream clones when the repository contains secret
2060 changesets. (default: False)
2062 changesets. (default: False)
2061
2063
2062 ``preferuncompressed``
2064 ``preferuncompressed``
2063 When set, clients will try to use the uncompressed streaming
2065 When set, clients will try to use the uncompressed streaming
2064 protocol. (default: False)
2066 protocol. (default: False)
2065
2067
2066 ``disablefullbundle``
2068 ``disablefullbundle``
2067 When set, servers will refuse attempts to do pull-based clones.
2069 When set, servers will refuse attempts to do pull-based clones.
2068 If this option is set, ``preferuncompressed`` and/or clone bundles
2070 If this option is set, ``preferuncompressed`` and/or clone bundles
2069 are highly recommended. Partial clones will still be allowed.
2071 are highly recommended. Partial clones will still be allowed.
2070 (default: False)
2072 (default: False)
2071
2073
2072 ``streamunbundle``
2074 ``streamunbundle``
2073 When set, servers will apply data sent from the client directly,
2075 When set, servers will apply data sent from the client directly,
2074 otherwise it will be written to a temporary file first. This option
2076 otherwise it will be written to a temporary file first. This option
2075 effectively prevents concurrent pushes.
2077 effectively prevents concurrent pushes.
2076
2078
2077 ``pullbundle``
2079 ``pullbundle``
2078 When set, the server will check pullbundle.manifest for bundles
2080 When set, the server will check pullbundle.manifest for bundles
2079 covering the requested heads and common nodes. The first matching
2081 covering the requested heads and common nodes. The first matching
2080 entry will be streamed to the client.
2082 entry will be streamed to the client.
2081
2083
2082 For HTTP transport, the stream will still use zlib compression
2084 For HTTP transport, the stream will still use zlib compression
2083 for older clients.
2085 for older clients.
2084
2086
2085 ``concurrent-push-mode``
2087 ``concurrent-push-mode``
2086 Level of allowed race condition between two pushing clients.
2088 Level of allowed race condition between two pushing clients.
2087
2089
2088 - 'strict': push is abort if another client touched the repository
2090 - 'strict': push is abort if another client touched the repository
2089 while the push was preparing.
2091 while the push was preparing.
2090 - 'check-related': push is only aborted if it affects head that got also
2092 - 'check-related': push is only aborted if it affects head that got also
2091 affected while the push was preparing. (default since 5.4)
2093 affected while the push was preparing. (default since 5.4)
2092
2094
2093 'check-related' only takes effect for compatible clients (version
2095 'check-related' only takes effect for compatible clients (version
2094 4.3 and later). Older clients will use 'strict'.
2096 4.3 and later). Older clients will use 'strict'.
2095
2097
2096 ``validate``
2098 ``validate``
2097 Whether to validate the completeness of pushed changesets by
2099 Whether to validate the completeness of pushed changesets by
2098 checking that all new file revisions specified in manifests are
2100 checking that all new file revisions specified in manifests are
2099 present. (default: False)
2101 present. (default: False)
2100
2102
2101 ``maxhttpheaderlen``
2103 ``maxhttpheaderlen``
2102 Instruct HTTP clients not to send request headers longer than this
2104 Instruct HTTP clients not to send request headers longer than this
2103 many bytes. (default: 1024)
2105 many bytes. (default: 1024)
2104
2106
2105 ``bundle1``
2107 ``bundle1``
2106 Whether to allow clients to push and pull using the legacy bundle1
2108 Whether to allow clients to push and pull using the legacy bundle1
2107 exchange format. (default: True)
2109 exchange format. (default: True)
2108
2110
2109 ``bundle1gd``
2111 ``bundle1gd``
2110 Like ``bundle1`` but only used if the repository is using the
2112 Like ``bundle1`` but only used if the repository is using the
2111 *generaldelta* storage format. (default: True)
2113 *generaldelta* storage format. (default: True)
2112
2114
2113 ``bundle1.push``
2115 ``bundle1.push``
2114 Whether to allow clients to push using the legacy bundle1 exchange
2116 Whether to allow clients to push using the legacy bundle1 exchange
2115 format. (default: True)
2117 format. (default: True)
2116
2118
2117 ``bundle1gd.push``
2119 ``bundle1gd.push``
2118 Like ``bundle1.push`` but only used if the repository is using the
2120 Like ``bundle1.push`` but only used if the repository is using the
2119 *generaldelta* storage format. (default: True)
2121 *generaldelta* storage format. (default: True)
2120
2122
2121 ``bundle1.pull``
2123 ``bundle1.pull``
2122 Whether to allow clients to pull using the legacy bundle1 exchange
2124 Whether to allow clients to pull using the legacy bundle1 exchange
2123 format. (default: True)
2125 format. (default: True)
2124
2126
2125 ``bundle1gd.pull``
2127 ``bundle1gd.pull``
2126 Like ``bundle1.pull`` but only used if the repository is using the
2128 Like ``bundle1.pull`` but only used if the repository is using the
2127 *generaldelta* storage format. (default: True)
2129 *generaldelta* storage format. (default: True)
2128
2130
2129 Large repositories using the *generaldelta* storage format should
2131 Large repositories using the *generaldelta* storage format should
2130 consider setting this option because converting *generaldelta*
2132 consider setting this option because converting *generaldelta*
2131 repositories to the exchange format required by the bundle1 data
2133 repositories to the exchange format required by the bundle1 data
2132 format can consume a lot of CPU.
2134 format can consume a lot of CPU.
2133
2135
2134 ``bundle2.stream``
2136 ``bundle2.stream``
2135 Whether to allow clients to pull using the bundle2 streaming protocol.
2137 Whether to allow clients to pull using the bundle2 streaming protocol.
2136 (default: True)
2138 (default: True)
2137
2139
2138 ``zliblevel``
2140 ``zliblevel``
2139 Integer between ``-1`` and ``9`` that controls the zlib compression level
2141 Integer between ``-1`` and ``9`` that controls the zlib compression level
2140 for wire protocol commands that send zlib compressed output (notably the
2142 for wire protocol commands that send zlib compressed output (notably the
2141 commands that send repository history data).
2143 commands that send repository history data).
2142
2144
2143 The default (``-1``) uses the default zlib compression level, which is
2145 The default (``-1``) uses the default zlib compression level, which is
2144 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2146 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2145 maximum compression.
2147 maximum compression.
2146
2148
2147 Setting this option allows server operators to make trade-offs between
2149 Setting this option allows server operators to make trade-offs between
2148 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2150 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2149 but sends more bytes to clients.
2151 but sends more bytes to clients.
2150
2152
2151 This option only impacts the HTTP server.
2153 This option only impacts the HTTP server.
2152
2154
2153 ``zstdlevel``
2155 ``zstdlevel``
2154 Integer between ``1`` and ``22`` that controls the zstd compression level
2156 Integer between ``1`` and ``22`` that controls the zstd compression level
2155 for wire protocol commands. ``1`` is the minimal amount of compression and
2157 for wire protocol commands. ``1`` is the minimal amount of compression and
2156 ``22`` is the highest amount of compression.
2158 ``22`` is the highest amount of compression.
2157
2159
2158 The default (``3``) should be significantly faster than zlib while likely
2160 The default (``3``) should be significantly faster than zlib while likely
2159 delivering better compression ratios.
2161 delivering better compression ratios.
2160
2162
2161 This option only impacts the HTTP server.
2163 This option only impacts the HTTP server.
2162
2164
2163 See also ``server.zliblevel``.
2165 See also ``server.zliblevel``.
2164
2166
2165 ``view``
2167 ``view``
2166 Repository filter used when exchanging revisions with the peer.
2168 Repository filter used when exchanging revisions with the peer.
2167
2169
2168 The default view (``served``) excludes secret and hidden changesets.
2170 The default view (``served``) excludes secret and hidden changesets.
2169 Another useful value is ``immutable`` (no draft, secret or hidden
2171 Another useful value is ``immutable`` (no draft, secret or hidden
2170 changesets). (EXPERIMENTAL)
2172 changesets). (EXPERIMENTAL)
2171
2173
2172 ``smtp``
2174 ``smtp``
2173 --------
2175 --------
2174
2176
2175 Configuration for extensions that need to send email messages.
2177 Configuration for extensions that need to send email messages.
2176
2178
2177 ``host``
2179 ``host``
2178 Host name of mail server, e.g. "mail.example.com".
2180 Host name of mail server, e.g. "mail.example.com".
2179
2181
2180 ``port``
2182 ``port``
2181 Optional. Port to connect to on mail server. (default: 465 if
2183 Optional. Port to connect to on mail server. (default: 465 if
2182 ``tls`` is smtps; 25 otherwise)
2184 ``tls`` is smtps; 25 otherwise)
2183
2185
2184 ``tls``
2186 ``tls``
2185 Optional. Method to enable TLS when connecting to mail server: starttls,
2187 Optional. Method to enable TLS when connecting to mail server: starttls,
2186 smtps or none. (default: none)
2188 smtps or none. (default: none)
2187
2189
2188 ``username``
2190 ``username``
2189 Optional. User name for authenticating with the SMTP server.
2191 Optional. User name for authenticating with the SMTP server.
2190 (default: None)
2192 (default: None)
2191
2193
2192 ``password``
2194 ``password``
2193 Optional. Password for authenticating with the SMTP server. If not
2195 Optional. Password for authenticating with the SMTP server. If not
2194 specified, interactive sessions will prompt the user for a
2196 specified, interactive sessions will prompt the user for a
2195 password; non-interactive sessions will fail. (default: None)
2197 password; non-interactive sessions will fail. (default: None)
2196
2198
2197 ``local_hostname``
2199 ``local_hostname``
2198 Optional. The hostname that the sender can use to identify
2200 Optional. The hostname that the sender can use to identify
2199 itself to the MTA.
2201 itself to the MTA.
2200
2202
2201
2203
2202 ``subpaths``
2204 ``subpaths``
2203 ------------
2205 ------------
2204
2206
2205 Subrepository source URLs can go stale if a remote server changes name
2207 Subrepository source URLs can go stale if a remote server changes name
2206 or becomes temporarily unavailable. This section lets you define
2208 or becomes temporarily unavailable. This section lets you define
2207 rewrite rules of the form::
2209 rewrite rules of the form::
2208
2210
2209 <pattern> = <replacement>
2211 <pattern> = <replacement>
2210
2212
2211 where ``pattern`` is a regular expression matching a subrepository
2213 where ``pattern`` is a regular expression matching a subrepository
2212 source URL and ``replacement`` is the replacement string used to
2214 source URL and ``replacement`` is the replacement string used to
2213 rewrite it. Groups can be matched in ``pattern`` and referenced in
2215 rewrite it. Groups can be matched in ``pattern`` and referenced in
2214 ``replacements``. For instance::
2216 ``replacements``. For instance::
2215
2217
2216 http://server/(.*)-hg/ = http://hg.server/\1/
2218 http://server/(.*)-hg/ = http://hg.server/\1/
2217
2219
2218 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2220 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2219
2221
2220 Relative subrepository paths are first made absolute, and the
2222 Relative subrepository paths are first made absolute, and the
2221 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2223 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2222 doesn't match the full path, an attempt is made to apply it on the
2224 doesn't match the full path, an attempt is made to apply it on the
2223 relative path alone. The rules are applied in definition order.
2225 relative path alone. The rules are applied in definition order.
2224
2226
2225 ``subrepos``
2227 ``subrepos``
2226 ------------
2228 ------------
2227
2229
2228 This section contains options that control the behavior of the
2230 This section contains options that control the behavior of the
2229 subrepositories feature. See also :hg:`help subrepos`.
2231 subrepositories feature. See also :hg:`help subrepos`.
2230
2232
2231 Security note: auditing in Mercurial is known to be insufficient to
2233 Security note: auditing in Mercurial is known to be insufficient to
2232 prevent clone-time code execution with carefully constructed Git
2234 prevent clone-time code execution with carefully constructed Git
2233 subrepos. It is unknown if a similar detect is present in Subversion
2235 subrepos. It is unknown if a similar detect is present in Subversion
2234 subrepos. Both Git and Subversion subrepos are disabled by default
2236 subrepos. Both Git and Subversion subrepos are disabled by default
2235 out of security concerns. These subrepo types can be enabled using
2237 out of security concerns. These subrepo types can be enabled using
2236 the respective options below.
2238 the respective options below.
2237
2239
2238 ``allowed``
2240 ``allowed``
2239 Whether subrepositories are allowed in the working directory.
2241 Whether subrepositories are allowed in the working directory.
2240
2242
2241 When false, commands involving subrepositories (like :hg:`update`)
2243 When false, commands involving subrepositories (like :hg:`update`)
2242 will fail for all subrepository types.
2244 will fail for all subrepository types.
2243 (default: true)
2245 (default: true)
2244
2246
2245 ``hg:allowed``
2247 ``hg:allowed``
2246 Whether Mercurial subrepositories are allowed in the working
2248 Whether Mercurial subrepositories are allowed in the working
2247 directory. This option only has an effect if ``subrepos.allowed``
2249 directory. This option only has an effect if ``subrepos.allowed``
2248 is true.
2250 is true.
2249 (default: true)
2251 (default: true)
2250
2252
2251 ``git:allowed``
2253 ``git:allowed``
2252 Whether Git subrepositories are allowed in the working directory.
2254 Whether Git subrepositories are allowed in the working directory.
2253 This option only has an effect if ``subrepos.allowed`` is true.
2255 This option only has an effect if ``subrepos.allowed`` is true.
2254
2256
2255 See the security note above before enabling Git subrepos.
2257 See the security note above before enabling Git subrepos.
2256 (default: false)
2258 (default: false)
2257
2259
2258 ``svn:allowed``
2260 ``svn:allowed``
2259 Whether Subversion subrepositories are allowed in the working
2261 Whether Subversion subrepositories are allowed in the working
2260 directory. This option only has an effect if ``subrepos.allowed``
2262 directory. This option only has an effect if ``subrepos.allowed``
2261 is true.
2263 is true.
2262
2264
2263 See the security note above before enabling Subversion subrepos.
2265 See the security note above before enabling Subversion subrepos.
2264 (default: false)
2266 (default: false)
2265
2267
2266 ``templatealias``
2268 ``templatealias``
2267 -----------------
2269 -----------------
2268
2270
2269 Alias definitions for templates. See :hg:`help templates` for details.
2271 Alias definitions for templates. See :hg:`help templates` for details.
2270
2272
2271 ``templates``
2273 ``templates``
2272 -------------
2274 -------------
2273
2275
2274 Use the ``[templates]`` section to define template strings.
2276 Use the ``[templates]`` section to define template strings.
2275 See :hg:`help templates` for details.
2277 See :hg:`help templates` for details.
2276
2278
2277 ``trusted``
2279 ``trusted``
2278 -----------
2280 -----------
2279
2281
2280 Mercurial will not use the settings in the
2282 Mercurial will not use the settings in the
2281 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2283 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2282 user or to a trusted group, as various hgrc features allow arbitrary
2284 user or to a trusted group, as various hgrc features allow arbitrary
2283 commands to be run. This issue is often encountered when configuring
2285 commands to be run. This issue is often encountered when configuring
2284 hooks or extensions for shared repositories or servers. However,
2286 hooks or extensions for shared repositories or servers. However,
2285 the web interface will use some safe settings from the ``[web]``
2287 the web interface will use some safe settings from the ``[web]``
2286 section.
2288 section.
2287
2289
2288 This section specifies what users and groups are trusted. The
2290 This section specifies what users and groups are trusted. The
2289 current user is always trusted. To trust everybody, list a user or a
2291 current user is always trusted. To trust everybody, list a user or a
2290 group with name ``*``. These settings must be placed in an
2292 group with name ``*``. These settings must be placed in an
2291 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2293 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2292 user or service running Mercurial.
2294 user or service running Mercurial.
2293
2295
2294 ``users``
2296 ``users``
2295 Comma-separated list of trusted users.
2297 Comma-separated list of trusted users.
2296
2298
2297 ``groups``
2299 ``groups``
2298 Comma-separated list of trusted groups.
2300 Comma-separated list of trusted groups.
2299
2301
2300
2302
2301 ``ui``
2303 ``ui``
2302 ------
2304 ------
2303
2305
2304 User interface controls.
2306 User interface controls.
2305
2307
2306 ``archivemeta``
2308 ``archivemeta``
2307 Whether to include the .hg_archival.txt file containing meta data
2309 Whether to include the .hg_archival.txt file containing meta data
2308 (hashes for the repository base and for tip) in archives created
2310 (hashes for the repository base and for tip) in archives created
2309 by the :hg:`archive` command or downloaded via hgweb.
2311 by the :hg:`archive` command or downloaded via hgweb.
2310 (default: True)
2312 (default: True)
2311
2313
2312 ``askusername``
2314 ``askusername``
2313 Whether to prompt for a username when committing. If True, and
2315 Whether to prompt for a username when committing. If True, and
2314 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2316 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2315 be prompted to enter a username. If no username is entered, the
2317 be prompted to enter a username. If no username is entered, the
2316 default ``USER@HOST`` is used instead.
2318 default ``USER@HOST`` is used instead.
2317 (default: False)
2319 (default: False)
2318
2320
2319 ``clonebundles``
2321 ``clonebundles``
2320 Whether the "clone bundles" feature is enabled.
2322 Whether the "clone bundles" feature is enabled.
2321
2323
2322 When enabled, :hg:`clone` may download and apply a server-advertised
2324 When enabled, :hg:`clone` may download and apply a server-advertised
2323 bundle file from a URL instead of using the normal exchange mechanism.
2325 bundle file from a URL instead of using the normal exchange mechanism.
2324
2326
2325 This can likely result in faster and more reliable clones.
2327 This can likely result in faster and more reliable clones.
2326
2328
2327 (default: True)
2329 (default: True)
2328
2330
2329 ``clonebundlefallback``
2331 ``clonebundlefallback``
2330 Whether failure to apply an advertised "clone bundle" from a server
2332 Whether failure to apply an advertised "clone bundle" from a server
2331 should result in fallback to a regular clone.
2333 should result in fallback to a regular clone.
2332
2334
2333 This is disabled by default because servers advertising "clone
2335 This is disabled by default because servers advertising "clone
2334 bundles" often do so to reduce server load. If advertised bundles
2336 bundles" often do so to reduce server load. If advertised bundles
2335 start mass failing and clients automatically fall back to a regular
2337 start mass failing and clients automatically fall back to a regular
2336 clone, this would add significant and unexpected load to the server
2338 clone, this would add significant and unexpected load to the server
2337 since the server is expecting clone operations to be offloaded to
2339 since the server is expecting clone operations to be offloaded to
2338 pre-generated bundles. Failing fast (the default behavior) ensures
2340 pre-generated bundles. Failing fast (the default behavior) ensures
2339 clients don't overwhelm the server when "clone bundle" application
2341 clients don't overwhelm the server when "clone bundle" application
2340 fails.
2342 fails.
2341
2343
2342 (default: False)
2344 (default: False)
2343
2345
2344 ``clonebundleprefers``
2346 ``clonebundleprefers``
2345 Defines preferences for which "clone bundles" to use.
2347 Defines preferences for which "clone bundles" to use.
2346
2348
2347 Servers advertising "clone bundles" may advertise multiple available
2349 Servers advertising "clone bundles" may advertise multiple available
2348 bundles. Each bundle may have different attributes, such as the bundle
2350 bundles. Each bundle may have different attributes, such as the bundle
2349 type and compression format. This option is used to prefer a particular
2351 type and compression format. This option is used to prefer a particular
2350 bundle over another.
2352 bundle over another.
2351
2353
2352 The following keys are defined by Mercurial:
2354 The following keys are defined by Mercurial:
2353
2355
2354 BUNDLESPEC
2356 BUNDLESPEC
2355 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2357 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2356 e.g. ``gzip-v2`` or ``bzip2-v1``.
2358 e.g. ``gzip-v2`` or ``bzip2-v1``.
2357
2359
2358 COMPRESSION
2360 COMPRESSION
2359 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2361 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2360
2362
2361 Server operators may define custom keys.
2363 Server operators may define custom keys.
2362
2364
2363 Example values: ``COMPRESSION=bzip2``,
2365 Example values: ``COMPRESSION=bzip2``,
2364 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2366 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2365
2367
2366 By default, the first bundle advertised by the server is used.
2368 By default, the first bundle advertised by the server is used.
2367
2369
2368 ``color``
2370 ``color``
2369 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2371 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2370 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2372 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2371 seems possible. See :hg:`help color` for details.
2373 seems possible. See :hg:`help color` for details.
2372
2374
2373 ``commitsubrepos``
2375 ``commitsubrepos``
2374 Whether to commit modified subrepositories when committing the
2376 Whether to commit modified subrepositories when committing the
2375 parent repository. If False and one subrepository has uncommitted
2377 parent repository. If False and one subrepository has uncommitted
2376 changes, abort the commit.
2378 changes, abort the commit.
2377 (default: False)
2379 (default: False)
2378
2380
2379 ``debug``
2381 ``debug``
2380 Print debugging information. (default: False)
2382 Print debugging information. (default: False)
2381
2383
2382 ``editor``
2384 ``editor``
2383 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2385 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2384
2386
2385 ``fallbackencoding``
2387 ``fallbackencoding``
2386 Encoding to try if it's not possible to decode the changelog using
2388 Encoding to try if it's not possible to decode the changelog using
2387 UTF-8. (default: ISO-8859-1)
2389 UTF-8. (default: ISO-8859-1)
2388
2390
2389 ``graphnodetemplate``
2391 ``graphnodetemplate``
2390 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2392 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2391
2393
2392 ``ignore``
2394 ``ignore``
2393 A file to read per-user ignore patterns from. This file should be
2395 A file to read per-user ignore patterns from. This file should be
2394 in the same format as a repository-wide .hgignore file. Filenames
2396 in the same format as a repository-wide .hgignore file. Filenames
2395 are relative to the repository root. This option supports hook syntax,
2397 are relative to the repository root. This option supports hook syntax,
2396 so if you want to specify multiple ignore files, you can do so by
2398 so if you want to specify multiple ignore files, you can do so by
2397 setting something like ``ignore.other = ~/.hgignore2``. For details
2399 setting something like ``ignore.other = ~/.hgignore2``. For details
2398 of the ignore file format, see the ``hgignore(5)`` man page.
2400 of the ignore file format, see the ``hgignore(5)`` man page.
2399
2401
2400 ``interactive``
2402 ``interactive``
2401 Allow to prompt the user. (default: True)
2403 Allow to prompt the user. (default: True)
2402
2404
2403 ``interface``
2405 ``interface``
2404 Select the default interface for interactive features (default: text).
2406 Select the default interface for interactive features (default: text).
2405 Possible values are 'text' and 'curses'.
2407 Possible values are 'text' and 'curses'.
2406
2408
2407 ``interface.chunkselector``
2409 ``interface.chunkselector``
2408 Select the interface for change recording (e.g. :hg:`commit -i`).
2410 Select the interface for change recording (e.g. :hg:`commit -i`).
2409 Possible values are 'text' and 'curses'.
2411 Possible values are 'text' and 'curses'.
2410 This config overrides the interface specified by ui.interface.
2412 This config overrides the interface specified by ui.interface.
2411
2413
2412 ``large-file-limit``
2414 ``large-file-limit``
2413 Largest file size that gives no memory use warning.
2415 Largest file size that gives no memory use warning.
2414 Possible values are integers or 0 to disable the check.
2416 Possible values are integers or 0 to disable the check.
2415 (default: 10000000)
2417 (default: 10000000)
2416
2418
2417 ``logtemplate``
2419 ``logtemplate``
2418 (DEPRECATED) Use ``command-templates.log`` instead.
2420 (DEPRECATED) Use ``command-templates.log`` instead.
2419
2421
2420 ``merge``
2422 ``merge``
2421 The conflict resolution program to use during a manual merge.
2423 The conflict resolution program to use during a manual merge.
2422 For more information on merge tools see :hg:`help merge-tools`.
2424 For more information on merge tools see :hg:`help merge-tools`.
2423 For configuring merge tools see the ``[merge-tools]`` section.
2425 For configuring merge tools see the ``[merge-tools]`` section.
2424
2426
2425 ``mergemarkers``
2427 ``mergemarkers``
2426 Sets the merge conflict marker label styling. The ``detailed`` style
2428 Sets the merge conflict marker label styling. The ``detailed`` style
2427 uses the ``command-templates.mergemarker`` setting to style the labels.
2429 uses the ``command-templates.mergemarker`` setting to style the labels.
2428 The ``basic`` style just uses 'local' and 'other' as the marker label.
2430 The ``basic`` style just uses 'local' and 'other' as the marker label.
2429 One of ``basic`` or ``detailed``.
2431 One of ``basic`` or ``detailed``.
2430 (default: ``basic``)
2432 (default: ``basic``)
2431
2433
2432 ``mergemarkertemplate``
2434 ``mergemarkertemplate``
2433 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2435 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2434
2436
2435 ``message-output``
2437 ``message-output``
2436 Where to write status and error messages. (default: ``stdio``)
2438 Where to write status and error messages. (default: ``stdio``)
2437
2439
2438 ``channel``
2440 ``channel``
2439 Use separate channel for structured output. (Command-server only)
2441 Use separate channel for structured output. (Command-server only)
2440 ``stderr``
2442 ``stderr``
2441 Everything to stderr.
2443 Everything to stderr.
2442 ``stdio``
2444 ``stdio``
2443 Status to stdout, and error to stderr.
2445 Status to stdout, and error to stderr.
2444
2446
2445 ``origbackuppath``
2447 ``origbackuppath``
2446 The path to a directory used to store generated .orig files. If the path is
2448 The path to a directory used to store generated .orig files. If the path is
2447 not a directory, one will be created. If set, files stored in this
2449 not a directory, one will be created. If set, files stored in this
2448 directory have the same name as the original file and do not have a .orig
2450 directory have the same name as the original file and do not have a .orig
2449 suffix.
2451 suffix.
2450
2452
2451 ``paginate``
2453 ``paginate``
2452 Control the pagination of command output (default: True). See :hg:`help pager`
2454 Control the pagination of command output (default: True). See :hg:`help pager`
2453 for details.
2455 for details.
2454
2456
2455 ``patch``
2457 ``patch``
2456 An optional external tool that ``hg import`` and some extensions
2458 An optional external tool that ``hg import`` and some extensions
2457 will use for applying patches. By default Mercurial uses an
2459 will use for applying patches. By default Mercurial uses an
2458 internal patch utility. The external tool must work as the common
2460 internal patch utility. The external tool must work as the common
2459 Unix ``patch`` program. In particular, it must accept a ``-p``
2461 Unix ``patch`` program. In particular, it must accept a ``-p``
2460 argument to strip patch headers, a ``-d`` argument to specify the
2462 argument to strip patch headers, a ``-d`` argument to specify the
2461 current directory, a file name to patch, and a patch file to take
2463 current directory, a file name to patch, and a patch file to take
2462 from stdin.
2464 from stdin.
2463
2465
2464 It is possible to specify a patch tool together with extra
2466 It is possible to specify a patch tool together with extra
2465 arguments. For example, setting this option to ``patch --merge``
2467 arguments. For example, setting this option to ``patch --merge``
2466 will use the ``patch`` program with its 2-way merge option.
2468 will use the ``patch`` program with its 2-way merge option.
2467
2469
2468 ``portablefilenames``
2470 ``portablefilenames``
2469 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2471 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2470 (default: ``warn``)
2472 (default: ``warn``)
2471
2473
2472 ``warn``
2474 ``warn``
2473 Print a warning message on POSIX platforms, if a file with a non-portable
2475 Print a warning message on POSIX platforms, if a file with a non-portable
2474 filename is added (e.g. a file with a name that can't be created on
2476 filename is added (e.g. a file with a name that can't be created on
2475 Windows because it contains reserved parts like ``AUX``, reserved
2477 Windows because it contains reserved parts like ``AUX``, reserved
2476 characters like ``:``, or would cause a case collision with an existing
2478 characters like ``:``, or would cause a case collision with an existing
2477 file).
2479 file).
2478
2480
2479 ``ignore``
2481 ``ignore``
2480 Don't print a warning.
2482 Don't print a warning.
2481
2483
2482 ``abort``
2484 ``abort``
2483 The command is aborted.
2485 The command is aborted.
2484
2486
2485 ``true``
2487 ``true``
2486 Alias for ``warn``.
2488 Alias for ``warn``.
2487
2489
2488 ``false``
2490 ``false``
2489 Alias for ``ignore``.
2491 Alias for ``ignore``.
2490
2492
2491 .. container:: windows
2493 .. container:: windows
2492
2494
2493 On Windows, this configuration option is ignored and the command aborted.
2495 On Windows, this configuration option is ignored and the command aborted.
2494
2496
2495 ``pre-merge-tool-output-template``
2497 ``pre-merge-tool-output-template``
2496 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2498 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2497
2499
2498 ``quiet``
2500 ``quiet``
2499 Reduce the amount of output printed.
2501 Reduce the amount of output printed.
2500 (default: False)
2502 (default: False)
2501
2503
2502 ``relative-paths``
2504 ``relative-paths``
2503 Prefer relative paths in the UI.
2505 Prefer relative paths in the UI.
2504
2506
2505 ``remotecmd``
2507 ``remotecmd``
2506 Remote command to use for clone/push/pull operations.
2508 Remote command to use for clone/push/pull operations.
2507 (default: ``hg``)
2509 (default: ``hg``)
2508
2510
2509 ``report_untrusted``
2511 ``report_untrusted``
2510 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2512 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2511 trusted user or group.
2513 trusted user or group.
2512 (default: True)
2514 (default: True)
2513
2515
2514 ``slash``
2516 ``slash``
2515 (Deprecated. Use ``slashpath`` template filter instead.)
2517 (Deprecated. Use ``slashpath`` template filter instead.)
2516
2518
2517 Display paths using a slash (``/``) as the path separator. This
2519 Display paths using a slash (``/``) as the path separator. This
2518 only makes a difference on systems where the default path
2520 only makes a difference on systems where the default path
2519 separator is not the slash character (e.g. Windows uses the
2521 separator is not the slash character (e.g. Windows uses the
2520 backslash character (``\``)).
2522 backslash character (``\``)).
2521 (default: False)
2523 (default: False)
2522
2524
2523 ``statuscopies``
2525 ``statuscopies``
2524 Display copies in the status command.
2526 Display copies in the status command.
2525
2527
2526 ``ssh``
2528 ``ssh``
2527 Command to use for SSH connections. (default: ``ssh``)
2529 Command to use for SSH connections. (default: ``ssh``)
2528
2530
2529 ``ssherrorhint``
2531 ``ssherrorhint``
2530 A hint shown to the user in the case of SSH error (e.g.
2532 A hint shown to the user in the case of SSH error (e.g.
2531 ``Please see http://company/internalwiki/ssh.html``)
2533 ``Please see http://company/internalwiki/ssh.html``)
2532
2534
2533 ``strict``
2535 ``strict``
2534 Require exact command names, instead of allowing unambiguous
2536 Require exact command names, instead of allowing unambiguous
2535 abbreviations. (default: False)
2537 abbreviations. (default: False)
2536
2538
2537 ``style``
2539 ``style``
2538 Name of style to use for command output.
2540 Name of style to use for command output.
2539
2541
2540 ``supportcontact``
2542 ``supportcontact``
2541 A URL where users should report a Mercurial traceback. Use this if you are a
2543 A URL where users should report a Mercurial traceback. Use this if you are a
2542 large organisation with its own Mercurial deployment process and crash
2544 large organisation with its own Mercurial deployment process and crash
2543 reports should be addressed to your internal support.
2545 reports should be addressed to your internal support.
2544
2546
2545 ``textwidth``
2547 ``textwidth``
2546 Maximum width of help text. A longer line generated by ``hg help`` or
2548 Maximum width of help text. A longer line generated by ``hg help`` or
2547 ``hg subcommand --help`` will be broken after white space to get this
2549 ``hg subcommand --help`` will be broken after white space to get this
2548 width or the terminal width, whichever comes first.
2550 width or the terminal width, whichever comes first.
2549 A non-positive value will disable this and the terminal width will be
2551 A non-positive value will disable this and the terminal width will be
2550 used. (default: 78)
2552 used. (default: 78)
2551
2553
2552 ``timeout``
2554 ``timeout``
2553 The timeout used when a lock is held (in seconds), a negative value
2555 The timeout used when a lock is held (in seconds), a negative value
2554 means no timeout. (default: 600)
2556 means no timeout. (default: 600)
2555
2557
2556 ``timeout.warn``
2558 ``timeout.warn``
2557 Time (in seconds) before a warning is printed about held lock. A negative
2559 Time (in seconds) before a warning is printed about held lock. A negative
2558 value means no warning. (default: 0)
2560 value means no warning. (default: 0)
2559
2561
2560 ``traceback``
2562 ``traceback``
2561 Mercurial always prints a traceback when an unknown exception
2563 Mercurial always prints a traceback when an unknown exception
2562 occurs. Setting this to True will make Mercurial print a traceback
2564 occurs. Setting this to True will make Mercurial print a traceback
2563 on all exceptions, even those recognized by Mercurial (such as
2565 on all exceptions, even those recognized by Mercurial (such as
2564 IOError or MemoryError). (default: False)
2566 IOError or MemoryError). (default: False)
2565
2567
2566 ``tweakdefaults``
2568 ``tweakdefaults``
2567
2569
2568 By default Mercurial's behavior changes very little from release
2570 By default Mercurial's behavior changes very little from release
2569 to release, but over time the recommended config settings
2571 to release, but over time the recommended config settings
2570 shift. Enable this config to opt in to get automatic tweaks to
2572 shift. Enable this config to opt in to get automatic tweaks to
2571 Mercurial's behavior over time. This config setting will have no
2573 Mercurial's behavior over time. This config setting will have no
2572 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2574 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2573 not include ``tweakdefaults``. (default: False)
2575 not include ``tweakdefaults``. (default: False)
2574
2576
2575 It currently means::
2577 It currently means::
2576
2578
2577 .. tweakdefaultsmarker
2579 .. tweakdefaultsmarker
2578
2580
2579 ``username``
2581 ``username``
2580 The committer of a changeset created when running "commit".
2582 The committer of a changeset created when running "commit".
2581 Typically a person's name and email address, e.g. ``Fred Widget
2583 Typically a person's name and email address, e.g. ``Fred Widget
2582 <fred@example.com>``. Environment variables in the
2584 <fred@example.com>``. Environment variables in the
2583 username are expanded.
2585 username are expanded.
2584
2586
2585 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2587 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2586 hgrc is empty, e.g. if the system admin set ``username =`` in the
2588 hgrc is empty, e.g. if the system admin set ``username =`` in the
2587 system hgrc, it has to be specified manually or in a different
2589 system hgrc, it has to be specified manually or in a different
2588 hgrc file)
2590 hgrc file)
2589
2591
2590 ``verbose``
2592 ``verbose``
2591 Increase the amount of output printed. (default: False)
2593 Increase the amount of output printed. (default: False)
2592
2594
2593
2595
2594 ``command-templates``
2596 ``command-templates``
2595 ---------------------
2597 ---------------------
2596
2598
2597 Templates used for customizing the output of commands.
2599 Templates used for customizing the output of commands.
2598
2600
2599 ``graphnode``
2601 ``graphnode``
2600 The template used to print changeset nodes in an ASCII revision graph.
2602 The template used to print changeset nodes in an ASCII revision graph.
2601 (default: ``{graphnode}``)
2603 (default: ``{graphnode}``)
2602
2604
2603 ``log``
2605 ``log``
2604 Template string for commands that print changesets.
2606 Template string for commands that print changesets.
2605
2607
2606 ``mergemarker``
2608 ``mergemarker``
2607 The template used to print the commit description next to each conflict
2609 The template used to print the commit description next to each conflict
2608 marker during merge conflicts. See :hg:`help templates` for the template
2610 marker during merge conflicts. See :hg:`help templates` for the template
2609 format.
2611 format.
2610
2612
2611 Defaults to showing the hash, tags, branches, bookmarks, author, and
2613 Defaults to showing the hash, tags, branches, bookmarks, author, and
2612 the first line of the commit description.
2614 the first line of the commit description.
2613
2615
2614 If you use non-ASCII characters in names for tags, branches, bookmarks,
2616 If you use non-ASCII characters in names for tags, branches, bookmarks,
2615 authors, and/or commit descriptions, you must pay attention to encodings of
2617 authors, and/or commit descriptions, you must pay attention to encodings of
2616 managed files. At template expansion, non-ASCII characters use the encoding
2618 managed files. At template expansion, non-ASCII characters use the encoding
2617 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2619 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2618 environment variables that govern your locale. If the encoding of the merge
2620 environment variables that govern your locale. If the encoding of the merge
2619 markers is different from the encoding of the merged files,
2621 markers is different from the encoding of the merged files,
2620 serious problems may occur.
2622 serious problems may occur.
2621
2623
2622 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2624 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2623
2625
2624 ``oneline-summary``
2626 ``oneline-summary``
2625 A template used by `hg rebase` and other commands for showing a one-line
2627 A template used by `hg rebase` and other commands for showing a one-line
2626 summary of a commit. If the template configured here is longer than one
2628 summary of a commit. If the template configured here is longer than one
2627 line, then only the first line is used.
2629 line, then only the first line is used.
2628
2630
2629 The template can be overridden per command by defining a template in
2631 The template can be overridden per command by defining a template in
2630 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2632 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2631
2633
2632 ``pre-merge-tool-output``
2634 ``pre-merge-tool-output``
2633 A template that is printed before executing an external merge tool. This can
2635 A template that is printed before executing an external merge tool. This can
2634 be used to print out additional context that might be useful to have during
2636 be used to print out additional context that might be useful to have during
2635 the conflict resolution, such as the description of the various commits
2637 the conflict resolution, such as the description of the various commits
2636 involved or bookmarks/tags.
2638 involved or bookmarks/tags.
2637
2639
2638 Additional information is available in the ``local`, ``base``, and ``other``
2640 Additional information is available in the ``local`, ``base``, and ``other``
2639 dicts. For example: ``{local.label}``, ``{base.name}``, or
2641 dicts. For example: ``{local.label}``, ``{base.name}``, or
2640 ``{other.islink}``.
2642 ``{other.islink}``.
2641
2643
2642
2644
2643 ``web``
2645 ``web``
2644 -------
2646 -------
2645
2647
2646 Web interface configuration. The settings in this section apply to
2648 Web interface configuration. The settings in this section apply to
2647 both the builtin webserver (started by :hg:`serve`) and the script you
2649 both the builtin webserver (started by :hg:`serve`) and the script you
2648 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2650 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2649 and WSGI).
2651 and WSGI).
2650
2652
2651 The Mercurial webserver does no authentication (it does not prompt for
2653 The Mercurial webserver does no authentication (it does not prompt for
2652 usernames and passwords to validate *who* users are), but it does do
2654 usernames and passwords to validate *who* users are), but it does do
2653 authorization (it grants or denies access for *authenticated users*
2655 authorization (it grants or denies access for *authenticated users*
2654 based on settings in this section). You must either configure your
2656 based on settings in this section). You must either configure your
2655 webserver to do authentication for you, or disable the authorization
2657 webserver to do authentication for you, or disable the authorization
2656 checks.
2658 checks.
2657
2659
2658 For a quick setup in a trusted environment, e.g., a private LAN, where
2660 For a quick setup in a trusted environment, e.g., a private LAN, where
2659 you want it to accept pushes from anybody, you can use the following
2661 you want it to accept pushes from anybody, you can use the following
2660 command line::
2662 command line::
2661
2663
2662 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2664 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2663
2665
2664 Note that this will allow anybody to push anything to the server and
2666 Note that this will allow anybody to push anything to the server and
2665 that this should not be used for public servers.
2667 that this should not be used for public servers.
2666
2668
2667 The full set of options is:
2669 The full set of options is:
2668
2670
2669 ``accesslog``
2671 ``accesslog``
2670 Where to output the access log. (default: stdout)
2672 Where to output the access log. (default: stdout)
2671
2673
2672 ``address``
2674 ``address``
2673 Interface address to bind to. (default: all)
2675 Interface address to bind to. (default: all)
2674
2676
2675 ``allow-archive``
2677 ``allow-archive``
2676 List of archive format (bz2, gz, zip) allowed for downloading.
2678 List of archive format (bz2, gz, zip) allowed for downloading.
2677 (default: empty)
2679 (default: empty)
2678
2680
2679 ``allowbz2``
2681 ``allowbz2``
2680 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2682 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2681 revisions.
2683 revisions.
2682 (default: False)
2684 (default: False)
2683
2685
2684 ``allowgz``
2686 ``allowgz``
2685 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2687 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2686 revisions.
2688 revisions.
2687 (default: False)
2689 (default: False)
2688
2690
2689 ``allow-pull``
2691 ``allow-pull``
2690 Whether to allow pulling from the repository. (default: True)
2692 Whether to allow pulling from the repository. (default: True)
2691
2693
2692 ``allow-push``
2694 ``allow-push``
2693 Whether to allow pushing to the repository. If empty or not set,
2695 Whether to allow pushing to the repository. If empty or not set,
2694 pushing is not allowed. If the special value ``*``, any remote
2696 pushing is not allowed. If the special value ``*``, any remote
2695 user can push, including unauthenticated users. Otherwise, the
2697 user can push, including unauthenticated users. Otherwise, the
2696 remote user must have been authenticated, and the authenticated
2698 remote user must have been authenticated, and the authenticated
2697 user name must be present in this list. The contents of the
2699 user name must be present in this list. The contents of the
2698 allow-push list are examined after the deny_push list.
2700 allow-push list are examined after the deny_push list.
2699
2701
2700 ``allow_read``
2702 ``allow_read``
2701 If the user has not already been denied repository access due to
2703 If the user has not already been denied repository access due to
2702 the contents of deny_read, this list determines whether to grant
2704 the contents of deny_read, this list determines whether to grant
2703 repository access to the user. If this list is not empty, and the
2705 repository access to the user. If this list is not empty, and the
2704 user is unauthenticated or not present in the list, then access is
2706 user is unauthenticated or not present in the list, then access is
2705 denied for the user. If the list is empty or not set, then access
2707 denied for the user. If the list is empty or not set, then access
2706 is permitted to all users by default. Setting allow_read to the
2708 is permitted to all users by default. Setting allow_read to the
2707 special value ``*`` is equivalent to it not being set (i.e. access
2709 special value ``*`` is equivalent to it not being set (i.e. access
2708 is permitted to all users). The contents of the allow_read list are
2710 is permitted to all users). The contents of the allow_read list are
2709 examined after the deny_read list.
2711 examined after the deny_read list.
2710
2712
2711 ``allowzip``
2713 ``allowzip``
2712 (DEPRECATED) Whether to allow .zip downloading of repository
2714 (DEPRECATED) Whether to allow .zip downloading of repository
2713 revisions. This feature creates temporary files.
2715 revisions. This feature creates temporary files.
2714 (default: False)
2716 (default: False)
2715
2717
2716 ``archivesubrepos``
2718 ``archivesubrepos``
2717 Whether to recurse into subrepositories when archiving.
2719 Whether to recurse into subrepositories when archiving.
2718 (default: False)
2720 (default: False)
2719
2721
2720 ``baseurl``
2722 ``baseurl``
2721 Base URL to use when publishing URLs in other locations, so
2723 Base URL to use when publishing URLs in other locations, so
2722 third-party tools like email notification hooks can construct
2724 third-party tools like email notification hooks can construct
2723 URLs. Example: ``http://hgserver/repos/``.
2725 URLs. Example: ``http://hgserver/repos/``.
2724
2726
2725 ``cacerts``
2727 ``cacerts``
2726 Path to file containing a list of PEM encoded certificate
2728 Path to file containing a list of PEM encoded certificate
2727 authority certificates. Environment variables and ``~user``
2729 authority certificates. Environment variables and ``~user``
2728 constructs are expanded in the filename. If specified on the
2730 constructs are expanded in the filename. If specified on the
2729 client, then it will verify the identity of remote HTTPS servers
2731 client, then it will verify the identity of remote HTTPS servers
2730 with these certificates.
2732 with these certificates.
2731
2733
2732 To disable SSL verification temporarily, specify ``--insecure`` from
2734 To disable SSL verification temporarily, specify ``--insecure`` from
2733 command line.
2735 command line.
2734
2736
2735 You can use OpenSSL's CA certificate file if your platform has
2737 You can use OpenSSL's CA certificate file if your platform has
2736 one. On most Linux systems this will be
2738 one. On most Linux systems this will be
2737 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2739 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2738 generate this file manually. The form must be as follows::
2740 generate this file manually. The form must be as follows::
2739
2741
2740 -----BEGIN CERTIFICATE-----
2742 -----BEGIN CERTIFICATE-----
2741 ... (certificate in base64 PEM encoding) ...
2743 ... (certificate in base64 PEM encoding) ...
2742 -----END CERTIFICATE-----
2744 -----END CERTIFICATE-----
2743 -----BEGIN CERTIFICATE-----
2745 -----BEGIN CERTIFICATE-----
2744 ... (certificate in base64 PEM encoding) ...
2746 ... (certificate in base64 PEM encoding) ...
2745 -----END CERTIFICATE-----
2747 -----END CERTIFICATE-----
2746
2748
2747 ``cache``
2749 ``cache``
2748 Whether to support caching in hgweb. (default: True)
2750 Whether to support caching in hgweb. (default: True)
2749
2751
2750 ``certificate``
2752 ``certificate``
2751 Certificate to use when running :hg:`serve`.
2753 Certificate to use when running :hg:`serve`.
2752
2754
2753 ``collapse``
2755 ``collapse``
2754 With ``descend`` enabled, repositories in subdirectories are shown at
2756 With ``descend`` enabled, repositories in subdirectories are shown at
2755 a single level alongside repositories in the current path. With
2757 a single level alongside repositories in the current path. With
2756 ``collapse`` also enabled, repositories residing at a deeper level than
2758 ``collapse`` also enabled, repositories residing at a deeper level than
2757 the current path are grouped behind navigable directory entries that
2759 the current path are grouped behind navigable directory entries that
2758 lead to the locations of these repositories. In effect, this setting
2760 lead to the locations of these repositories. In effect, this setting
2759 collapses each collection of repositories found within a subdirectory
2761 collapses each collection of repositories found within a subdirectory
2760 into a single entry for that subdirectory. (default: False)
2762 into a single entry for that subdirectory. (default: False)
2761
2763
2762 ``comparisoncontext``
2764 ``comparisoncontext``
2763 Number of lines of context to show in side-by-side file comparison. If
2765 Number of lines of context to show in side-by-side file comparison. If
2764 negative or the value ``full``, whole files are shown. (default: 5)
2766 negative or the value ``full``, whole files are shown. (default: 5)
2765
2767
2766 This setting can be overridden by a ``context`` request parameter to the
2768 This setting can be overridden by a ``context`` request parameter to the
2767 ``comparison`` command, taking the same values.
2769 ``comparison`` command, taking the same values.
2768
2770
2769 ``contact``
2771 ``contact``
2770 Name or email address of the person in charge of the repository.
2772 Name or email address of the person in charge of the repository.
2771 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2773 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2772
2774
2773 ``csp``
2775 ``csp``
2774 Send a ``Content-Security-Policy`` HTTP header with this value.
2776 Send a ``Content-Security-Policy`` HTTP header with this value.
2775
2777
2776 The value may contain a special string ``%nonce%``, which will be replaced
2778 The value may contain a special string ``%nonce%``, which will be replaced
2777 by a randomly-generated one-time use value. If the value contains
2779 by a randomly-generated one-time use value. If the value contains
2778 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2780 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2779 one-time property of the nonce. This nonce will also be inserted into
2781 one-time property of the nonce. This nonce will also be inserted into
2780 ``<script>`` elements containing inline JavaScript.
2782 ``<script>`` elements containing inline JavaScript.
2781
2783
2782 Note: lots of HTML content sent by the server is derived from repository
2784 Note: lots of HTML content sent by the server is derived from repository
2783 data. Please consider the potential for malicious repository data to
2785 data. Please consider the potential for malicious repository data to
2784 "inject" itself into generated HTML content as part of your security
2786 "inject" itself into generated HTML content as part of your security
2785 threat model.
2787 threat model.
2786
2788
2787 ``deny_push``
2789 ``deny_push``
2788 Whether to deny pushing to the repository. If empty or not set,
2790 Whether to deny pushing to the repository. If empty or not set,
2789 push is not denied. If the special value ``*``, all remote users are
2791 push is not denied. If the special value ``*``, all remote users are
2790 denied push. Otherwise, unauthenticated users are all denied, and
2792 denied push. Otherwise, unauthenticated users are all denied, and
2791 any authenticated user name present in this list is also denied. The
2793 any authenticated user name present in this list is also denied. The
2792 contents of the deny_push list are examined before the allow-push list.
2794 contents of the deny_push list are examined before the allow-push list.
2793
2795
2794 ``deny_read``
2796 ``deny_read``
2795 Whether to deny reading/viewing of the repository. If this list is
2797 Whether to deny reading/viewing of the repository. If this list is
2796 not empty, unauthenticated users are all denied, and any
2798 not empty, unauthenticated users are all denied, and any
2797 authenticated user name present in this list is also denied access to
2799 authenticated user name present in this list is also denied access to
2798 the repository. If set to the special value ``*``, all remote users
2800 the repository. If set to the special value ``*``, all remote users
2799 are denied access (rarely needed ;). If deny_read is empty or not set,
2801 are denied access (rarely needed ;). If deny_read is empty or not set,
2800 the determination of repository access depends on the presence and
2802 the determination of repository access depends on the presence and
2801 content of the allow_read list (see description). If both
2803 content of the allow_read list (see description). If both
2802 deny_read and allow_read are empty or not set, then access is
2804 deny_read and allow_read are empty or not set, then access is
2803 permitted to all users by default. If the repository is being
2805 permitted to all users by default. If the repository is being
2804 served via hgwebdir, denied users will not be able to see it in
2806 served via hgwebdir, denied users will not be able to see it in
2805 the list of repositories. The contents of the deny_read list have
2807 the list of repositories. The contents of the deny_read list have
2806 priority over (are examined before) the contents of the allow_read
2808 priority over (are examined before) the contents of the allow_read
2807 list.
2809 list.
2808
2810
2809 ``descend``
2811 ``descend``
2810 hgwebdir indexes will not descend into subdirectories. Only repositories
2812 hgwebdir indexes will not descend into subdirectories. Only repositories
2811 directly in the current path will be shown (other repositories are still
2813 directly in the current path will be shown (other repositories are still
2812 available from the index corresponding to their containing path).
2814 available from the index corresponding to their containing path).
2813
2815
2814 ``description``
2816 ``description``
2815 Textual description of the repository's purpose or contents.
2817 Textual description of the repository's purpose or contents.
2816 (default: "unknown")
2818 (default: "unknown")
2817
2819
2818 ``encoding``
2820 ``encoding``
2819 Character encoding name. (default: the current locale charset)
2821 Character encoding name. (default: the current locale charset)
2820 Example: "UTF-8".
2822 Example: "UTF-8".
2821
2823
2822 ``errorlog``
2824 ``errorlog``
2823 Where to output the error log. (default: stderr)
2825 Where to output the error log. (default: stderr)
2824
2826
2825 ``guessmime``
2827 ``guessmime``
2826 Control MIME types for raw download of file content.
2828 Control MIME types for raw download of file content.
2827 Set to True to let hgweb guess the content type from the file
2829 Set to True to let hgweb guess the content type from the file
2828 extension. This will serve HTML files as ``text/html`` and might
2830 extension. This will serve HTML files as ``text/html`` and might
2829 allow cross-site scripting attacks when serving untrusted
2831 allow cross-site scripting attacks when serving untrusted
2830 repositories. (default: False)
2832 repositories. (default: False)
2831
2833
2832 ``hidden``
2834 ``hidden``
2833 Whether to hide the repository in the hgwebdir index.
2835 Whether to hide the repository in the hgwebdir index.
2834 (default: False)
2836 (default: False)
2835
2837
2836 ``ipv6``
2838 ``ipv6``
2837 Whether to use IPv6. (default: False)
2839 Whether to use IPv6. (default: False)
2838
2840
2839 ``labels``
2841 ``labels``
2840 List of string *labels* associated with the repository.
2842 List of string *labels* associated with the repository.
2841
2843
2842 Labels are exposed as a template keyword and can be used to customize
2844 Labels are exposed as a template keyword and can be used to customize
2843 output. e.g. the ``index`` template can group or filter repositories
2845 output. e.g. the ``index`` template can group or filter repositories
2844 by labels and the ``summary`` template can display additional content
2846 by labels and the ``summary`` template can display additional content
2845 if a specific label is present.
2847 if a specific label is present.
2846
2848
2847 ``logoimg``
2849 ``logoimg``
2848 File name of the logo image that some templates display on each page.
2850 File name of the logo image that some templates display on each page.
2849 The file name is relative to ``staticurl``. That is, the full path to
2851 The file name is relative to ``staticurl``. That is, the full path to
2850 the logo image is "staticurl/logoimg".
2852 the logo image is "staticurl/logoimg".
2851 If unset, ``hglogo.png`` will be used.
2853 If unset, ``hglogo.png`` will be used.
2852
2854
2853 ``logourl``
2855 ``logourl``
2854 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2856 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2855 will be used.
2857 will be used.
2856
2858
2857 ``maxchanges``
2859 ``maxchanges``
2858 Maximum number of changes to list on the changelog. (default: 10)
2860 Maximum number of changes to list on the changelog. (default: 10)
2859
2861
2860 ``maxfiles``
2862 ``maxfiles``
2861 Maximum number of files to list per changeset. (default: 10)
2863 Maximum number of files to list per changeset. (default: 10)
2862
2864
2863 ``maxshortchanges``
2865 ``maxshortchanges``
2864 Maximum number of changes to list on the shortlog, graph or filelog
2866 Maximum number of changes to list on the shortlog, graph or filelog
2865 pages. (default: 60)
2867 pages. (default: 60)
2866
2868
2867 ``name``
2869 ``name``
2868 Repository name to use in the web interface.
2870 Repository name to use in the web interface.
2869 (default: current working directory)
2871 (default: current working directory)
2870
2872
2871 ``port``
2873 ``port``
2872 Port to listen on. (default: 8000)
2874 Port to listen on. (default: 8000)
2873
2875
2874 ``prefix``
2876 ``prefix``
2875 Prefix path to serve from. (default: '' (server root))
2877 Prefix path to serve from. (default: '' (server root))
2876
2878
2877 ``push_ssl``
2879 ``push_ssl``
2878 Whether to require that inbound pushes be transported over SSL to
2880 Whether to require that inbound pushes be transported over SSL to
2879 prevent password sniffing. (default: True)
2881 prevent password sniffing. (default: True)
2880
2882
2881 ``refreshinterval``
2883 ``refreshinterval``
2882 How frequently directory listings re-scan the filesystem for new
2884 How frequently directory listings re-scan the filesystem for new
2883 repositories, in seconds. This is relevant when wildcards are used
2885 repositories, in seconds. This is relevant when wildcards are used
2884 to define paths. Depending on how much filesystem traversal is
2886 to define paths. Depending on how much filesystem traversal is
2885 required, refreshing may negatively impact performance.
2887 required, refreshing may negatively impact performance.
2886
2888
2887 Values less than or equal to 0 always refresh.
2889 Values less than or equal to 0 always refresh.
2888 (default: 20)
2890 (default: 20)
2889
2891
2890 ``server-header``
2892 ``server-header``
2891 Value for HTTP ``Server`` response header.
2893 Value for HTTP ``Server`` response header.
2892
2894
2893 ``static``
2895 ``static``
2894 Directory where static files are served from.
2896 Directory where static files are served from.
2895
2897
2896 ``staticurl``
2898 ``staticurl``
2897 Base URL to use for static files. If unset, static files (e.g. the
2899 Base URL to use for static files. If unset, static files (e.g. the
2898 hgicon.png favicon) will be served by the CGI script itself. Use
2900 hgicon.png favicon) will be served by the CGI script itself. Use
2899 this setting to serve them directly with the HTTP server.
2901 this setting to serve them directly with the HTTP server.
2900 Example: ``http://hgserver/static/``.
2902 Example: ``http://hgserver/static/``.
2901
2903
2902 ``stripes``
2904 ``stripes``
2903 How many lines a "zebra stripe" should span in multi-line output.
2905 How many lines a "zebra stripe" should span in multi-line output.
2904 Set to 0 to disable. (default: 1)
2906 Set to 0 to disable. (default: 1)
2905
2907
2906 ``style``
2908 ``style``
2907 Which template map style to use. The available options are the names of
2909 Which template map style to use. The available options are the names of
2908 subdirectories in the HTML templates path. (default: ``paper``)
2910 subdirectories in the HTML templates path. (default: ``paper``)
2909 Example: ``monoblue``.
2911 Example: ``monoblue``.
2910
2912
2911 ``templates``
2913 ``templates``
2912 Where to find the HTML templates. The default path to the HTML templates
2914 Where to find the HTML templates. The default path to the HTML templates
2913 can be obtained from ``hg debuginstall``.
2915 can be obtained from ``hg debuginstall``.
2914
2916
2915 ``websub``
2917 ``websub``
2916 ----------
2918 ----------
2917
2919
2918 Web substitution filter definition. You can use this section to
2920 Web substitution filter definition. You can use this section to
2919 define a set of regular expression substitution patterns which
2921 define a set of regular expression substitution patterns which
2920 let you automatically modify the hgweb server output.
2922 let you automatically modify the hgweb server output.
2921
2923
2922 The default hgweb templates only apply these substitution patterns
2924 The default hgweb templates only apply these substitution patterns
2923 on the revision description fields. You can apply them anywhere
2925 on the revision description fields. You can apply them anywhere
2924 you want when you create your own templates by adding calls to the
2926 you want when you create your own templates by adding calls to the
2925 "websub" filter (usually after calling the "escape" filter).
2927 "websub" filter (usually after calling the "escape" filter).
2926
2928
2927 This can be used, for example, to convert issue references to links
2929 This can be used, for example, to convert issue references to links
2928 to your issue tracker, or to convert "markdown-like" syntax into
2930 to your issue tracker, or to convert "markdown-like" syntax into
2929 HTML (see the examples below).
2931 HTML (see the examples below).
2930
2932
2931 Each entry in this section names a substitution filter.
2933 Each entry in this section names a substitution filter.
2932 The value of each entry defines the substitution expression itself.
2934 The value of each entry defines the substitution expression itself.
2933 The websub expressions follow the old interhg extension syntax,
2935 The websub expressions follow the old interhg extension syntax,
2934 which in turn imitates the Unix sed replacement syntax::
2936 which in turn imitates the Unix sed replacement syntax::
2935
2937
2936 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2938 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2937
2939
2938 You can use any separator other than "/". The final "i" is optional
2940 You can use any separator other than "/". The final "i" is optional
2939 and indicates that the search must be case insensitive.
2941 and indicates that the search must be case insensitive.
2940
2942
2941 Examples::
2943 Examples::
2942
2944
2943 [websub]
2945 [websub]
2944 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2946 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2945 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2947 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2946 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2948 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2947
2949
2948 ``worker``
2950 ``worker``
2949 ----------
2951 ----------
2950
2952
2951 Parallel master/worker configuration. We currently perform working
2953 Parallel master/worker configuration. We currently perform working
2952 directory updates in parallel on Unix-like systems, which greatly
2954 directory updates in parallel on Unix-like systems, which greatly
2953 helps performance.
2955 helps performance.
2954
2956
2955 ``enabled``
2957 ``enabled``
2956 Whether to enable workers code to be used.
2958 Whether to enable workers code to be used.
2957 (default: true)
2959 (default: true)
2958
2960
2959 ``numcpus``
2961 ``numcpus``
2960 Number of CPUs to use for parallel operations. A zero or
2962 Number of CPUs to use for parallel operations. A zero or
2961 negative value is treated as ``use the default``.
2963 negative value is treated as ``use the default``.
2962 (default: 4 or the number of CPUs on the system, whichever is larger)
2964 (default: 4 or the number of CPUs on the system, whichever is larger)
2963
2965
2964 ``backgroundclose``
2966 ``backgroundclose``
2965 Whether to enable closing file handles on background threads during certain
2967 Whether to enable closing file handles on background threads during certain
2966 operations. Some platforms aren't very efficient at closing file
2968 operations. Some platforms aren't very efficient at closing file
2967 handles that have been written or appended to. By performing file closing
2969 handles that have been written or appended to. By performing file closing
2968 on background threads, file write rate can increase substantially.
2970 on background threads, file write rate can increase substantially.
2969 (default: true on Windows, false elsewhere)
2971 (default: true on Windows, false elsewhere)
2970
2972
2971 ``backgroundcloseminfilecount``
2973 ``backgroundcloseminfilecount``
2972 Minimum number of files required to trigger background file closing.
2974 Minimum number of files required to trigger background file closing.
2973 Operations not writing this many files won't start background close
2975 Operations not writing this many files won't start background close
2974 threads.
2976 threads.
2975 (default: 2048)
2977 (default: 2048)
2976
2978
2977 ``backgroundclosemaxqueue``
2979 ``backgroundclosemaxqueue``
2978 The maximum number of opened file handles waiting to be closed in the
2980 The maximum number of opened file handles waiting to be closed in the
2979 background. This option only has an effect if ``backgroundclose`` is
2981 background. This option only has an effect if ``backgroundclose`` is
2980 enabled.
2982 enabled.
2981 (default: 384)
2983 (default: 384)
2982
2984
2983 ``backgroundclosethreadcount``
2985 ``backgroundclosethreadcount``
2984 Number of threads to process background file closes. Only relevant if
2986 Number of threads to process background file closes. Only relevant if
2985 ``backgroundclose`` is enabled.
2987 ``backgroundclose`` is enabled.
2986 (default: 4)
2988 (default: 4)
@@ -1,3650 +1,3653 b''
1 # localrepo.py - read/write repository class for mercurial
1 # localrepo.py - read/write repository class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import functools
11 import functools
12 import os
12 import os
13 import random
13 import random
14 import sys
14 import sys
15 import time
15 import time
16 import weakref
16 import weakref
17
17
18 from .i18n import _
18 from .i18n import _
19 from .node import (
19 from .node import (
20 bin,
20 bin,
21 hex,
21 hex,
22 nullid,
22 nullid,
23 nullrev,
23 nullrev,
24 short,
24 short,
25 )
25 )
26 from .pycompat import (
26 from .pycompat import (
27 delattr,
27 delattr,
28 getattr,
28 getattr,
29 )
29 )
30 from . import (
30 from . import (
31 bookmarks,
31 bookmarks,
32 branchmap,
32 branchmap,
33 bundle2,
33 bundle2,
34 bundlecaches,
34 bundlecaches,
35 changegroup,
35 changegroup,
36 color,
36 color,
37 commit,
37 commit,
38 context,
38 context,
39 dirstate,
39 dirstate,
40 dirstateguard,
40 dirstateguard,
41 discovery,
41 discovery,
42 encoding,
42 encoding,
43 error,
43 error,
44 exchange,
44 exchange,
45 extensions,
45 extensions,
46 filelog,
46 filelog,
47 hook,
47 hook,
48 lock as lockmod,
48 lock as lockmod,
49 match as matchmod,
49 match as matchmod,
50 mergestate as mergestatemod,
50 mergestate as mergestatemod,
51 mergeutil,
51 mergeutil,
52 namespaces,
52 namespaces,
53 narrowspec,
53 narrowspec,
54 obsolete,
54 obsolete,
55 pathutil,
55 pathutil,
56 phases,
56 phases,
57 pushkey,
57 pushkey,
58 pycompat,
58 pycompat,
59 rcutil,
59 rcutil,
60 repoview,
60 repoview,
61 requirements as requirementsmod,
61 requirements as requirementsmod,
62 revlog,
62 revlog,
63 revset,
63 revset,
64 revsetlang,
64 revsetlang,
65 scmutil,
65 scmutil,
66 sparse,
66 sparse,
67 store as storemod,
67 store as storemod,
68 subrepoutil,
68 subrepoutil,
69 tags as tagsmod,
69 tags as tagsmod,
70 transaction,
70 transaction,
71 txnutil,
71 txnutil,
72 util,
72 util,
73 vfs as vfsmod,
73 vfs as vfsmod,
74 )
74 )
75
75
76 from .interfaces import (
76 from .interfaces import (
77 repository,
77 repository,
78 util as interfaceutil,
78 util as interfaceutil,
79 )
79 )
80
80
81 from .utils import (
81 from .utils import (
82 hashutil,
82 hashutil,
83 procutil,
83 procutil,
84 stringutil,
84 stringutil,
85 )
85 )
86
86
87 from .revlogutils import constants as revlogconst
87 from .revlogutils import constants as revlogconst
88
88
89 release = lockmod.release
89 release = lockmod.release
90 urlerr = util.urlerr
90 urlerr = util.urlerr
91 urlreq = util.urlreq
91 urlreq = util.urlreq
92
92
93 # set of (path, vfs-location) tuples. vfs-location is:
93 # set of (path, vfs-location) tuples. vfs-location is:
94 # - 'plain for vfs relative paths
94 # - 'plain for vfs relative paths
95 # - '' for svfs relative paths
95 # - '' for svfs relative paths
96 _cachedfiles = set()
96 _cachedfiles = set()
97
97
98
98
99 class _basefilecache(scmutil.filecache):
99 class _basefilecache(scmutil.filecache):
100 """All filecache usage on repo are done for logic that should be unfiltered"""
100 """All filecache usage on repo are done for logic that should be unfiltered"""
101
101
102 def __get__(self, repo, type=None):
102 def __get__(self, repo, type=None):
103 if repo is None:
103 if repo is None:
104 return self
104 return self
105 # proxy to unfiltered __dict__ since filtered repo has no entry
105 # proxy to unfiltered __dict__ since filtered repo has no entry
106 unfi = repo.unfiltered()
106 unfi = repo.unfiltered()
107 try:
107 try:
108 return unfi.__dict__[self.sname]
108 return unfi.__dict__[self.sname]
109 except KeyError:
109 except KeyError:
110 pass
110 pass
111 return super(_basefilecache, self).__get__(unfi, type)
111 return super(_basefilecache, self).__get__(unfi, type)
112
112
113 def set(self, repo, value):
113 def set(self, repo, value):
114 return super(_basefilecache, self).set(repo.unfiltered(), value)
114 return super(_basefilecache, self).set(repo.unfiltered(), value)
115
115
116
116
117 class repofilecache(_basefilecache):
117 class repofilecache(_basefilecache):
118 """filecache for files in .hg but outside of .hg/store"""
118 """filecache for files in .hg but outside of .hg/store"""
119
119
120 def __init__(self, *paths):
120 def __init__(self, *paths):
121 super(repofilecache, self).__init__(*paths)
121 super(repofilecache, self).__init__(*paths)
122 for path in paths:
122 for path in paths:
123 _cachedfiles.add((path, b'plain'))
123 _cachedfiles.add((path, b'plain'))
124
124
125 def join(self, obj, fname):
125 def join(self, obj, fname):
126 return obj.vfs.join(fname)
126 return obj.vfs.join(fname)
127
127
128
128
129 class storecache(_basefilecache):
129 class storecache(_basefilecache):
130 """filecache for files in the store"""
130 """filecache for files in the store"""
131
131
132 def __init__(self, *paths):
132 def __init__(self, *paths):
133 super(storecache, self).__init__(*paths)
133 super(storecache, self).__init__(*paths)
134 for path in paths:
134 for path in paths:
135 _cachedfiles.add((path, b''))
135 _cachedfiles.add((path, b''))
136
136
137 def join(self, obj, fname):
137 def join(self, obj, fname):
138 return obj.sjoin(fname)
138 return obj.sjoin(fname)
139
139
140
140
141 class mixedrepostorecache(_basefilecache):
141 class mixedrepostorecache(_basefilecache):
142 """filecache for a mix files in .hg/store and outside"""
142 """filecache for a mix files in .hg/store and outside"""
143
143
144 def __init__(self, *pathsandlocations):
144 def __init__(self, *pathsandlocations):
145 # scmutil.filecache only uses the path for passing back into our
145 # scmutil.filecache only uses the path for passing back into our
146 # join(), so we can safely pass a list of paths and locations
146 # join(), so we can safely pass a list of paths and locations
147 super(mixedrepostorecache, self).__init__(*pathsandlocations)
147 super(mixedrepostorecache, self).__init__(*pathsandlocations)
148 _cachedfiles.update(pathsandlocations)
148 _cachedfiles.update(pathsandlocations)
149
149
150 def join(self, obj, fnameandlocation):
150 def join(self, obj, fnameandlocation):
151 fname, location = fnameandlocation
151 fname, location = fnameandlocation
152 if location == b'plain':
152 if location == b'plain':
153 return obj.vfs.join(fname)
153 return obj.vfs.join(fname)
154 else:
154 else:
155 if location != b'':
155 if location != b'':
156 raise error.ProgrammingError(
156 raise error.ProgrammingError(
157 b'unexpected location: %s' % location
157 b'unexpected location: %s' % location
158 )
158 )
159 return obj.sjoin(fname)
159 return obj.sjoin(fname)
160
160
161
161
162 def isfilecached(repo, name):
162 def isfilecached(repo, name):
163 """check if a repo has already cached "name" filecache-ed property
163 """check if a repo has already cached "name" filecache-ed property
164
164
165 This returns (cachedobj-or-None, iscached) tuple.
165 This returns (cachedobj-or-None, iscached) tuple.
166 """
166 """
167 cacheentry = repo.unfiltered()._filecache.get(name, None)
167 cacheentry = repo.unfiltered()._filecache.get(name, None)
168 if not cacheentry:
168 if not cacheentry:
169 return None, False
169 return None, False
170 return cacheentry.obj, True
170 return cacheentry.obj, True
171
171
172
172
173 class unfilteredpropertycache(util.propertycache):
173 class unfilteredpropertycache(util.propertycache):
174 """propertycache that apply to unfiltered repo only"""
174 """propertycache that apply to unfiltered repo only"""
175
175
176 def __get__(self, repo, type=None):
176 def __get__(self, repo, type=None):
177 unfi = repo.unfiltered()
177 unfi = repo.unfiltered()
178 if unfi is repo:
178 if unfi is repo:
179 return super(unfilteredpropertycache, self).__get__(unfi)
179 return super(unfilteredpropertycache, self).__get__(unfi)
180 return getattr(unfi, self.name)
180 return getattr(unfi, self.name)
181
181
182
182
183 class filteredpropertycache(util.propertycache):
183 class filteredpropertycache(util.propertycache):
184 """propertycache that must take filtering in account"""
184 """propertycache that must take filtering in account"""
185
185
186 def cachevalue(self, obj, value):
186 def cachevalue(self, obj, value):
187 object.__setattr__(obj, self.name, value)
187 object.__setattr__(obj, self.name, value)
188
188
189
189
190 def hasunfilteredcache(repo, name):
190 def hasunfilteredcache(repo, name):
191 """check if a repo has an unfilteredpropertycache value for <name>"""
191 """check if a repo has an unfilteredpropertycache value for <name>"""
192 return name in vars(repo.unfiltered())
192 return name in vars(repo.unfiltered())
193
193
194
194
195 def unfilteredmethod(orig):
195 def unfilteredmethod(orig):
196 """decorate method that always need to be run on unfiltered version"""
196 """decorate method that always need to be run on unfiltered version"""
197
197
198 @functools.wraps(orig)
198 @functools.wraps(orig)
199 def wrapper(repo, *args, **kwargs):
199 def wrapper(repo, *args, **kwargs):
200 return orig(repo.unfiltered(), *args, **kwargs)
200 return orig(repo.unfiltered(), *args, **kwargs)
201
201
202 return wrapper
202 return wrapper
203
203
204
204
205 moderncaps = {
205 moderncaps = {
206 b'lookup',
206 b'lookup',
207 b'branchmap',
207 b'branchmap',
208 b'pushkey',
208 b'pushkey',
209 b'known',
209 b'known',
210 b'getbundle',
210 b'getbundle',
211 b'unbundle',
211 b'unbundle',
212 }
212 }
213 legacycaps = moderncaps.union({b'changegroupsubset'})
213 legacycaps = moderncaps.union({b'changegroupsubset'})
214
214
215
215
216 @interfaceutil.implementer(repository.ipeercommandexecutor)
216 @interfaceutil.implementer(repository.ipeercommandexecutor)
217 class localcommandexecutor(object):
217 class localcommandexecutor(object):
218 def __init__(self, peer):
218 def __init__(self, peer):
219 self._peer = peer
219 self._peer = peer
220 self._sent = False
220 self._sent = False
221 self._closed = False
221 self._closed = False
222
222
223 def __enter__(self):
223 def __enter__(self):
224 return self
224 return self
225
225
226 def __exit__(self, exctype, excvalue, exctb):
226 def __exit__(self, exctype, excvalue, exctb):
227 self.close()
227 self.close()
228
228
229 def callcommand(self, command, args):
229 def callcommand(self, command, args):
230 if self._sent:
230 if self._sent:
231 raise error.ProgrammingError(
231 raise error.ProgrammingError(
232 b'callcommand() cannot be used after sendcommands()'
232 b'callcommand() cannot be used after sendcommands()'
233 )
233 )
234
234
235 if self._closed:
235 if self._closed:
236 raise error.ProgrammingError(
236 raise error.ProgrammingError(
237 b'callcommand() cannot be used after close()'
237 b'callcommand() cannot be used after close()'
238 )
238 )
239
239
240 # We don't need to support anything fancy. Just call the named
240 # We don't need to support anything fancy. Just call the named
241 # method on the peer and return a resolved future.
241 # method on the peer and return a resolved future.
242 fn = getattr(self._peer, pycompat.sysstr(command))
242 fn = getattr(self._peer, pycompat.sysstr(command))
243
243
244 f = pycompat.futures.Future()
244 f = pycompat.futures.Future()
245
245
246 try:
246 try:
247 result = fn(**pycompat.strkwargs(args))
247 result = fn(**pycompat.strkwargs(args))
248 except Exception:
248 except Exception:
249 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
249 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
250 else:
250 else:
251 f.set_result(result)
251 f.set_result(result)
252
252
253 return f
253 return f
254
254
255 def sendcommands(self):
255 def sendcommands(self):
256 self._sent = True
256 self._sent = True
257
257
258 def close(self):
258 def close(self):
259 self._closed = True
259 self._closed = True
260
260
261
261
262 @interfaceutil.implementer(repository.ipeercommands)
262 @interfaceutil.implementer(repository.ipeercommands)
263 class localpeer(repository.peer):
263 class localpeer(repository.peer):
264 '''peer for a local repo; reflects only the most recent API'''
264 '''peer for a local repo; reflects only the most recent API'''
265
265
266 def __init__(self, repo, caps=None):
266 def __init__(self, repo, caps=None):
267 super(localpeer, self).__init__()
267 super(localpeer, self).__init__()
268
268
269 if caps is None:
269 if caps is None:
270 caps = moderncaps.copy()
270 caps = moderncaps.copy()
271 self._repo = repo.filtered(b'served')
271 self._repo = repo.filtered(b'served')
272 self.ui = repo.ui
272 self.ui = repo.ui
273 self._caps = repo._restrictcapabilities(caps)
273 self._caps = repo._restrictcapabilities(caps)
274
274
275 # Begin of _basepeer interface.
275 # Begin of _basepeer interface.
276
276
277 def url(self):
277 def url(self):
278 return self._repo.url()
278 return self._repo.url()
279
279
280 def local(self):
280 def local(self):
281 return self._repo
281 return self._repo
282
282
283 def peer(self):
283 def peer(self):
284 return self
284 return self
285
285
286 def canpush(self):
286 def canpush(self):
287 return True
287 return True
288
288
289 def close(self):
289 def close(self):
290 self._repo.close()
290 self._repo.close()
291
291
292 # End of _basepeer interface.
292 # End of _basepeer interface.
293
293
294 # Begin of _basewirecommands interface.
294 # Begin of _basewirecommands interface.
295
295
296 def branchmap(self):
296 def branchmap(self):
297 return self._repo.branchmap()
297 return self._repo.branchmap()
298
298
299 def capabilities(self):
299 def capabilities(self):
300 return self._caps
300 return self._caps
301
301
302 def clonebundles(self):
302 def clonebundles(self):
303 return self._repo.tryread(bundlecaches.CB_MANIFEST_FILE)
303 return self._repo.tryread(bundlecaches.CB_MANIFEST_FILE)
304
304
305 def debugwireargs(self, one, two, three=None, four=None, five=None):
305 def debugwireargs(self, one, two, three=None, four=None, five=None):
306 """Used to test argument passing over the wire"""
306 """Used to test argument passing over the wire"""
307 return b"%s %s %s %s %s" % (
307 return b"%s %s %s %s %s" % (
308 one,
308 one,
309 two,
309 two,
310 pycompat.bytestr(three),
310 pycompat.bytestr(three),
311 pycompat.bytestr(four),
311 pycompat.bytestr(four),
312 pycompat.bytestr(five),
312 pycompat.bytestr(five),
313 )
313 )
314
314
315 def getbundle(
315 def getbundle(
316 self, source, heads=None, common=None, bundlecaps=None, **kwargs
316 self, source, heads=None, common=None, bundlecaps=None, **kwargs
317 ):
317 ):
318 chunks = exchange.getbundlechunks(
318 chunks = exchange.getbundlechunks(
319 self._repo,
319 self._repo,
320 source,
320 source,
321 heads=heads,
321 heads=heads,
322 common=common,
322 common=common,
323 bundlecaps=bundlecaps,
323 bundlecaps=bundlecaps,
324 **kwargs
324 **kwargs
325 )[1]
325 )[1]
326 cb = util.chunkbuffer(chunks)
326 cb = util.chunkbuffer(chunks)
327
327
328 if exchange.bundle2requested(bundlecaps):
328 if exchange.bundle2requested(bundlecaps):
329 # When requesting a bundle2, getbundle returns a stream to make the
329 # When requesting a bundle2, getbundle returns a stream to make the
330 # wire level function happier. We need to build a proper object
330 # wire level function happier. We need to build a proper object
331 # from it in local peer.
331 # from it in local peer.
332 return bundle2.getunbundler(self.ui, cb)
332 return bundle2.getunbundler(self.ui, cb)
333 else:
333 else:
334 return changegroup.getunbundler(b'01', cb, None)
334 return changegroup.getunbundler(b'01', cb, None)
335
335
336 def heads(self):
336 def heads(self):
337 return self._repo.heads()
337 return self._repo.heads()
338
338
339 def known(self, nodes):
339 def known(self, nodes):
340 return self._repo.known(nodes)
340 return self._repo.known(nodes)
341
341
342 def listkeys(self, namespace):
342 def listkeys(self, namespace):
343 return self._repo.listkeys(namespace)
343 return self._repo.listkeys(namespace)
344
344
345 def lookup(self, key):
345 def lookup(self, key):
346 return self._repo.lookup(key)
346 return self._repo.lookup(key)
347
347
348 def pushkey(self, namespace, key, old, new):
348 def pushkey(self, namespace, key, old, new):
349 return self._repo.pushkey(namespace, key, old, new)
349 return self._repo.pushkey(namespace, key, old, new)
350
350
351 def stream_out(self):
351 def stream_out(self):
352 raise error.Abort(_(b'cannot perform stream clone against local peer'))
352 raise error.Abort(_(b'cannot perform stream clone against local peer'))
353
353
354 def unbundle(self, bundle, heads, url):
354 def unbundle(self, bundle, heads, url):
355 """apply a bundle on a repo
355 """apply a bundle on a repo
356
356
357 This function handles the repo locking itself."""
357 This function handles the repo locking itself."""
358 try:
358 try:
359 try:
359 try:
360 bundle = exchange.readbundle(self.ui, bundle, None)
360 bundle = exchange.readbundle(self.ui, bundle, None)
361 ret = exchange.unbundle(self._repo, bundle, heads, b'push', url)
361 ret = exchange.unbundle(self._repo, bundle, heads, b'push', url)
362 if util.safehasattr(ret, b'getchunks'):
362 if util.safehasattr(ret, b'getchunks'):
363 # This is a bundle20 object, turn it into an unbundler.
363 # This is a bundle20 object, turn it into an unbundler.
364 # This little dance should be dropped eventually when the
364 # This little dance should be dropped eventually when the
365 # API is finally improved.
365 # API is finally improved.
366 stream = util.chunkbuffer(ret.getchunks())
366 stream = util.chunkbuffer(ret.getchunks())
367 ret = bundle2.getunbundler(self.ui, stream)
367 ret = bundle2.getunbundler(self.ui, stream)
368 return ret
368 return ret
369 except Exception as exc:
369 except Exception as exc:
370 # If the exception contains output salvaged from a bundle2
370 # If the exception contains output salvaged from a bundle2
371 # reply, we need to make sure it is printed before continuing
371 # reply, we need to make sure it is printed before continuing
372 # to fail. So we build a bundle2 with such output and consume
372 # to fail. So we build a bundle2 with such output and consume
373 # it directly.
373 # it directly.
374 #
374 #
375 # This is not very elegant but allows a "simple" solution for
375 # This is not very elegant but allows a "simple" solution for
376 # issue4594
376 # issue4594
377 output = getattr(exc, '_bundle2salvagedoutput', ())
377 output = getattr(exc, '_bundle2salvagedoutput', ())
378 if output:
378 if output:
379 bundler = bundle2.bundle20(self._repo.ui)
379 bundler = bundle2.bundle20(self._repo.ui)
380 for out in output:
380 for out in output:
381 bundler.addpart(out)
381 bundler.addpart(out)
382 stream = util.chunkbuffer(bundler.getchunks())
382 stream = util.chunkbuffer(bundler.getchunks())
383 b = bundle2.getunbundler(self.ui, stream)
383 b = bundle2.getunbundler(self.ui, stream)
384 bundle2.processbundle(self._repo, b)
384 bundle2.processbundle(self._repo, b)
385 raise
385 raise
386 except error.PushRaced as exc:
386 except error.PushRaced as exc:
387 raise error.ResponseError(
387 raise error.ResponseError(
388 _(b'push failed:'), stringutil.forcebytestr(exc)
388 _(b'push failed:'), stringutil.forcebytestr(exc)
389 )
389 )
390
390
391 # End of _basewirecommands interface.
391 # End of _basewirecommands interface.
392
392
393 # Begin of peer interface.
393 # Begin of peer interface.
394
394
395 def commandexecutor(self):
395 def commandexecutor(self):
396 return localcommandexecutor(self)
396 return localcommandexecutor(self)
397
397
398 # End of peer interface.
398 # End of peer interface.
399
399
400
400
401 @interfaceutil.implementer(repository.ipeerlegacycommands)
401 @interfaceutil.implementer(repository.ipeerlegacycommands)
402 class locallegacypeer(localpeer):
402 class locallegacypeer(localpeer):
403 """peer extension which implements legacy methods too; used for tests with
403 """peer extension which implements legacy methods too; used for tests with
404 restricted capabilities"""
404 restricted capabilities"""
405
405
406 def __init__(self, repo):
406 def __init__(self, repo):
407 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
407 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
408
408
409 # Begin of baselegacywirecommands interface.
409 # Begin of baselegacywirecommands interface.
410
410
411 def between(self, pairs):
411 def between(self, pairs):
412 return self._repo.between(pairs)
412 return self._repo.between(pairs)
413
413
414 def branches(self, nodes):
414 def branches(self, nodes):
415 return self._repo.branches(nodes)
415 return self._repo.branches(nodes)
416
416
417 def changegroup(self, nodes, source):
417 def changegroup(self, nodes, source):
418 outgoing = discovery.outgoing(
418 outgoing = discovery.outgoing(
419 self._repo, missingroots=nodes, ancestorsof=self._repo.heads()
419 self._repo, missingroots=nodes, ancestorsof=self._repo.heads()
420 )
420 )
421 return changegroup.makechangegroup(self._repo, outgoing, b'01', source)
421 return changegroup.makechangegroup(self._repo, outgoing, b'01', source)
422
422
423 def changegroupsubset(self, bases, heads, source):
423 def changegroupsubset(self, bases, heads, source):
424 outgoing = discovery.outgoing(
424 outgoing = discovery.outgoing(
425 self._repo, missingroots=bases, ancestorsof=heads
425 self._repo, missingroots=bases, ancestorsof=heads
426 )
426 )
427 return changegroup.makechangegroup(self._repo, outgoing, b'01', source)
427 return changegroup.makechangegroup(self._repo, outgoing, b'01', source)
428
428
429 # End of baselegacywirecommands interface.
429 # End of baselegacywirecommands interface.
430
430
431
431
432 # Functions receiving (ui, features) that extensions can register to impact
432 # Functions receiving (ui, features) that extensions can register to impact
433 # the ability to load repositories with custom requirements. Only
433 # the ability to load repositories with custom requirements. Only
434 # functions defined in loaded extensions are called.
434 # functions defined in loaded extensions are called.
435 #
435 #
436 # The function receives a set of requirement strings that the repository
436 # The function receives a set of requirement strings that the repository
437 # is capable of opening. Functions will typically add elements to the
437 # is capable of opening. Functions will typically add elements to the
438 # set to reflect that the extension knows how to handle that requirements.
438 # set to reflect that the extension knows how to handle that requirements.
439 featuresetupfuncs = set()
439 featuresetupfuncs = set()
440
440
441
441
442 def _getsharedvfs(hgvfs, requirements):
442 def _getsharedvfs(hgvfs, requirements):
443 """returns the vfs object pointing to root of shared source
443 """returns the vfs object pointing to root of shared source
444 repo for a shared repository
444 repo for a shared repository
445
445
446 hgvfs is vfs pointing at .hg/ of current repo (shared one)
446 hgvfs is vfs pointing at .hg/ of current repo (shared one)
447 requirements is a set of requirements of current repo (shared one)
447 requirements is a set of requirements of current repo (shared one)
448 """
448 """
449 # The ``shared`` or ``relshared`` requirements indicate the
449 # The ``shared`` or ``relshared`` requirements indicate the
450 # store lives in the path contained in the ``.hg/sharedpath`` file.
450 # store lives in the path contained in the ``.hg/sharedpath`` file.
451 # This is an absolute path for ``shared`` and relative to
451 # This is an absolute path for ``shared`` and relative to
452 # ``.hg/`` for ``relshared``.
452 # ``.hg/`` for ``relshared``.
453 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
453 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
454 if requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements:
454 if requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements:
455 sharedpath = hgvfs.join(sharedpath)
455 sharedpath = hgvfs.join(sharedpath)
456
456
457 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
457 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
458
458
459 if not sharedvfs.exists():
459 if not sharedvfs.exists():
460 raise error.RepoError(
460 raise error.RepoError(
461 _(b'.hg/sharedpath points to nonexistent directory %s')
461 _(b'.hg/sharedpath points to nonexistent directory %s')
462 % sharedvfs.base
462 % sharedvfs.base
463 )
463 )
464 return sharedvfs
464 return sharedvfs
465
465
466
466
467 def _readrequires(vfs, allowmissing):
467 def _readrequires(vfs, allowmissing):
468 """reads the require file present at root of this vfs
468 """reads the require file present at root of this vfs
469 and return a set of requirements
469 and return a set of requirements
470
470
471 If allowmissing is True, we suppress ENOENT if raised"""
471 If allowmissing is True, we suppress ENOENT if raised"""
472 # requires file contains a newline-delimited list of
472 # requires file contains a newline-delimited list of
473 # features/capabilities the opener (us) must have in order to use
473 # features/capabilities the opener (us) must have in order to use
474 # the repository. This file was introduced in Mercurial 0.9.2,
474 # the repository. This file was introduced in Mercurial 0.9.2,
475 # which means very old repositories may not have one. We assume
475 # which means very old repositories may not have one. We assume
476 # a missing file translates to no requirements.
476 # a missing file translates to no requirements.
477 try:
477 try:
478 requirements = set(vfs.read(b'requires').splitlines())
478 requirements = set(vfs.read(b'requires').splitlines())
479 except IOError as e:
479 except IOError as e:
480 if not (allowmissing and e.errno == errno.ENOENT):
480 if not (allowmissing and e.errno == errno.ENOENT):
481 raise
481 raise
482 requirements = set()
482 requirements = set()
483 return requirements
483 return requirements
484
484
485
485
486 def makelocalrepository(baseui, path, intents=None):
486 def makelocalrepository(baseui, path, intents=None):
487 """Create a local repository object.
487 """Create a local repository object.
488
488
489 Given arguments needed to construct a local repository, this function
489 Given arguments needed to construct a local repository, this function
490 performs various early repository loading functionality (such as
490 performs various early repository loading functionality (such as
491 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
491 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
492 the repository can be opened, derives a type suitable for representing
492 the repository can be opened, derives a type suitable for representing
493 that repository, and returns an instance of it.
493 that repository, and returns an instance of it.
494
494
495 The returned object conforms to the ``repository.completelocalrepository``
495 The returned object conforms to the ``repository.completelocalrepository``
496 interface.
496 interface.
497
497
498 The repository type is derived by calling a series of factory functions
498 The repository type is derived by calling a series of factory functions
499 for each aspect/interface of the final repository. These are defined by
499 for each aspect/interface of the final repository. These are defined by
500 ``REPO_INTERFACES``.
500 ``REPO_INTERFACES``.
501
501
502 Each factory function is called to produce a type implementing a specific
502 Each factory function is called to produce a type implementing a specific
503 interface. The cumulative list of returned types will be combined into a
503 interface. The cumulative list of returned types will be combined into a
504 new type and that type will be instantiated to represent the local
504 new type and that type will be instantiated to represent the local
505 repository.
505 repository.
506
506
507 The factory functions each receive various state that may be consulted
507 The factory functions each receive various state that may be consulted
508 as part of deriving a type.
508 as part of deriving a type.
509
509
510 Extensions should wrap these factory functions to customize repository type
510 Extensions should wrap these factory functions to customize repository type
511 creation. Note that an extension's wrapped function may be called even if
511 creation. Note that an extension's wrapped function may be called even if
512 that extension is not loaded for the repo being constructed. Extensions
512 that extension is not loaded for the repo being constructed. Extensions
513 should check if their ``__name__`` appears in the
513 should check if their ``__name__`` appears in the
514 ``extensionmodulenames`` set passed to the factory function and no-op if
514 ``extensionmodulenames`` set passed to the factory function and no-op if
515 not.
515 not.
516 """
516 """
517 ui = baseui.copy()
517 ui = baseui.copy()
518 # Prevent copying repo configuration.
518 # Prevent copying repo configuration.
519 ui.copy = baseui.copy
519 ui.copy = baseui.copy
520
520
521 # Working directory VFS rooted at repository root.
521 # Working directory VFS rooted at repository root.
522 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
522 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
523
523
524 # Main VFS for .hg/ directory.
524 # Main VFS for .hg/ directory.
525 hgpath = wdirvfs.join(b'.hg')
525 hgpath = wdirvfs.join(b'.hg')
526 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
526 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
527 # Whether this repository is shared one or not
527 # Whether this repository is shared one or not
528 shared = False
528 shared = False
529 # If this repository is shared, vfs pointing to shared repo
529 # If this repository is shared, vfs pointing to shared repo
530 sharedvfs = None
530 sharedvfs = None
531
531
532 # The .hg/ path should exist and should be a directory. All other
532 # The .hg/ path should exist and should be a directory. All other
533 # cases are errors.
533 # cases are errors.
534 if not hgvfs.isdir():
534 if not hgvfs.isdir():
535 try:
535 try:
536 hgvfs.stat()
536 hgvfs.stat()
537 except OSError as e:
537 except OSError as e:
538 if e.errno != errno.ENOENT:
538 if e.errno != errno.ENOENT:
539 raise
539 raise
540 except ValueError as e:
540 except ValueError as e:
541 # Can be raised on Python 3.8 when path is invalid.
541 # Can be raised on Python 3.8 when path is invalid.
542 raise error.Abort(
542 raise error.Abort(
543 _(b'invalid path %s: %s') % (path, pycompat.bytestr(e))
543 _(b'invalid path %s: %s') % (path, pycompat.bytestr(e))
544 )
544 )
545
545
546 raise error.RepoError(_(b'repository %s not found') % path)
546 raise error.RepoError(_(b'repository %s not found') % path)
547
547
548 requirements = _readrequires(hgvfs, True)
548 requirements = _readrequires(hgvfs, True)
549 shared = (
549 shared = (
550 requirementsmod.SHARED_REQUIREMENT in requirements
550 requirementsmod.SHARED_REQUIREMENT in requirements
551 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
551 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
552 )
552 )
553 storevfs = None
553 storevfs = None
554 if shared:
554 if shared:
555 # This is a shared repo
555 # This is a shared repo
556 sharedvfs = _getsharedvfs(hgvfs, requirements)
556 sharedvfs = _getsharedvfs(hgvfs, requirements)
557 storevfs = vfsmod.vfs(sharedvfs.join(b'store'))
557 storevfs = vfsmod.vfs(sharedvfs.join(b'store'))
558 else:
558 else:
559 storevfs = vfsmod.vfs(hgvfs.join(b'store'))
559 storevfs = vfsmod.vfs(hgvfs.join(b'store'))
560
560
561 # if .hg/requires contains the sharesafe requirement, it means
561 # if .hg/requires contains the sharesafe requirement, it means
562 # there exists a `.hg/store/requires` too and we should read it
562 # there exists a `.hg/store/requires` too and we should read it
563 # NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
563 # NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
564 # is present. We never write SHARESAFE_REQUIREMENT for a repo if store
564 # is present. We never write SHARESAFE_REQUIREMENT for a repo if store
565 # is not present, refer checkrequirementscompat() for that
565 # is not present, refer checkrequirementscompat() for that
566 #
566 #
567 # However, if SHARESAFE_REQUIREMENT is not present, it means that the
567 # However, if SHARESAFE_REQUIREMENT is not present, it means that the
568 # repository was shared the old way. We check the share source .hg/requires
568 # repository was shared the old way. We check the share source .hg/requires
569 # for SHARESAFE_REQUIREMENT to detect whether the current repository needs
569 # for SHARESAFE_REQUIREMENT to detect whether the current repository needs
570 # to be reshared
570 # to be reshared
571 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
571 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
572
572
573 if (
573 if (
574 shared
574 shared
575 and requirementsmod.SHARESAFE_REQUIREMENT
575 and requirementsmod.SHARESAFE_REQUIREMENT
576 not in _readrequires(sharedvfs, True)
576 not in _readrequires(sharedvfs, True)
577 ):
577 ):
578 if ui.configbool(
578 if ui.configbool(
579 b'experimental', b'sharesafe-auto-downgrade-shares'
579 b'experimental', b'sharesafe-auto-downgrade-shares'
580 ):
580 ):
581 # prevent cyclic import localrepo -> upgrade -> localrepo
581 # prevent cyclic import localrepo -> upgrade -> localrepo
582 from . import upgrade
582 from . import upgrade
583
583
584 upgrade.downgrade_share_to_non_safe(
584 upgrade.downgrade_share_to_non_safe(
585 ui,
585 ui,
586 hgvfs,
586 hgvfs,
587 sharedvfs,
587 sharedvfs,
588 requirements,
588 requirements,
589 )
589 )
590 else:
590 else:
591 raise error.Abort(
591 raise error.Abort(
592 _(
592 _(
593 b"share source does not support exp-sharesafe requirement"
593 b"share source does not support exp-sharesafe requirement"
594 )
594 )
595 )
595 )
596 else:
596 else:
597 requirements |= _readrequires(storevfs, False)
597 requirements |= _readrequires(storevfs, False)
598 elif shared:
598 elif shared:
599 sourcerequires = _readrequires(sharedvfs, False)
599 sourcerequires = _readrequires(sharedvfs, False)
600 if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires:
600 if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires:
601 if ui.configbool(b'experimental', b'sharesafe-auto-upgrade-shares'):
601 if ui.configbool(b'experimental', b'sharesafe-auto-upgrade-shares'):
602 # prevent cyclic import localrepo -> upgrade -> localrepo
602 # prevent cyclic import localrepo -> upgrade -> localrepo
603 from . import upgrade
603 from . import upgrade
604
604
605 upgrade.upgrade_share_to_safe(
605 upgrade.upgrade_share_to_safe(
606 ui,
606 ui,
607 hgvfs,
607 hgvfs,
608 storevfs,
608 storevfs,
609 requirements,
609 requirements,
610 )
610 )
611 elif ui.configbool(
611 elif ui.configbool(
612 b'experimental', b'sharesafe-warn-outdated-shares'
612 b'experimental', b'sharesafe-warn-outdated-shares'
613 ):
613 ):
614 ui.warn(
614 ui.warn(
615 _(
615 _(
616 b'warning: source repository supports share-safe functionality.'
616 b'warning: source repository supports share-safe functionality.'
617 b' Reshare to upgrade.\n'
617 b' Reshare to upgrade.\n'
618 )
618 )
619 )
619 )
620
620
621 # The .hg/hgrc file may load extensions or contain config options
621 # The .hg/hgrc file may load extensions or contain config options
622 # that influence repository construction. Attempt to load it and
622 # that influence repository construction. Attempt to load it and
623 # process any new extensions that it may have pulled in.
623 # process any new extensions that it may have pulled in.
624 if loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs):
624 if loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs):
625 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
625 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
626 extensions.loadall(ui)
626 extensions.loadall(ui)
627 extensions.populateui(ui)
627 extensions.populateui(ui)
628
628
629 # Set of module names of extensions loaded for this repository.
629 # Set of module names of extensions loaded for this repository.
630 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
630 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
631
631
632 supportedrequirements = gathersupportedrequirements(ui)
632 supportedrequirements = gathersupportedrequirements(ui)
633
633
634 # We first validate the requirements are known.
634 # We first validate the requirements are known.
635 ensurerequirementsrecognized(requirements, supportedrequirements)
635 ensurerequirementsrecognized(requirements, supportedrequirements)
636
636
637 # Then we validate that the known set is reasonable to use together.
637 # Then we validate that the known set is reasonable to use together.
638 ensurerequirementscompatible(ui, requirements)
638 ensurerequirementscompatible(ui, requirements)
639
639
640 # TODO there are unhandled edge cases related to opening repositories with
640 # TODO there are unhandled edge cases related to opening repositories with
641 # shared storage. If storage is shared, we should also test for requirements
641 # shared storage. If storage is shared, we should also test for requirements
642 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
642 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
643 # that repo, as that repo may load extensions needed to open it. This is a
643 # that repo, as that repo may load extensions needed to open it. This is a
644 # bit complicated because we don't want the other hgrc to overwrite settings
644 # bit complicated because we don't want the other hgrc to overwrite settings
645 # in this hgrc.
645 # in this hgrc.
646 #
646 #
647 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
647 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
648 # file when sharing repos. But if a requirement is added after the share is
648 # file when sharing repos. But if a requirement is added after the share is
649 # performed, thereby introducing a new requirement for the opener, we may
649 # performed, thereby introducing a new requirement for the opener, we may
650 # will not see that and could encounter a run-time error interacting with
650 # will not see that and could encounter a run-time error interacting with
651 # that shared store since it has an unknown-to-us requirement.
651 # that shared store since it has an unknown-to-us requirement.
652
652
653 # At this point, we know we should be capable of opening the repository.
653 # At this point, we know we should be capable of opening the repository.
654 # Now get on with doing that.
654 # Now get on with doing that.
655
655
656 features = set()
656 features = set()
657
657
658 # The "store" part of the repository holds versioned data. How it is
658 # The "store" part of the repository holds versioned data. How it is
659 # accessed is determined by various requirements. If `shared` or
659 # accessed is determined by various requirements. If `shared` or
660 # `relshared` requirements are present, this indicates current repository
660 # `relshared` requirements are present, this indicates current repository
661 # is a share and store exists in path mentioned in `.hg/sharedpath`
661 # is a share and store exists in path mentioned in `.hg/sharedpath`
662 if shared:
662 if shared:
663 storebasepath = sharedvfs.base
663 storebasepath = sharedvfs.base
664 cachepath = sharedvfs.join(b'cache')
664 cachepath = sharedvfs.join(b'cache')
665 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
665 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
666 else:
666 else:
667 storebasepath = hgvfs.base
667 storebasepath = hgvfs.base
668 cachepath = hgvfs.join(b'cache')
668 cachepath = hgvfs.join(b'cache')
669 wcachepath = hgvfs.join(b'wcache')
669 wcachepath = hgvfs.join(b'wcache')
670
670
671 # The store has changed over time and the exact layout is dictated by
671 # The store has changed over time and the exact layout is dictated by
672 # requirements. The store interface abstracts differences across all
672 # requirements. The store interface abstracts differences across all
673 # of them.
673 # of them.
674 store = makestore(
674 store = makestore(
675 requirements,
675 requirements,
676 storebasepath,
676 storebasepath,
677 lambda base: vfsmod.vfs(base, cacheaudited=True),
677 lambda base: vfsmod.vfs(base, cacheaudited=True),
678 )
678 )
679 hgvfs.createmode = store.createmode
679 hgvfs.createmode = store.createmode
680
680
681 storevfs = store.vfs
681 storevfs = store.vfs
682 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
682 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
683
683
684 # The cache vfs is used to manage cache files.
684 # The cache vfs is used to manage cache files.
685 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
685 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
686 cachevfs.createmode = store.createmode
686 cachevfs.createmode = store.createmode
687 # The cache vfs is used to manage cache files related to the working copy
687 # The cache vfs is used to manage cache files related to the working copy
688 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
688 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
689 wcachevfs.createmode = store.createmode
689 wcachevfs.createmode = store.createmode
690
690
691 # Now resolve the type for the repository object. We do this by repeatedly
691 # Now resolve the type for the repository object. We do this by repeatedly
692 # calling a factory function to produces types for specific aspects of the
692 # calling a factory function to produces types for specific aspects of the
693 # repo's operation. The aggregate returned types are used as base classes
693 # repo's operation. The aggregate returned types are used as base classes
694 # for a dynamically-derived type, which will represent our new repository.
694 # for a dynamically-derived type, which will represent our new repository.
695
695
696 bases = []
696 bases = []
697 extrastate = {}
697 extrastate = {}
698
698
699 for iface, fn in REPO_INTERFACES:
699 for iface, fn in REPO_INTERFACES:
700 # We pass all potentially useful state to give extensions tons of
700 # We pass all potentially useful state to give extensions tons of
701 # flexibility.
701 # flexibility.
702 typ = fn()(
702 typ = fn()(
703 ui=ui,
703 ui=ui,
704 intents=intents,
704 intents=intents,
705 requirements=requirements,
705 requirements=requirements,
706 features=features,
706 features=features,
707 wdirvfs=wdirvfs,
707 wdirvfs=wdirvfs,
708 hgvfs=hgvfs,
708 hgvfs=hgvfs,
709 store=store,
709 store=store,
710 storevfs=storevfs,
710 storevfs=storevfs,
711 storeoptions=storevfs.options,
711 storeoptions=storevfs.options,
712 cachevfs=cachevfs,
712 cachevfs=cachevfs,
713 wcachevfs=wcachevfs,
713 wcachevfs=wcachevfs,
714 extensionmodulenames=extensionmodulenames,
714 extensionmodulenames=extensionmodulenames,
715 extrastate=extrastate,
715 extrastate=extrastate,
716 baseclasses=bases,
716 baseclasses=bases,
717 )
717 )
718
718
719 if not isinstance(typ, type):
719 if not isinstance(typ, type):
720 raise error.ProgrammingError(
720 raise error.ProgrammingError(
721 b'unable to construct type for %s' % iface
721 b'unable to construct type for %s' % iface
722 )
722 )
723
723
724 bases.append(typ)
724 bases.append(typ)
725
725
726 # type() allows you to use characters in type names that wouldn't be
726 # type() allows you to use characters in type names that wouldn't be
727 # recognized as Python symbols in source code. We abuse that to add
727 # recognized as Python symbols in source code. We abuse that to add
728 # rich information about our constructed repo.
728 # rich information about our constructed repo.
729 name = pycompat.sysstr(
729 name = pycompat.sysstr(
730 b'derivedrepo:%s<%s>' % (wdirvfs.base, b','.join(sorted(requirements)))
730 b'derivedrepo:%s<%s>' % (wdirvfs.base, b','.join(sorted(requirements)))
731 )
731 )
732
732
733 cls = type(name, tuple(bases), {})
733 cls = type(name, tuple(bases), {})
734
734
735 return cls(
735 return cls(
736 baseui=baseui,
736 baseui=baseui,
737 ui=ui,
737 ui=ui,
738 origroot=path,
738 origroot=path,
739 wdirvfs=wdirvfs,
739 wdirvfs=wdirvfs,
740 hgvfs=hgvfs,
740 hgvfs=hgvfs,
741 requirements=requirements,
741 requirements=requirements,
742 supportedrequirements=supportedrequirements,
742 supportedrequirements=supportedrequirements,
743 sharedpath=storebasepath,
743 sharedpath=storebasepath,
744 store=store,
744 store=store,
745 cachevfs=cachevfs,
745 cachevfs=cachevfs,
746 wcachevfs=wcachevfs,
746 wcachevfs=wcachevfs,
747 features=features,
747 features=features,
748 intents=intents,
748 intents=intents,
749 )
749 )
750
750
751
751
752 def loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs=None):
752 def loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs=None):
753 """Load hgrc files/content into a ui instance.
753 """Load hgrc files/content into a ui instance.
754
754
755 This is called during repository opening to load any additional
755 This is called during repository opening to load any additional
756 config files or settings relevant to the current repository.
756 config files or settings relevant to the current repository.
757
757
758 Returns a bool indicating whether any additional configs were loaded.
758 Returns a bool indicating whether any additional configs were loaded.
759
759
760 Extensions should monkeypatch this function to modify how per-repo
760 Extensions should monkeypatch this function to modify how per-repo
761 configs are loaded. For example, an extension may wish to pull in
761 configs are loaded. For example, an extension may wish to pull in
762 configs from alternate files or sources.
762 configs from alternate files or sources.
763
763
764 sharedvfs is vfs object pointing to source repo if the current one is a
764 sharedvfs is vfs object pointing to source repo if the current one is a
765 shared one
765 shared one
766 """
766 """
767 if not rcutil.use_repo_hgrc():
767 if not rcutil.use_repo_hgrc():
768 return False
768 return False
769
769
770 ret = False
770 ret = False
771 # first load config from shared source if we has to
771 # first load config from shared source if we has to
772 if requirementsmod.SHARESAFE_REQUIREMENT in requirements and sharedvfs:
772 if requirementsmod.SHARESAFE_REQUIREMENT in requirements and sharedvfs:
773 try:
773 try:
774 ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
774 ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
775 ret = True
775 ret = True
776 except IOError:
776 except IOError:
777 pass
777 pass
778
778
779 try:
779 try:
780 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
780 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
781 ret = True
781 ret = True
782 except IOError:
782 except IOError:
783 pass
783 pass
784
784
785 try:
785 try:
786 ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
786 ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
787 ret = True
787 ret = True
788 except IOError:
788 except IOError:
789 pass
789 pass
790
790
791 return ret
791 return ret
792
792
793
793
794 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
794 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
795 """Perform additional actions after .hg/hgrc is loaded.
795 """Perform additional actions after .hg/hgrc is loaded.
796
796
797 This function is called during repository loading immediately after
797 This function is called during repository loading immediately after
798 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
798 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
799
799
800 The function can be used to validate configs, automatically add
800 The function can be used to validate configs, automatically add
801 options (including extensions) based on requirements, etc.
801 options (including extensions) based on requirements, etc.
802 """
802 """
803
803
804 # Map of requirements to list of extensions to load automatically when
804 # Map of requirements to list of extensions to load automatically when
805 # requirement is present.
805 # requirement is present.
806 autoextensions = {
806 autoextensions = {
807 b'git': [b'git'],
807 b'git': [b'git'],
808 b'largefiles': [b'largefiles'],
808 b'largefiles': [b'largefiles'],
809 b'lfs': [b'lfs'],
809 b'lfs': [b'lfs'],
810 }
810 }
811
811
812 for requirement, names in sorted(autoextensions.items()):
812 for requirement, names in sorted(autoextensions.items()):
813 if requirement not in requirements:
813 if requirement not in requirements:
814 continue
814 continue
815
815
816 for name in names:
816 for name in names:
817 if not ui.hasconfig(b'extensions', name):
817 if not ui.hasconfig(b'extensions', name):
818 ui.setconfig(b'extensions', name, b'', source=b'autoload')
818 ui.setconfig(b'extensions', name, b'', source=b'autoload')
819
819
820
820
821 def gathersupportedrequirements(ui):
821 def gathersupportedrequirements(ui):
822 """Determine the complete set of recognized requirements."""
822 """Determine the complete set of recognized requirements."""
823 # Start with all requirements supported by this file.
823 # Start with all requirements supported by this file.
824 supported = set(localrepository._basesupported)
824 supported = set(localrepository._basesupported)
825
825
826 # Execute ``featuresetupfuncs`` entries if they belong to an extension
826 # Execute ``featuresetupfuncs`` entries if they belong to an extension
827 # relevant to this ui instance.
827 # relevant to this ui instance.
828 modules = {m.__name__ for n, m in extensions.extensions(ui)}
828 modules = {m.__name__ for n, m in extensions.extensions(ui)}
829
829
830 for fn in featuresetupfuncs:
830 for fn in featuresetupfuncs:
831 if fn.__module__ in modules:
831 if fn.__module__ in modules:
832 fn(ui, supported)
832 fn(ui, supported)
833
833
834 # Add derived requirements from registered compression engines.
834 # Add derived requirements from registered compression engines.
835 for name in util.compengines:
835 for name in util.compengines:
836 engine = util.compengines[name]
836 engine = util.compengines[name]
837 if engine.available() and engine.revlogheader():
837 if engine.available() and engine.revlogheader():
838 supported.add(b'exp-compression-%s' % name)
838 supported.add(b'exp-compression-%s' % name)
839 if engine.name() == b'zstd':
839 if engine.name() == b'zstd':
840 supported.add(b'revlog-compression-zstd')
840 supported.add(b'revlog-compression-zstd')
841
841
842 return supported
842 return supported
843
843
844
844
845 def ensurerequirementsrecognized(requirements, supported):
845 def ensurerequirementsrecognized(requirements, supported):
846 """Validate that a set of local requirements is recognized.
846 """Validate that a set of local requirements is recognized.
847
847
848 Receives a set of requirements. Raises an ``error.RepoError`` if there
848 Receives a set of requirements. Raises an ``error.RepoError`` if there
849 exists any requirement in that set that currently loaded code doesn't
849 exists any requirement in that set that currently loaded code doesn't
850 recognize.
850 recognize.
851
851
852 Returns a set of supported requirements.
852 Returns a set of supported requirements.
853 """
853 """
854 missing = set()
854 missing = set()
855
855
856 for requirement in requirements:
856 for requirement in requirements:
857 if requirement in supported:
857 if requirement in supported:
858 continue
858 continue
859
859
860 if not requirement or not requirement[0:1].isalnum():
860 if not requirement or not requirement[0:1].isalnum():
861 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
861 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
862
862
863 missing.add(requirement)
863 missing.add(requirement)
864
864
865 if missing:
865 if missing:
866 raise error.RequirementError(
866 raise error.RequirementError(
867 _(b'repository requires features unknown to this Mercurial: %s')
867 _(b'repository requires features unknown to this Mercurial: %s')
868 % b' '.join(sorted(missing)),
868 % b' '.join(sorted(missing)),
869 hint=_(
869 hint=_(
870 b'see https://mercurial-scm.org/wiki/MissingRequirement '
870 b'see https://mercurial-scm.org/wiki/MissingRequirement '
871 b'for more information'
871 b'for more information'
872 ),
872 ),
873 )
873 )
874
874
875
875
876 def ensurerequirementscompatible(ui, requirements):
876 def ensurerequirementscompatible(ui, requirements):
877 """Validates that a set of recognized requirements is mutually compatible.
877 """Validates that a set of recognized requirements is mutually compatible.
878
878
879 Some requirements may not be compatible with others or require
879 Some requirements may not be compatible with others or require
880 config options that aren't enabled. This function is called during
880 config options that aren't enabled. This function is called during
881 repository opening to ensure that the set of requirements needed
881 repository opening to ensure that the set of requirements needed
882 to open a repository is sane and compatible with config options.
882 to open a repository is sane and compatible with config options.
883
883
884 Extensions can monkeypatch this function to perform additional
884 Extensions can monkeypatch this function to perform additional
885 checking.
885 checking.
886
886
887 ``error.RepoError`` should be raised on failure.
887 ``error.RepoError`` should be raised on failure.
888 """
888 """
889 if (
889 if (
890 requirementsmod.SPARSE_REQUIREMENT in requirements
890 requirementsmod.SPARSE_REQUIREMENT in requirements
891 and not sparse.enabled
891 and not sparse.enabled
892 ):
892 ):
893 raise error.RepoError(
893 raise error.RepoError(
894 _(
894 _(
895 b'repository is using sparse feature but '
895 b'repository is using sparse feature but '
896 b'sparse is not enabled; enable the '
896 b'sparse is not enabled; enable the '
897 b'"sparse" extensions to access'
897 b'"sparse" extensions to access'
898 )
898 )
899 )
899 )
900
900
901
901
902 def makestore(requirements, path, vfstype):
902 def makestore(requirements, path, vfstype):
903 """Construct a storage object for a repository."""
903 """Construct a storage object for a repository."""
904 if b'store' in requirements:
904 if b'store' in requirements:
905 if b'fncache' in requirements:
905 if b'fncache' in requirements:
906 return storemod.fncachestore(
906 return storemod.fncachestore(
907 path, vfstype, b'dotencode' in requirements
907 path, vfstype, b'dotencode' in requirements
908 )
908 )
909
909
910 return storemod.encodedstore(path, vfstype)
910 return storemod.encodedstore(path, vfstype)
911
911
912 return storemod.basicstore(path, vfstype)
912 return storemod.basicstore(path, vfstype)
913
913
914
914
915 def resolvestorevfsoptions(ui, requirements, features):
915 def resolvestorevfsoptions(ui, requirements, features):
916 """Resolve the options to pass to the store vfs opener.
916 """Resolve the options to pass to the store vfs opener.
917
917
918 The returned dict is used to influence behavior of the storage layer.
918 The returned dict is used to influence behavior of the storage layer.
919 """
919 """
920 options = {}
920 options = {}
921
921
922 if requirementsmod.TREEMANIFEST_REQUIREMENT in requirements:
922 if requirementsmod.TREEMANIFEST_REQUIREMENT in requirements:
923 options[b'treemanifest'] = True
923 options[b'treemanifest'] = True
924
924
925 # experimental config: format.manifestcachesize
925 # experimental config: format.manifestcachesize
926 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
926 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
927 if manifestcachesize is not None:
927 if manifestcachesize is not None:
928 options[b'manifestcachesize'] = manifestcachesize
928 options[b'manifestcachesize'] = manifestcachesize
929
929
930 # In the absence of another requirement superseding a revlog-related
930 # In the absence of another requirement superseding a revlog-related
931 # requirement, we have to assume the repo is using revlog version 0.
931 # requirement, we have to assume the repo is using revlog version 0.
932 # This revlog format is super old and we don't bother trying to parse
932 # This revlog format is super old and we don't bother trying to parse
933 # opener options for it because those options wouldn't do anything
933 # opener options for it because those options wouldn't do anything
934 # meaningful on such old repos.
934 # meaningful on such old repos.
935 if (
935 if (
936 b'revlogv1' in requirements
936 b'revlogv1' in requirements
937 or requirementsmod.REVLOGV2_REQUIREMENT in requirements
937 or requirementsmod.REVLOGV2_REQUIREMENT in requirements
938 ):
938 ):
939 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
939 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
940 else: # explicitly mark repo as using revlogv0
940 else: # explicitly mark repo as using revlogv0
941 options[b'revlogv0'] = True
941 options[b'revlogv0'] = True
942
942
943 if requirementsmod.COPIESSDC_REQUIREMENT in requirements:
943 if requirementsmod.COPIESSDC_REQUIREMENT in requirements:
944 options[b'copies-storage'] = b'changeset-sidedata'
944 options[b'copies-storage'] = b'changeset-sidedata'
945 else:
945 else:
946 writecopiesto = ui.config(b'experimental', b'copies.write-to')
946 writecopiesto = ui.config(b'experimental', b'copies.write-to')
947 copiesextramode = (b'changeset-only', b'compatibility')
947 copiesextramode = (b'changeset-only', b'compatibility')
948 if writecopiesto in copiesextramode:
948 if writecopiesto in copiesextramode:
949 options[b'copies-storage'] = b'extra'
949 options[b'copies-storage'] = b'extra'
950
950
951 return options
951 return options
952
952
953
953
954 def resolverevlogstorevfsoptions(ui, requirements, features):
954 def resolverevlogstorevfsoptions(ui, requirements, features):
955 """Resolve opener options specific to revlogs."""
955 """Resolve opener options specific to revlogs."""
956
956
957 options = {}
957 options = {}
958 options[b'flagprocessors'] = {}
958 options[b'flagprocessors'] = {}
959
959
960 if b'revlogv1' in requirements:
960 if b'revlogv1' in requirements:
961 options[b'revlogv1'] = True
961 options[b'revlogv1'] = True
962 if requirementsmod.REVLOGV2_REQUIREMENT in requirements:
962 if requirementsmod.REVLOGV2_REQUIREMENT in requirements:
963 options[b'revlogv2'] = True
963 options[b'revlogv2'] = True
964
964
965 if b'generaldelta' in requirements:
965 if b'generaldelta' in requirements:
966 options[b'generaldelta'] = True
966 options[b'generaldelta'] = True
967
967
968 # experimental config: format.chunkcachesize
968 # experimental config: format.chunkcachesize
969 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
969 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
970 if chunkcachesize is not None:
970 if chunkcachesize is not None:
971 options[b'chunkcachesize'] = chunkcachesize
971 options[b'chunkcachesize'] = chunkcachesize
972
972
973 deltabothparents = ui.configbool(
973 deltabothparents = ui.configbool(
974 b'storage', b'revlog.optimize-delta-parent-choice'
974 b'storage', b'revlog.optimize-delta-parent-choice'
975 )
975 )
976 options[b'deltabothparents'] = deltabothparents
976 options[b'deltabothparents'] = deltabothparents
977
977
978 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
978 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
979 lazydeltabase = False
979 lazydeltabase = False
980 if lazydelta:
980 if lazydelta:
981 lazydeltabase = ui.configbool(
981 lazydeltabase = ui.configbool(
982 b'storage', b'revlog.reuse-external-delta-parent'
982 b'storage', b'revlog.reuse-external-delta-parent'
983 )
983 )
984 if lazydeltabase is None:
984 if lazydeltabase is None:
985 lazydeltabase = not scmutil.gddeltaconfig(ui)
985 lazydeltabase = not scmutil.gddeltaconfig(ui)
986 options[b'lazydelta'] = lazydelta
986 options[b'lazydelta'] = lazydelta
987 options[b'lazydeltabase'] = lazydeltabase
987 options[b'lazydeltabase'] = lazydeltabase
988
988
989 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
989 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
990 if 0 <= chainspan:
990 if 0 <= chainspan:
991 options[b'maxdeltachainspan'] = chainspan
991 options[b'maxdeltachainspan'] = chainspan
992
992
993 mmapindexthreshold = ui.configbytes(b'experimental', b'mmapindexthreshold')
993 mmapindexthreshold = ui.configbytes(b'experimental', b'mmapindexthreshold')
994 if mmapindexthreshold is not None:
994 if mmapindexthreshold is not None:
995 options[b'mmapindexthreshold'] = mmapindexthreshold
995 options[b'mmapindexthreshold'] = mmapindexthreshold
996
996
997 withsparseread = ui.configbool(b'experimental', b'sparse-read')
997 withsparseread = ui.configbool(b'experimental', b'sparse-read')
998 srdensitythres = float(
998 srdensitythres = float(
999 ui.config(b'experimental', b'sparse-read.density-threshold')
999 ui.config(b'experimental', b'sparse-read.density-threshold')
1000 )
1000 )
1001 srmingapsize = ui.configbytes(b'experimental', b'sparse-read.min-gap-size')
1001 srmingapsize = ui.configbytes(b'experimental', b'sparse-read.min-gap-size')
1002 options[b'with-sparse-read'] = withsparseread
1002 options[b'with-sparse-read'] = withsparseread
1003 options[b'sparse-read-density-threshold'] = srdensitythres
1003 options[b'sparse-read-density-threshold'] = srdensitythres
1004 options[b'sparse-read-min-gap-size'] = srmingapsize
1004 options[b'sparse-read-min-gap-size'] = srmingapsize
1005
1005
1006 sparserevlog = requirementsmod.SPARSEREVLOG_REQUIREMENT in requirements
1006 sparserevlog = requirementsmod.SPARSEREVLOG_REQUIREMENT in requirements
1007 options[b'sparse-revlog'] = sparserevlog
1007 options[b'sparse-revlog'] = sparserevlog
1008 if sparserevlog:
1008 if sparserevlog:
1009 options[b'generaldelta'] = True
1009 options[b'generaldelta'] = True
1010
1010
1011 sidedata = requirementsmod.SIDEDATA_REQUIREMENT in requirements
1011 sidedata = requirementsmod.SIDEDATA_REQUIREMENT in requirements
1012 options[b'side-data'] = sidedata
1012 options[b'side-data'] = sidedata
1013
1013
1014 maxchainlen = None
1014 maxchainlen = None
1015 if sparserevlog:
1015 if sparserevlog:
1016 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
1016 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
1017 # experimental config: format.maxchainlen
1017 # experimental config: format.maxchainlen
1018 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
1018 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
1019 if maxchainlen is not None:
1019 if maxchainlen is not None:
1020 options[b'maxchainlen'] = maxchainlen
1020 options[b'maxchainlen'] = maxchainlen
1021
1021
1022 for r in requirements:
1022 for r in requirements:
1023 # we allow multiple compression engine requirement to co-exist because
1023 # we allow multiple compression engine requirement to co-exist because
1024 # strickly speaking, revlog seems to support mixed compression style.
1024 # strickly speaking, revlog seems to support mixed compression style.
1025 #
1025 #
1026 # The compression used for new entries will be "the last one"
1026 # The compression used for new entries will be "the last one"
1027 prefix = r.startswith
1027 prefix = r.startswith
1028 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
1028 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
1029 options[b'compengine'] = r.split(b'-', 2)[2]
1029 options[b'compengine'] = r.split(b'-', 2)[2]
1030
1030
1031 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
1031 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
1032 if options[b'zlib.level'] is not None:
1032 if options[b'zlib.level'] is not None:
1033 if not (0 <= options[b'zlib.level'] <= 9):
1033 if not (0 <= options[b'zlib.level'] <= 9):
1034 msg = _(b'invalid value for `storage.revlog.zlib.level` config: %d')
1034 msg = _(b'invalid value for `storage.revlog.zlib.level` config: %d')
1035 raise error.Abort(msg % options[b'zlib.level'])
1035 raise error.Abort(msg % options[b'zlib.level'])
1036 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
1036 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
1037 if options[b'zstd.level'] is not None:
1037 if options[b'zstd.level'] is not None:
1038 if not (0 <= options[b'zstd.level'] <= 22):
1038 if not (0 <= options[b'zstd.level'] <= 22):
1039 msg = _(b'invalid value for `storage.revlog.zstd.level` config: %d')
1039 msg = _(b'invalid value for `storage.revlog.zstd.level` config: %d')
1040 raise error.Abort(msg % options[b'zstd.level'])
1040 raise error.Abort(msg % options[b'zstd.level'])
1041
1041
1042 if requirementsmod.NARROW_REQUIREMENT in requirements:
1042 if requirementsmod.NARROW_REQUIREMENT in requirements:
1043 options[b'enableellipsis'] = True
1043 options[b'enableellipsis'] = True
1044
1044
1045 if ui.configbool(b'experimental', b'rust.index'):
1045 if ui.configbool(b'experimental', b'rust.index'):
1046 options[b'rust.index'] = True
1046 options[b'rust.index'] = True
1047 if requirementsmod.NODEMAP_REQUIREMENT in requirements:
1047 if requirementsmod.NODEMAP_REQUIREMENT in requirements:
1048 slow_path = ui.config(
1048 slow_path = ui.config(
1049 b'storage', b'revlog.persistent-nodemap.slow-path'
1049 b'storage', b'revlog.persistent-nodemap.slow-path'
1050 )
1050 )
1051 if slow_path not in (b'allow', b'warn'):
1051 if slow_path not in (b'allow', b'warn', b'abort'):
1052 default = ui.config_default(
1052 default = ui.config_default(
1053 b'storage', b'revlog.persistent-nodemap.slow-path'
1053 b'storage', b'revlog.persistent-nodemap.slow-path'
1054 )
1054 )
1055 msg = _(
1055 msg = _(
1056 b'unknown value for config '
1056 b'unknown value for config '
1057 b'"storage.revlog.persistent-nodemap.slow-path": "%s"\n'
1057 b'"storage.revlog.persistent-nodemap.slow-path": "%s"\n'
1058 )
1058 )
1059 ui.warn(msg % slow_path)
1059 ui.warn(msg % slow_path)
1060 if not ui.quiet:
1060 if not ui.quiet:
1061 ui.warn(_(b'falling back to default value: %s\n') % default)
1061 ui.warn(_(b'falling back to default value: %s\n') % default)
1062 slow_path = default
1062 slow_path = default
1063
1063
1064 msg = _(
1064 msg = _(
1065 b"accessing `persistent-nodemap` repository without associated "
1065 b"accessing `persistent-nodemap` repository without associated "
1066 b"fast implementation."
1066 b"fast implementation."
1067 )
1067 )
1068 hint = _(
1068 hint = _(
1069 b"check `hg help config.format.use-persistent-nodemap` "
1069 b"check `hg help config.format.use-persistent-nodemap` "
1070 b"for details"
1070 b"for details"
1071 )
1071 )
1072 if slow_path == b'warn' and not revlog.HAS_FAST_PERSISTENT_NODEMAP:
1072 if not revlog.HAS_FAST_PERSISTENT_NODEMAP:
1073 msg = b"warning: " + msg + b'\n'
1073 if slow_path == b'warn':
1074 ui.warn(msg)
1074 msg = b"warning: " + msg + b'\n'
1075 if not ui.quiet:
1075 ui.warn(msg)
1076 hint = b'(' + hint + b')\n'
1076 if not ui.quiet:
1077 ui.warn(hint)
1077 hint = b'(' + hint + b')\n'
1078 ui.warn(hint)
1079 if slow_path == b'abort':
1080 raise error.Abort(msg, hint=hint)
1078 options[b'persistent-nodemap'] = True
1081 options[b'persistent-nodemap'] = True
1079 if ui.configbool(b'storage', b'revlog.persistent-nodemap.mmap'):
1082 if ui.configbool(b'storage', b'revlog.persistent-nodemap.mmap'):
1080 options[b'persistent-nodemap.mmap'] = True
1083 options[b'persistent-nodemap.mmap'] = True
1081 epnm = ui.config(b'storage', b'revlog.nodemap.mode')
1084 epnm = ui.config(b'storage', b'revlog.nodemap.mode')
1082 options[b'persistent-nodemap.mode'] = epnm
1085 options[b'persistent-nodemap.mode'] = epnm
1083 if ui.configbool(b'devel', b'persistent-nodemap'):
1086 if ui.configbool(b'devel', b'persistent-nodemap'):
1084 options[b'devel-force-nodemap'] = True
1087 options[b'devel-force-nodemap'] = True
1085
1088
1086 return options
1089 return options
1087
1090
1088
1091
1089 def makemain(**kwargs):
1092 def makemain(**kwargs):
1090 """Produce a type conforming to ``ilocalrepositorymain``."""
1093 """Produce a type conforming to ``ilocalrepositorymain``."""
1091 return localrepository
1094 return localrepository
1092
1095
1093
1096
1094 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1097 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1095 class revlogfilestorage(object):
1098 class revlogfilestorage(object):
1096 """File storage when using revlogs."""
1099 """File storage when using revlogs."""
1097
1100
1098 def file(self, path):
1101 def file(self, path):
1099 if path[0] == b'/':
1102 if path[0] == b'/':
1100 path = path[1:]
1103 path = path[1:]
1101
1104
1102 return filelog.filelog(self.svfs, path)
1105 return filelog.filelog(self.svfs, path)
1103
1106
1104
1107
1105 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1108 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1106 class revlognarrowfilestorage(object):
1109 class revlognarrowfilestorage(object):
1107 """File storage when using revlogs and narrow files."""
1110 """File storage when using revlogs and narrow files."""
1108
1111
1109 def file(self, path):
1112 def file(self, path):
1110 if path[0] == b'/':
1113 if path[0] == b'/':
1111 path = path[1:]
1114 path = path[1:]
1112
1115
1113 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
1116 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
1114
1117
1115
1118
1116 def makefilestorage(requirements, features, **kwargs):
1119 def makefilestorage(requirements, features, **kwargs):
1117 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
1120 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
1118 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
1121 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
1119 features.add(repository.REPO_FEATURE_STREAM_CLONE)
1122 features.add(repository.REPO_FEATURE_STREAM_CLONE)
1120
1123
1121 if requirementsmod.NARROW_REQUIREMENT in requirements:
1124 if requirementsmod.NARROW_REQUIREMENT in requirements:
1122 return revlognarrowfilestorage
1125 return revlognarrowfilestorage
1123 else:
1126 else:
1124 return revlogfilestorage
1127 return revlogfilestorage
1125
1128
1126
1129
1127 # List of repository interfaces and factory functions for them. Each
1130 # List of repository interfaces and factory functions for them. Each
1128 # will be called in order during ``makelocalrepository()`` to iteratively
1131 # will be called in order during ``makelocalrepository()`` to iteratively
1129 # derive the final type for a local repository instance. We capture the
1132 # derive the final type for a local repository instance. We capture the
1130 # function as a lambda so we don't hold a reference and the module-level
1133 # function as a lambda so we don't hold a reference and the module-level
1131 # functions can be wrapped.
1134 # functions can be wrapped.
1132 REPO_INTERFACES = [
1135 REPO_INTERFACES = [
1133 (repository.ilocalrepositorymain, lambda: makemain),
1136 (repository.ilocalrepositorymain, lambda: makemain),
1134 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
1137 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
1135 ]
1138 ]
1136
1139
1137
1140
1138 @interfaceutil.implementer(repository.ilocalrepositorymain)
1141 @interfaceutil.implementer(repository.ilocalrepositorymain)
1139 class localrepository(object):
1142 class localrepository(object):
1140 """Main class for representing local repositories.
1143 """Main class for representing local repositories.
1141
1144
1142 All local repositories are instances of this class.
1145 All local repositories are instances of this class.
1143
1146
1144 Constructed on its own, instances of this class are not usable as
1147 Constructed on its own, instances of this class are not usable as
1145 repository objects. To obtain a usable repository object, call
1148 repository objects. To obtain a usable repository object, call
1146 ``hg.repository()``, ``localrepo.instance()``, or
1149 ``hg.repository()``, ``localrepo.instance()``, or
1147 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
1150 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
1148 ``instance()`` adds support for creating new repositories.
1151 ``instance()`` adds support for creating new repositories.
1149 ``hg.repository()`` adds more extension integration, including calling
1152 ``hg.repository()`` adds more extension integration, including calling
1150 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
1153 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
1151 used.
1154 used.
1152 """
1155 """
1153
1156
1154 # obsolete experimental requirements:
1157 # obsolete experimental requirements:
1155 # - manifestv2: An experimental new manifest format that allowed
1158 # - manifestv2: An experimental new manifest format that allowed
1156 # for stem compression of long paths. Experiment ended up not
1159 # for stem compression of long paths. Experiment ended up not
1157 # being successful (repository sizes went up due to worse delta
1160 # being successful (repository sizes went up due to worse delta
1158 # chains), and the code was deleted in 4.6.
1161 # chains), and the code was deleted in 4.6.
1159 supportedformats = {
1162 supportedformats = {
1160 b'revlogv1',
1163 b'revlogv1',
1161 b'generaldelta',
1164 b'generaldelta',
1162 requirementsmod.TREEMANIFEST_REQUIREMENT,
1165 requirementsmod.TREEMANIFEST_REQUIREMENT,
1163 requirementsmod.COPIESSDC_REQUIREMENT,
1166 requirementsmod.COPIESSDC_REQUIREMENT,
1164 requirementsmod.REVLOGV2_REQUIREMENT,
1167 requirementsmod.REVLOGV2_REQUIREMENT,
1165 requirementsmod.SIDEDATA_REQUIREMENT,
1168 requirementsmod.SIDEDATA_REQUIREMENT,
1166 requirementsmod.SPARSEREVLOG_REQUIREMENT,
1169 requirementsmod.SPARSEREVLOG_REQUIREMENT,
1167 requirementsmod.NODEMAP_REQUIREMENT,
1170 requirementsmod.NODEMAP_REQUIREMENT,
1168 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
1171 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
1169 requirementsmod.SHARESAFE_REQUIREMENT,
1172 requirementsmod.SHARESAFE_REQUIREMENT,
1170 }
1173 }
1171 _basesupported = supportedformats | {
1174 _basesupported = supportedformats | {
1172 b'store',
1175 b'store',
1173 b'fncache',
1176 b'fncache',
1174 requirementsmod.SHARED_REQUIREMENT,
1177 requirementsmod.SHARED_REQUIREMENT,
1175 requirementsmod.RELATIVE_SHARED_REQUIREMENT,
1178 requirementsmod.RELATIVE_SHARED_REQUIREMENT,
1176 b'dotencode',
1179 b'dotencode',
1177 requirementsmod.SPARSE_REQUIREMENT,
1180 requirementsmod.SPARSE_REQUIREMENT,
1178 requirementsmod.INTERNAL_PHASE_REQUIREMENT,
1181 requirementsmod.INTERNAL_PHASE_REQUIREMENT,
1179 }
1182 }
1180
1183
1181 # list of prefix for file which can be written without 'wlock'
1184 # list of prefix for file which can be written without 'wlock'
1182 # Extensions should extend this list when needed
1185 # Extensions should extend this list when needed
1183 _wlockfreeprefix = {
1186 _wlockfreeprefix = {
1184 # We migh consider requiring 'wlock' for the next
1187 # We migh consider requiring 'wlock' for the next
1185 # two, but pretty much all the existing code assume
1188 # two, but pretty much all the existing code assume
1186 # wlock is not needed so we keep them excluded for
1189 # wlock is not needed so we keep them excluded for
1187 # now.
1190 # now.
1188 b'hgrc',
1191 b'hgrc',
1189 b'requires',
1192 b'requires',
1190 # XXX cache is a complicatged business someone
1193 # XXX cache is a complicatged business someone
1191 # should investigate this in depth at some point
1194 # should investigate this in depth at some point
1192 b'cache/',
1195 b'cache/',
1193 # XXX shouldn't be dirstate covered by the wlock?
1196 # XXX shouldn't be dirstate covered by the wlock?
1194 b'dirstate',
1197 b'dirstate',
1195 # XXX bisect was still a bit too messy at the time
1198 # XXX bisect was still a bit too messy at the time
1196 # this changeset was introduced. Someone should fix
1199 # this changeset was introduced. Someone should fix
1197 # the remainig bit and drop this line
1200 # the remainig bit and drop this line
1198 b'bisect.state',
1201 b'bisect.state',
1199 }
1202 }
1200
1203
1201 def __init__(
1204 def __init__(
1202 self,
1205 self,
1203 baseui,
1206 baseui,
1204 ui,
1207 ui,
1205 origroot,
1208 origroot,
1206 wdirvfs,
1209 wdirvfs,
1207 hgvfs,
1210 hgvfs,
1208 requirements,
1211 requirements,
1209 supportedrequirements,
1212 supportedrequirements,
1210 sharedpath,
1213 sharedpath,
1211 store,
1214 store,
1212 cachevfs,
1215 cachevfs,
1213 wcachevfs,
1216 wcachevfs,
1214 features,
1217 features,
1215 intents=None,
1218 intents=None,
1216 ):
1219 ):
1217 """Create a new local repository instance.
1220 """Create a new local repository instance.
1218
1221
1219 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
1222 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
1220 or ``localrepo.makelocalrepository()`` for obtaining a new repository
1223 or ``localrepo.makelocalrepository()`` for obtaining a new repository
1221 object.
1224 object.
1222
1225
1223 Arguments:
1226 Arguments:
1224
1227
1225 baseui
1228 baseui
1226 ``ui.ui`` instance that ``ui`` argument was based off of.
1229 ``ui.ui`` instance that ``ui`` argument was based off of.
1227
1230
1228 ui
1231 ui
1229 ``ui.ui`` instance for use by the repository.
1232 ``ui.ui`` instance for use by the repository.
1230
1233
1231 origroot
1234 origroot
1232 ``bytes`` path to working directory root of this repository.
1235 ``bytes`` path to working directory root of this repository.
1233
1236
1234 wdirvfs
1237 wdirvfs
1235 ``vfs.vfs`` rooted at the working directory.
1238 ``vfs.vfs`` rooted at the working directory.
1236
1239
1237 hgvfs
1240 hgvfs
1238 ``vfs.vfs`` rooted at .hg/
1241 ``vfs.vfs`` rooted at .hg/
1239
1242
1240 requirements
1243 requirements
1241 ``set`` of bytestrings representing repository opening requirements.
1244 ``set`` of bytestrings representing repository opening requirements.
1242
1245
1243 supportedrequirements
1246 supportedrequirements
1244 ``set`` of bytestrings representing repository requirements that we
1247 ``set`` of bytestrings representing repository requirements that we
1245 know how to open. May be a supetset of ``requirements``.
1248 know how to open. May be a supetset of ``requirements``.
1246
1249
1247 sharedpath
1250 sharedpath
1248 ``bytes`` Defining path to storage base directory. Points to a
1251 ``bytes`` Defining path to storage base directory. Points to a
1249 ``.hg/`` directory somewhere.
1252 ``.hg/`` directory somewhere.
1250
1253
1251 store
1254 store
1252 ``store.basicstore`` (or derived) instance providing access to
1255 ``store.basicstore`` (or derived) instance providing access to
1253 versioned storage.
1256 versioned storage.
1254
1257
1255 cachevfs
1258 cachevfs
1256 ``vfs.vfs`` used for cache files.
1259 ``vfs.vfs`` used for cache files.
1257
1260
1258 wcachevfs
1261 wcachevfs
1259 ``vfs.vfs`` used for cache files related to the working copy.
1262 ``vfs.vfs`` used for cache files related to the working copy.
1260
1263
1261 features
1264 features
1262 ``set`` of bytestrings defining features/capabilities of this
1265 ``set`` of bytestrings defining features/capabilities of this
1263 instance.
1266 instance.
1264
1267
1265 intents
1268 intents
1266 ``set`` of system strings indicating what this repo will be used
1269 ``set`` of system strings indicating what this repo will be used
1267 for.
1270 for.
1268 """
1271 """
1269 self.baseui = baseui
1272 self.baseui = baseui
1270 self.ui = ui
1273 self.ui = ui
1271 self.origroot = origroot
1274 self.origroot = origroot
1272 # vfs rooted at working directory.
1275 # vfs rooted at working directory.
1273 self.wvfs = wdirvfs
1276 self.wvfs = wdirvfs
1274 self.root = wdirvfs.base
1277 self.root = wdirvfs.base
1275 # vfs rooted at .hg/. Used to access most non-store paths.
1278 # vfs rooted at .hg/. Used to access most non-store paths.
1276 self.vfs = hgvfs
1279 self.vfs = hgvfs
1277 self.path = hgvfs.base
1280 self.path = hgvfs.base
1278 self.requirements = requirements
1281 self.requirements = requirements
1279 self.supported = supportedrequirements
1282 self.supported = supportedrequirements
1280 self.sharedpath = sharedpath
1283 self.sharedpath = sharedpath
1281 self.store = store
1284 self.store = store
1282 self.cachevfs = cachevfs
1285 self.cachevfs = cachevfs
1283 self.wcachevfs = wcachevfs
1286 self.wcachevfs = wcachevfs
1284 self.features = features
1287 self.features = features
1285
1288
1286 self.filtername = None
1289 self.filtername = None
1287
1290
1288 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1291 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1289 b'devel', b'check-locks'
1292 b'devel', b'check-locks'
1290 ):
1293 ):
1291 self.vfs.audit = self._getvfsward(self.vfs.audit)
1294 self.vfs.audit = self._getvfsward(self.vfs.audit)
1292 # A list of callback to shape the phase if no data were found.
1295 # A list of callback to shape the phase if no data were found.
1293 # Callback are in the form: func(repo, roots) --> processed root.
1296 # Callback are in the form: func(repo, roots) --> processed root.
1294 # This list it to be filled by extension during repo setup
1297 # This list it to be filled by extension during repo setup
1295 self._phasedefaults = []
1298 self._phasedefaults = []
1296
1299
1297 color.setup(self.ui)
1300 color.setup(self.ui)
1298
1301
1299 self.spath = self.store.path
1302 self.spath = self.store.path
1300 self.svfs = self.store.vfs
1303 self.svfs = self.store.vfs
1301 self.sjoin = self.store.join
1304 self.sjoin = self.store.join
1302 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1305 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1303 b'devel', b'check-locks'
1306 b'devel', b'check-locks'
1304 ):
1307 ):
1305 if util.safehasattr(self.svfs, b'vfs'): # this is filtervfs
1308 if util.safehasattr(self.svfs, b'vfs'): # this is filtervfs
1306 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1309 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1307 else: # standard vfs
1310 else: # standard vfs
1308 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1311 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1309
1312
1310 self._dirstatevalidatewarned = False
1313 self._dirstatevalidatewarned = False
1311
1314
1312 self._branchcaches = branchmap.BranchMapCache()
1315 self._branchcaches = branchmap.BranchMapCache()
1313 self._revbranchcache = None
1316 self._revbranchcache = None
1314 self._filterpats = {}
1317 self._filterpats = {}
1315 self._datafilters = {}
1318 self._datafilters = {}
1316 self._transref = self._lockref = self._wlockref = None
1319 self._transref = self._lockref = self._wlockref = None
1317
1320
1318 # A cache for various files under .hg/ that tracks file changes,
1321 # A cache for various files under .hg/ that tracks file changes,
1319 # (used by the filecache decorator)
1322 # (used by the filecache decorator)
1320 #
1323 #
1321 # Maps a property name to its util.filecacheentry
1324 # Maps a property name to its util.filecacheentry
1322 self._filecache = {}
1325 self._filecache = {}
1323
1326
1324 # hold sets of revision to be filtered
1327 # hold sets of revision to be filtered
1325 # should be cleared when something might have changed the filter value:
1328 # should be cleared when something might have changed the filter value:
1326 # - new changesets,
1329 # - new changesets,
1327 # - phase change,
1330 # - phase change,
1328 # - new obsolescence marker,
1331 # - new obsolescence marker,
1329 # - working directory parent change,
1332 # - working directory parent change,
1330 # - bookmark changes
1333 # - bookmark changes
1331 self.filteredrevcache = {}
1334 self.filteredrevcache = {}
1332
1335
1333 # post-dirstate-status hooks
1336 # post-dirstate-status hooks
1334 self._postdsstatus = []
1337 self._postdsstatus = []
1335
1338
1336 # generic mapping between names and nodes
1339 # generic mapping between names and nodes
1337 self.names = namespaces.namespaces()
1340 self.names = namespaces.namespaces()
1338
1341
1339 # Key to signature value.
1342 # Key to signature value.
1340 self._sparsesignaturecache = {}
1343 self._sparsesignaturecache = {}
1341 # Signature to cached matcher instance.
1344 # Signature to cached matcher instance.
1342 self._sparsematchercache = {}
1345 self._sparsematchercache = {}
1343
1346
1344 self._extrafilterid = repoview.extrafilter(ui)
1347 self._extrafilterid = repoview.extrafilter(ui)
1345
1348
1346 self.filecopiesmode = None
1349 self.filecopiesmode = None
1347 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1350 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1348 self.filecopiesmode = b'changeset-sidedata'
1351 self.filecopiesmode = b'changeset-sidedata'
1349
1352
1350 def _getvfsward(self, origfunc):
1353 def _getvfsward(self, origfunc):
1351 """build a ward for self.vfs"""
1354 """build a ward for self.vfs"""
1352 rref = weakref.ref(self)
1355 rref = weakref.ref(self)
1353
1356
1354 def checkvfs(path, mode=None):
1357 def checkvfs(path, mode=None):
1355 ret = origfunc(path, mode=mode)
1358 ret = origfunc(path, mode=mode)
1356 repo = rref()
1359 repo = rref()
1357 if (
1360 if (
1358 repo is None
1361 repo is None
1359 or not util.safehasattr(repo, b'_wlockref')
1362 or not util.safehasattr(repo, b'_wlockref')
1360 or not util.safehasattr(repo, b'_lockref')
1363 or not util.safehasattr(repo, b'_lockref')
1361 ):
1364 ):
1362 return
1365 return
1363 if mode in (None, b'r', b'rb'):
1366 if mode in (None, b'r', b'rb'):
1364 return
1367 return
1365 if path.startswith(repo.path):
1368 if path.startswith(repo.path):
1366 # truncate name relative to the repository (.hg)
1369 # truncate name relative to the repository (.hg)
1367 path = path[len(repo.path) + 1 :]
1370 path = path[len(repo.path) + 1 :]
1368 if path.startswith(b'cache/'):
1371 if path.startswith(b'cache/'):
1369 msg = b'accessing cache with vfs instead of cachevfs: "%s"'
1372 msg = b'accessing cache with vfs instead of cachevfs: "%s"'
1370 repo.ui.develwarn(msg % path, stacklevel=3, config=b"cache-vfs")
1373 repo.ui.develwarn(msg % path, stacklevel=3, config=b"cache-vfs")
1371 # path prefixes covered by 'lock'
1374 # path prefixes covered by 'lock'
1372 vfs_path_prefixes = (
1375 vfs_path_prefixes = (
1373 b'journal.',
1376 b'journal.',
1374 b'undo.',
1377 b'undo.',
1375 b'strip-backup/',
1378 b'strip-backup/',
1376 b'cache/',
1379 b'cache/',
1377 )
1380 )
1378 if any(path.startswith(prefix) for prefix in vfs_path_prefixes):
1381 if any(path.startswith(prefix) for prefix in vfs_path_prefixes):
1379 if repo._currentlock(repo._lockref) is None:
1382 if repo._currentlock(repo._lockref) is None:
1380 repo.ui.develwarn(
1383 repo.ui.develwarn(
1381 b'write with no lock: "%s"' % path,
1384 b'write with no lock: "%s"' % path,
1382 stacklevel=3,
1385 stacklevel=3,
1383 config=b'check-locks',
1386 config=b'check-locks',
1384 )
1387 )
1385 elif repo._currentlock(repo._wlockref) is None:
1388 elif repo._currentlock(repo._wlockref) is None:
1386 # rest of vfs files are covered by 'wlock'
1389 # rest of vfs files are covered by 'wlock'
1387 #
1390 #
1388 # exclude special files
1391 # exclude special files
1389 for prefix in self._wlockfreeprefix:
1392 for prefix in self._wlockfreeprefix:
1390 if path.startswith(prefix):
1393 if path.startswith(prefix):
1391 return
1394 return
1392 repo.ui.develwarn(
1395 repo.ui.develwarn(
1393 b'write with no wlock: "%s"' % path,
1396 b'write with no wlock: "%s"' % path,
1394 stacklevel=3,
1397 stacklevel=3,
1395 config=b'check-locks',
1398 config=b'check-locks',
1396 )
1399 )
1397 return ret
1400 return ret
1398
1401
1399 return checkvfs
1402 return checkvfs
1400
1403
1401 def _getsvfsward(self, origfunc):
1404 def _getsvfsward(self, origfunc):
1402 """build a ward for self.svfs"""
1405 """build a ward for self.svfs"""
1403 rref = weakref.ref(self)
1406 rref = weakref.ref(self)
1404
1407
1405 def checksvfs(path, mode=None):
1408 def checksvfs(path, mode=None):
1406 ret = origfunc(path, mode=mode)
1409 ret = origfunc(path, mode=mode)
1407 repo = rref()
1410 repo = rref()
1408 if repo is None or not util.safehasattr(repo, b'_lockref'):
1411 if repo is None or not util.safehasattr(repo, b'_lockref'):
1409 return
1412 return
1410 if mode in (None, b'r', b'rb'):
1413 if mode in (None, b'r', b'rb'):
1411 return
1414 return
1412 if path.startswith(repo.sharedpath):
1415 if path.startswith(repo.sharedpath):
1413 # truncate name relative to the repository (.hg)
1416 # truncate name relative to the repository (.hg)
1414 path = path[len(repo.sharedpath) + 1 :]
1417 path = path[len(repo.sharedpath) + 1 :]
1415 if repo._currentlock(repo._lockref) is None:
1418 if repo._currentlock(repo._lockref) is None:
1416 repo.ui.develwarn(
1419 repo.ui.develwarn(
1417 b'write with no lock: "%s"' % path, stacklevel=4
1420 b'write with no lock: "%s"' % path, stacklevel=4
1418 )
1421 )
1419 return ret
1422 return ret
1420
1423
1421 return checksvfs
1424 return checksvfs
1422
1425
1423 def close(self):
1426 def close(self):
1424 self._writecaches()
1427 self._writecaches()
1425
1428
1426 def _writecaches(self):
1429 def _writecaches(self):
1427 if self._revbranchcache:
1430 if self._revbranchcache:
1428 self._revbranchcache.write()
1431 self._revbranchcache.write()
1429
1432
1430 def _restrictcapabilities(self, caps):
1433 def _restrictcapabilities(self, caps):
1431 if self.ui.configbool(b'experimental', b'bundle2-advertise'):
1434 if self.ui.configbool(b'experimental', b'bundle2-advertise'):
1432 caps = set(caps)
1435 caps = set(caps)
1433 capsblob = bundle2.encodecaps(
1436 capsblob = bundle2.encodecaps(
1434 bundle2.getrepocaps(self, role=b'client')
1437 bundle2.getrepocaps(self, role=b'client')
1435 )
1438 )
1436 caps.add(b'bundle2=' + urlreq.quote(capsblob))
1439 caps.add(b'bundle2=' + urlreq.quote(capsblob))
1437 return caps
1440 return caps
1438
1441
1439 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1442 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1440 # self -> auditor -> self._checknested -> self
1443 # self -> auditor -> self._checknested -> self
1441
1444
1442 @property
1445 @property
1443 def auditor(self):
1446 def auditor(self):
1444 # This is only used by context.workingctx.match in order to
1447 # This is only used by context.workingctx.match in order to
1445 # detect files in subrepos.
1448 # detect files in subrepos.
1446 return pathutil.pathauditor(self.root, callback=self._checknested)
1449 return pathutil.pathauditor(self.root, callback=self._checknested)
1447
1450
1448 @property
1451 @property
1449 def nofsauditor(self):
1452 def nofsauditor(self):
1450 # This is only used by context.basectx.match in order to detect
1453 # This is only used by context.basectx.match in order to detect
1451 # files in subrepos.
1454 # files in subrepos.
1452 return pathutil.pathauditor(
1455 return pathutil.pathauditor(
1453 self.root, callback=self._checknested, realfs=False, cached=True
1456 self.root, callback=self._checknested, realfs=False, cached=True
1454 )
1457 )
1455
1458
1456 def _checknested(self, path):
1459 def _checknested(self, path):
1457 """Determine if path is a legal nested repository."""
1460 """Determine if path is a legal nested repository."""
1458 if not path.startswith(self.root):
1461 if not path.startswith(self.root):
1459 return False
1462 return False
1460 subpath = path[len(self.root) + 1 :]
1463 subpath = path[len(self.root) + 1 :]
1461 normsubpath = util.pconvert(subpath)
1464 normsubpath = util.pconvert(subpath)
1462
1465
1463 # XXX: Checking against the current working copy is wrong in
1466 # XXX: Checking against the current working copy is wrong in
1464 # the sense that it can reject things like
1467 # the sense that it can reject things like
1465 #
1468 #
1466 # $ hg cat -r 10 sub/x.txt
1469 # $ hg cat -r 10 sub/x.txt
1467 #
1470 #
1468 # if sub/ is no longer a subrepository in the working copy
1471 # if sub/ is no longer a subrepository in the working copy
1469 # parent revision.
1472 # parent revision.
1470 #
1473 #
1471 # However, it can of course also allow things that would have
1474 # However, it can of course also allow things that would have
1472 # been rejected before, such as the above cat command if sub/
1475 # been rejected before, such as the above cat command if sub/
1473 # is a subrepository now, but was a normal directory before.
1476 # is a subrepository now, but was a normal directory before.
1474 # The old path auditor would have rejected by mistake since it
1477 # The old path auditor would have rejected by mistake since it
1475 # panics when it sees sub/.hg/.
1478 # panics when it sees sub/.hg/.
1476 #
1479 #
1477 # All in all, checking against the working copy seems sensible
1480 # All in all, checking against the working copy seems sensible
1478 # since we want to prevent access to nested repositories on
1481 # since we want to prevent access to nested repositories on
1479 # the filesystem *now*.
1482 # the filesystem *now*.
1480 ctx = self[None]
1483 ctx = self[None]
1481 parts = util.splitpath(subpath)
1484 parts = util.splitpath(subpath)
1482 while parts:
1485 while parts:
1483 prefix = b'/'.join(parts)
1486 prefix = b'/'.join(parts)
1484 if prefix in ctx.substate:
1487 if prefix in ctx.substate:
1485 if prefix == normsubpath:
1488 if prefix == normsubpath:
1486 return True
1489 return True
1487 else:
1490 else:
1488 sub = ctx.sub(prefix)
1491 sub = ctx.sub(prefix)
1489 return sub.checknested(subpath[len(prefix) + 1 :])
1492 return sub.checknested(subpath[len(prefix) + 1 :])
1490 else:
1493 else:
1491 parts.pop()
1494 parts.pop()
1492 return False
1495 return False
1493
1496
1494 def peer(self):
1497 def peer(self):
1495 return localpeer(self) # not cached to avoid reference cycle
1498 return localpeer(self) # not cached to avoid reference cycle
1496
1499
1497 def unfiltered(self):
1500 def unfiltered(self):
1498 """Return unfiltered version of the repository
1501 """Return unfiltered version of the repository
1499
1502
1500 Intended to be overwritten by filtered repo."""
1503 Intended to be overwritten by filtered repo."""
1501 return self
1504 return self
1502
1505
1503 def filtered(self, name, visibilityexceptions=None):
1506 def filtered(self, name, visibilityexceptions=None):
1504 """Return a filtered version of a repository
1507 """Return a filtered version of a repository
1505
1508
1506 The `name` parameter is the identifier of the requested view. This
1509 The `name` parameter is the identifier of the requested view. This
1507 will return a repoview object set "exactly" to the specified view.
1510 will return a repoview object set "exactly" to the specified view.
1508
1511
1509 This function does not apply recursive filtering to a repository. For
1512 This function does not apply recursive filtering to a repository. For
1510 example calling `repo.filtered("served")` will return a repoview using
1513 example calling `repo.filtered("served")` will return a repoview using
1511 the "served" view, regardless of the initial view used by `repo`.
1514 the "served" view, regardless of the initial view used by `repo`.
1512
1515
1513 In other word, there is always only one level of `repoview` "filtering".
1516 In other word, there is always only one level of `repoview` "filtering".
1514 """
1517 """
1515 if self._extrafilterid is not None and b'%' not in name:
1518 if self._extrafilterid is not None and b'%' not in name:
1516 name = name + b'%' + self._extrafilterid
1519 name = name + b'%' + self._extrafilterid
1517
1520
1518 cls = repoview.newtype(self.unfiltered().__class__)
1521 cls = repoview.newtype(self.unfiltered().__class__)
1519 return cls(self, name, visibilityexceptions)
1522 return cls(self, name, visibilityexceptions)
1520
1523
1521 @mixedrepostorecache(
1524 @mixedrepostorecache(
1522 (b'bookmarks', b'plain'),
1525 (b'bookmarks', b'plain'),
1523 (b'bookmarks.current', b'plain'),
1526 (b'bookmarks.current', b'plain'),
1524 (b'bookmarks', b''),
1527 (b'bookmarks', b''),
1525 (b'00changelog.i', b''),
1528 (b'00changelog.i', b''),
1526 )
1529 )
1527 def _bookmarks(self):
1530 def _bookmarks(self):
1528 # Since the multiple files involved in the transaction cannot be
1531 # Since the multiple files involved in the transaction cannot be
1529 # written atomically (with current repository format), there is a race
1532 # written atomically (with current repository format), there is a race
1530 # condition here.
1533 # condition here.
1531 #
1534 #
1532 # 1) changelog content A is read
1535 # 1) changelog content A is read
1533 # 2) outside transaction update changelog to content B
1536 # 2) outside transaction update changelog to content B
1534 # 3) outside transaction update bookmark file referring to content B
1537 # 3) outside transaction update bookmark file referring to content B
1535 # 4) bookmarks file content is read and filtered against changelog-A
1538 # 4) bookmarks file content is read and filtered against changelog-A
1536 #
1539 #
1537 # When this happens, bookmarks against nodes missing from A are dropped.
1540 # When this happens, bookmarks against nodes missing from A are dropped.
1538 #
1541 #
1539 # Having this happening during read is not great, but it become worse
1542 # Having this happening during read is not great, but it become worse
1540 # when this happen during write because the bookmarks to the "unknown"
1543 # when this happen during write because the bookmarks to the "unknown"
1541 # nodes will be dropped for good. However, writes happen within locks.
1544 # nodes will be dropped for good. However, writes happen within locks.
1542 # This locking makes it possible to have a race free consistent read.
1545 # This locking makes it possible to have a race free consistent read.
1543 # For this purpose data read from disc before locking are
1546 # For this purpose data read from disc before locking are
1544 # "invalidated" right after the locks are taken. This invalidations are
1547 # "invalidated" right after the locks are taken. This invalidations are
1545 # "light", the `filecache` mechanism keep the data in memory and will
1548 # "light", the `filecache` mechanism keep the data in memory and will
1546 # reuse them if the underlying files did not changed. Not parsing the
1549 # reuse them if the underlying files did not changed. Not parsing the
1547 # same data multiple times helps performances.
1550 # same data multiple times helps performances.
1548 #
1551 #
1549 # Unfortunately in the case describe above, the files tracked by the
1552 # Unfortunately in the case describe above, the files tracked by the
1550 # bookmarks file cache might not have changed, but the in-memory
1553 # bookmarks file cache might not have changed, but the in-memory
1551 # content is still "wrong" because we used an older changelog content
1554 # content is still "wrong" because we used an older changelog content
1552 # to process the on-disk data. So after locking, the changelog would be
1555 # to process the on-disk data. So after locking, the changelog would be
1553 # refreshed but `_bookmarks` would be preserved.
1556 # refreshed but `_bookmarks` would be preserved.
1554 # Adding `00changelog.i` to the list of tracked file is not
1557 # Adding `00changelog.i` to the list of tracked file is not
1555 # enough, because at the time we build the content for `_bookmarks` in
1558 # enough, because at the time we build the content for `_bookmarks` in
1556 # (4), the changelog file has already diverged from the content used
1559 # (4), the changelog file has already diverged from the content used
1557 # for loading `changelog` in (1)
1560 # for loading `changelog` in (1)
1558 #
1561 #
1559 # To prevent the issue, we force the changelog to be explicitly
1562 # To prevent the issue, we force the changelog to be explicitly
1560 # reloaded while computing `_bookmarks`. The data race can still happen
1563 # reloaded while computing `_bookmarks`. The data race can still happen
1561 # without the lock (with a narrower window), but it would no longer go
1564 # without the lock (with a narrower window), but it would no longer go
1562 # undetected during the lock time refresh.
1565 # undetected during the lock time refresh.
1563 #
1566 #
1564 # The new schedule is as follow
1567 # The new schedule is as follow
1565 #
1568 #
1566 # 1) filecache logic detect that `_bookmarks` needs to be computed
1569 # 1) filecache logic detect that `_bookmarks` needs to be computed
1567 # 2) cachestat for `bookmarks` and `changelog` are captured (for book)
1570 # 2) cachestat for `bookmarks` and `changelog` are captured (for book)
1568 # 3) We force `changelog` filecache to be tested
1571 # 3) We force `changelog` filecache to be tested
1569 # 4) cachestat for `changelog` are captured (for changelog)
1572 # 4) cachestat for `changelog` are captured (for changelog)
1570 # 5) `_bookmarks` is computed and cached
1573 # 5) `_bookmarks` is computed and cached
1571 #
1574 #
1572 # The step in (3) ensure we have a changelog at least as recent as the
1575 # The step in (3) ensure we have a changelog at least as recent as the
1573 # cache stat computed in (1). As a result at locking time:
1576 # cache stat computed in (1). As a result at locking time:
1574 # * if the changelog did not changed since (1) -> we can reuse the data
1577 # * if the changelog did not changed since (1) -> we can reuse the data
1575 # * otherwise -> the bookmarks get refreshed.
1578 # * otherwise -> the bookmarks get refreshed.
1576 self._refreshchangelog()
1579 self._refreshchangelog()
1577 return bookmarks.bmstore(self)
1580 return bookmarks.bmstore(self)
1578
1581
1579 def _refreshchangelog(self):
1582 def _refreshchangelog(self):
1580 """make sure the in memory changelog match the on-disk one"""
1583 """make sure the in memory changelog match the on-disk one"""
1581 if 'changelog' in vars(self) and self.currenttransaction() is None:
1584 if 'changelog' in vars(self) and self.currenttransaction() is None:
1582 del self.changelog
1585 del self.changelog
1583
1586
1584 @property
1587 @property
1585 def _activebookmark(self):
1588 def _activebookmark(self):
1586 return self._bookmarks.active
1589 return self._bookmarks.active
1587
1590
1588 # _phasesets depend on changelog. what we need is to call
1591 # _phasesets depend on changelog. what we need is to call
1589 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1592 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1590 # can't be easily expressed in filecache mechanism.
1593 # can't be easily expressed in filecache mechanism.
1591 @storecache(b'phaseroots', b'00changelog.i')
1594 @storecache(b'phaseroots', b'00changelog.i')
1592 def _phasecache(self):
1595 def _phasecache(self):
1593 return phases.phasecache(self, self._phasedefaults)
1596 return phases.phasecache(self, self._phasedefaults)
1594
1597
1595 @storecache(b'obsstore')
1598 @storecache(b'obsstore')
1596 def obsstore(self):
1599 def obsstore(self):
1597 return obsolete.makestore(self.ui, self)
1600 return obsolete.makestore(self.ui, self)
1598
1601
1599 @storecache(b'00changelog.i')
1602 @storecache(b'00changelog.i')
1600 def changelog(self):
1603 def changelog(self):
1601 # load dirstate before changelog to avoid race see issue6303
1604 # load dirstate before changelog to avoid race see issue6303
1602 self.dirstate.prefetch_parents()
1605 self.dirstate.prefetch_parents()
1603 return self.store.changelog(txnutil.mayhavepending(self.root))
1606 return self.store.changelog(txnutil.mayhavepending(self.root))
1604
1607
1605 @storecache(b'00manifest.i')
1608 @storecache(b'00manifest.i')
1606 def manifestlog(self):
1609 def manifestlog(self):
1607 return self.store.manifestlog(self, self._storenarrowmatch)
1610 return self.store.manifestlog(self, self._storenarrowmatch)
1608
1611
1609 @repofilecache(b'dirstate')
1612 @repofilecache(b'dirstate')
1610 def dirstate(self):
1613 def dirstate(self):
1611 return self._makedirstate()
1614 return self._makedirstate()
1612
1615
1613 def _makedirstate(self):
1616 def _makedirstate(self):
1614 """Extension point for wrapping the dirstate per-repo."""
1617 """Extension point for wrapping the dirstate per-repo."""
1615 sparsematchfn = lambda: sparse.matcher(self)
1618 sparsematchfn = lambda: sparse.matcher(self)
1616
1619
1617 return dirstate.dirstate(
1620 return dirstate.dirstate(
1618 self.vfs, self.ui, self.root, self._dirstatevalidate, sparsematchfn
1621 self.vfs, self.ui, self.root, self._dirstatevalidate, sparsematchfn
1619 )
1622 )
1620
1623
1621 def _dirstatevalidate(self, node):
1624 def _dirstatevalidate(self, node):
1622 try:
1625 try:
1623 self.changelog.rev(node)
1626 self.changelog.rev(node)
1624 return node
1627 return node
1625 except error.LookupError:
1628 except error.LookupError:
1626 if not self._dirstatevalidatewarned:
1629 if not self._dirstatevalidatewarned:
1627 self._dirstatevalidatewarned = True
1630 self._dirstatevalidatewarned = True
1628 self.ui.warn(
1631 self.ui.warn(
1629 _(b"warning: ignoring unknown working parent %s!\n")
1632 _(b"warning: ignoring unknown working parent %s!\n")
1630 % short(node)
1633 % short(node)
1631 )
1634 )
1632 return nullid
1635 return nullid
1633
1636
1634 @storecache(narrowspec.FILENAME)
1637 @storecache(narrowspec.FILENAME)
1635 def narrowpats(self):
1638 def narrowpats(self):
1636 """matcher patterns for this repository's narrowspec
1639 """matcher patterns for this repository's narrowspec
1637
1640
1638 A tuple of (includes, excludes).
1641 A tuple of (includes, excludes).
1639 """
1642 """
1640 return narrowspec.load(self)
1643 return narrowspec.load(self)
1641
1644
1642 @storecache(narrowspec.FILENAME)
1645 @storecache(narrowspec.FILENAME)
1643 def _storenarrowmatch(self):
1646 def _storenarrowmatch(self):
1644 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1647 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1645 return matchmod.always()
1648 return matchmod.always()
1646 include, exclude = self.narrowpats
1649 include, exclude = self.narrowpats
1647 return narrowspec.match(self.root, include=include, exclude=exclude)
1650 return narrowspec.match(self.root, include=include, exclude=exclude)
1648
1651
1649 @storecache(narrowspec.FILENAME)
1652 @storecache(narrowspec.FILENAME)
1650 def _narrowmatch(self):
1653 def _narrowmatch(self):
1651 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1654 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1652 return matchmod.always()
1655 return matchmod.always()
1653 narrowspec.checkworkingcopynarrowspec(self)
1656 narrowspec.checkworkingcopynarrowspec(self)
1654 include, exclude = self.narrowpats
1657 include, exclude = self.narrowpats
1655 return narrowspec.match(self.root, include=include, exclude=exclude)
1658 return narrowspec.match(self.root, include=include, exclude=exclude)
1656
1659
1657 def narrowmatch(self, match=None, includeexact=False):
1660 def narrowmatch(self, match=None, includeexact=False):
1658 """matcher corresponding the the repo's narrowspec
1661 """matcher corresponding the the repo's narrowspec
1659
1662
1660 If `match` is given, then that will be intersected with the narrow
1663 If `match` is given, then that will be intersected with the narrow
1661 matcher.
1664 matcher.
1662
1665
1663 If `includeexact` is True, then any exact matches from `match` will
1666 If `includeexact` is True, then any exact matches from `match` will
1664 be included even if they're outside the narrowspec.
1667 be included even if they're outside the narrowspec.
1665 """
1668 """
1666 if match:
1669 if match:
1667 if includeexact and not self._narrowmatch.always():
1670 if includeexact and not self._narrowmatch.always():
1668 # do not exclude explicitly-specified paths so that they can
1671 # do not exclude explicitly-specified paths so that they can
1669 # be warned later on
1672 # be warned later on
1670 em = matchmod.exact(match.files())
1673 em = matchmod.exact(match.files())
1671 nm = matchmod.unionmatcher([self._narrowmatch, em])
1674 nm = matchmod.unionmatcher([self._narrowmatch, em])
1672 return matchmod.intersectmatchers(match, nm)
1675 return matchmod.intersectmatchers(match, nm)
1673 return matchmod.intersectmatchers(match, self._narrowmatch)
1676 return matchmod.intersectmatchers(match, self._narrowmatch)
1674 return self._narrowmatch
1677 return self._narrowmatch
1675
1678
1676 def setnarrowpats(self, newincludes, newexcludes):
1679 def setnarrowpats(self, newincludes, newexcludes):
1677 narrowspec.save(self, newincludes, newexcludes)
1680 narrowspec.save(self, newincludes, newexcludes)
1678 self.invalidate(clearfilecache=True)
1681 self.invalidate(clearfilecache=True)
1679
1682
1680 @unfilteredpropertycache
1683 @unfilteredpropertycache
1681 def _quick_access_changeid_null(self):
1684 def _quick_access_changeid_null(self):
1682 return {
1685 return {
1683 b'null': (nullrev, nullid),
1686 b'null': (nullrev, nullid),
1684 nullrev: (nullrev, nullid),
1687 nullrev: (nullrev, nullid),
1685 nullid: (nullrev, nullid),
1688 nullid: (nullrev, nullid),
1686 }
1689 }
1687
1690
1688 @unfilteredpropertycache
1691 @unfilteredpropertycache
1689 def _quick_access_changeid_wc(self):
1692 def _quick_access_changeid_wc(self):
1690 # also fast path access to the working copy parents
1693 # also fast path access to the working copy parents
1691 # however, only do it for filter that ensure wc is visible.
1694 # however, only do it for filter that ensure wc is visible.
1692 quick = self._quick_access_changeid_null.copy()
1695 quick = self._quick_access_changeid_null.copy()
1693 cl = self.unfiltered().changelog
1696 cl = self.unfiltered().changelog
1694 for node in self.dirstate.parents():
1697 for node in self.dirstate.parents():
1695 if node == nullid:
1698 if node == nullid:
1696 continue
1699 continue
1697 rev = cl.index.get_rev(node)
1700 rev = cl.index.get_rev(node)
1698 if rev is None:
1701 if rev is None:
1699 # unknown working copy parent case:
1702 # unknown working copy parent case:
1700 #
1703 #
1701 # skip the fast path and let higher code deal with it
1704 # skip the fast path and let higher code deal with it
1702 continue
1705 continue
1703 pair = (rev, node)
1706 pair = (rev, node)
1704 quick[rev] = pair
1707 quick[rev] = pair
1705 quick[node] = pair
1708 quick[node] = pair
1706 # also add the parents of the parents
1709 # also add the parents of the parents
1707 for r in cl.parentrevs(rev):
1710 for r in cl.parentrevs(rev):
1708 if r == nullrev:
1711 if r == nullrev:
1709 continue
1712 continue
1710 n = cl.node(r)
1713 n = cl.node(r)
1711 pair = (r, n)
1714 pair = (r, n)
1712 quick[r] = pair
1715 quick[r] = pair
1713 quick[n] = pair
1716 quick[n] = pair
1714 p1node = self.dirstate.p1()
1717 p1node = self.dirstate.p1()
1715 if p1node != nullid:
1718 if p1node != nullid:
1716 quick[b'.'] = quick[p1node]
1719 quick[b'.'] = quick[p1node]
1717 return quick
1720 return quick
1718
1721
1719 @unfilteredmethod
1722 @unfilteredmethod
1720 def _quick_access_changeid_invalidate(self):
1723 def _quick_access_changeid_invalidate(self):
1721 if '_quick_access_changeid_wc' in vars(self):
1724 if '_quick_access_changeid_wc' in vars(self):
1722 del self.__dict__['_quick_access_changeid_wc']
1725 del self.__dict__['_quick_access_changeid_wc']
1723
1726
1724 @property
1727 @property
1725 def _quick_access_changeid(self):
1728 def _quick_access_changeid(self):
1726 """an helper dictionnary for __getitem__ calls
1729 """an helper dictionnary for __getitem__ calls
1727
1730
1728 This contains a list of symbol we can recognise right away without
1731 This contains a list of symbol we can recognise right away without
1729 further processing.
1732 further processing.
1730 """
1733 """
1731 if self.filtername in repoview.filter_has_wc:
1734 if self.filtername in repoview.filter_has_wc:
1732 return self._quick_access_changeid_wc
1735 return self._quick_access_changeid_wc
1733 return self._quick_access_changeid_null
1736 return self._quick_access_changeid_null
1734
1737
1735 def __getitem__(self, changeid):
1738 def __getitem__(self, changeid):
1736 # dealing with special cases
1739 # dealing with special cases
1737 if changeid is None:
1740 if changeid is None:
1738 return context.workingctx(self)
1741 return context.workingctx(self)
1739 if isinstance(changeid, context.basectx):
1742 if isinstance(changeid, context.basectx):
1740 return changeid
1743 return changeid
1741
1744
1742 # dealing with multiple revisions
1745 # dealing with multiple revisions
1743 if isinstance(changeid, slice):
1746 if isinstance(changeid, slice):
1744 # wdirrev isn't contiguous so the slice shouldn't include it
1747 # wdirrev isn't contiguous so the slice shouldn't include it
1745 return [
1748 return [
1746 self[i]
1749 self[i]
1747 for i in pycompat.xrange(*changeid.indices(len(self)))
1750 for i in pycompat.xrange(*changeid.indices(len(self)))
1748 if i not in self.changelog.filteredrevs
1751 if i not in self.changelog.filteredrevs
1749 ]
1752 ]
1750
1753
1751 # dealing with some special values
1754 # dealing with some special values
1752 quick_access = self._quick_access_changeid.get(changeid)
1755 quick_access = self._quick_access_changeid.get(changeid)
1753 if quick_access is not None:
1756 if quick_access is not None:
1754 rev, node = quick_access
1757 rev, node = quick_access
1755 return context.changectx(self, rev, node, maybe_filtered=False)
1758 return context.changectx(self, rev, node, maybe_filtered=False)
1756 if changeid == b'tip':
1759 if changeid == b'tip':
1757 node = self.changelog.tip()
1760 node = self.changelog.tip()
1758 rev = self.changelog.rev(node)
1761 rev = self.changelog.rev(node)
1759 return context.changectx(self, rev, node)
1762 return context.changectx(self, rev, node)
1760
1763
1761 # dealing with arbitrary values
1764 # dealing with arbitrary values
1762 try:
1765 try:
1763 if isinstance(changeid, int):
1766 if isinstance(changeid, int):
1764 node = self.changelog.node(changeid)
1767 node = self.changelog.node(changeid)
1765 rev = changeid
1768 rev = changeid
1766 elif changeid == b'.':
1769 elif changeid == b'.':
1767 # this is a hack to delay/avoid loading obsmarkers
1770 # this is a hack to delay/avoid loading obsmarkers
1768 # when we know that '.' won't be hidden
1771 # when we know that '.' won't be hidden
1769 node = self.dirstate.p1()
1772 node = self.dirstate.p1()
1770 rev = self.unfiltered().changelog.rev(node)
1773 rev = self.unfiltered().changelog.rev(node)
1771 elif len(changeid) == 20:
1774 elif len(changeid) == 20:
1772 try:
1775 try:
1773 node = changeid
1776 node = changeid
1774 rev = self.changelog.rev(changeid)
1777 rev = self.changelog.rev(changeid)
1775 except error.FilteredLookupError:
1778 except error.FilteredLookupError:
1776 changeid = hex(changeid) # for the error message
1779 changeid = hex(changeid) # for the error message
1777 raise
1780 raise
1778 except LookupError:
1781 except LookupError:
1779 # check if it might have come from damaged dirstate
1782 # check if it might have come from damaged dirstate
1780 #
1783 #
1781 # XXX we could avoid the unfiltered if we had a recognizable
1784 # XXX we could avoid the unfiltered if we had a recognizable
1782 # exception for filtered changeset access
1785 # exception for filtered changeset access
1783 if (
1786 if (
1784 self.local()
1787 self.local()
1785 and changeid in self.unfiltered().dirstate.parents()
1788 and changeid in self.unfiltered().dirstate.parents()
1786 ):
1789 ):
1787 msg = _(b"working directory has unknown parent '%s'!")
1790 msg = _(b"working directory has unknown parent '%s'!")
1788 raise error.Abort(msg % short(changeid))
1791 raise error.Abort(msg % short(changeid))
1789 changeid = hex(changeid) # for the error message
1792 changeid = hex(changeid) # for the error message
1790 raise
1793 raise
1791
1794
1792 elif len(changeid) == 40:
1795 elif len(changeid) == 40:
1793 node = bin(changeid)
1796 node = bin(changeid)
1794 rev = self.changelog.rev(node)
1797 rev = self.changelog.rev(node)
1795 else:
1798 else:
1796 raise error.ProgrammingError(
1799 raise error.ProgrammingError(
1797 b"unsupported changeid '%s' of type %s"
1800 b"unsupported changeid '%s' of type %s"
1798 % (changeid, pycompat.bytestr(type(changeid)))
1801 % (changeid, pycompat.bytestr(type(changeid)))
1799 )
1802 )
1800
1803
1801 return context.changectx(self, rev, node)
1804 return context.changectx(self, rev, node)
1802
1805
1803 except (error.FilteredIndexError, error.FilteredLookupError):
1806 except (error.FilteredIndexError, error.FilteredLookupError):
1804 raise error.FilteredRepoLookupError(
1807 raise error.FilteredRepoLookupError(
1805 _(b"filtered revision '%s'") % pycompat.bytestr(changeid)
1808 _(b"filtered revision '%s'") % pycompat.bytestr(changeid)
1806 )
1809 )
1807 except (IndexError, LookupError):
1810 except (IndexError, LookupError):
1808 raise error.RepoLookupError(
1811 raise error.RepoLookupError(
1809 _(b"unknown revision '%s'") % pycompat.bytestr(changeid)
1812 _(b"unknown revision '%s'") % pycompat.bytestr(changeid)
1810 )
1813 )
1811 except error.WdirUnsupported:
1814 except error.WdirUnsupported:
1812 return context.workingctx(self)
1815 return context.workingctx(self)
1813
1816
1814 def __contains__(self, changeid):
1817 def __contains__(self, changeid):
1815 """True if the given changeid exists"""
1818 """True if the given changeid exists"""
1816 try:
1819 try:
1817 self[changeid]
1820 self[changeid]
1818 return True
1821 return True
1819 except error.RepoLookupError:
1822 except error.RepoLookupError:
1820 return False
1823 return False
1821
1824
1822 def __nonzero__(self):
1825 def __nonzero__(self):
1823 return True
1826 return True
1824
1827
1825 __bool__ = __nonzero__
1828 __bool__ = __nonzero__
1826
1829
1827 def __len__(self):
1830 def __len__(self):
1828 # no need to pay the cost of repoview.changelog
1831 # no need to pay the cost of repoview.changelog
1829 unfi = self.unfiltered()
1832 unfi = self.unfiltered()
1830 return len(unfi.changelog)
1833 return len(unfi.changelog)
1831
1834
1832 def __iter__(self):
1835 def __iter__(self):
1833 return iter(self.changelog)
1836 return iter(self.changelog)
1834
1837
1835 def revs(self, expr, *args):
1838 def revs(self, expr, *args):
1836 """Find revisions matching a revset.
1839 """Find revisions matching a revset.
1837
1840
1838 The revset is specified as a string ``expr`` that may contain
1841 The revset is specified as a string ``expr`` that may contain
1839 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1842 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1840
1843
1841 Revset aliases from the configuration are not expanded. To expand
1844 Revset aliases from the configuration are not expanded. To expand
1842 user aliases, consider calling ``scmutil.revrange()`` or
1845 user aliases, consider calling ``scmutil.revrange()`` or
1843 ``repo.anyrevs([expr], user=True)``.
1846 ``repo.anyrevs([expr], user=True)``.
1844
1847
1845 Returns a smartset.abstractsmartset, which is a list-like interface
1848 Returns a smartset.abstractsmartset, which is a list-like interface
1846 that contains integer revisions.
1849 that contains integer revisions.
1847 """
1850 """
1848 tree = revsetlang.spectree(expr, *args)
1851 tree = revsetlang.spectree(expr, *args)
1849 return revset.makematcher(tree)(self)
1852 return revset.makematcher(tree)(self)
1850
1853
1851 def set(self, expr, *args):
1854 def set(self, expr, *args):
1852 """Find revisions matching a revset and emit changectx instances.
1855 """Find revisions matching a revset and emit changectx instances.
1853
1856
1854 This is a convenience wrapper around ``revs()`` that iterates the
1857 This is a convenience wrapper around ``revs()`` that iterates the
1855 result and is a generator of changectx instances.
1858 result and is a generator of changectx instances.
1856
1859
1857 Revset aliases from the configuration are not expanded. To expand
1860 Revset aliases from the configuration are not expanded. To expand
1858 user aliases, consider calling ``scmutil.revrange()``.
1861 user aliases, consider calling ``scmutil.revrange()``.
1859 """
1862 """
1860 for r in self.revs(expr, *args):
1863 for r in self.revs(expr, *args):
1861 yield self[r]
1864 yield self[r]
1862
1865
1863 def anyrevs(self, specs, user=False, localalias=None):
1866 def anyrevs(self, specs, user=False, localalias=None):
1864 """Find revisions matching one of the given revsets.
1867 """Find revisions matching one of the given revsets.
1865
1868
1866 Revset aliases from the configuration are not expanded by default. To
1869 Revset aliases from the configuration are not expanded by default. To
1867 expand user aliases, specify ``user=True``. To provide some local
1870 expand user aliases, specify ``user=True``. To provide some local
1868 definitions overriding user aliases, set ``localalias`` to
1871 definitions overriding user aliases, set ``localalias`` to
1869 ``{name: definitionstring}``.
1872 ``{name: definitionstring}``.
1870 """
1873 """
1871 if specs == [b'null']:
1874 if specs == [b'null']:
1872 return revset.baseset([nullrev])
1875 return revset.baseset([nullrev])
1873 if specs == [b'.']:
1876 if specs == [b'.']:
1874 quick_data = self._quick_access_changeid.get(b'.')
1877 quick_data = self._quick_access_changeid.get(b'.')
1875 if quick_data is not None:
1878 if quick_data is not None:
1876 return revset.baseset([quick_data[0]])
1879 return revset.baseset([quick_data[0]])
1877 if user:
1880 if user:
1878 m = revset.matchany(
1881 m = revset.matchany(
1879 self.ui,
1882 self.ui,
1880 specs,
1883 specs,
1881 lookup=revset.lookupfn(self),
1884 lookup=revset.lookupfn(self),
1882 localalias=localalias,
1885 localalias=localalias,
1883 )
1886 )
1884 else:
1887 else:
1885 m = revset.matchany(None, specs, localalias=localalias)
1888 m = revset.matchany(None, specs, localalias=localalias)
1886 return m(self)
1889 return m(self)
1887
1890
1888 def url(self):
1891 def url(self):
1889 return b'file:' + self.root
1892 return b'file:' + self.root
1890
1893
1891 def hook(self, name, throw=False, **args):
1894 def hook(self, name, throw=False, **args):
1892 """Call a hook, passing this repo instance.
1895 """Call a hook, passing this repo instance.
1893
1896
1894 This a convenience method to aid invoking hooks. Extensions likely
1897 This a convenience method to aid invoking hooks. Extensions likely
1895 won't call this unless they have registered a custom hook or are
1898 won't call this unless they have registered a custom hook or are
1896 replacing code that is expected to call a hook.
1899 replacing code that is expected to call a hook.
1897 """
1900 """
1898 return hook.hook(self.ui, self, name, throw, **args)
1901 return hook.hook(self.ui, self, name, throw, **args)
1899
1902
1900 @filteredpropertycache
1903 @filteredpropertycache
1901 def _tagscache(self):
1904 def _tagscache(self):
1902 """Returns a tagscache object that contains various tags related
1905 """Returns a tagscache object that contains various tags related
1903 caches."""
1906 caches."""
1904
1907
1905 # This simplifies its cache management by having one decorated
1908 # This simplifies its cache management by having one decorated
1906 # function (this one) and the rest simply fetch things from it.
1909 # function (this one) and the rest simply fetch things from it.
1907 class tagscache(object):
1910 class tagscache(object):
1908 def __init__(self):
1911 def __init__(self):
1909 # These two define the set of tags for this repository. tags
1912 # These two define the set of tags for this repository. tags
1910 # maps tag name to node; tagtypes maps tag name to 'global' or
1913 # maps tag name to node; tagtypes maps tag name to 'global' or
1911 # 'local'. (Global tags are defined by .hgtags across all
1914 # 'local'. (Global tags are defined by .hgtags across all
1912 # heads, and local tags are defined in .hg/localtags.)
1915 # heads, and local tags are defined in .hg/localtags.)
1913 # They constitute the in-memory cache of tags.
1916 # They constitute the in-memory cache of tags.
1914 self.tags = self.tagtypes = None
1917 self.tags = self.tagtypes = None
1915
1918
1916 self.nodetagscache = self.tagslist = None
1919 self.nodetagscache = self.tagslist = None
1917
1920
1918 cache = tagscache()
1921 cache = tagscache()
1919 cache.tags, cache.tagtypes = self._findtags()
1922 cache.tags, cache.tagtypes = self._findtags()
1920
1923
1921 return cache
1924 return cache
1922
1925
1923 def tags(self):
1926 def tags(self):
1924 '''return a mapping of tag to node'''
1927 '''return a mapping of tag to node'''
1925 t = {}
1928 t = {}
1926 if self.changelog.filteredrevs:
1929 if self.changelog.filteredrevs:
1927 tags, tt = self._findtags()
1930 tags, tt = self._findtags()
1928 else:
1931 else:
1929 tags = self._tagscache.tags
1932 tags = self._tagscache.tags
1930 rev = self.changelog.rev
1933 rev = self.changelog.rev
1931 for k, v in pycompat.iteritems(tags):
1934 for k, v in pycompat.iteritems(tags):
1932 try:
1935 try:
1933 # ignore tags to unknown nodes
1936 # ignore tags to unknown nodes
1934 rev(v)
1937 rev(v)
1935 t[k] = v
1938 t[k] = v
1936 except (error.LookupError, ValueError):
1939 except (error.LookupError, ValueError):
1937 pass
1940 pass
1938 return t
1941 return t
1939
1942
1940 def _findtags(self):
1943 def _findtags(self):
1941 """Do the hard work of finding tags. Return a pair of dicts
1944 """Do the hard work of finding tags. Return a pair of dicts
1942 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1945 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1943 maps tag name to a string like \'global\' or \'local\'.
1946 maps tag name to a string like \'global\' or \'local\'.
1944 Subclasses or extensions are free to add their own tags, but
1947 Subclasses or extensions are free to add their own tags, but
1945 should be aware that the returned dicts will be retained for the
1948 should be aware that the returned dicts will be retained for the
1946 duration of the localrepo object."""
1949 duration of the localrepo object."""
1947
1950
1948 # XXX what tagtype should subclasses/extensions use? Currently
1951 # XXX what tagtype should subclasses/extensions use? Currently
1949 # mq and bookmarks add tags, but do not set the tagtype at all.
1952 # mq and bookmarks add tags, but do not set the tagtype at all.
1950 # Should each extension invent its own tag type? Should there
1953 # Should each extension invent its own tag type? Should there
1951 # be one tagtype for all such "virtual" tags? Or is the status
1954 # be one tagtype for all such "virtual" tags? Or is the status
1952 # quo fine?
1955 # quo fine?
1953
1956
1954 # map tag name to (node, hist)
1957 # map tag name to (node, hist)
1955 alltags = tagsmod.findglobaltags(self.ui, self)
1958 alltags = tagsmod.findglobaltags(self.ui, self)
1956 # map tag name to tag type
1959 # map tag name to tag type
1957 tagtypes = {tag: b'global' for tag in alltags}
1960 tagtypes = {tag: b'global' for tag in alltags}
1958
1961
1959 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1962 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1960
1963
1961 # Build the return dicts. Have to re-encode tag names because
1964 # Build the return dicts. Have to re-encode tag names because
1962 # the tags module always uses UTF-8 (in order not to lose info
1965 # the tags module always uses UTF-8 (in order not to lose info
1963 # writing to the cache), but the rest of Mercurial wants them in
1966 # writing to the cache), but the rest of Mercurial wants them in
1964 # local encoding.
1967 # local encoding.
1965 tags = {}
1968 tags = {}
1966 for (name, (node, hist)) in pycompat.iteritems(alltags):
1969 for (name, (node, hist)) in pycompat.iteritems(alltags):
1967 if node != nullid:
1970 if node != nullid:
1968 tags[encoding.tolocal(name)] = node
1971 tags[encoding.tolocal(name)] = node
1969 tags[b'tip'] = self.changelog.tip()
1972 tags[b'tip'] = self.changelog.tip()
1970 tagtypes = {
1973 tagtypes = {
1971 encoding.tolocal(name): value
1974 encoding.tolocal(name): value
1972 for (name, value) in pycompat.iteritems(tagtypes)
1975 for (name, value) in pycompat.iteritems(tagtypes)
1973 }
1976 }
1974 return (tags, tagtypes)
1977 return (tags, tagtypes)
1975
1978
1976 def tagtype(self, tagname):
1979 def tagtype(self, tagname):
1977 """
1980 """
1978 return the type of the given tag. result can be:
1981 return the type of the given tag. result can be:
1979
1982
1980 'local' : a local tag
1983 'local' : a local tag
1981 'global' : a global tag
1984 'global' : a global tag
1982 None : tag does not exist
1985 None : tag does not exist
1983 """
1986 """
1984
1987
1985 return self._tagscache.tagtypes.get(tagname)
1988 return self._tagscache.tagtypes.get(tagname)
1986
1989
1987 def tagslist(self):
1990 def tagslist(self):
1988 '''return a list of tags ordered by revision'''
1991 '''return a list of tags ordered by revision'''
1989 if not self._tagscache.tagslist:
1992 if not self._tagscache.tagslist:
1990 l = []
1993 l = []
1991 for t, n in pycompat.iteritems(self.tags()):
1994 for t, n in pycompat.iteritems(self.tags()):
1992 l.append((self.changelog.rev(n), t, n))
1995 l.append((self.changelog.rev(n), t, n))
1993 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1996 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1994
1997
1995 return self._tagscache.tagslist
1998 return self._tagscache.tagslist
1996
1999
1997 def nodetags(self, node):
2000 def nodetags(self, node):
1998 '''return the tags associated with a node'''
2001 '''return the tags associated with a node'''
1999 if not self._tagscache.nodetagscache:
2002 if not self._tagscache.nodetagscache:
2000 nodetagscache = {}
2003 nodetagscache = {}
2001 for t, n in pycompat.iteritems(self._tagscache.tags):
2004 for t, n in pycompat.iteritems(self._tagscache.tags):
2002 nodetagscache.setdefault(n, []).append(t)
2005 nodetagscache.setdefault(n, []).append(t)
2003 for tags in pycompat.itervalues(nodetagscache):
2006 for tags in pycompat.itervalues(nodetagscache):
2004 tags.sort()
2007 tags.sort()
2005 self._tagscache.nodetagscache = nodetagscache
2008 self._tagscache.nodetagscache = nodetagscache
2006 return self._tagscache.nodetagscache.get(node, [])
2009 return self._tagscache.nodetagscache.get(node, [])
2007
2010
2008 def nodebookmarks(self, node):
2011 def nodebookmarks(self, node):
2009 """return the list of bookmarks pointing to the specified node"""
2012 """return the list of bookmarks pointing to the specified node"""
2010 return self._bookmarks.names(node)
2013 return self._bookmarks.names(node)
2011
2014
2012 def branchmap(self):
2015 def branchmap(self):
2013 """returns a dictionary {branch: [branchheads]} with branchheads
2016 """returns a dictionary {branch: [branchheads]} with branchheads
2014 ordered by increasing revision number"""
2017 ordered by increasing revision number"""
2015 return self._branchcaches[self]
2018 return self._branchcaches[self]
2016
2019
2017 @unfilteredmethod
2020 @unfilteredmethod
2018 def revbranchcache(self):
2021 def revbranchcache(self):
2019 if not self._revbranchcache:
2022 if not self._revbranchcache:
2020 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
2023 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
2021 return self._revbranchcache
2024 return self._revbranchcache
2022
2025
2023 def branchtip(self, branch, ignoremissing=False):
2026 def branchtip(self, branch, ignoremissing=False):
2024 """return the tip node for a given branch
2027 """return the tip node for a given branch
2025
2028
2026 If ignoremissing is True, then this method will not raise an error.
2029 If ignoremissing is True, then this method will not raise an error.
2027 This is helpful for callers that only expect None for a missing branch
2030 This is helpful for callers that only expect None for a missing branch
2028 (e.g. namespace).
2031 (e.g. namespace).
2029
2032
2030 """
2033 """
2031 try:
2034 try:
2032 return self.branchmap().branchtip(branch)
2035 return self.branchmap().branchtip(branch)
2033 except KeyError:
2036 except KeyError:
2034 if not ignoremissing:
2037 if not ignoremissing:
2035 raise error.RepoLookupError(_(b"unknown branch '%s'") % branch)
2038 raise error.RepoLookupError(_(b"unknown branch '%s'") % branch)
2036 else:
2039 else:
2037 pass
2040 pass
2038
2041
2039 def lookup(self, key):
2042 def lookup(self, key):
2040 node = scmutil.revsymbol(self, key).node()
2043 node = scmutil.revsymbol(self, key).node()
2041 if node is None:
2044 if node is None:
2042 raise error.RepoLookupError(_(b"unknown revision '%s'") % key)
2045 raise error.RepoLookupError(_(b"unknown revision '%s'") % key)
2043 return node
2046 return node
2044
2047
2045 def lookupbranch(self, key):
2048 def lookupbranch(self, key):
2046 if self.branchmap().hasbranch(key):
2049 if self.branchmap().hasbranch(key):
2047 return key
2050 return key
2048
2051
2049 return scmutil.revsymbol(self, key).branch()
2052 return scmutil.revsymbol(self, key).branch()
2050
2053
2051 def known(self, nodes):
2054 def known(self, nodes):
2052 cl = self.changelog
2055 cl = self.changelog
2053 get_rev = cl.index.get_rev
2056 get_rev = cl.index.get_rev
2054 filtered = cl.filteredrevs
2057 filtered = cl.filteredrevs
2055 result = []
2058 result = []
2056 for n in nodes:
2059 for n in nodes:
2057 r = get_rev(n)
2060 r = get_rev(n)
2058 resp = not (r is None or r in filtered)
2061 resp = not (r is None or r in filtered)
2059 result.append(resp)
2062 result.append(resp)
2060 return result
2063 return result
2061
2064
2062 def local(self):
2065 def local(self):
2063 return self
2066 return self
2064
2067
2065 def publishing(self):
2068 def publishing(self):
2066 # it's safe (and desirable) to trust the publish flag unconditionally
2069 # it's safe (and desirable) to trust the publish flag unconditionally
2067 # so that we don't finalize changes shared between users via ssh or nfs
2070 # so that we don't finalize changes shared between users via ssh or nfs
2068 return self.ui.configbool(b'phases', b'publish', untrusted=True)
2071 return self.ui.configbool(b'phases', b'publish', untrusted=True)
2069
2072
2070 def cancopy(self):
2073 def cancopy(self):
2071 # so statichttprepo's override of local() works
2074 # so statichttprepo's override of local() works
2072 if not self.local():
2075 if not self.local():
2073 return False
2076 return False
2074 if not self.publishing():
2077 if not self.publishing():
2075 return True
2078 return True
2076 # if publishing we can't copy if there is filtered content
2079 # if publishing we can't copy if there is filtered content
2077 return not self.filtered(b'visible').changelog.filteredrevs
2080 return not self.filtered(b'visible').changelog.filteredrevs
2078
2081
2079 def shared(self):
2082 def shared(self):
2080 '''the type of shared repository (None if not shared)'''
2083 '''the type of shared repository (None if not shared)'''
2081 if self.sharedpath != self.path:
2084 if self.sharedpath != self.path:
2082 return b'store'
2085 return b'store'
2083 return None
2086 return None
2084
2087
2085 def wjoin(self, f, *insidef):
2088 def wjoin(self, f, *insidef):
2086 return self.vfs.reljoin(self.root, f, *insidef)
2089 return self.vfs.reljoin(self.root, f, *insidef)
2087
2090
2088 def setparents(self, p1, p2=nullid):
2091 def setparents(self, p1, p2=nullid):
2089 self[None].setparents(p1, p2)
2092 self[None].setparents(p1, p2)
2090 self._quick_access_changeid_invalidate()
2093 self._quick_access_changeid_invalidate()
2091
2094
2092 def filectx(self, path, changeid=None, fileid=None, changectx=None):
2095 def filectx(self, path, changeid=None, fileid=None, changectx=None):
2093 """changeid must be a changeset revision, if specified.
2096 """changeid must be a changeset revision, if specified.
2094 fileid can be a file revision or node."""
2097 fileid can be a file revision or node."""
2095 return context.filectx(
2098 return context.filectx(
2096 self, path, changeid, fileid, changectx=changectx
2099 self, path, changeid, fileid, changectx=changectx
2097 )
2100 )
2098
2101
2099 def getcwd(self):
2102 def getcwd(self):
2100 return self.dirstate.getcwd()
2103 return self.dirstate.getcwd()
2101
2104
2102 def pathto(self, f, cwd=None):
2105 def pathto(self, f, cwd=None):
2103 return self.dirstate.pathto(f, cwd)
2106 return self.dirstate.pathto(f, cwd)
2104
2107
2105 def _loadfilter(self, filter):
2108 def _loadfilter(self, filter):
2106 if filter not in self._filterpats:
2109 if filter not in self._filterpats:
2107 l = []
2110 l = []
2108 for pat, cmd in self.ui.configitems(filter):
2111 for pat, cmd in self.ui.configitems(filter):
2109 if cmd == b'!':
2112 if cmd == b'!':
2110 continue
2113 continue
2111 mf = matchmod.match(self.root, b'', [pat])
2114 mf = matchmod.match(self.root, b'', [pat])
2112 fn = None
2115 fn = None
2113 params = cmd
2116 params = cmd
2114 for name, filterfn in pycompat.iteritems(self._datafilters):
2117 for name, filterfn in pycompat.iteritems(self._datafilters):
2115 if cmd.startswith(name):
2118 if cmd.startswith(name):
2116 fn = filterfn
2119 fn = filterfn
2117 params = cmd[len(name) :].lstrip()
2120 params = cmd[len(name) :].lstrip()
2118 break
2121 break
2119 if not fn:
2122 if not fn:
2120 fn = lambda s, c, **kwargs: procutil.filter(s, c)
2123 fn = lambda s, c, **kwargs: procutil.filter(s, c)
2121 fn.__name__ = 'commandfilter'
2124 fn.__name__ = 'commandfilter'
2122 # Wrap old filters not supporting keyword arguments
2125 # Wrap old filters not supporting keyword arguments
2123 if not pycompat.getargspec(fn)[2]:
2126 if not pycompat.getargspec(fn)[2]:
2124 oldfn = fn
2127 oldfn = fn
2125 fn = lambda s, c, oldfn=oldfn, **kwargs: oldfn(s, c)
2128 fn = lambda s, c, oldfn=oldfn, **kwargs: oldfn(s, c)
2126 fn.__name__ = 'compat-' + oldfn.__name__
2129 fn.__name__ = 'compat-' + oldfn.__name__
2127 l.append((mf, fn, params))
2130 l.append((mf, fn, params))
2128 self._filterpats[filter] = l
2131 self._filterpats[filter] = l
2129 return self._filterpats[filter]
2132 return self._filterpats[filter]
2130
2133
2131 def _filter(self, filterpats, filename, data):
2134 def _filter(self, filterpats, filename, data):
2132 for mf, fn, cmd in filterpats:
2135 for mf, fn, cmd in filterpats:
2133 if mf(filename):
2136 if mf(filename):
2134 self.ui.debug(
2137 self.ui.debug(
2135 b"filtering %s through %s\n"
2138 b"filtering %s through %s\n"
2136 % (filename, cmd or pycompat.sysbytes(fn.__name__))
2139 % (filename, cmd or pycompat.sysbytes(fn.__name__))
2137 )
2140 )
2138 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
2141 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
2139 break
2142 break
2140
2143
2141 return data
2144 return data
2142
2145
2143 @unfilteredpropertycache
2146 @unfilteredpropertycache
2144 def _encodefilterpats(self):
2147 def _encodefilterpats(self):
2145 return self._loadfilter(b'encode')
2148 return self._loadfilter(b'encode')
2146
2149
2147 @unfilteredpropertycache
2150 @unfilteredpropertycache
2148 def _decodefilterpats(self):
2151 def _decodefilterpats(self):
2149 return self._loadfilter(b'decode')
2152 return self._loadfilter(b'decode')
2150
2153
2151 def adddatafilter(self, name, filter):
2154 def adddatafilter(self, name, filter):
2152 self._datafilters[name] = filter
2155 self._datafilters[name] = filter
2153
2156
2154 def wread(self, filename):
2157 def wread(self, filename):
2155 if self.wvfs.islink(filename):
2158 if self.wvfs.islink(filename):
2156 data = self.wvfs.readlink(filename)
2159 data = self.wvfs.readlink(filename)
2157 else:
2160 else:
2158 data = self.wvfs.read(filename)
2161 data = self.wvfs.read(filename)
2159 return self._filter(self._encodefilterpats, filename, data)
2162 return self._filter(self._encodefilterpats, filename, data)
2160
2163
2161 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
2164 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
2162 """write ``data`` into ``filename`` in the working directory
2165 """write ``data`` into ``filename`` in the working directory
2163
2166
2164 This returns length of written (maybe decoded) data.
2167 This returns length of written (maybe decoded) data.
2165 """
2168 """
2166 data = self._filter(self._decodefilterpats, filename, data)
2169 data = self._filter(self._decodefilterpats, filename, data)
2167 if b'l' in flags:
2170 if b'l' in flags:
2168 self.wvfs.symlink(data, filename)
2171 self.wvfs.symlink(data, filename)
2169 else:
2172 else:
2170 self.wvfs.write(
2173 self.wvfs.write(
2171 filename, data, backgroundclose=backgroundclose, **kwargs
2174 filename, data, backgroundclose=backgroundclose, **kwargs
2172 )
2175 )
2173 if b'x' in flags:
2176 if b'x' in flags:
2174 self.wvfs.setflags(filename, False, True)
2177 self.wvfs.setflags(filename, False, True)
2175 else:
2178 else:
2176 self.wvfs.setflags(filename, False, False)
2179 self.wvfs.setflags(filename, False, False)
2177 return len(data)
2180 return len(data)
2178
2181
2179 def wwritedata(self, filename, data):
2182 def wwritedata(self, filename, data):
2180 return self._filter(self._decodefilterpats, filename, data)
2183 return self._filter(self._decodefilterpats, filename, data)
2181
2184
2182 def currenttransaction(self):
2185 def currenttransaction(self):
2183 """return the current transaction or None if non exists"""
2186 """return the current transaction or None if non exists"""
2184 if self._transref:
2187 if self._transref:
2185 tr = self._transref()
2188 tr = self._transref()
2186 else:
2189 else:
2187 tr = None
2190 tr = None
2188
2191
2189 if tr and tr.running():
2192 if tr and tr.running():
2190 return tr
2193 return tr
2191 return None
2194 return None
2192
2195
2193 def transaction(self, desc, report=None):
2196 def transaction(self, desc, report=None):
2194 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
2197 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
2195 b'devel', b'check-locks'
2198 b'devel', b'check-locks'
2196 ):
2199 ):
2197 if self._currentlock(self._lockref) is None:
2200 if self._currentlock(self._lockref) is None:
2198 raise error.ProgrammingError(b'transaction requires locking')
2201 raise error.ProgrammingError(b'transaction requires locking')
2199 tr = self.currenttransaction()
2202 tr = self.currenttransaction()
2200 if tr is not None:
2203 if tr is not None:
2201 return tr.nest(name=desc)
2204 return tr.nest(name=desc)
2202
2205
2203 # abort here if the journal already exists
2206 # abort here if the journal already exists
2204 if self.svfs.exists(b"journal"):
2207 if self.svfs.exists(b"journal"):
2205 raise error.RepoError(
2208 raise error.RepoError(
2206 _(b"abandoned transaction found"),
2209 _(b"abandoned transaction found"),
2207 hint=_(b"run 'hg recover' to clean up transaction"),
2210 hint=_(b"run 'hg recover' to clean up transaction"),
2208 )
2211 )
2209
2212
2210 idbase = b"%.40f#%f" % (random.random(), time.time())
2213 idbase = b"%.40f#%f" % (random.random(), time.time())
2211 ha = hex(hashutil.sha1(idbase).digest())
2214 ha = hex(hashutil.sha1(idbase).digest())
2212 txnid = b'TXN:' + ha
2215 txnid = b'TXN:' + ha
2213 self.hook(b'pretxnopen', throw=True, txnname=desc, txnid=txnid)
2216 self.hook(b'pretxnopen', throw=True, txnname=desc, txnid=txnid)
2214
2217
2215 self._writejournal(desc)
2218 self._writejournal(desc)
2216 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
2219 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
2217 if report:
2220 if report:
2218 rp = report
2221 rp = report
2219 else:
2222 else:
2220 rp = self.ui.warn
2223 rp = self.ui.warn
2221 vfsmap = {b'plain': self.vfs, b'store': self.svfs} # root of .hg/
2224 vfsmap = {b'plain': self.vfs, b'store': self.svfs} # root of .hg/
2222 # we must avoid cyclic reference between repo and transaction.
2225 # we must avoid cyclic reference between repo and transaction.
2223 reporef = weakref.ref(self)
2226 reporef = weakref.ref(self)
2224 # Code to track tag movement
2227 # Code to track tag movement
2225 #
2228 #
2226 # Since tags are all handled as file content, it is actually quite hard
2229 # Since tags are all handled as file content, it is actually quite hard
2227 # to track these movement from a code perspective. So we fallback to a
2230 # to track these movement from a code perspective. So we fallback to a
2228 # tracking at the repository level. One could envision to track changes
2231 # tracking at the repository level. One could envision to track changes
2229 # to the '.hgtags' file through changegroup apply but that fails to
2232 # to the '.hgtags' file through changegroup apply but that fails to
2230 # cope with case where transaction expose new heads without changegroup
2233 # cope with case where transaction expose new heads without changegroup
2231 # being involved (eg: phase movement).
2234 # being involved (eg: phase movement).
2232 #
2235 #
2233 # For now, We gate the feature behind a flag since this likely comes
2236 # For now, We gate the feature behind a flag since this likely comes
2234 # with performance impacts. The current code run more often than needed
2237 # with performance impacts. The current code run more often than needed
2235 # and do not use caches as much as it could. The current focus is on
2238 # and do not use caches as much as it could. The current focus is on
2236 # the behavior of the feature so we disable it by default. The flag
2239 # the behavior of the feature so we disable it by default. The flag
2237 # will be removed when we are happy with the performance impact.
2240 # will be removed when we are happy with the performance impact.
2238 #
2241 #
2239 # Once this feature is no longer experimental move the following
2242 # Once this feature is no longer experimental move the following
2240 # documentation to the appropriate help section:
2243 # documentation to the appropriate help section:
2241 #
2244 #
2242 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
2245 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
2243 # tags (new or changed or deleted tags). In addition the details of
2246 # tags (new or changed or deleted tags). In addition the details of
2244 # these changes are made available in a file at:
2247 # these changes are made available in a file at:
2245 # ``REPOROOT/.hg/changes/tags.changes``.
2248 # ``REPOROOT/.hg/changes/tags.changes``.
2246 # Make sure you check for HG_TAG_MOVED before reading that file as it
2249 # Make sure you check for HG_TAG_MOVED before reading that file as it
2247 # might exist from a previous transaction even if no tag were touched
2250 # might exist from a previous transaction even if no tag were touched
2248 # in this one. Changes are recorded in a line base format::
2251 # in this one. Changes are recorded in a line base format::
2249 #
2252 #
2250 # <action> <hex-node> <tag-name>\n
2253 # <action> <hex-node> <tag-name>\n
2251 #
2254 #
2252 # Actions are defined as follow:
2255 # Actions are defined as follow:
2253 # "-R": tag is removed,
2256 # "-R": tag is removed,
2254 # "+A": tag is added,
2257 # "+A": tag is added,
2255 # "-M": tag is moved (old value),
2258 # "-M": tag is moved (old value),
2256 # "+M": tag is moved (new value),
2259 # "+M": tag is moved (new value),
2257 tracktags = lambda x: None
2260 tracktags = lambda x: None
2258 # experimental config: experimental.hook-track-tags
2261 # experimental config: experimental.hook-track-tags
2259 shouldtracktags = self.ui.configbool(
2262 shouldtracktags = self.ui.configbool(
2260 b'experimental', b'hook-track-tags'
2263 b'experimental', b'hook-track-tags'
2261 )
2264 )
2262 if desc != b'strip' and shouldtracktags:
2265 if desc != b'strip' and shouldtracktags:
2263 oldheads = self.changelog.headrevs()
2266 oldheads = self.changelog.headrevs()
2264
2267
2265 def tracktags(tr2):
2268 def tracktags(tr2):
2266 repo = reporef()
2269 repo = reporef()
2267 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
2270 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
2268 newheads = repo.changelog.headrevs()
2271 newheads = repo.changelog.headrevs()
2269 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
2272 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
2270 # notes: we compare lists here.
2273 # notes: we compare lists here.
2271 # As we do it only once buiding set would not be cheaper
2274 # As we do it only once buiding set would not be cheaper
2272 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
2275 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
2273 if changes:
2276 if changes:
2274 tr2.hookargs[b'tag_moved'] = b'1'
2277 tr2.hookargs[b'tag_moved'] = b'1'
2275 with repo.vfs(
2278 with repo.vfs(
2276 b'changes/tags.changes', b'w', atomictemp=True
2279 b'changes/tags.changes', b'w', atomictemp=True
2277 ) as changesfile:
2280 ) as changesfile:
2278 # note: we do not register the file to the transaction
2281 # note: we do not register the file to the transaction
2279 # because we needs it to still exist on the transaction
2282 # because we needs it to still exist on the transaction
2280 # is close (for txnclose hooks)
2283 # is close (for txnclose hooks)
2281 tagsmod.writediff(changesfile, changes)
2284 tagsmod.writediff(changesfile, changes)
2282
2285
2283 def validate(tr2):
2286 def validate(tr2):
2284 """will run pre-closing hooks"""
2287 """will run pre-closing hooks"""
2285 # XXX the transaction API is a bit lacking here so we take a hacky
2288 # XXX the transaction API is a bit lacking here so we take a hacky
2286 # path for now
2289 # path for now
2287 #
2290 #
2288 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
2291 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
2289 # dict is copied before these run. In addition we needs the data
2292 # dict is copied before these run. In addition we needs the data
2290 # available to in memory hooks too.
2293 # available to in memory hooks too.
2291 #
2294 #
2292 # Moreover, we also need to make sure this runs before txnclose
2295 # Moreover, we also need to make sure this runs before txnclose
2293 # hooks and there is no "pending" mechanism that would execute
2296 # hooks and there is no "pending" mechanism that would execute
2294 # logic only if hooks are about to run.
2297 # logic only if hooks are about to run.
2295 #
2298 #
2296 # Fixing this limitation of the transaction is also needed to track
2299 # Fixing this limitation of the transaction is also needed to track
2297 # other families of changes (bookmarks, phases, obsolescence).
2300 # other families of changes (bookmarks, phases, obsolescence).
2298 #
2301 #
2299 # This will have to be fixed before we remove the experimental
2302 # This will have to be fixed before we remove the experimental
2300 # gating.
2303 # gating.
2301 tracktags(tr2)
2304 tracktags(tr2)
2302 repo = reporef()
2305 repo = reporef()
2303
2306
2304 singleheadopt = (b'experimental', b'single-head-per-branch')
2307 singleheadopt = (b'experimental', b'single-head-per-branch')
2305 singlehead = repo.ui.configbool(*singleheadopt)
2308 singlehead = repo.ui.configbool(*singleheadopt)
2306 if singlehead:
2309 if singlehead:
2307 singleheadsub = repo.ui.configsuboptions(*singleheadopt)[1]
2310 singleheadsub = repo.ui.configsuboptions(*singleheadopt)[1]
2308 accountclosed = singleheadsub.get(
2311 accountclosed = singleheadsub.get(
2309 b"account-closed-heads", False
2312 b"account-closed-heads", False
2310 )
2313 )
2311 if singleheadsub.get(b"public-changes-only", False):
2314 if singleheadsub.get(b"public-changes-only", False):
2312 filtername = b"immutable"
2315 filtername = b"immutable"
2313 else:
2316 else:
2314 filtername = b"visible"
2317 filtername = b"visible"
2315 scmutil.enforcesinglehead(
2318 scmutil.enforcesinglehead(
2316 repo, tr2, desc, accountclosed, filtername
2319 repo, tr2, desc, accountclosed, filtername
2317 )
2320 )
2318 if hook.hashook(repo.ui, b'pretxnclose-bookmark'):
2321 if hook.hashook(repo.ui, b'pretxnclose-bookmark'):
2319 for name, (old, new) in sorted(
2322 for name, (old, new) in sorted(
2320 tr.changes[b'bookmarks'].items()
2323 tr.changes[b'bookmarks'].items()
2321 ):
2324 ):
2322 args = tr.hookargs.copy()
2325 args = tr.hookargs.copy()
2323 args.update(bookmarks.preparehookargs(name, old, new))
2326 args.update(bookmarks.preparehookargs(name, old, new))
2324 repo.hook(
2327 repo.hook(
2325 b'pretxnclose-bookmark',
2328 b'pretxnclose-bookmark',
2326 throw=True,
2329 throw=True,
2327 **pycompat.strkwargs(args)
2330 **pycompat.strkwargs(args)
2328 )
2331 )
2329 if hook.hashook(repo.ui, b'pretxnclose-phase'):
2332 if hook.hashook(repo.ui, b'pretxnclose-phase'):
2330 cl = repo.unfiltered().changelog
2333 cl = repo.unfiltered().changelog
2331 for revs, (old, new) in tr.changes[b'phases']:
2334 for revs, (old, new) in tr.changes[b'phases']:
2332 for rev in revs:
2335 for rev in revs:
2333 args = tr.hookargs.copy()
2336 args = tr.hookargs.copy()
2334 node = hex(cl.node(rev))
2337 node = hex(cl.node(rev))
2335 args.update(phases.preparehookargs(node, old, new))
2338 args.update(phases.preparehookargs(node, old, new))
2336 repo.hook(
2339 repo.hook(
2337 b'pretxnclose-phase',
2340 b'pretxnclose-phase',
2338 throw=True,
2341 throw=True,
2339 **pycompat.strkwargs(args)
2342 **pycompat.strkwargs(args)
2340 )
2343 )
2341
2344
2342 repo.hook(
2345 repo.hook(
2343 b'pretxnclose', throw=True, **pycompat.strkwargs(tr.hookargs)
2346 b'pretxnclose', throw=True, **pycompat.strkwargs(tr.hookargs)
2344 )
2347 )
2345
2348
2346 def releasefn(tr, success):
2349 def releasefn(tr, success):
2347 repo = reporef()
2350 repo = reporef()
2348 if repo is None:
2351 if repo is None:
2349 # If the repo has been GC'd (and this release function is being
2352 # If the repo has been GC'd (and this release function is being
2350 # called from transaction.__del__), there's not much we can do,
2353 # called from transaction.__del__), there's not much we can do,
2351 # so just leave the unfinished transaction there and let the
2354 # so just leave the unfinished transaction there and let the
2352 # user run `hg recover`.
2355 # user run `hg recover`.
2353 return
2356 return
2354 if success:
2357 if success:
2355 # this should be explicitly invoked here, because
2358 # this should be explicitly invoked here, because
2356 # in-memory changes aren't written out at closing
2359 # in-memory changes aren't written out at closing
2357 # transaction, if tr.addfilegenerator (via
2360 # transaction, if tr.addfilegenerator (via
2358 # dirstate.write or so) isn't invoked while
2361 # dirstate.write or so) isn't invoked while
2359 # transaction running
2362 # transaction running
2360 repo.dirstate.write(None)
2363 repo.dirstate.write(None)
2361 else:
2364 else:
2362 # discard all changes (including ones already written
2365 # discard all changes (including ones already written
2363 # out) in this transaction
2366 # out) in this transaction
2364 narrowspec.restorebackup(self, b'journal.narrowspec')
2367 narrowspec.restorebackup(self, b'journal.narrowspec')
2365 narrowspec.restorewcbackup(self, b'journal.narrowspec.dirstate')
2368 narrowspec.restorewcbackup(self, b'journal.narrowspec.dirstate')
2366 repo.dirstate.restorebackup(None, b'journal.dirstate')
2369 repo.dirstate.restorebackup(None, b'journal.dirstate')
2367
2370
2368 repo.invalidate(clearfilecache=True)
2371 repo.invalidate(clearfilecache=True)
2369
2372
2370 tr = transaction.transaction(
2373 tr = transaction.transaction(
2371 rp,
2374 rp,
2372 self.svfs,
2375 self.svfs,
2373 vfsmap,
2376 vfsmap,
2374 b"journal",
2377 b"journal",
2375 b"undo",
2378 b"undo",
2376 aftertrans(renames),
2379 aftertrans(renames),
2377 self.store.createmode,
2380 self.store.createmode,
2378 validator=validate,
2381 validator=validate,
2379 releasefn=releasefn,
2382 releasefn=releasefn,
2380 checkambigfiles=_cachedfiles,
2383 checkambigfiles=_cachedfiles,
2381 name=desc,
2384 name=desc,
2382 )
2385 )
2383 tr.changes[b'origrepolen'] = len(self)
2386 tr.changes[b'origrepolen'] = len(self)
2384 tr.changes[b'obsmarkers'] = set()
2387 tr.changes[b'obsmarkers'] = set()
2385 tr.changes[b'phases'] = []
2388 tr.changes[b'phases'] = []
2386 tr.changes[b'bookmarks'] = {}
2389 tr.changes[b'bookmarks'] = {}
2387
2390
2388 tr.hookargs[b'txnid'] = txnid
2391 tr.hookargs[b'txnid'] = txnid
2389 tr.hookargs[b'txnname'] = desc
2392 tr.hookargs[b'txnname'] = desc
2390 tr.hookargs[b'changes'] = tr.changes
2393 tr.hookargs[b'changes'] = tr.changes
2391 # note: writing the fncache only during finalize mean that the file is
2394 # note: writing the fncache only during finalize mean that the file is
2392 # outdated when running hooks. As fncache is used for streaming clone,
2395 # outdated when running hooks. As fncache is used for streaming clone,
2393 # this is not expected to break anything that happen during the hooks.
2396 # this is not expected to break anything that happen during the hooks.
2394 tr.addfinalize(b'flush-fncache', self.store.write)
2397 tr.addfinalize(b'flush-fncache', self.store.write)
2395
2398
2396 def txnclosehook(tr2):
2399 def txnclosehook(tr2):
2397 """To be run if transaction is successful, will schedule a hook run"""
2400 """To be run if transaction is successful, will schedule a hook run"""
2398 # Don't reference tr2 in hook() so we don't hold a reference.
2401 # Don't reference tr2 in hook() so we don't hold a reference.
2399 # This reduces memory consumption when there are multiple
2402 # This reduces memory consumption when there are multiple
2400 # transactions per lock. This can likely go away if issue5045
2403 # transactions per lock. This can likely go away if issue5045
2401 # fixes the function accumulation.
2404 # fixes the function accumulation.
2402 hookargs = tr2.hookargs
2405 hookargs = tr2.hookargs
2403
2406
2404 def hookfunc(unused_success):
2407 def hookfunc(unused_success):
2405 repo = reporef()
2408 repo = reporef()
2406 if hook.hashook(repo.ui, b'txnclose-bookmark'):
2409 if hook.hashook(repo.ui, b'txnclose-bookmark'):
2407 bmchanges = sorted(tr.changes[b'bookmarks'].items())
2410 bmchanges = sorted(tr.changes[b'bookmarks'].items())
2408 for name, (old, new) in bmchanges:
2411 for name, (old, new) in bmchanges:
2409 args = tr.hookargs.copy()
2412 args = tr.hookargs.copy()
2410 args.update(bookmarks.preparehookargs(name, old, new))
2413 args.update(bookmarks.preparehookargs(name, old, new))
2411 repo.hook(
2414 repo.hook(
2412 b'txnclose-bookmark',
2415 b'txnclose-bookmark',
2413 throw=False,
2416 throw=False,
2414 **pycompat.strkwargs(args)
2417 **pycompat.strkwargs(args)
2415 )
2418 )
2416
2419
2417 if hook.hashook(repo.ui, b'txnclose-phase'):
2420 if hook.hashook(repo.ui, b'txnclose-phase'):
2418 cl = repo.unfiltered().changelog
2421 cl = repo.unfiltered().changelog
2419 phasemv = sorted(
2422 phasemv = sorted(
2420 tr.changes[b'phases'], key=lambda r: r[0][0]
2423 tr.changes[b'phases'], key=lambda r: r[0][0]
2421 )
2424 )
2422 for revs, (old, new) in phasemv:
2425 for revs, (old, new) in phasemv:
2423 for rev in revs:
2426 for rev in revs:
2424 args = tr.hookargs.copy()
2427 args = tr.hookargs.copy()
2425 node = hex(cl.node(rev))
2428 node = hex(cl.node(rev))
2426 args.update(phases.preparehookargs(node, old, new))
2429 args.update(phases.preparehookargs(node, old, new))
2427 repo.hook(
2430 repo.hook(
2428 b'txnclose-phase',
2431 b'txnclose-phase',
2429 throw=False,
2432 throw=False,
2430 **pycompat.strkwargs(args)
2433 **pycompat.strkwargs(args)
2431 )
2434 )
2432
2435
2433 repo.hook(
2436 repo.hook(
2434 b'txnclose', throw=False, **pycompat.strkwargs(hookargs)
2437 b'txnclose', throw=False, **pycompat.strkwargs(hookargs)
2435 )
2438 )
2436
2439
2437 reporef()._afterlock(hookfunc)
2440 reporef()._afterlock(hookfunc)
2438
2441
2439 tr.addfinalize(b'txnclose-hook', txnclosehook)
2442 tr.addfinalize(b'txnclose-hook', txnclosehook)
2440 # Include a leading "-" to make it happen before the transaction summary
2443 # Include a leading "-" to make it happen before the transaction summary
2441 # reports registered via scmutil.registersummarycallback() whose names
2444 # reports registered via scmutil.registersummarycallback() whose names
2442 # are 00-txnreport etc. That way, the caches will be warm when the
2445 # are 00-txnreport etc. That way, the caches will be warm when the
2443 # callbacks run.
2446 # callbacks run.
2444 tr.addpostclose(b'-warm-cache', self._buildcacheupdater(tr))
2447 tr.addpostclose(b'-warm-cache', self._buildcacheupdater(tr))
2445
2448
2446 def txnaborthook(tr2):
2449 def txnaborthook(tr2):
2447 """To be run if transaction is aborted"""
2450 """To be run if transaction is aborted"""
2448 reporef().hook(
2451 reporef().hook(
2449 b'txnabort', throw=False, **pycompat.strkwargs(tr2.hookargs)
2452 b'txnabort', throw=False, **pycompat.strkwargs(tr2.hookargs)
2450 )
2453 )
2451
2454
2452 tr.addabort(b'txnabort-hook', txnaborthook)
2455 tr.addabort(b'txnabort-hook', txnaborthook)
2453 # avoid eager cache invalidation. in-memory data should be identical
2456 # avoid eager cache invalidation. in-memory data should be identical
2454 # to stored data if transaction has no error.
2457 # to stored data if transaction has no error.
2455 tr.addpostclose(b'refresh-filecachestats', self._refreshfilecachestats)
2458 tr.addpostclose(b'refresh-filecachestats', self._refreshfilecachestats)
2456 self._transref = weakref.ref(tr)
2459 self._transref = weakref.ref(tr)
2457 scmutil.registersummarycallback(self, tr, desc)
2460 scmutil.registersummarycallback(self, tr, desc)
2458 return tr
2461 return tr
2459
2462
2460 def _journalfiles(self):
2463 def _journalfiles(self):
2461 return (
2464 return (
2462 (self.svfs, b'journal'),
2465 (self.svfs, b'journal'),
2463 (self.svfs, b'journal.narrowspec'),
2466 (self.svfs, b'journal.narrowspec'),
2464 (self.vfs, b'journal.narrowspec.dirstate'),
2467 (self.vfs, b'journal.narrowspec.dirstate'),
2465 (self.vfs, b'journal.dirstate'),
2468 (self.vfs, b'journal.dirstate'),
2466 (self.vfs, b'journal.branch'),
2469 (self.vfs, b'journal.branch'),
2467 (self.vfs, b'journal.desc'),
2470 (self.vfs, b'journal.desc'),
2468 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2471 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2469 (self.svfs, b'journal.phaseroots'),
2472 (self.svfs, b'journal.phaseroots'),
2470 )
2473 )
2471
2474
2472 def undofiles(self):
2475 def undofiles(self):
2473 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
2476 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
2474
2477
2475 @unfilteredmethod
2478 @unfilteredmethod
2476 def _writejournal(self, desc):
2479 def _writejournal(self, desc):
2477 self.dirstate.savebackup(None, b'journal.dirstate')
2480 self.dirstate.savebackup(None, b'journal.dirstate')
2478 narrowspec.savewcbackup(self, b'journal.narrowspec.dirstate')
2481 narrowspec.savewcbackup(self, b'journal.narrowspec.dirstate')
2479 narrowspec.savebackup(self, b'journal.narrowspec')
2482 narrowspec.savebackup(self, b'journal.narrowspec')
2480 self.vfs.write(
2483 self.vfs.write(
2481 b"journal.branch", encoding.fromlocal(self.dirstate.branch())
2484 b"journal.branch", encoding.fromlocal(self.dirstate.branch())
2482 )
2485 )
2483 self.vfs.write(b"journal.desc", b"%d\n%s\n" % (len(self), desc))
2486 self.vfs.write(b"journal.desc", b"%d\n%s\n" % (len(self), desc))
2484 bookmarksvfs = bookmarks.bookmarksvfs(self)
2487 bookmarksvfs = bookmarks.bookmarksvfs(self)
2485 bookmarksvfs.write(
2488 bookmarksvfs.write(
2486 b"journal.bookmarks", bookmarksvfs.tryread(b"bookmarks")
2489 b"journal.bookmarks", bookmarksvfs.tryread(b"bookmarks")
2487 )
2490 )
2488 self.svfs.write(b"journal.phaseroots", self.svfs.tryread(b"phaseroots"))
2491 self.svfs.write(b"journal.phaseroots", self.svfs.tryread(b"phaseroots"))
2489
2492
2490 def recover(self):
2493 def recover(self):
2491 with self.lock():
2494 with self.lock():
2492 if self.svfs.exists(b"journal"):
2495 if self.svfs.exists(b"journal"):
2493 self.ui.status(_(b"rolling back interrupted transaction\n"))
2496 self.ui.status(_(b"rolling back interrupted transaction\n"))
2494 vfsmap = {
2497 vfsmap = {
2495 b'': self.svfs,
2498 b'': self.svfs,
2496 b'plain': self.vfs,
2499 b'plain': self.vfs,
2497 }
2500 }
2498 transaction.rollback(
2501 transaction.rollback(
2499 self.svfs,
2502 self.svfs,
2500 vfsmap,
2503 vfsmap,
2501 b"journal",
2504 b"journal",
2502 self.ui.warn,
2505 self.ui.warn,
2503 checkambigfiles=_cachedfiles,
2506 checkambigfiles=_cachedfiles,
2504 )
2507 )
2505 self.invalidate()
2508 self.invalidate()
2506 return True
2509 return True
2507 else:
2510 else:
2508 self.ui.warn(_(b"no interrupted transaction available\n"))
2511 self.ui.warn(_(b"no interrupted transaction available\n"))
2509 return False
2512 return False
2510
2513
2511 def rollback(self, dryrun=False, force=False):
2514 def rollback(self, dryrun=False, force=False):
2512 wlock = lock = dsguard = None
2515 wlock = lock = dsguard = None
2513 try:
2516 try:
2514 wlock = self.wlock()
2517 wlock = self.wlock()
2515 lock = self.lock()
2518 lock = self.lock()
2516 if self.svfs.exists(b"undo"):
2519 if self.svfs.exists(b"undo"):
2517 dsguard = dirstateguard.dirstateguard(self, b'rollback')
2520 dsguard = dirstateguard.dirstateguard(self, b'rollback')
2518
2521
2519 return self._rollback(dryrun, force, dsguard)
2522 return self._rollback(dryrun, force, dsguard)
2520 else:
2523 else:
2521 self.ui.warn(_(b"no rollback information available\n"))
2524 self.ui.warn(_(b"no rollback information available\n"))
2522 return 1
2525 return 1
2523 finally:
2526 finally:
2524 release(dsguard, lock, wlock)
2527 release(dsguard, lock, wlock)
2525
2528
2526 @unfilteredmethod # Until we get smarter cache management
2529 @unfilteredmethod # Until we get smarter cache management
2527 def _rollback(self, dryrun, force, dsguard):
2530 def _rollback(self, dryrun, force, dsguard):
2528 ui = self.ui
2531 ui = self.ui
2529 try:
2532 try:
2530 args = self.vfs.read(b'undo.desc').splitlines()
2533 args = self.vfs.read(b'undo.desc').splitlines()
2531 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2534 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2532 if len(args) >= 3:
2535 if len(args) >= 3:
2533 detail = args[2]
2536 detail = args[2]
2534 oldtip = oldlen - 1
2537 oldtip = oldlen - 1
2535
2538
2536 if detail and ui.verbose:
2539 if detail and ui.verbose:
2537 msg = _(
2540 msg = _(
2538 b'repository tip rolled back to revision %d'
2541 b'repository tip rolled back to revision %d'
2539 b' (undo %s: %s)\n'
2542 b' (undo %s: %s)\n'
2540 ) % (oldtip, desc, detail)
2543 ) % (oldtip, desc, detail)
2541 else:
2544 else:
2542 msg = _(
2545 msg = _(
2543 b'repository tip rolled back to revision %d (undo %s)\n'
2546 b'repository tip rolled back to revision %d (undo %s)\n'
2544 ) % (oldtip, desc)
2547 ) % (oldtip, desc)
2545 except IOError:
2548 except IOError:
2546 msg = _(b'rolling back unknown transaction\n')
2549 msg = _(b'rolling back unknown transaction\n')
2547 desc = None
2550 desc = None
2548
2551
2549 if not force and self[b'.'] != self[b'tip'] and desc == b'commit':
2552 if not force and self[b'.'] != self[b'tip'] and desc == b'commit':
2550 raise error.Abort(
2553 raise error.Abort(
2551 _(
2554 _(
2552 b'rollback of last commit while not checked out '
2555 b'rollback of last commit while not checked out '
2553 b'may lose data'
2556 b'may lose data'
2554 ),
2557 ),
2555 hint=_(b'use -f to force'),
2558 hint=_(b'use -f to force'),
2556 )
2559 )
2557
2560
2558 ui.status(msg)
2561 ui.status(msg)
2559 if dryrun:
2562 if dryrun:
2560 return 0
2563 return 0
2561
2564
2562 parents = self.dirstate.parents()
2565 parents = self.dirstate.parents()
2563 self.destroying()
2566 self.destroying()
2564 vfsmap = {b'plain': self.vfs, b'': self.svfs}
2567 vfsmap = {b'plain': self.vfs, b'': self.svfs}
2565 transaction.rollback(
2568 transaction.rollback(
2566 self.svfs, vfsmap, b'undo', ui.warn, checkambigfiles=_cachedfiles
2569 self.svfs, vfsmap, b'undo', ui.warn, checkambigfiles=_cachedfiles
2567 )
2570 )
2568 bookmarksvfs = bookmarks.bookmarksvfs(self)
2571 bookmarksvfs = bookmarks.bookmarksvfs(self)
2569 if bookmarksvfs.exists(b'undo.bookmarks'):
2572 if bookmarksvfs.exists(b'undo.bookmarks'):
2570 bookmarksvfs.rename(
2573 bookmarksvfs.rename(
2571 b'undo.bookmarks', b'bookmarks', checkambig=True
2574 b'undo.bookmarks', b'bookmarks', checkambig=True
2572 )
2575 )
2573 if self.svfs.exists(b'undo.phaseroots'):
2576 if self.svfs.exists(b'undo.phaseroots'):
2574 self.svfs.rename(b'undo.phaseroots', b'phaseroots', checkambig=True)
2577 self.svfs.rename(b'undo.phaseroots', b'phaseroots', checkambig=True)
2575 self.invalidate()
2578 self.invalidate()
2576
2579
2577 has_node = self.changelog.index.has_node
2580 has_node = self.changelog.index.has_node
2578 parentgone = any(not has_node(p) for p in parents)
2581 parentgone = any(not has_node(p) for p in parents)
2579 if parentgone:
2582 if parentgone:
2580 # prevent dirstateguard from overwriting already restored one
2583 # prevent dirstateguard from overwriting already restored one
2581 dsguard.close()
2584 dsguard.close()
2582
2585
2583 narrowspec.restorebackup(self, b'undo.narrowspec')
2586 narrowspec.restorebackup(self, b'undo.narrowspec')
2584 narrowspec.restorewcbackup(self, b'undo.narrowspec.dirstate')
2587 narrowspec.restorewcbackup(self, b'undo.narrowspec.dirstate')
2585 self.dirstate.restorebackup(None, b'undo.dirstate')
2588 self.dirstate.restorebackup(None, b'undo.dirstate')
2586 try:
2589 try:
2587 branch = self.vfs.read(b'undo.branch')
2590 branch = self.vfs.read(b'undo.branch')
2588 self.dirstate.setbranch(encoding.tolocal(branch))
2591 self.dirstate.setbranch(encoding.tolocal(branch))
2589 except IOError:
2592 except IOError:
2590 ui.warn(
2593 ui.warn(
2591 _(
2594 _(
2592 b'named branch could not be reset: '
2595 b'named branch could not be reset: '
2593 b'current branch is still \'%s\'\n'
2596 b'current branch is still \'%s\'\n'
2594 )
2597 )
2595 % self.dirstate.branch()
2598 % self.dirstate.branch()
2596 )
2599 )
2597
2600
2598 parents = tuple([p.rev() for p in self[None].parents()])
2601 parents = tuple([p.rev() for p in self[None].parents()])
2599 if len(parents) > 1:
2602 if len(parents) > 1:
2600 ui.status(
2603 ui.status(
2601 _(
2604 _(
2602 b'working directory now based on '
2605 b'working directory now based on '
2603 b'revisions %d and %d\n'
2606 b'revisions %d and %d\n'
2604 )
2607 )
2605 % parents
2608 % parents
2606 )
2609 )
2607 else:
2610 else:
2608 ui.status(
2611 ui.status(
2609 _(b'working directory now based on revision %d\n') % parents
2612 _(b'working directory now based on revision %d\n') % parents
2610 )
2613 )
2611 mergestatemod.mergestate.clean(self)
2614 mergestatemod.mergestate.clean(self)
2612
2615
2613 # TODO: if we know which new heads may result from this rollback, pass
2616 # TODO: if we know which new heads may result from this rollback, pass
2614 # them to destroy(), which will prevent the branchhead cache from being
2617 # them to destroy(), which will prevent the branchhead cache from being
2615 # invalidated.
2618 # invalidated.
2616 self.destroyed()
2619 self.destroyed()
2617 return 0
2620 return 0
2618
2621
2619 def _buildcacheupdater(self, newtransaction):
2622 def _buildcacheupdater(self, newtransaction):
2620 """called during transaction to build the callback updating cache
2623 """called during transaction to build the callback updating cache
2621
2624
2622 Lives on the repository to help extension who might want to augment
2625 Lives on the repository to help extension who might want to augment
2623 this logic. For this purpose, the created transaction is passed to the
2626 this logic. For this purpose, the created transaction is passed to the
2624 method.
2627 method.
2625 """
2628 """
2626 # we must avoid cyclic reference between repo and transaction.
2629 # we must avoid cyclic reference between repo and transaction.
2627 reporef = weakref.ref(self)
2630 reporef = weakref.ref(self)
2628
2631
2629 def updater(tr):
2632 def updater(tr):
2630 repo = reporef()
2633 repo = reporef()
2631 repo.updatecaches(tr)
2634 repo.updatecaches(tr)
2632
2635
2633 return updater
2636 return updater
2634
2637
2635 @unfilteredmethod
2638 @unfilteredmethod
2636 def updatecaches(self, tr=None, full=False):
2639 def updatecaches(self, tr=None, full=False):
2637 """warm appropriate caches
2640 """warm appropriate caches
2638
2641
2639 If this function is called after a transaction closed. The transaction
2642 If this function is called after a transaction closed. The transaction
2640 will be available in the 'tr' argument. This can be used to selectively
2643 will be available in the 'tr' argument. This can be used to selectively
2641 update caches relevant to the changes in that transaction.
2644 update caches relevant to the changes in that transaction.
2642
2645
2643 If 'full' is set, make sure all caches the function knows about have
2646 If 'full' is set, make sure all caches the function knows about have
2644 up-to-date data. Even the ones usually loaded more lazily.
2647 up-to-date data. Even the ones usually loaded more lazily.
2645 """
2648 """
2646 if tr is not None and tr.hookargs.get(b'source') == b'strip':
2649 if tr is not None and tr.hookargs.get(b'source') == b'strip':
2647 # During strip, many caches are invalid but
2650 # During strip, many caches are invalid but
2648 # later call to `destroyed` will refresh them.
2651 # later call to `destroyed` will refresh them.
2649 return
2652 return
2650
2653
2651 if tr is None or tr.changes[b'origrepolen'] < len(self):
2654 if tr is None or tr.changes[b'origrepolen'] < len(self):
2652 # accessing the 'served' branchmap should refresh all the others,
2655 # accessing the 'served' branchmap should refresh all the others,
2653 self.ui.debug(b'updating the branch cache\n')
2656 self.ui.debug(b'updating the branch cache\n')
2654 self.filtered(b'served').branchmap()
2657 self.filtered(b'served').branchmap()
2655 self.filtered(b'served.hidden').branchmap()
2658 self.filtered(b'served.hidden').branchmap()
2656
2659
2657 if full:
2660 if full:
2658 unfi = self.unfiltered()
2661 unfi = self.unfiltered()
2659
2662
2660 self.changelog.update_caches(transaction=tr)
2663 self.changelog.update_caches(transaction=tr)
2661 self.manifestlog.update_caches(transaction=tr)
2664 self.manifestlog.update_caches(transaction=tr)
2662
2665
2663 rbc = unfi.revbranchcache()
2666 rbc = unfi.revbranchcache()
2664 for r in unfi.changelog:
2667 for r in unfi.changelog:
2665 rbc.branchinfo(r)
2668 rbc.branchinfo(r)
2666 rbc.write()
2669 rbc.write()
2667
2670
2668 # ensure the working copy parents are in the manifestfulltextcache
2671 # ensure the working copy parents are in the manifestfulltextcache
2669 for ctx in self[b'.'].parents():
2672 for ctx in self[b'.'].parents():
2670 ctx.manifest() # accessing the manifest is enough
2673 ctx.manifest() # accessing the manifest is enough
2671
2674
2672 # accessing fnode cache warms the cache
2675 # accessing fnode cache warms the cache
2673 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2676 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2674 # accessing tags warm the cache
2677 # accessing tags warm the cache
2675 self.tags()
2678 self.tags()
2676 self.filtered(b'served').tags()
2679 self.filtered(b'served').tags()
2677
2680
2678 # The `full` arg is documented as updating even the lazily-loaded
2681 # The `full` arg is documented as updating even the lazily-loaded
2679 # caches immediately, so we're forcing a write to cause these caches
2682 # caches immediately, so we're forcing a write to cause these caches
2680 # to be warmed up even if they haven't explicitly been requested
2683 # to be warmed up even if they haven't explicitly been requested
2681 # yet (if they've never been used by hg, they won't ever have been
2684 # yet (if they've never been used by hg, they won't ever have been
2682 # written, even if they're a subset of another kind of cache that
2685 # written, even if they're a subset of another kind of cache that
2683 # *has* been used).
2686 # *has* been used).
2684 for filt in repoview.filtertable.keys():
2687 for filt in repoview.filtertable.keys():
2685 filtered = self.filtered(filt)
2688 filtered = self.filtered(filt)
2686 filtered.branchmap().write(filtered)
2689 filtered.branchmap().write(filtered)
2687
2690
2688 def invalidatecaches(self):
2691 def invalidatecaches(self):
2689
2692
2690 if '_tagscache' in vars(self):
2693 if '_tagscache' in vars(self):
2691 # can't use delattr on proxy
2694 # can't use delattr on proxy
2692 del self.__dict__['_tagscache']
2695 del self.__dict__['_tagscache']
2693
2696
2694 self._branchcaches.clear()
2697 self._branchcaches.clear()
2695 self.invalidatevolatilesets()
2698 self.invalidatevolatilesets()
2696 self._sparsesignaturecache.clear()
2699 self._sparsesignaturecache.clear()
2697
2700
2698 def invalidatevolatilesets(self):
2701 def invalidatevolatilesets(self):
2699 self.filteredrevcache.clear()
2702 self.filteredrevcache.clear()
2700 obsolete.clearobscaches(self)
2703 obsolete.clearobscaches(self)
2701 self._quick_access_changeid_invalidate()
2704 self._quick_access_changeid_invalidate()
2702
2705
2703 def invalidatedirstate(self):
2706 def invalidatedirstate(self):
2704 """Invalidates the dirstate, causing the next call to dirstate
2707 """Invalidates the dirstate, causing the next call to dirstate
2705 to check if it was modified since the last time it was read,
2708 to check if it was modified since the last time it was read,
2706 rereading it if it has.
2709 rereading it if it has.
2707
2710
2708 This is different to dirstate.invalidate() that it doesn't always
2711 This is different to dirstate.invalidate() that it doesn't always
2709 rereads the dirstate. Use dirstate.invalidate() if you want to
2712 rereads the dirstate. Use dirstate.invalidate() if you want to
2710 explicitly read the dirstate again (i.e. restoring it to a previous
2713 explicitly read the dirstate again (i.e. restoring it to a previous
2711 known good state)."""
2714 known good state)."""
2712 if hasunfilteredcache(self, 'dirstate'):
2715 if hasunfilteredcache(self, 'dirstate'):
2713 for k in self.dirstate._filecache:
2716 for k in self.dirstate._filecache:
2714 try:
2717 try:
2715 delattr(self.dirstate, k)
2718 delattr(self.dirstate, k)
2716 except AttributeError:
2719 except AttributeError:
2717 pass
2720 pass
2718 delattr(self.unfiltered(), 'dirstate')
2721 delattr(self.unfiltered(), 'dirstate')
2719
2722
2720 def invalidate(self, clearfilecache=False):
2723 def invalidate(self, clearfilecache=False):
2721 """Invalidates both store and non-store parts other than dirstate
2724 """Invalidates both store and non-store parts other than dirstate
2722
2725
2723 If a transaction is running, invalidation of store is omitted,
2726 If a transaction is running, invalidation of store is omitted,
2724 because discarding in-memory changes might cause inconsistency
2727 because discarding in-memory changes might cause inconsistency
2725 (e.g. incomplete fncache causes unintentional failure, but
2728 (e.g. incomplete fncache causes unintentional failure, but
2726 redundant one doesn't).
2729 redundant one doesn't).
2727 """
2730 """
2728 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2731 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2729 for k in list(self._filecache.keys()):
2732 for k in list(self._filecache.keys()):
2730 # dirstate is invalidated separately in invalidatedirstate()
2733 # dirstate is invalidated separately in invalidatedirstate()
2731 if k == b'dirstate':
2734 if k == b'dirstate':
2732 continue
2735 continue
2733 if (
2736 if (
2734 k == b'changelog'
2737 k == b'changelog'
2735 and self.currenttransaction()
2738 and self.currenttransaction()
2736 and self.changelog._delayed
2739 and self.changelog._delayed
2737 ):
2740 ):
2738 # The changelog object may store unwritten revisions. We don't
2741 # The changelog object may store unwritten revisions. We don't
2739 # want to lose them.
2742 # want to lose them.
2740 # TODO: Solve the problem instead of working around it.
2743 # TODO: Solve the problem instead of working around it.
2741 continue
2744 continue
2742
2745
2743 if clearfilecache:
2746 if clearfilecache:
2744 del self._filecache[k]
2747 del self._filecache[k]
2745 try:
2748 try:
2746 delattr(unfiltered, k)
2749 delattr(unfiltered, k)
2747 except AttributeError:
2750 except AttributeError:
2748 pass
2751 pass
2749 self.invalidatecaches()
2752 self.invalidatecaches()
2750 if not self.currenttransaction():
2753 if not self.currenttransaction():
2751 # TODO: Changing contents of store outside transaction
2754 # TODO: Changing contents of store outside transaction
2752 # causes inconsistency. We should make in-memory store
2755 # causes inconsistency. We should make in-memory store
2753 # changes detectable, and abort if changed.
2756 # changes detectable, and abort if changed.
2754 self.store.invalidatecaches()
2757 self.store.invalidatecaches()
2755
2758
2756 def invalidateall(self):
2759 def invalidateall(self):
2757 """Fully invalidates both store and non-store parts, causing the
2760 """Fully invalidates both store and non-store parts, causing the
2758 subsequent operation to reread any outside changes."""
2761 subsequent operation to reread any outside changes."""
2759 # extension should hook this to invalidate its caches
2762 # extension should hook this to invalidate its caches
2760 self.invalidate()
2763 self.invalidate()
2761 self.invalidatedirstate()
2764 self.invalidatedirstate()
2762
2765
2763 @unfilteredmethod
2766 @unfilteredmethod
2764 def _refreshfilecachestats(self, tr):
2767 def _refreshfilecachestats(self, tr):
2765 """Reload stats of cached files so that they are flagged as valid"""
2768 """Reload stats of cached files so that they are flagged as valid"""
2766 for k, ce in self._filecache.items():
2769 for k, ce in self._filecache.items():
2767 k = pycompat.sysstr(k)
2770 k = pycompat.sysstr(k)
2768 if k == 'dirstate' or k not in self.__dict__:
2771 if k == 'dirstate' or k not in self.__dict__:
2769 continue
2772 continue
2770 ce.refresh()
2773 ce.refresh()
2771
2774
2772 def _lock(
2775 def _lock(
2773 self,
2776 self,
2774 vfs,
2777 vfs,
2775 lockname,
2778 lockname,
2776 wait,
2779 wait,
2777 releasefn,
2780 releasefn,
2778 acquirefn,
2781 acquirefn,
2779 desc,
2782 desc,
2780 ):
2783 ):
2781 timeout = 0
2784 timeout = 0
2782 warntimeout = 0
2785 warntimeout = 0
2783 if wait:
2786 if wait:
2784 timeout = self.ui.configint(b"ui", b"timeout")
2787 timeout = self.ui.configint(b"ui", b"timeout")
2785 warntimeout = self.ui.configint(b"ui", b"timeout.warn")
2788 warntimeout = self.ui.configint(b"ui", b"timeout.warn")
2786 # internal config: ui.signal-safe-lock
2789 # internal config: ui.signal-safe-lock
2787 signalsafe = self.ui.configbool(b'ui', b'signal-safe-lock')
2790 signalsafe = self.ui.configbool(b'ui', b'signal-safe-lock')
2788
2791
2789 l = lockmod.trylock(
2792 l = lockmod.trylock(
2790 self.ui,
2793 self.ui,
2791 vfs,
2794 vfs,
2792 lockname,
2795 lockname,
2793 timeout,
2796 timeout,
2794 warntimeout,
2797 warntimeout,
2795 releasefn=releasefn,
2798 releasefn=releasefn,
2796 acquirefn=acquirefn,
2799 acquirefn=acquirefn,
2797 desc=desc,
2800 desc=desc,
2798 signalsafe=signalsafe,
2801 signalsafe=signalsafe,
2799 )
2802 )
2800 return l
2803 return l
2801
2804
2802 def _afterlock(self, callback):
2805 def _afterlock(self, callback):
2803 """add a callback to be run when the repository is fully unlocked
2806 """add a callback to be run when the repository is fully unlocked
2804
2807
2805 The callback will be executed when the outermost lock is released
2808 The callback will be executed when the outermost lock is released
2806 (with wlock being higher level than 'lock')."""
2809 (with wlock being higher level than 'lock')."""
2807 for ref in (self._wlockref, self._lockref):
2810 for ref in (self._wlockref, self._lockref):
2808 l = ref and ref()
2811 l = ref and ref()
2809 if l and l.held:
2812 if l and l.held:
2810 l.postrelease.append(callback)
2813 l.postrelease.append(callback)
2811 break
2814 break
2812 else: # no lock have been found.
2815 else: # no lock have been found.
2813 callback(True)
2816 callback(True)
2814
2817
2815 def lock(self, wait=True):
2818 def lock(self, wait=True):
2816 """Lock the repository store (.hg/store) and return a weak reference
2819 """Lock the repository store (.hg/store) and return a weak reference
2817 to the lock. Use this before modifying the store (e.g. committing or
2820 to the lock. Use this before modifying the store (e.g. committing or
2818 stripping). If you are opening a transaction, get a lock as well.)
2821 stripping). If you are opening a transaction, get a lock as well.)
2819
2822
2820 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2823 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2821 'wlock' first to avoid a dead-lock hazard."""
2824 'wlock' first to avoid a dead-lock hazard."""
2822 l = self._currentlock(self._lockref)
2825 l = self._currentlock(self._lockref)
2823 if l is not None:
2826 if l is not None:
2824 l.lock()
2827 l.lock()
2825 return l
2828 return l
2826
2829
2827 l = self._lock(
2830 l = self._lock(
2828 vfs=self.svfs,
2831 vfs=self.svfs,
2829 lockname=b"lock",
2832 lockname=b"lock",
2830 wait=wait,
2833 wait=wait,
2831 releasefn=None,
2834 releasefn=None,
2832 acquirefn=self.invalidate,
2835 acquirefn=self.invalidate,
2833 desc=_(b'repository %s') % self.origroot,
2836 desc=_(b'repository %s') % self.origroot,
2834 )
2837 )
2835 self._lockref = weakref.ref(l)
2838 self._lockref = weakref.ref(l)
2836 return l
2839 return l
2837
2840
2838 def wlock(self, wait=True):
2841 def wlock(self, wait=True):
2839 """Lock the non-store parts of the repository (everything under
2842 """Lock the non-store parts of the repository (everything under
2840 .hg except .hg/store) and return a weak reference to the lock.
2843 .hg except .hg/store) and return a weak reference to the lock.
2841
2844
2842 Use this before modifying files in .hg.
2845 Use this before modifying files in .hg.
2843
2846
2844 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2847 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2845 'wlock' first to avoid a dead-lock hazard."""
2848 'wlock' first to avoid a dead-lock hazard."""
2846 l = self._wlockref and self._wlockref()
2849 l = self._wlockref and self._wlockref()
2847 if l is not None and l.held:
2850 if l is not None and l.held:
2848 l.lock()
2851 l.lock()
2849 return l
2852 return l
2850
2853
2851 # We do not need to check for non-waiting lock acquisition. Such
2854 # We do not need to check for non-waiting lock acquisition. Such
2852 # acquisition would not cause dead-lock as they would just fail.
2855 # acquisition would not cause dead-lock as they would just fail.
2853 if wait and (
2856 if wait and (
2854 self.ui.configbool(b'devel', b'all-warnings')
2857 self.ui.configbool(b'devel', b'all-warnings')
2855 or self.ui.configbool(b'devel', b'check-locks')
2858 or self.ui.configbool(b'devel', b'check-locks')
2856 ):
2859 ):
2857 if self._currentlock(self._lockref) is not None:
2860 if self._currentlock(self._lockref) is not None:
2858 self.ui.develwarn(b'"wlock" acquired after "lock"')
2861 self.ui.develwarn(b'"wlock" acquired after "lock"')
2859
2862
2860 def unlock():
2863 def unlock():
2861 if self.dirstate.pendingparentchange():
2864 if self.dirstate.pendingparentchange():
2862 self.dirstate.invalidate()
2865 self.dirstate.invalidate()
2863 else:
2866 else:
2864 self.dirstate.write(None)
2867 self.dirstate.write(None)
2865
2868
2866 self._filecache[b'dirstate'].refresh()
2869 self._filecache[b'dirstate'].refresh()
2867
2870
2868 l = self._lock(
2871 l = self._lock(
2869 self.vfs,
2872 self.vfs,
2870 b"wlock",
2873 b"wlock",
2871 wait,
2874 wait,
2872 unlock,
2875 unlock,
2873 self.invalidatedirstate,
2876 self.invalidatedirstate,
2874 _(b'working directory of %s') % self.origroot,
2877 _(b'working directory of %s') % self.origroot,
2875 )
2878 )
2876 self._wlockref = weakref.ref(l)
2879 self._wlockref = weakref.ref(l)
2877 return l
2880 return l
2878
2881
2879 def _currentlock(self, lockref):
2882 def _currentlock(self, lockref):
2880 """Returns the lock if it's held, or None if it's not."""
2883 """Returns the lock if it's held, or None if it's not."""
2881 if lockref is None:
2884 if lockref is None:
2882 return None
2885 return None
2883 l = lockref()
2886 l = lockref()
2884 if l is None or not l.held:
2887 if l is None or not l.held:
2885 return None
2888 return None
2886 return l
2889 return l
2887
2890
2888 def currentwlock(self):
2891 def currentwlock(self):
2889 """Returns the wlock if it's held, or None if it's not."""
2892 """Returns the wlock if it's held, or None if it's not."""
2890 return self._currentlock(self._wlockref)
2893 return self._currentlock(self._wlockref)
2891
2894
2892 def checkcommitpatterns(self, wctx, match, status, fail):
2895 def checkcommitpatterns(self, wctx, match, status, fail):
2893 """check for commit arguments that aren't committable"""
2896 """check for commit arguments that aren't committable"""
2894 if match.isexact() or match.prefix():
2897 if match.isexact() or match.prefix():
2895 matched = set(status.modified + status.added + status.removed)
2898 matched = set(status.modified + status.added + status.removed)
2896
2899
2897 for f in match.files():
2900 for f in match.files():
2898 f = self.dirstate.normalize(f)
2901 f = self.dirstate.normalize(f)
2899 if f == b'.' or f in matched or f in wctx.substate:
2902 if f == b'.' or f in matched or f in wctx.substate:
2900 continue
2903 continue
2901 if f in status.deleted:
2904 if f in status.deleted:
2902 fail(f, _(b'file not found!'))
2905 fail(f, _(b'file not found!'))
2903 # Is it a directory that exists or used to exist?
2906 # Is it a directory that exists or used to exist?
2904 if self.wvfs.isdir(f) or wctx.p1().hasdir(f):
2907 if self.wvfs.isdir(f) or wctx.p1().hasdir(f):
2905 d = f + b'/'
2908 d = f + b'/'
2906 for mf in matched:
2909 for mf in matched:
2907 if mf.startswith(d):
2910 if mf.startswith(d):
2908 break
2911 break
2909 else:
2912 else:
2910 fail(f, _(b"no match under directory!"))
2913 fail(f, _(b"no match under directory!"))
2911 elif f not in self.dirstate:
2914 elif f not in self.dirstate:
2912 fail(f, _(b"file not tracked!"))
2915 fail(f, _(b"file not tracked!"))
2913
2916
2914 @unfilteredmethod
2917 @unfilteredmethod
2915 def commit(
2918 def commit(
2916 self,
2919 self,
2917 text=b"",
2920 text=b"",
2918 user=None,
2921 user=None,
2919 date=None,
2922 date=None,
2920 match=None,
2923 match=None,
2921 force=False,
2924 force=False,
2922 editor=None,
2925 editor=None,
2923 extra=None,
2926 extra=None,
2924 ):
2927 ):
2925 """Add a new revision to current repository.
2928 """Add a new revision to current repository.
2926
2929
2927 Revision information is gathered from the working directory,
2930 Revision information is gathered from the working directory,
2928 match can be used to filter the committed files. If editor is
2931 match can be used to filter the committed files. If editor is
2929 supplied, it is called to get a commit message.
2932 supplied, it is called to get a commit message.
2930 """
2933 """
2931 if extra is None:
2934 if extra is None:
2932 extra = {}
2935 extra = {}
2933
2936
2934 def fail(f, msg):
2937 def fail(f, msg):
2935 raise error.InputError(b'%s: %s' % (f, msg))
2938 raise error.InputError(b'%s: %s' % (f, msg))
2936
2939
2937 if not match:
2940 if not match:
2938 match = matchmod.always()
2941 match = matchmod.always()
2939
2942
2940 if not force:
2943 if not force:
2941 match.bad = fail
2944 match.bad = fail
2942
2945
2943 # lock() for recent changelog (see issue4368)
2946 # lock() for recent changelog (see issue4368)
2944 with self.wlock(), self.lock():
2947 with self.wlock(), self.lock():
2945 wctx = self[None]
2948 wctx = self[None]
2946 merge = len(wctx.parents()) > 1
2949 merge = len(wctx.parents()) > 1
2947
2950
2948 if not force and merge and not match.always():
2951 if not force and merge and not match.always():
2949 raise error.Abort(
2952 raise error.Abort(
2950 _(
2953 _(
2951 b'cannot partially commit a merge '
2954 b'cannot partially commit a merge '
2952 b'(do not specify files or patterns)'
2955 b'(do not specify files or patterns)'
2953 )
2956 )
2954 )
2957 )
2955
2958
2956 status = self.status(match=match, clean=force)
2959 status = self.status(match=match, clean=force)
2957 if force:
2960 if force:
2958 status.modified.extend(
2961 status.modified.extend(
2959 status.clean
2962 status.clean
2960 ) # mq may commit clean files
2963 ) # mq may commit clean files
2961
2964
2962 # check subrepos
2965 # check subrepos
2963 subs, commitsubs, newstate = subrepoutil.precommit(
2966 subs, commitsubs, newstate = subrepoutil.precommit(
2964 self.ui, wctx, status, match, force=force
2967 self.ui, wctx, status, match, force=force
2965 )
2968 )
2966
2969
2967 # make sure all explicit patterns are matched
2970 # make sure all explicit patterns are matched
2968 if not force:
2971 if not force:
2969 self.checkcommitpatterns(wctx, match, status, fail)
2972 self.checkcommitpatterns(wctx, match, status, fail)
2970
2973
2971 cctx = context.workingcommitctx(
2974 cctx = context.workingcommitctx(
2972 self, status, text, user, date, extra
2975 self, status, text, user, date, extra
2973 )
2976 )
2974
2977
2975 ms = mergestatemod.mergestate.read(self)
2978 ms = mergestatemod.mergestate.read(self)
2976 mergeutil.checkunresolved(ms)
2979 mergeutil.checkunresolved(ms)
2977
2980
2978 # internal config: ui.allowemptycommit
2981 # internal config: ui.allowemptycommit
2979 if cctx.isempty() and not self.ui.configbool(
2982 if cctx.isempty() and not self.ui.configbool(
2980 b'ui', b'allowemptycommit'
2983 b'ui', b'allowemptycommit'
2981 ):
2984 ):
2982 self.ui.debug(b'nothing to commit, clearing merge state\n')
2985 self.ui.debug(b'nothing to commit, clearing merge state\n')
2983 ms.reset()
2986 ms.reset()
2984 return None
2987 return None
2985
2988
2986 if merge and cctx.deleted():
2989 if merge and cctx.deleted():
2987 raise error.Abort(_(b"cannot commit merge with missing files"))
2990 raise error.Abort(_(b"cannot commit merge with missing files"))
2988
2991
2989 if editor:
2992 if editor:
2990 cctx._text = editor(self, cctx, subs)
2993 cctx._text = editor(self, cctx, subs)
2991 edited = text != cctx._text
2994 edited = text != cctx._text
2992
2995
2993 # Save commit message in case this transaction gets rolled back
2996 # Save commit message in case this transaction gets rolled back
2994 # (e.g. by a pretxncommit hook). Leave the content alone on
2997 # (e.g. by a pretxncommit hook). Leave the content alone on
2995 # the assumption that the user will use the same editor again.
2998 # the assumption that the user will use the same editor again.
2996 msgfn = self.savecommitmessage(cctx._text)
2999 msgfn = self.savecommitmessage(cctx._text)
2997
3000
2998 # commit subs and write new state
3001 # commit subs and write new state
2999 if subs:
3002 if subs:
3000 uipathfn = scmutil.getuipathfn(self)
3003 uipathfn = scmutil.getuipathfn(self)
3001 for s in sorted(commitsubs):
3004 for s in sorted(commitsubs):
3002 sub = wctx.sub(s)
3005 sub = wctx.sub(s)
3003 self.ui.status(
3006 self.ui.status(
3004 _(b'committing subrepository %s\n')
3007 _(b'committing subrepository %s\n')
3005 % uipathfn(subrepoutil.subrelpath(sub))
3008 % uipathfn(subrepoutil.subrelpath(sub))
3006 )
3009 )
3007 sr = sub.commit(cctx._text, user, date)
3010 sr = sub.commit(cctx._text, user, date)
3008 newstate[s] = (newstate[s][0], sr)
3011 newstate[s] = (newstate[s][0], sr)
3009 subrepoutil.writestate(self, newstate)
3012 subrepoutil.writestate(self, newstate)
3010
3013
3011 p1, p2 = self.dirstate.parents()
3014 p1, p2 = self.dirstate.parents()
3012 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or b'')
3015 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or b'')
3013 try:
3016 try:
3014 self.hook(
3017 self.hook(
3015 b"precommit", throw=True, parent1=hookp1, parent2=hookp2
3018 b"precommit", throw=True, parent1=hookp1, parent2=hookp2
3016 )
3019 )
3017 with self.transaction(b'commit'):
3020 with self.transaction(b'commit'):
3018 ret = self.commitctx(cctx, True)
3021 ret = self.commitctx(cctx, True)
3019 # update bookmarks, dirstate and mergestate
3022 # update bookmarks, dirstate and mergestate
3020 bookmarks.update(self, [p1, p2], ret)
3023 bookmarks.update(self, [p1, p2], ret)
3021 cctx.markcommitted(ret)
3024 cctx.markcommitted(ret)
3022 ms.reset()
3025 ms.reset()
3023 except: # re-raises
3026 except: # re-raises
3024 if edited:
3027 if edited:
3025 self.ui.write(
3028 self.ui.write(
3026 _(b'note: commit message saved in %s\n') % msgfn
3029 _(b'note: commit message saved in %s\n') % msgfn
3027 )
3030 )
3028 self.ui.write(
3031 self.ui.write(
3029 _(
3032 _(
3030 b"note: use 'hg commit --logfile "
3033 b"note: use 'hg commit --logfile "
3031 b".hg/last-message.txt --edit' to reuse it\n"
3034 b".hg/last-message.txt --edit' to reuse it\n"
3032 )
3035 )
3033 )
3036 )
3034 raise
3037 raise
3035
3038
3036 def commithook(unused_success):
3039 def commithook(unused_success):
3037 # hack for command that use a temporary commit (eg: histedit)
3040 # hack for command that use a temporary commit (eg: histedit)
3038 # temporary commit got stripped before hook release
3041 # temporary commit got stripped before hook release
3039 if self.changelog.hasnode(ret):
3042 if self.changelog.hasnode(ret):
3040 self.hook(
3043 self.hook(
3041 b"commit", node=hex(ret), parent1=hookp1, parent2=hookp2
3044 b"commit", node=hex(ret), parent1=hookp1, parent2=hookp2
3042 )
3045 )
3043
3046
3044 self._afterlock(commithook)
3047 self._afterlock(commithook)
3045 return ret
3048 return ret
3046
3049
3047 @unfilteredmethod
3050 @unfilteredmethod
3048 def commitctx(self, ctx, error=False, origctx=None):
3051 def commitctx(self, ctx, error=False, origctx=None):
3049 return commit.commitctx(self, ctx, error=error, origctx=origctx)
3052 return commit.commitctx(self, ctx, error=error, origctx=origctx)
3050
3053
3051 @unfilteredmethod
3054 @unfilteredmethod
3052 def destroying(self):
3055 def destroying(self):
3053 """Inform the repository that nodes are about to be destroyed.
3056 """Inform the repository that nodes are about to be destroyed.
3054 Intended for use by strip and rollback, so there's a common
3057 Intended for use by strip and rollback, so there's a common
3055 place for anything that has to be done before destroying history.
3058 place for anything that has to be done before destroying history.
3056
3059
3057 This is mostly useful for saving state that is in memory and waiting
3060 This is mostly useful for saving state that is in memory and waiting
3058 to be flushed when the current lock is released. Because a call to
3061 to be flushed when the current lock is released. Because a call to
3059 destroyed is imminent, the repo will be invalidated causing those
3062 destroyed is imminent, the repo will be invalidated causing those
3060 changes to stay in memory (waiting for the next unlock), or vanish
3063 changes to stay in memory (waiting for the next unlock), or vanish
3061 completely.
3064 completely.
3062 """
3065 """
3063 # When using the same lock to commit and strip, the phasecache is left
3066 # When using the same lock to commit and strip, the phasecache is left
3064 # dirty after committing. Then when we strip, the repo is invalidated,
3067 # dirty after committing. Then when we strip, the repo is invalidated,
3065 # causing those changes to disappear.
3068 # causing those changes to disappear.
3066 if '_phasecache' in vars(self):
3069 if '_phasecache' in vars(self):
3067 self._phasecache.write()
3070 self._phasecache.write()
3068
3071
3069 @unfilteredmethod
3072 @unfilteredmethod
3070 def destroyed(self):
3073 def destroyed(self):
3071 """Inform the repository that nodes have been destroyed.
3074 """Inform the repository that nodes have been destroyed.
3072 Intended for use by strip and rollback, so there's a common
3075 Intended for use by strip and rollback, so there's a common
3073 place for anything that has to be done after destroying history.
3076 place for anything that has to be done after destroying history.
3074 """
3077 """
3075 # When one tries to:
3078 # When one tries to:
3076 # 1) destroy nodes thus calling this method (e.g. strip)
3079 # 1) destroy nodes thus calling this method (e.g. strip)
3077 # 2) use phasecache somewhere (e.g. commit)
3080 # 2) use phasecache somewhere (e.g. commit)
3078 #
3081 #
3079 # then 2) will fail because the phasecache contains nodes that were
3082 # then 2) will fail because the phasecache contains nodes that were
3080 # removed. We can either remove phasecache from the filecache,
3083 # removed. We can either remove phasecache from the filecache,
3081 # causing it to reload next time it is accessed, or simply filter
3084 # causing it to reload next time it is accessed, or simply filter
3082 # the removed nodes now and write the updated cache.
3085 # the removed nodes now and write the updated cache.
3083 self._phasecache.filterunknown(self)
3086 self._phasecache.filterunknown(self)
3084 self._phasecache.write()
3087 self._phasecache.write()
3085
3088
3086 # refresh all repository caches
3089 # refresh all repository caches
3087 self.updatecaches()
3090 self.updatecaches()
3088
3091
3089 # Ensure the persistent tag cache is updated. Doing it now
3092 # Ensure the persistent tag cache is updated. Doing it now
3090 # means that the tag cache only has to worry about destroyed
3093 # means that the tag cache only has to worry about destroyed
3091 # heads immediately after a strip/rollback. That in turn
3094 # heads immediately after a strip/rollback. That in turn
3092 # guarantees that "cachetip == currenttip" (comparing both rev
3095 # guarantees that "cachetip == currenttip" (comparing both rev
3093 # and node) always means no nodes have been added or destroyed.
3096 # and node) always means no nodes have been added or destroyed.
3094
3097
3095 # XXX this is suboptimal when qrefresh'ing: we strip the current
3098 # XXX this is suboptimal when qrefresh'ing: we strip the current
3096 # head, refresh the tag cache, then immediately add a new head.
3099 # head, refresh the tag cache, then immediately add a new head.
3097 # But I think doing it this way is necessary for the "instant
3100 # But I think doing it this way is necessary for the "instant
3098 # tag cache retrieval" case to work.
3101 # tag cache retrieval" case to work.
3099 self.invalidate()
3102 self.invalidate()
3100
3103
3101 def status(
3104 def status(
3102 self,
3105 self,
3103 node1=b'.',
3106 node1=b'.',
3104 node2=None,
3107 node2=None,
3105 match=None,
3108 match=None,
3106 ignored=False,
3109 ignored=False,
3107 clean=False,
3110 clean=False,
3108 unknown=False,
3111 unknown=False,
3109 listsubrepos=False,
3112 listsubrepos=False,
3110 ):
3113 ):
3111 '''a convenience method that calls node1.status(node2)'''
3114 '''a convenience method that calls node1.status(node2)'''
3112 return self[node1].status(
3115 return self[node1].status(
3113 node2, match, ignored, clean, unknown, listsubrepos
3116 node2, match, ignored, clean, unknown, listsubrepos
3114 )
3117 )
3115
3118
3116 def addpostdsstatus(self, ps):
3119 def addpostdsstatus(self, ps):
3117 """Add a callback to run within the wlock, at the point at which status
3120 """Add a callback to run within the wlock, at the point at which status
3118 fixups happen.
3121 fixups happen.
3119
3122
3120 On status completion, callback(wctx, status) will be called with the
3123 On status completion, callback(wctx, status) will be called with the
3121 wlock held, unless the dirstate has changed from underneath or the wlock
3124 wlock held, unless the dirstate has changed from underneath or the wlock
3122 couldn't be grabbed.
3125 couldn't be grabbed.
3123
3126
3124 Callbacks should not capture and use a cached copy of the dirstate --
3127 Callbacks should not capture and use a cached copy of the dirstate --
3125 it might change in the meanwhile. Instead, they should access the
3128 it might change in the meanwhile. Instead, they should access the
3126 dirstate via wctx.repo().dirstate.
3129 dirstate via wctx.repo().dirstate.
3127
3130
3128 This list is emptied out after each status run -- extensions should
3131 This list is emptied out after each status run -- extensions should
3129 make sure it adds to this list each time dirstate.status is called.
3132 make sure it adds to this list each time dirstate.status is called.
3130 Extensions should also make sure they don't call this for statuses
3133 Extensions should also make sure they don't call this for statuses
3131 that don't involve the dirstate.
3134 that don't involve the dirstate.
3132 """
3135 """
3133
3136
3134 # The list is located here for uniqueness reasons -- it is actually
3137 # The list is located here for uniqueness reasons -- it is actually
3135 # managed by the workingctx, but that isn't unique per-repo.
3138 # managed by the workingctx, but that isn't unique per-repo.
3136 self._postdsstatus.append(ps)
3139 self._postdsstatus.append(ps)
3137
3140
3138 def postdsstatus(self):
3141 def postdsstatus(self):
3139 """Used by workingctx to get the list of post-dirstate-status hooks."""
3142 """Used by workingctx to get the list of post-dirstate-status hooks."""
3140 return self._postdsstatus
3143 return self._postdsstatus
3141
3144
3142 def clearpostdsstatus(self):
3145 def clearpostdsstatus(self):
3143 """Used by workingctx to clear post-dirstate-status hooks."""
3146 """Used by workingctx to clear post-dirstate-status hooks."""
3144 del self._postdsstatus[:]
3147 del self._postdsstatus[:]
3145
3148
3146 def heads(self, start=None):
3149 def heads(self, start=None):
3147 if start is None:
3150 if start is None:
3148 cl = self.changelog
3151 cl = self.changelog
3149 headrevs = reversed(cl.headrevs())
3152 headrevs = reversed(cl.headrevs())
3150 return [cl.node(rev) for rev in headrevs]
3153 return [cl.node(rev) for rev in headrevs]
3151
3154
3152 heads = self.changelog.heads(start)
3155 heads = self.changelog.heads(start)
3153 # sort the output in rev descending order
3156 # sort the output in rev descending order
3154 return sorted(heads, key=self.changelog.rev, reverse=True)
3157 return sorted(heads, key=self.changelog.rev, reverse=True)
3155
3158
3156 def branchheads(self, branch=None, start=None, closed=False):
3159 def branchheads(self, branch=None, start=None, closed=False):
3157 """return a (possibly filtered) list of heads for the given branch
3160 """return a (possibly filtered) list of heads for the given branch
3158
3161
3159 Heads are returned in topological order, from newest to oldest.
3162 Heads are returned in topological order, from newest to oldest.
3160 If branch is None, use the dirstate branch.
3163 If branch is None, use the dirstate branch.
3161 If start is not None, return only heads reachable from start.
3164 If start is not None, return only heads reachable from start.
3162 If closed is True, return heads that are marked as closed as well.
3165 If closed is True, return heads that are marked as closed as well.
3163 """
3166 """
3164 if branch is None:
3167 if branch is None:
3165 branch = self[None].branch()
3168 branch = self[None].branch()
3166 branches = self.branchmap()
3169 branches = self.branchmap()
3167 if not branches.hasbranch(branch):
3170 if not branches.hasbranch(branch):
3168 return []
3171 return []
3169 # the cache returns heads ordered lowest to highest
3172 # the cache returns heads ordered lowest to highest
3170 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
3173 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
3171 if start is not None:
3174 if start is not None:
3172 # filter out the heads that cannot be reached from startrev
3175 # filter out the heads that cannot be reached from startrev
3173 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
3176 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
3174 bheads = [h for h in bheads if h in fbheads]
3177 bheads = [h for h in bheads if h in fbheads]
3175 return bheads
3178 return bheads
3176
3179
3177 def branches(self, nodes):
3180 def branches(self, nodes):
3178 if not nodes:
3181 if not nodes:
3179 nodes = [self.changelog.tip()]
3182 nodes = [self.changelog.tip()]
3180 b = []
3183 b = []
3181 for n in nodes:
3184 for n in nodes:
3182 t = n
3185 t = n
3183 while True:
3186 while True:
3184 p = self.changelog.parents(n)
3187 p = self.changelog.parents(n)
3185 if p[1] != nullid or p[0] == nullid:
3188 if p[1] != nullid or p[0] == nullid:
3186 b.append((t, n, p[0], p[1]))
3189 b.append((t, n, p[0], p[1]))
3187 break
3190 break
3188 n = p[0]
3191 n = p[0]
3189 return b
3192 return b
3190
3193
3191 def between(self, pairs):
3194 def between(self, pairs):
3192 r = []
3195 r = []
3193
3196
3194 for top, bottom in pairs:
3197 for top, bottom in pairs:
3195 n, l, i = top, [], 0
3198 n, l, i = top, [], 0
3196 f = 1
3199 f = 1
3197
3200
3198 while n != bottom and n != nullid:
3201 while n != bottom and n != nullid:
3199 p = self.changelog.parents(n)[0]
3202 p = self.changelog.parents(n)[0]
3200 if i == f:
3203 if i == f:
3201 l.append(n)
3204 l.append(n)
3202 f = f * 2
3205 f = f * 2
3203 n = p
3206 n = p
3204 i += 1
3207 i += 1
3205
3208
3206 r.append(l)
3209 r.append(l)
3207
3210
3208 return r
3211 return r
3209
3212
3210 def checkpush(self, pushop):
3213 def checkpush(self, pushop):
3211 """Extensions can override this function if additional checks have
3214 """Extensions can override this function if additional checks have
3212 to be performed before pushing, or call it if they override push
3215 to be performed before pushing, or call it if they override push
3213 command.
3216 command.
3214 """
3217 """
3215
3218
3216 @unfilteredpropertycache
3219 @unfilteredpropertycache
3217 def prepushoutgoinghooks(self):
3220 def prepushoutgoinghooks(self):
3218 """Return util.hooks consists of a pushop with repo, remote, outgoing
3221 """Return util.hooks consists of a pushop with repo, remote, outgoing
3219 methods, which are called before pushing changesets.
3222 methods, which are called before pushing changesets.
3220 """
3223 """
3221 return util.hooks()
3224 return util.hooks()
3222
3225
3223 def pushkey(self, namespace, key, old, new):
3226 def pushkey(self, namespace, key, old, new):
3224 try:
3227 try:
3225 tr = self.currenttransaction()
3228 tr = self.currenttransaction()
3226 hookargs = {}
3229 hookargs = {}
3227 if tr is not None:
3230 if tr is not None:
3228 hookargs.update(tr.hookargs)
3231 hookargs.update(tr.hookargs)
3229 hookargs = pycompat.strkwargs(hookargs)
3232 hookargs = pycompat.strkwargs(hookargs)
3230 hookargs['namespace'] = namespace
3233 hookargs['namespace'] = namespace
3231 hookargs['key'] = key
3234 hookargs['key'] = key
3232 hookargs['old'] = old
3235 hookargs['old'] = old
3233 hookargs['new'] = new
3236 hookargs['new'] = new
3234 self.hook(b'prepushkey', throw=True, **hookargs)
3237 self.hook(b'prepushkey', throw=True, **hookargs)
3235 except error.HookAbort as exc:
3238 except error.HookAbort as exc:
3236 self.ui.write_err(_(b"pushkey-abort: %s\n") % exc)
3239 self.ui.write_err(_(b"pushkey-abort: %s\n") % exc)
3237 if exc.hint:
3240 if exc.hint:
3238 self.ui.write_err(_(b"(%s)\n") % exc.hint)
3241 self.ui.write_err(_(b"(%s)\n") % exc.hint)
3239 return False
3242 return False
3240 self.ui.debug(b'pushing key for "%s:%s"\n' % (namespace, key))
3243 self.ui.debug(b'pushing key for "%s:%s"\n' % (namespace, key))
3241 ret = pushkey.push(self, namespace, key, old, new)
3244 ret = pushkey.push(self, namespace, key, old, new)
3242
3245
3243 def runhook(unused_success):
3246 def runhook(unused_success):
3244 self.hook(
3247 self.hook(
3245 b'pushkey',
3248 b'pushkey',
3246 namespace=namespace,
3249 namespace=namespace,
3247 key=key,
3250 key=key,
3248 old=old,
3251 old=old,
3249 new=new,
3252 new=new,
3250 ret=ret,
3253 ret=ret,
3251 )
3254 )
3252
3255
3253 self._afterlock(runhook)
3256 self._afterlock(runhook)
3254 return ret
3257 return ret
3255
3258
3256 def listkeys(self, namespace):
3259 def listkeys(self, namespace):
3257 self.hook(b'prelistkeys', throw=True, namespace=namespace)
3260 self.hook(b'prelistkeys', throw=True, namespace=namespace)
3258 self.ui.debug(b'listing keys for "%s"\n' % namespace)
3261 self.ui.debug(b'listing keys for "%s"\n' % namespace)
3259 values = pushkey.list(self, namespace)
3262 values = pushkey.list(self, namespace)
3260 self.hook(b'listkeys', namespace=namespace, values=values)
3263 self.hook(b'listkeys', namespace=namespace, values=values)
3261 return values
3264 return values
3262
3265
3263 def debugwireargs(self, one, two, three=None, four=None, five=None):
3266 def debugwireargs(self, one, two, three=None, four=None, five=None):
3264 '''used to test argument passing over the wire'''
3267 '''used to test argument passing over the wire'''
3265 return b"%s %s %s %s %s" % (
3268 return b"%s %s %s %s %s" % (
3266 one,
3269 one,
3267 two,
3270 two,
3268 pycompat.bytestr(three),
3271 pycompat.bytestr(three),
3269 pycompat.bytestr(four),
3272 pycompat.bytestr(four),
3270 pycompat.bytestr(five),
3273 pycompat.bytestr(five),
3271 )
3274 )
3272
3275
3273 def savecommitmessage(self, text):
3276 def savecommitmessage(self, text):
3274 fp = self.vfs(b'last-message.txt', b'wb')
3277 fp = self.vfs(b'last-message.txt', b'wb')
3275 try:
3278 try:
3276 fp.write(text)
3279 fp.write(text)
3277 finally:
3280 finally:
3278 fp.close()
3281 fp.close()
3279 return self.pathto(fp.name[len(self.root) + 1 :])
3282 return self.pathto(fp.name[len(self.root) + 1 :])
3280
3283
3281
3284
3282 # used to avoid circular references so destructors work
3285 # used to avoid circular references so destructors work
3283 def aftertrans(files):
3286 def aftertrans(files):
3284 renamefiles = [tuple(t) for t in files]
3287 renamefiles = [tuple(t) for t in files]
3285
3288
3286 def a():
3289 def a():
3287 for vfs, src, dest in renamefiles:
3290 for vfs, src, dest in renamefiles:
3288 # if src and dest refer to a same file, vfs.rename is a no-op,
3291 # if src and dest refer to a same file, vfs.rename is a no-op,
3289 # leaving both src and dest on disk. delete dest to make sure
3292 # leaving both src and dest on disk. delete dest to make sure
3290 # the rename couldn't be such a no-op.
3293 # the rename couldn't be such a no-op.
3291 vfs.tryunlink(dest)
3294 vfs.tryunlink(dest)
3292 try:
3295 try:
3293 vfs.rename(src, dest)
3296 vfs.rename(src, dest)
3294 except OSError: # journal file does not yet exist
3297 except OSError: # journal file does not yet exist
3295 pass
3298 pass
3296
3299
3297 return a
3300 return a
3298
3301
3299
3302
3300 def undoname(fn):
3303 def undoname(fn):
3301 base, name = os.path.split(fn)
3304 base, name = os.path.split(fn)
3302 assert name.startswith(b'journal')
3305 assert name.startswith(b'journal')
3303 return os.path.join(base, name.replace(b'journal', b'undo', 1))
3306 return os.path.join(base, name.replace(b'journal', b'undo', 1))
3304
3307
3305
3308
3306 def instance(ui, path, create, intents=None, createopts=None):
3309 def instance(ui, path, create, intents=None, createopts=None):
3307 localpath = util.urllocalpath(path)
3310 localpath = util.urllocalpath(path)
3308 if create:
3311 if create:
3309 createrepository(ui, localpath, createopts=createopts)
3312 createrepository(ui, localpath, createopts=createopts)
3310
3313
3311 return makelocalrepository(ui, localpath, intents=intents)
3314 return makelocalrepository(ui, localpath, intents=intents)
3312
3315
3313
3316
3314 def islocal(path):
3317 def islocal(path):
3315 return True
3318 return True
3316
3319
3317
3320
3318 def defaultcreateopts(ui, createopts=None):
3321 def defaultcreateopts(ui, createopts=None):
3319 """Populate the default creation options for a repository.
3322 """Populate the default creation options for a repository.
3320
3323
3321 A dictionary of explicitly requested creation options can be passed
3324 A dictionary of explicitly requested creation options can be passed
3322 in. Missing keys will be populated.
3325 in. Missing keys will be populated.
3323 """
3326 """
3324 createopts = dict(createopts or {})
3327 createopts = dict(createopts or {})
3325
3328
3326 if b'backend' not in createopts:
3329 if b'backend' not in createopts:
3327 # experimental config: storage.new-repo-backend
3330 # experimental config: storage.new-repo-backend
3328 createopts[b'backend'] = ui.config(b'storage', b'new-repo-backend')
3331 createopts[b'backend'] = ui.config(b'storage', b'new-repo-backend')
3329
3332
3330 return createopts
3333 return createopts
3331
3334
3332
3335
3333 def newreporequirements(ui, createopts):
3336 def newreporequirements(ui, createopts):
3334 """Determine the set of requirements for a new local repository.
3337 """Determine the set of requirements for a new local repository.
3335
3338
3336 Extensions can wrap this function to specify custom requirements for
3339 Extensions can wrap this function to specify custom requirements for
3337 new repositories.
3340 new repositories.
3338 """
3341 """
3339 # If the repo is being created from a shared repository, we copy
3342 # If the repo is being created from a shared repository, we copy
3340 # its requirements.
3343 # its requirements.
3341 if b'sharedrepo' in createopts:
3344 if b'sharedrepo' in createopts:
3342 requirements = set(createopts[b'sharedrepo'].requirements)
3345 requirements = set(createopts[b'sharedrepo'].requirements)
3343 if createopts.get(b'sharedrelative'):
3346 if createopts.get(b'sharedrelative'):
3344 requirements.add(requirementsmod.RELATIVE_SHARED_REQUIREMENT)
3347 requirements.add(requirementsmod.RELATIVE_SHARED_REQUIREMENT)
3345 else:
3348 else:
3346 requirements.add(requirementsmod.SHARED_REQUIREMENT)
3349 requirements.add(requirementsmod.SHARED_REQUIREMENT)
3347
3350
3348 return requirements
3351 return requirements
3349
3352
3350 if b'backend' not in createopts:
3353 if b'backend' not in createopts:
3351 raise error.ProgrammingError(
3354 raise error.ProgrammingError(
3352 b'backend key not present in createopts; '
3355 b'backend key not present in createopts; '
3353 b'was defaultcreateopts() called?'
3356 b'was defaultcreateopts() called?'
3354 )
3357 )
3355
3358
3356 if createopts[b'backend'] != b'revlogv1':
3359 if createopts[b'backend'] != b'revlogv1':
3357 raise error.Abort(
3360 raise error.Abort(
3358 _(
3361 _(
3359 b'unable to determine repository requirements for '
3362 b'unable to determine repository requirements for '
3360 b'storage backend: %s'
3363 b'storage backend: %s'
3361 )
3364 )
3362 % createopts[b'backend']
3365 % createopts[b'backend']
3363 )
3366 )
3364
3367
3365 requirements = {b'revlogv1'}
3368 requirements = {b'revlogv1'}
3366 if ui.configbool(b'format', b'usestore'):
3369 if ui.configbool(b'format', b'usestore'):
3367 requirements.add(b'store')
3370 requirements.add(b'store')
3368 if ui.configbool(b'format', b'usefncache'):
3371 if ui.configbool(b'format', b'usefncache'):
3369 requirements.add(b'fncache')
3372 requirements.add(b'fncache')
3370 if ui.configbool(b'format', b'dotencode'):
3373 if ui.configbool(b'format', b'dotencode'):
3371 requirements.add(b'dotencode')
3374 requirements.add(b'dotencode')
3372
3375
3373 compengines = ui.configlist(b'format', b'revlog-compression')
3376 compengines = ui.configlist(b'format', b'revlog-compression')
3374 for compengine in compengines:
3377 for compengine in compengines:
3375 if compengine in util.compengines:
3378 if compengine in util.compengines:
3376 break
3379 break
3377 else:
3380 else:
3378 raise error.Abort(
3381 raise error.Abort(
3379 _(
3382 _(
3380 b'compression engines %s defined by '
3383 b'compression engines %s defined by '
3381 b'format.revlog-compression not available'
3384 b'format.revlog-compression not available'
3382 )
3385 )
3383 % b', '.join(b'"%s"' % e for e in compengines),
3386 % b', '.join(b'"%s"' % e for e in compengines),
3384 hint=_(
3387 hint=_(
3385 b'run "hg debuginstall" to list available '
3388 b'run "hg debuginstall" to list available '
3386 b'compression engines'
3389 b'compression engines'
3387 ),
3390 ),
3388 )
3391 )
3389
3392
3390 # zlib is the historical default and doesn't need an explicit requirement.
3393 # zlib is the historical default and doesn't need an explicit requirement.
3391 if compengine == b'zstd':
3394 if compengine == b'zstd':
3392 requirements.add(b'revlog-compression-zstd')
3395 requirements.add(b'revlog-compression-zstd')
3393 elif compengine != b'zlib':
3396 elif compengine != b'zlib':
3394 requirements.add(b'exp-compression-%s' % compengine)
3397 requirements.add(b'exp-compression-%s' % compengine)
3395
3398
3396 if scmutil.gdinitconfig(ui):
3399 if scmutil.gdinitconfig(ui):
3397 requirements.add(b'generaldelta')
3400 requirements.add(b'generaldelta')
3398 if ui.configbool(b'format', b'sparse-revlog'):
3401 if ui.configbool(b'format', b'sparse-revlog'):
3399 requirements.add(requirementsmod.SPARSEREVLOG_REQUIREMENT)
3402 requirements.add(requirementsmod.SPARSEREVLOG_REQUIREMENT)
3400
3403
3401 # experimental config: format.exp-use-side-data
3404 # experimental config: format.exp-use-side-data
3402 if ui.configbool(b'format', b'exp-use-side-data'):
3405 if ui.configbool(b'format', b'exp-use-side-data'):
3403 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3406 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3404 # experimental config: format.exp-use-copies-side-data-changeset
3407 # experimental config: format.exp-use-copies-side-data-changeset
3405 if ui.configbool(b'format', b'exp-use-copies-side-data-changeset'):
3408 if ui.configbool(b'format', b'exp-use-copies-side-data-changeset'):
3406 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3409 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3407 requirements.add(requirementsmod.COPIESSDC_REQUIREMENT)
3410 requirements.add(requirementsmod.COPIESSDC_REQUIREMENT)
3408 if ui.configbool(b'experimental', b'treemanifest'):
3411 if ui.configbool(b'experimental', b'treemanifest'):
3409 requirements.add(requirementsmod.TREEMANIFEST_REQUIREMENT)
3412 requirements.add(requirementsmod.TREEMANIFEST_REQUIREMENT)
3410
3413
3411 revlogv2 = ui.config(b'experimental', b'revlogv2')
3414 revlogv2 = ui.config(b'experimental', b'revlogv2')
3412 if revlogv2 == b'enable-unstable-format-and-corrupt-my-data':
3415 if revlogv2 == b'enable-unstable-format-and-corrupt-my-data':
3413 requirements.remove(b'revlogv1')
3416 requirements.remove(b'revlogv1')
3414 # generaldelta is implied by revlogv2.
3417 # generaldelta is implied by revlogv2.
3415 requirements.discard(b'generaldelta')
3418 requirements.discard(b'generaldelta')
3416 requirements.add(requirementsmod.REVLOGV2_REQUIREMENT)
3419 requirements.add(requirementsmod.REVLOGV2_REQUIREMENT)
3417 # experimental config: format.internal-phase
3420 # experimental config: format.internal-phase
3418 if ui.configbool(b'format', b'internal-phase'):
3421 if ui.configbool(b'format', b'internal-phase'):
3419 requirements.add(requirementsmod.INTERNAL_PHASE_REQUIREMENT)
3422 requirements.add(requirementsmod.INTERNAL_PHASE_REQUIREMENT)
3420
3423
3421 if createopts.get(b'narrowfiles'):
3424 if createopts.get(b'narrowfiles'):
3422 requirements.add(requirementsmod.NARROW_REQUIREMENT)
3425 requirements.add(requirementsmod.NARROW_REQUIREMENT)
3423
3426
3424 if createopts.get(b'lfs'):
3427 if createopts.get(b'lfs'):
3425 requirements.add(b'lfs')
3428 requirements.add(b'lfs')
3426
3429
3427 if ui.configbool(b'format', b'bookmarks-in-store'):
3430 if ui.configbool(b'format', b'bookmarks-in-store'):
3428 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3431 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3429
3432
3430 if ui.configbool(b'format', b'use-persistent-nodemap'):
3433 if ui.configbool(b'format', b'use-persistent-nodemap'):
3431 requirements.add(requirementsmod.NODEMAP_REQUIREMENT)
3434 requirements.add(requirementsmod.NODEMAP_REQUIREMENT)
3432
3435
3433 # if share-safe is enabled, let's create the new repository with the new
3436 # if share-safe is enabled, let's create the new repository with the new
3434 # requirement
3437 # requirement
3435 if ui.configbool(b'format', b'exp-share-safe'):
3438 if ui.configbool(b'format', b'exp-share-safe'):
3436 requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
3439 requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
3437
3440
3438 return requirements
3441 return requirements
3439
3442
3440
3443
3441 def checkrequirementscompat(ui, requirements):
3444 def checkrequirementscompat(ui, requirements):
3442 """Checks compatibility of repository requirements enabled and disabled.
3445 """Checks compatibility of repository requirements enabled and disabled.
3443
3446
3444 Returns a set of requirements which needs to be dropped because dependend
3447 Returns a set of requirements which needs to be dropped because dependend
3445 requirements are not enabled. Also warns users about it"""
3448 requirements are not enabled. Also warns users about it"""
3446
3449
3447 dropped = set()
3450 dropped = set()
3448
3451
3449 if b'store' not in requirements:
3452 if b'store' not in requirements:
3450 if bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT in requirements:
3453 if bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT in requirements:
3451 ui.warn(
3454 ui.warn(
3452 _(
3455 _(
3453 b'ignoring enabled \'format.bookmarks-in-store\' config '
3456 b'ignoring enabled \'format.bookmarks-in-store\' config '
3454 b'beacuse it is incompatible with disabled '
3457 b'beacuse it is incompatible with disabled '
3455 b'\'format.usestore\' config\n'
3458 b'\'format.usestore\' config\n'
3456 )
3459 )
3457 )
3460 )
3458 dropped.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3461 dropped.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3459
3462
3460 if (
3463 if (
3461 requirementsmod.SHARED_REQUIREMENT in requirements
3464 requirementsmod.SHARED_REQUIREMENT in requirements
3462 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
3465 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
3463 ):
3466 ):
3464 raise error.Abort(
3467 raise error.Abort(
3465 _(
3468 _(
3466 b"cannot create shared repository as source was created"
3469 b"cannot create shared repository as source was created"
3467 b" with 'format.usestore' config disabled"
3470 b" with 'format.usestore' config disabled"
3468 )
3471 )
3469 )
3472 )
3470
3473
3471 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
3474 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
3472 ui.warn(
3475 ui.warn(
3473 _(
3476 _(
3474 b"ignoring enabled 'format.exp-share-safe' config because "
3477 b"ignoring enabled 'format.exp-share-safe' config because "
3475 b"it is incompatible with disabled 'format.usestore'"
3478 b"it is incompatible with disabled 'format.usestore'"
3476 b" config\n"
3479 b" config\n"
3477 )
3480 )
3478 )
3481 )
3479 dropped.add(requirementsmod.SHARESAFE_REQUIREMENT)
3482 dropped.add(requirementsmod.SHARESAFE_REQUIREMENT)
3480
3483
3481 return dropped
3484 return dropped
3482
3485
3483
3486
3484 def filterknowncreateopts(ui, createopts):
3487 def filterknowncreateopts(ui, createopts):
3485 """Filters a dict of repo creation options against options that are known.
3488 """Filters a dict of repo creation options against options that are known.
3486
3489
3487 Receives a dict of repo creation options and returns a dict of those
3490 Receives a dict of repo creation options and returns a dict of those
3488 options that we don't know how to handle.
3491 options that we don't know how to handle.
3489
3492
3490 This function is called as part of repository creation. If the
3493 This function is called as part of repository creation. If the
3491 returned dict contains any items, repository creation will not
3494 returned dict contains any items, repository creation will not
3492 be allowed, as it means there was a request to create a repository
3495 be allowed, as it means there was a request to create a repository
3493 with options not recognized by loaded code.
3496 with options not recognized by loaded code.
3494
3497
3495 Extensions can wrap this function to filter out creation options
3498 Extensions can wrap this function to filter out creation options
3496 they know how to handle.
3499 they know how to handle.
3497 """
3500 """
3498 known = {
3501 known = {
3499 b'backend',
3502 b'backend',
3500 b'lfs',
3503 b'lfs',
3501 b'narrowfiles',
3504 b'narrowfiles',
3502 b'sharedrepo',
3505 b'sharedrepo',
3503 b'sharedrelative',
3506 b'sharedrelative',
3504 b'shareditems',
3507 b'shareditems',
3505 b'shallowfilestore',
3508 b'shallowfilestore',
3506 }
3509 }
3507
3510
3508 return {k: v for k, v in createopts.items() if k not in known}
3511 return {k: v for k, v in createopts.items() if k not in known}
3509
3512
3510
3513
3511 def createrepository(ui, path, createopts=None):
3514 def createrepository(ui, path, createopts=None):
3512 """Create a new repository in a vfs.
3515 """Create a new repository in a vfs.
3513
3516
3514 ``path`` path to the new repo's working directory.
3517 ``path`` path to the new repo's working directory.
3515 ``createopts`` options for the new repository.
3518 ``createopts`` options for the new repository.
3516
3519
3517 The following keys for ``createopts`` are recognized:
3520 The following keys for ``createopts`` are recognized:
3518
3521
3519 backend
3522 backend
3520 The storage backend to use.
3523 The storage backend to use.
3521 lfs
3524 lfs
3522 Repository will be created with ``lfs`` requirement. The lfs extension
3525 Repository will be created with ``lfs`` requirement. The lfs extension
3523 will automatically be loaded when the repository is accessed.
3526 will automatically be loaded when the repository is accessed.
3524 narrowfiles
3527 narrowfiles
3525 Set up repository to support narrow file storage.
3528 Set up repository to support narrow file storage.
3526 sharedrepo
3529 sharedrepo
3527 Repository object from which storage should be shared.
3530 Repository object from which storage should be shared.
3528 sharedrelative
3531 sharedrelative
3529 Boolean indicating if the path to the shared repo should be
3532 Boolean indicating if the path to the shared repo should be
3530 stored as relative. By default, the pointer to the "parent" repo
3533 stored as relative. By default, the pointer to the "parent" repo
3531 is stored as an absolute path.
3534 is stored as an absolute path.
3532 shareditems
3535 shareditems
3533 Set of items to share to the new repository (in addition to storage).
3536 Set of items to share to the new repository (in addition to storage).
3534 shallowfilestore
3537 shallowfilestore
3535 Indicates that storage for files should be shallow (not all ancestor
3538 Indicates that storage for files should be shallow (not all ancestor
3536 revisions are known).
3539 revisions are known).
3537 """
3540 """
3538 createopts = defaultcreateopts(ui, createopts=createopts)
3541 createopts = defaultcreateopts(ui, createopts=createopts)
3539
3542
3540 unknownopts = filterknowncreateopts(ui, createopts)
3543 unknownopts = filterknowncreateopts(ui, createopts)
3541
3544
3542 if not isinstance(unknownopts, dict):
3545 if not isinstance(unknownopts, dict):
3543 raise error.ProgrammingError(
3546 raise error.ProgrammingError(
3544 b'filterknowncreateopts() did not return a dict'
3547 b'filterknowncreateopts() did not return a dict'
3545 )
3548 )
3546
3549
3547 if unknownopts:
3550 if unknownopts:
3548 raise error.Abort(
3551 raise error.Abort(
3549 _(
3552 _(
3550 b'unable to create repository because of unknown '
3553 b'unable to create repository because of unknown '
3551 b'creation option: %s'
3554 b'creation option: %s'
3552 )
3555 )
3553 % b', '.join(sorted(unknownopts)),
3556 % b', '.join(sorted(unknownopts)),
3554 hint=_(b'is a required extension not loaded?'),
3557 hint=_(b'is a required extension not loaded?'),
3555 )
3558 )
3556
3559
3557 requirements = newreporequirements(ui, createopts=createopts)
3560 requirements = newreporequirements(ui, createopts=createopts)
3558 requirements -= checkrequirementscompat(ui, requirements)
3561 requirements -= checkrequirementscompat(ui, requirements)
3559
3562
3560 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3563 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3561
3564
3562 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3565 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3563 if hgvfs.exists():
3566 if hgvfs.exists():
3564 raise error.RepoError(_(b'repository %s already exists') % path)
3567 raise error.RepoError(_(b'repository %s already exists') % path)
3565
3568
3566 if b'sharedrepo' in createopts:
3569 if b'sharedrepo' in createopts:
3567 sharedpath = createopts[b'sharedrepo'].sharedpath
3570 sharedpath = createopts[b'sharedrepo'].sharedpath
3568
3571
3569 if createopts.get(b'sharedrelative'):
3572 if createopts.get(b'sharedrelative'):
3570 try:
3573 try:
3571 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3574 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3572 except (IOError, ValueError) as e:
3575 except (IOError, ValueError) as e:
3573 # ValueError is raised on Windows if the drive letters differ
3576 # ValueError is raised on Windows if the drive letters differ
3574 # on each path.
3577 # on each path.
3575 raise error.Abort(
3578 raise error.Abort(
3576 _(b'cannot calculate relative path'),
3579 _(b'cannot calculate relative path'),
3577 hint=stringutil.forcebytestr(e),
3580 hint=stringutil.forcebytestr(e),
3578 )
3581 )
3579
3582
3580 if not wdirvfs.exists():
3583 if not wdirvfs.exists():
3581 wdirvfs.makedirs()
3584 wdirvfs.makedirs()
3582
3585
3583 hgvfs.makedir(notindexed=True)
3586 hgvfs.makedir(notindexed=True)
3584 if b'sharedrepo' not in createopts:
3587 if b'sharedrepo' not in createopts:
3585 hgvfs.mkdir(b'cache')
3588 hgvfs.mkdir(b'cache')
3586 hgvfs.mkdir(b'wcache')
3589 hgvfs.mkdir(b'wcache')
3587
3590
3588 if b'store' in requirements and b'sharedrepo' not in createopts:
3591 if b'store' in requirements and b'sharedrepo' not in createopts:
3589 hgvfs.mkdir(b'store')
3592 hgvfs.mkdir(b'store')
3590
3593
3591 # We create an invalid changelog outside the store so very old
3594 # We create an invalid changelog outside the store so very old
3592 # Mercurial versions (which didn't know about the requirements
3595 # Mercurial versions (which didn't know about the requirements
3593 # file) encounter an error on reading the changelog. This
3596 # file) encounter an error on reading the changelog. This
3594 # effectively locks out old clients and prevents them from
3597 # effectively locks out old clients and prevents them from
3595 # mucking with a repo in an unknown format.
3598 # mucking with a repo in an unknown format.
3596 #
3599 #
3597 # The revlog header has version 2, which won't be recognized by
3600 # The revlog header has version 2, which won't be recognized by
3598 # such old clients.
3601 # such old clients.
3599 hgvfs.append(
3602 hgvfs.append(
3600 b'00changelog.i',
3603 b'00changelog.i',
3601 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3604 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3602 b'layout',
3605 b'layout',
3603 )
3606 )
3604
3607
3605 # Filter the requirements into working copy and store ones
3608 # Filter the requirements into working copy and store ones
3606 wcreq, storereq = scmutil.filterrequirements(requirements)
3609 wcreq, storereq = scmutil.filterrequirements(requirements)
3607 # write working copy ones
3610 # write working copy ones
3608 scmutil.writerequires(hgvfs, wcreq)
3611 scmutil.writerequires(hgvfs, wcreq)
3609 # If there are store requirements and the current repository
3612 # If there are store requirements and the current repository
3610 # is not a shared one, write stored requirements
3613 # is not a shared one, write stored requirements
3611 # For new shared repository, we don't need to write the store
3614 # For new shared repository, we don't need to write the store
3612 # requirements as they are already present in store requires
3615 # requirements as they are already present in store requires
3613 if storereq and b'sharedrepo' not in createopts:
3616 if storereq and b'sharedrepo' not in createopts:
3614 storevfs = vfsmod.vfs(hgvfs.join(b'store'), cacheaudited=True)
3617 storevfs = vfsmod.vfs(hgvfs.join(b'store'), cacheaudited=True)
3615 scmutil.writerequires(storevfs, storereq)
3618 scmutil.writerequires(storevfs, storereq)
3616
3619
3617 # Write out file telling readers where to find the shared store.
3620 # Write out file telling readers where to find the shared store.
3618 if b'sharedrepo' in createopts:
3621 if b'sharedrepo' in createopts:
3619 hgvfs.write(b'sharedpath', sharedpath)
3622 hgvfs.write(b'sharedpath', sharedpath)
3620
3623
3621 if createopts.get(b'shareditems'):
3624 if createopts.get(b'shareditems'):
3622 shared = b'\n'.join(sorted(createopts[b'shareditems'])) + b'\n'
3625 shared = b'\n'.join(sorted(createopts[b'shareditems'])) + b'\n'
3623 hgvfs.write(b'shared', shared)
3626 hgvfs.write(b'shared', shared)
3624
3627
3625
3628
3626 def poisonrepository(repo):
3629 def poisonrepository(repo):
3627 """Poison a repository instance so it can no longer be used."""
3630 """Poison a repository instance so it can no longer be used."""
3628 # Perform any cleanup on the instance.
3631 # Perform any cleanup on the instance.
3629 repo.close()
3632 repo.close()
3630
3633
3631 # Our strategy is to replace the type of the object with one that
3634 # Our strategy is to replace the type of the object with one that
3632 # has all attribute lookups result in error.
3635 # has all attribute lookups result in error.
3633 #
3636 #
3634 # But we have to allow the close() method because some constructors
3637 # But we have to allow the close() method because some constructors
3635 # of repos call close() on repo references.
3638 # of repos call close() on repo references.
3636 class poisonedrepository(object):
3639 class poisonedrepository(object):
3637 def __getattribute__(self, item):
3640 def __getattribute__(self, item):
3638 if item == 'close':
3641 if item == 'close':
3639 return object.__getattribute__(self, item)
3642 return object.__getattribute__(self, item)
3640
3643
3641 raise error.ProgrammingError(
3644 raise error.ProgrammingError(
3642 b'repo instances should not be used after unshare'
3645 b'repo instances should not be used after unshare'
3643 )
3646 )
3644
3647
3645 def close(self):
3648 def close(self):
3646 pass
3649 pass
3647
3650
3648 # We may have a repoview, which intercepts __setattr__. So be sure
3651 # We may have a repoview, which intercepts __setattr__. So be sure
3649 # we operate at the lowest level possible.
3652 # we operate at the lowest level possible.
3650 object.__setattr__(repo, '__class__', poisonedrepository)
3653 object.__setattr__(repo, '__class__', poisonedrepository)
@@ -1,669 +1,675 b''
1 ===================================
1 ===================================
2 Test the persistent on-disk nodemap
2 Test the persistent on-disk nodemap
3 ===================================
3 ===================================
4
4
5 $ cat << EOF >> $HGRCPATH
5 $ cat << EOF >> $HGRCPATH
6 > [format]
6 > [format]
7 > use-persistent-nodemap=yes
7 > use-persistent-nodemap=yes
8 > [devel]
8 > [devel]
9 > persistent-nodemap=yes
9 > persistent-nodemap=yes
10 > EOF
10 > EOF
11
11
12 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
12 $ hg init test-repo --config storage.revlog.persistent-nodemap.slow-path=allow
13 $ cd test-repo
13 $ cd test-repo
14
14
15 Check handling of the default slow-path value
15 Check handling of the default slow-path value
16
16
17 #if no-pure no-rust
17 #if no-pure no-rust
18
18
19 $ hg id
19 $ hg id
20 warning: accessing `persistent-nodemap` repository without associated fast implementation.
20 abort: accessing `persistent-nodemap` repository without associated fast implementation.
21 (check `hg help config.format.use-persistent-nodemap` for details)
21 (check `hg help config.format.use-persistent-nodemap` for details)
22 000000000000 tip
22 [255]
23
23
24 Unlock further check (we are here to test the feature)
24 Unlock further check (we are here to test the feature)
25
25
26 $ cat << EOF >> $HGRCPATH
26 $ cat << EOF >> $HGRCPATH
27 > [storage]
27 > [storage]
28 > # to avoid spamming the test
28 > # to avoid spamming the test
29 > revlog.persistent-nodemap.slow-path=allow
29 > revlog.persistent-nodemap.slow-path=allow
30 > EOF
30 > EOF
31
31
32 #endif
32 #endif
33
33
34
34
35 $ hg debugformat
35 $ hg debugformat
36 format-variant repo
36 format-variant repo
37 fncache: yes
37 fncache: yes
38 dotencode: yes
38 dotencode: yes
39 generaldelta: yes
39 generaldelta: yes
40 exp-sharesafe: no
40 exp-sharesafe: no
41 sparserevlog: yes
41 sparserevlog: yes
42 sidedata: no
42 sidedata: no
43 persistent-nodemap: yes
43 persistent-nodemap: yes
44 copies-sdc: no
44 copies-sdc: no
45 plain-cl-delta: yes
45 plain-cl-delta: yes
46 compression: zlib
46 compression: zlib
47 compression-level: default
47 compression-level: default
48 $ hg debugbuilddag .+5000 --new-file
48 $ hg debugbuilddag .+5000 --new-file
49
49
50 $ hg debugnodemap --metadata
50 $ hg debugnodemap --metadata
51 uid: ???????????????? (glob)
51 uid: ???????????????? (glob)
52 tip-rev: 5000
52 tip-rev: 5000
53 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
53 tip-node: 6b02b8c7b96654c25e86ba69eda198d7e6ad8b3c
54 data-length: 121088
54 data-length: 121088
55 data-unused: 0
55 data-unused: 0
56 data-unused: 0.000%
56 data-unused: 0.000%
57 $ f --size .hg/store/00changelog.n
57 $ f --size .hg/store/00changelog.n
58 .hg/store/00changelog.n: size=70
58 .hg/store/00changelog.n: size=70
59
59
60 Simple lookup works
60 Simple lookup works
61
61
62 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
62 $ ANYNODE=`hg log --template '{node|short}\n' --rev tip`
63 $ hg log -r "$ANYNODE" --template '{rev}\n'
63 $ hg log -r "$ANYNODE" --template '{rev}\n'
64 5000
64 5000
65
65
66
66
67 #if rust
67 #if rust
68
68
69 $ f --sha256 .hg/store/00changelog-*.nd
69 $ f --sha256 .hg/store/00changelog-*.nd
70 .hg/store/00changelog-????????????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
70 .hg/store/00changelog-????????????????.nd: sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd (glob)
71
71
72 $ f --sha256 .hg/store/00manifest-*.nd
72 $ f --sha256 .hg/store/00manifest-*.nd
73 .hg/store/00manifest-????????????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
73 .hg/store/00manifest-????????????????.nd: sha256=97117b1c064ea2f86664a124589e47db0e254e8d34739b5c5cc5bf31c9da2b51 (glob)
74 $ hg debugnodemap --dump-new | f --sha256 --size
74 $ hg debugnodemap --dump-new | f --sha256 --size
75 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
75 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
76 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
76 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
77 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
77 size=121088, sha256=2e029d3200bd1a986b32784fc2ef1a3bd60dc331f025718bcf5ff44d93f026fd
78 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
78 0000: 00 00 00 91 00 00 00 20 00 00 00 bb 00 00 00 e7 |....... ........|
79 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
79 0010: 00 00 00 66 00 00 00 a1 00 00 01 13 00 00 01 22 |...f..........."|
80 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
80 0020: 00 00 00 23 00 00 00 fc 00 00 00 ba 00 00 00 5e |...#...........^|
81 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
81 0030: 00 00 00 df 00 00 01 4e 00 00 01 65 00 00 00 ab |.......N...e....|
82 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
82 0040: 00 00 00 a9 00 00 00 95 00 00 00 73 00 00 00 38 |...........s...8|
83 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
83 0050: 00 00 00 cc 00 00 00 92 00 00 00 90 00 00 00 69 |...............i|
84 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
84 0060: 00 00 00 ec 00 00 00 8d 00 00 01 4f 00 00 00 12 |...........O....|
85 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
85 0070: 00 00 02 0c 00 00 00 77 00 00 00 9c 00 00 00 8f |.......w........|
86 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
86 0080: 00 00 00 d5 00 00 00 6b 00 00 00 48 00 00 00 b3 |.......k...H....|
87 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
87 0090: 00 00 00 e5 00 00 00 b5 00 00 00 8e 00 00 00 ad |................|
88 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
88 00a0: 00 00 00 7b 00 00 00 7c 00 00 00 0b 00 00 00 2b |...{...|.......+|
89 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
89 00b0: 00 00 00 c6 00 00 00 1e 00 00 01 08 00 00 00 11 |................|
90 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
90 00c0: 00 00 01 30 00 00 00 26 00 00 01 9c 00 00 00 35 |...0...&.......5|
91 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
91 00d0: 00 00 00 b8 00 00 01 31 00 00 00 2c 00 00 00 55 |.......1...,...U|
92 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
92 00e0: 00 00 00 8a 00 00 00 9a 00 00 00 0c 00 00 01 1e |................|
93 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
93 00f0: 00 00 00 a4 00 00 00 83 00 00 00 c9 00 00 00 8c |................|
94
94
95
95
96 #else
96 #else
97
97
98 $ f --sha256 .hg/store/00changelog-*.nd
98 $ f --sha256 .hg/store/00changelog-*.nd
99 .hg/store/00changelog-????????????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
99 .hg/store/00changelog-????????????????.nd: sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79 (glob)
100 $ hg debugnodemap --dump-new | f --sha256 --size
100 $ hg debugnodemap --dump-new | f --sha256 --size
101 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
101 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
102 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
102 $ hg debugnodemap --dump-disk | f --sha256 --bytes=256 --hexdump --size
103 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
103 size=121088, sha256=f544f5462ff46097432caf6d764091f6d8c46d6121be315ead8576d548c9dd79
104 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
104 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
105 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
105 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
106 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
106 0020: ff ff ff ff ff ff f5 06 ff ff ff ff ff ff f3 e7 |................|
107 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
107 0030: ff ff ef ca ff ff ff ff ff ff ff ff ff ff ff ff |................|
108 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
108 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
109 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
109 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ed 08 |................|
110 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
110 0060: ff ff ed 66 ff ff ff ff ff ff ff ff ff ff ff ff |...f............|
111 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
111 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
112 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
112 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
113 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
113 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6 ed |................|
114 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
114 00a0: ff ff ff ff ff ff fe 61 ff ff ff ff ff ff ff ff |.......a........|
115 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
115 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
116 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
116 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
117 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
117 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
118 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
118 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 |................|
119 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
119 00f0: ff ff ff ff ff ff ed 1b ff ff ff ff ff ff ff ff |................|
120
120
121 #endif
121 #endif
122
122
123 $ hg debugnodemap --check
123 $ hg debugnodemap --check
124 revision in index: 5001
124 revision in index: 5001
125 revision in nodemap: 5001
125 revision in nodemap: 5001
126
126
127 add a new commit
127 add a new commit
128
128
129 $ hg up
129 $ hg up
130 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
130 5001 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 $ echo foo > foo
131 $ echo foo > foo
132 $ hg add foo
132 $ hg add foo
133
133
134
134
135 Check slow-path config value handling
135 Check slow-path config value handling
136 -------------------------------------
136 -------------------------------------
137
137
138 #if no-pure no-rust
139
138 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
140 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
139 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
141 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
140 falling back to default value: warn
142 falling back to default value: abort
141 warning: accessing `persistent-nodemap` repository without associated fast implementation. (no-pure no-rust !)
143 abort: accessing `persistent-nodemap` repository without associated fast implementation.
142 (check `hg help config.format.use-persistent-nodemap` for details) (no-pure no-rust !)
144 (check `hg help config.format.use-persistent-nodemap` for details)
143 6b02b8c7b966+ tip
145 [255]
144
145 #if no-pure no-rust
146
146
147 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
147 $ hg log -r . --config "storage.revlog.persistent-nodemap.slow-path=warn"
148 warning: accessing `persistent-nodemap` repository without associated fast implementation.
148 warning: accessing `persistent-nodemap` repository without associated fast implementation.
149 (check `hg help config.format.use-persistent-nodemap` for details)
149 (check `hg help config.format.use-persistent-nodemap` for details)
150 changeset: 5000:6b02b8c7b966
150 changeset: 5000:6b02b8c7b966
151 tag: tip
151 tag: tip
152 user: debugbuilddag
152 user: debugbuilddag
153 date: Thu Jan 01 01:23:20 1970 +0000
153 date: Thu Jan 01 01:23:20 1970 +0000
154 summary: r5000
154 summary: r5000
155
155
156 $ hg ci -m 'foo' --config "storage.revlog.nodemap.mode=strict"
156 $ hg ci -m 'foo' --config "storage.revlog.persistent-nodemap.slow-path=abort"
157 transaction abort!
157 abort: accessing `persistent-nodemap` repository without associated fast implementation.
158 rollback completed
158 (check `hg help config.format.use-persistent-nodemap` for details)
159 abort: persistent nodemap in strict mode without efficient method
160 [255]
159 [255]
161
160
161 #else
162
163 $ hg id --config "storage.revlog.persistent-nodemap.slow-path=invalid-value"
164 unknown value for config "storage.revlog.persistent-nodemap.slow-path": "invalid-value"
165 falling back to default value: abort
166 6b02b8c7b966+ tip
167
162 #endif
168 #endif
163
169
164 $ hg ci -m 'foo'
170 $ hg ci -m 'foo'
165
171
166 #if no-pure no-rust
172 #if no-pure no-rust
167 $ hg debugnodemap --metadata
173 $ hg debugnodemap --metadata
168 uid: ???????????????? (glob)
174 uid: ???????????????? (glob)
169 tip-rev: 5001
175 tip-rev: 5001
170 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
176 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
171 data-length: 121088
177 data-length: 121088
172 data-unused: 0
178 data-unused: 0
173 data-unused: 0.000%
179 data-unused: 0.000%
174 #else
180 #else
175 $ hg debugnodemap --metadata
181 $ hg debugnodemap --metadata
176 uid: ???????????????? (glob)
182 uid: ???????????????? (glob)
177 tip-rev: 5001
183 tip-rev: 5001
178 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
184 tip-node: 16395c3cf7e231394735e6b1717823ada303fb0c
179 data-length: 121344
185 data-length: 121344
180 data-unused: 256
186 data-unused: 256
181 data-unused: 0.211%
187 data-unused: 0.211%
182 #endif
188 #endif
183
189
184 $ f --size .hg/store/00changelog.n
190 $ f --size .hg/store/00changelog.n
185 .hg/store/00changelog.n: size=70
191 .hg/store/00changelog.n: size=70
186
192
187 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
193 (The pure code use the debug code that perform incremental update, the C code reencode from scratch)
188
194
189 #if pure
195 #if pure
190 $ f --sha256 .hg/store/00changelog-*.nd --size
196 $ f --sha256 .hg/store/00changelog-*.nd --size
191 .hg/store/00changelog-????????????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
197 .hg/store/00changelog-????????????????.nd: size=121344, sha256=cce54c5da5bde3ad72a4938673ed4064c86231b9c64376b082b163fdb20f8f66 (glob)
192 #endif
198 #endif
193
199
194 #if rust
200 #if rust
195 $ f --sha256 .hg/store/00changelog-*.nd --size
201 $ f --sha256 .hg/store/00changelog-*.nd --size
196 .hg/store/00changelog-????????????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
202 .hg/store/00changelog-????????????????.nd: size=121344, sha256=952b042fcf614ceb37b542b1b723e04f18f83efe99bee4e0f5ccd232ef470e58 (glob)
197 #endif
203 #endif
198
204
199 #if no-pure no-rust
205 #if no-pure no-rust
200 $ f --sha256 .hg/store/00changelog-*.nd --size
206 $ f --sha256 .hg/store/00changelog-*.nd --size
201 .hg/store/00changelog-????????????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
207 .hg/store/00changelog-????????????????.nd: size=121088, sha256=df7c06a035b96cb28c7287d349d603baef43240be7736fe34eea419a49702e17 (glob)
202 #endif
208 #endif
203
209
204 $ hg debugnodemap --check
210 $ hg debugnodemap --check
205 revision in index: 5002
211 revision in index: 5002
206 revision in nodemap: 5002
212 revision in nodemap: 5002
207
213
208 Test code path without mmap
214 Test code path without mmap
209 ---------------------------
215 ---------------------------
210
216
211 $ echo bar > bar
217 $ echo bar > bar
212 $ hg add bar
218 $ hg add bar
213 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
219 $ hg ci -m 'bar' --config storage.revlog.persistent-nodemap.mmap=no
214
220
215 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
221 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=yes
216 revision in index: 5003
222 revision in index: 5003
217 revision in nodemap: 5003
223 revision in nodemap: 5003
218 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
224 $ hg debugnodemap --check --config storage.revlog.persistent-nodemap.mmap=no
219 revision in index: 5003
225 revision in index: 5003
220 revision in nodemap: 5003
226 revision in nodemap: 5003
221
227
222
228
223 #if pure
229 #if pure
224 $ hg debugnodemap --metadata
230 $ hg debugnodemap --metadata
225 uid: ???????????????? (glob)
231 uid: ???????????????? (glob)
226 tip-rev: 5002
232 tip-rev: 5002
227 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
233 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
228 data-length: 121600
234 data-length: 121600
229 data-unused: 512
235 data-unused: 512
230 data-unused: 0.421%
236 data-unused: 0.421%
231 $ f --sha256 .hg/store/00changelog-*.nd --size
237 $ f --sha256 .hg/store/00changelog-*.nd --size
232 .hg/store/00changelog-????????????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
238 .hg/store/00changelog-????????????????.nd: size=121600, sha256=def52503d049ccb823974af313a98a935319ba61f40f3aa06a8be4d35c215054 (glob)
233 #endif
239 #endif
234 #if rust
240 #if rust
235 $ hg debugnodemap --metadata
241 $ hg debugnodemap --metadata
236 uid: ???????????????? (glob)
242 uid: ???????????????? (glob)
237 tip-rev: 5002
243 tip-rev: 5002
238 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
244 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
239 data-length: 121600
245 data-length: 121600
240 data-unused: 512
246 data-unused: 512
241 data-unused: 0.421%
247 data-unused: 0.421%
242 $ f --sha256 .hg/store/00changelog-*.nd --size
248 $ f --sha256 .hg/store/00changelog-*.nd --size
243 .hg/store/00changelog-????????????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
249 .hg/store/00changelog-????????????????.nd: size=121600, sha256=dacf5b5f1d4585fee7527d0e67cad5b1ba0930e6a0928f650f779aefb04ce3fb (glob)
244 #endif
250 #endif
245 #if no-pure no-rust
251 #if no-pure no-rust
246 $ hg debugnodemap --metadata
252 $ hg debugnodemap --metadata
247 uid: ???????????????? (glob)
253 uid: ???????????????? (glob)
248 tip-rev: 5002
254 tip-rev: 5002
249 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
255 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
250 data-length: 121088
256 data-length: 121088
251 data-unused: 0
257 data-unused: 0
252 data-unused: 0.000%
258 data-unused: 0.000%
253 $ f --sha256 .hg/store/00changelog-*.nd --size
259 $ f --sha256 .hg/store/00changelog-*.nd --size
254 .hg/store/00changelog-????????????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
260 .hg/store/00changelog-????????????????.nd: size=121088, sha256=59fcede3e3cc587755916ceed29e3c33748cd1aa7d2f91828ac83e7979d935e8 (glob)
255 #endif
261 #endif
256
262
257 Test force warming the cache
263 Test force warming the cache
258
264
259 $ rm .hg/store/00changelog.n
265 $ rm .hg/store/00changelog.n
260 $ hg debugnodemap --metadata
266 $ hg debugnodemap --metadata
261 $ hg debugupdatecache
267 $ hg debugupdatecache
262 #if pure
268 #if pure
263 $ hg debugnodemap --metadata
269 $ hg debugnodemap --metadata
264 uid: ???????????????? (glob)
270 uid: ???????????????? (glob)
265 tip-rev: 5002
271 tip-rev: 5002
266 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
272 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
267 data-length: 121088
273 data-length: 121088
268 data-unused: 0
274 data-unused: 0
269 data-unused: 0.000%
275 data-unused: 0.000%
270 #else
276 #else
271 $ hg debugnodemap --metadata
277 $ hg debugnodemap --metadata
272 uid: ???????????????? (glob)
278 uid: ???????????????? (glob)
273 tip-rev: 5002
279 tip-rev: 5002
274 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
280 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
275 data-length: 121088
281 data-length: 121088
276 data-unused: 0
282 data-unused: 0
277 data-unused: 0.000%
283 data-unused: 0.000%
278 #endif
284 #endif
279
285
280 Check out of sync nodemap
286 Check out of sync nodemap
281 =========================
287 =========================
282
288
283 First copy old data on the side.
289 First copy old data on the side.
284
290
285 $ mkdir ../tmp-copies
291 $ mkdir ../tmp-copies
286 $ cp .hg/store/00changelog-????????????????.nd .hg/store/00changelog.n ../tmp-copies
292 $ cp .hg/store/00changelog-????????????????.nd .hg/store/00changelog.n ../tmp-copies
287
293
288 Nodemap lagging behind
294 Nodemap lagging behind
289 ----------------------
295 ----------------------
290
296
291 make a new commit
297 make a new commit
292
298
293 $ echo bar2 > bar
299 $ echo bar2 > bar
294 $ hg ci -m 'bar2'
300 $ hg ci -m 'bar2'
295 $ NODE=`hg log -r tip -T '{node}\n'`
301 $ NODE=`hg log -r tip -T '{node}\n'`
296 $ hg log -r "$NODE" -T '{rev}\n'
302 $ hg log -r "$NODE" -T '{rev}\n'
297 5003
303 5003
298
304
299 If the nodemap is lagging behind, it can catch up fine
305 If the nodemap is lagging behind, it can catch up fine
300
306
301 $ hg debugnodemap --metadata
307 $ hg debugnodemap --metadata
302 uid: ???????????????? (glob)
308 uid: ???????????????? (glob)
303 tip-rev: 5003
309 tip-rev: 5003
304 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
310 tip-node: c9329770f979ade2d16912267c38ba5f82fd37b3
305 data-length: 121344 (pure !)
311 data-length: 121344 (pure !)
306 data-length: 121344 (rust !)
312 data-length: 121344 (rust !)
307 data-length: 121152 (no-rust no-pure !)
313 data-length: 121152 (no-rust no-pure !)
308 data-unused: 192 (pure !)
314 data-unused: 192 (pure !)
309 data-unused: 192 (rust !)
315 data-unused: 192 (rust !)
310 data-unused: 0 (no-rust no-pure !)
316 data-unused: 0 (no-rust no-pure !)
311 data-unused: 0.158% (pure !)
317 data-unused: 0.158% (pure !)
312 data-unused: 0.158% (rust !)
318 data-unused: 0.158% (rust !)
313 data-unused: 0.000% (no-rust no-pure !)
319 data-unused: 0.000% (no-rust no-pure !)
314 $ cp -f ../tmp-copies/* .hg/store/
320 $ cp -f ../tmp-copies/* .hg/store/
315 $ hg debugnodemap --metadata
321 $ hg debugnodemap --metadata
316 uid: ???????????????? (glob)
322 uid: ???????????????? (glob)
317 tip-rev: 5002
323 tip-rev: 5002
318 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
324 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
319 data-length: 121088
325 data-length: 121088
320 data-unused: 0
326 data-unused: 0
321 data-unused: 0.000%
327 data-unused: 0.000%
322 $ hg log -r "$NODE" -T '{rev}\n'
328 $ hg log -r "$NODE" -T '{rev}\n'
323 5003
329 5003
324
330
325 changelog altered
331 changelog altered
326 -----------------
332 -----------------
327
333
328 If the nodemap is not gated behind a requirements, an unaware client can alter
334 If the nodemap is not gated behind a requirements, an unaware client can alter
329 the repository so the revlog used to generate the nodemap is not longer
335 the repository so the revlog used to generate the nodemap is not longer
330 compatible with the persistent nodemap. We need to detect that.
336 compatible with the persistent nodemap. We need to detect that.
331
337
332 $ hg up "$NODE~5"
338 $ hg up "$NODE~5"
333 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
339 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
334 $ echo bar > babar
340 $ echo bar > babar
335 $ hg add babar
341 $ hg add babar
336 $ hg ci -m 'babar'
342 $ hg ci -m 'babar'
337 created new head
343 created new head
338 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
344 $ OTHERNODE=`hg log -r tip -T '{node}\n'`
339 $ hg log -r "$OTHERNODE" -T '{rev}\n'
345 $ hg log -r "$OTHERNODE" -T '{rev}\n'
340 5004
346 5004
341
347
342 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
348 $ hg --config extensions.strip= strip --rev "$NODE~1" --no-backup
343
349
344 the nodemap should detect the changelog have been tampered with and recover.
350 the nodemap should detect the changelog have been tampered with and recover.
345
351
346 $ hg debugnodemap --metadata
352 $ hg debugnodemap --metadata
347 uid: ???????????????? (glob)
353 uid: ???????????????? (glob)
348 tip-rev: 5002
354 tip-rev: 5002
349 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
355 tip-node: b355ef8adce0949b8bdf6afc72ca853740d65944
350 data-length: 121536 (pure !)
356 data-length: 121536 (pure !)
351 data-length: 121088 (rust !)
357 data-length: 121088 (rust !)
352 data-length: 121088 (no-pure no-rust !)
358 data-length: 121088 (no-pure no-rust !)
353 data-unused: 448 (pure !)
359 data-unused: 448 (pure !)
354 data-unused: 0 (rust !)
360 data-unused: 0 (rust !)
355 data-unused: 0 (no-pure no-rust !)
361 data-unused: 0 (no-pure no-rust !)
356 data-unused: 0.000% (rust !)
362 data-unused: 0.000% (rust !)
357 data-unused: 0.369% (pure !)
363 data-unused: 0.369% (pure !)
358 data-unused: 0.000% (no-pure no-rust !)
364 data-unused: 0.000% (no-pure no-rust !)
359
365
360 $ cp -f ../tmp-copies/* .hg/store/
366 $ cp -f ../tmp-copies/* .hg/store/
361 $ hg debugnodemap --metadata
367 $ hg debugnodemap --metadata
362 uid: ???????????????? (glob)
368 uid: ???????????????? (glob)
363 tip-rev: 5002
369 tip-rev: 5002
364 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
370 tip-node: 880b18d239dfa9f632413a2071bfdbcc4806a4fd
365 data-length: 121088
371 data-length: 121088
366 data-unused: 0
372 data-unused: 0
367 data-unused: 0.000%
373 data-unused: 0.000%
368 $ hg log -r "$OTHERNODE" -T '{rev}\n'
374 $ hg log -r "$OTHERNODE" -T '{rev}\n'
369 5002
375 5002
370
376
371 Check transaction related property
377 Check transaction related property
372 ==================================
378 ==================================
373
379
374 An up to date nodemap should be available to shell hooks,
380 An up to date nodemap should be available to shell hooks,
375
381
376 $ echo dsljfl > a
382 $ echo dsljfl > a
377 $ hg add a
383 $ hg add a
378 $ hg ci -m a
384 $ hg ci -m a
379 $ hg debugnodemap --metadata
385 $ hg debugnodemap --metadata
380 uid: ???????????????? (glob)
386 uid: ???????????????? (glob)
381 tip-rev: 5003
387 tip-rev: 5003
382 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
388 tip-node: a52c5079765b5865d97b993b303a18740113bbb2
383 data-length: 121088
389 data-length: 121088
384 data-unused: 0
390 data-unused: 0
385 data-unused: 0.000%
391 data-unused: 0.000%
386 $ echo babar2 > babar
392 $ echo babar2 > babar
387 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
393 $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata"
388 uid: ???????????????? (glob)
394 uid: ???????????????? (glob)
389 tip-rev: 5004
395 tip-rev: 5004
390 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
396 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
391 data-length: 121280 (pure !)
397 data-length: 121280 (pure !)
392 data-length: 121280 (rust !)
398 data-length: 121280 (rust !)
393 data-length: 121088 (no-pure no-rust !)
399 data-length: 121088 (no-pure no-rust !)
394 data-unused: 192 (pure !)
400 data-unused: 192 (pure !)
395 data-unused: 192 (rust !)
401 data-unused: 192 (rust !)
396 data-unused: 0 (no-pure no-rust !)
402 data-unused: 0 (no-pure no-rust !)
397 data-unused: 0.158% (pure !)
403 data-unused: 0.158% (pure !)
398 data-unused: 0.158% (rust !)
404 data-unused: 0.158% (rust !)
399 data-unused: 0.000% (no-pure no-rust !)
405 data-unused: 0.000% (no-pure no-rust !)
400 $ hg debugnodemap --metadata
406 $ hg debugnodemap --metadata
401 uid: ???????????????? (glob)
407 uid: ???????????????? (glob)
402 tip-rev: 5004
408 tip-rev: 5004
403 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
409 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
404 data-length: 121280 (pure !)
410 data-length: 121280 (pure !)
405 data-length: 121280 (rust !)
411 data-length: 121280 (rust !)
406 data-length: 121088 (no-pure no-rust !)
412 data-length: 121088 (no-pure no-rust !)
407 data-unused: 192 (pure !)
413 data-unused: 192 (pure !)
408 data-unused: 192 (rust !)
414 data-unused: 192 (rust !)
409 data-unused: 0 (no-pure no-rust !)
415 data-unused: 0 (no-pure no-rust !)
410 data-unused: 0.158% (pure !)
416 data-unused: 0.158% (pure !)
411 data-unused: 0.158% (rust !)
417 data-unused: 0.158% (rust !)
412 data-unused: 0.000% (no-pure no-rust !)
418 data-unused: 0.000% (no-pure no-rust !)
413
419
414 Another process does not see the pending nodemap content during run.
420 Another process does not see the pending nodemap content during run.
415
421
416 $ PATH=$RUNTESTDIR/testlib/:$PATH
422 $ PATH=$RUNTESTDIR/testlib/:$PATH
417 $ echo qpoasp > a
423 $ echo qpoasp > a
418 $ hg ci -m a2 \
424 $ hg ci -m a2 \
419 > --config "hooks.pretxnclose=wait-on-file 20 sync-repo-read sync-txn-pending" \
425 > --config "hooks.pretxnclose=wait-on-file 20 sync-repo-read sync-txn-pending" \
420 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
426 > --config "hooks.txnclose=touch sync-txn-close" > output.txt 2>&1 &
421
427
422 (read the repository while the commit transaction is pending)
428 (read the repository while the commit transaction is pending)
423
429
424 $ wait-on-file 20 sync-txn-pending && \
430 $ wait-on-file 20 sync-txn-pending && \
425 > hg debugnodemap --metadata && \
431 > hg debugnodemap --metadata && \
426 > wait-on-file 20 sync-txn-close sync-repo-read
432 > wait-on-file 20 sync-txn-close sync-repo-read
427 uid: ???????????????? (glob)
433 uid: ???????????????? (glob)
428 tip-rev: 5004
434 tip-rev: 5004
429 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
435 tip-node: 2f5fb1c06a16834c5679d672e90da7c5f3b1a984
430 data-length: 121280 (pure !)
436 data-length: 121280 (pure !)
431 data-length: 121280 (rust !)
437 data-length: 121280 (rust !)
432 data-length: 121088 (no-pure no-rust !)
438 data-length: 121088 (no-pure no-rust !)
433 data-unused: 192 (pure !)
439 data-unused: 192 (pure !)
434 data-unused: 192 (rust !)
440 data-unused: 192 (rust !)
435 data-unused: 0 (no-pure no-rust !)
441 data-unused: 0 (no-pure no-rust !)
436 data-unused: 0.158% (pure !)
442 data-unused: 0.158% (pure !)
437 data-unused: 0.158% (rust !)
443 data-unused: 0.158% (rust !)
438 data-unused: 0.000% (no-pure no-rust !)
444 data-unused: 0.000% (no-pure no-rust !)
439 $ hg debugnodemap --metadata
445 $ hg debugnodemap --metadata
440 uid: ???????????????? (glob)
446 uid: ???????????????? (glob)
441 tip-rev: 5005
447 tip-rev: 5005
442 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
448 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
443 data-length: 121536 (pure !)
449 data-length: 121536 (pure !)
444 data-length: 121536 (rust !)
450 data-length: 121536 (rust !)
445 data-length: 121088 (no-pure no-rust !)
451 data-length: 121088 (no-pure no-rust !)
446 data-unused: 448 (pure !)
452 data-unused: 448 (pure !)
447 data-unused: 448 (rust !)
453 data-unused: 448 (rust !)
448 data-unused: 0 (no-pure no-rust !)
454 data-unused: 0 (no-pure no-rust !)
449 data-unused: 0.369% (pure !)
455 data-unused: 0.369% (pure !)
450 data-unused: 0.369% (rust !)
456 data-unused: 0.369% (rust !)
451 data-unused: 0.000% (no-pure no-rust !)
457 data-unused: 0.000% (no-pure no-rust !)
452
458
453 $ cat output.txt
459 $ cat output.txt
454
460
455 Check that a failing transaction will properly revert the data
461 Check that a failing transaction will properly revert the data
456
462
457 $ echo plakfe > a
463 $ echo plakfe > a
458 $ f --size --sha256 .hg/store/00changelog-*.nd
464 $ f --size --sha256 .hg/store/00changelog-*.nd
459 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
465 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
460 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
466 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
461 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
467 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
462 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
468 $ hg ci -m a3 --config "extensions.abort=$RUNTESTDIR/testlib/crash_transaction_late.py"
463 transaction abort!
469 transaction abort!
464 rollback completed
470 rollback completed
465 abort: This is a late abort
471 abort: This is a late abort
466 [255]
472 [255]
467 $ hg debugnodemap --metadata
473 $ hg debugnodemap --metadata
468 uid: ???????????????? (glob)
474 uid: ???????????????? (glob)
469 tip-rev: 5005
475 tip-rev: 5005
470 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
476 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
471 data-length: 121536 (pure !)
477 data-length: 121536 (pure !)
472 data-length: 121536 (rust !)
478 data-length: 121536 (rust !)
473 data-length: 121088 (no-pure no-rust !)
479 data-length: 121088 (no-pure no-rust !)
474 data-unused: 448 (pure !)
480 data-unused: 448 (pure !)
475 data-unused: 448 (rust !)
481 data-unused: 448 (rust !)
476 data-unused: 0 (no-pure no-rust !)
482 data-unused: 0 (no-pure no-rust !)
477 data-unused: 0.369% (pure !)
483 data-unused: 0.369% (pure !)
478 data-unused: 0.369% (rust !)
484 data-unused: 0.369% (rust !)
479 data-unused: 0.000% (no-pure no-rust !)
485 data-unused: 0.000% (no-pure no-rust !)
480 $ f --size --sha256 .hg/store/00changelog-*.nd
486 $ f --size --sha256 .hg/store/00changelog-*.nd
481 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
487 .hg/store/00changelog-????????????????.nd: size=121536, sha256=bb414468d225cf52d69132e1237afba34d4346ee2eb81b505027e6197b107f03 (glob) (pure !)
482 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
488 .hg/store/00changelog-????????????????.nd: size=121536, sha256=909ac727bc4d1c0fda5f7bff3c620c98bd4a2967c143405a1503439e33b377da (glob) (rust !)
483 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
489 .hg/store/00changelog-????????????????.nd: size=121088, sha256=342d36d30d86dde67d3cb6c002606c4a75bcad665595d941493845066d9c8ee0 (glob) (no-pure no-rust !)
484
490
485 Check that removing content does not confuse the nodemap
491 Check that removing content does not confuse the nodemap
486 --------------------------------------------------------
492 --------------------------------------------------------
487
493
488 removing data with rollback
494 removing data with rollback
489
495
490 $ echo aso > a
496 $ echo aso > a
491 $ hg ci -m a4
497 $ hg ci -m a4
492 $ hg rollback
498 $ hg rollback
493 repository tip rolled back to revision 5005 (undo commit)
499 repository tip rolled back to revision 5005 (undo commit)
494 working directory now based on revision 5005
500 working directory now based on revision 5005
495 $ hg id -r .
501 $ hg id -r .
496 90d5d3ba2fc4 tip
502 90d5d3ba2fc4 tip
497
503
498 roming data with strip
504 roming data with strip
499
505
500 $ echo aso > a
506 $ echo aso > a
501 $ hg ci -m a4
507 $ hg ci -m a4
502 $ hg --config extensions.strip= strip -r . --no-backup
508 $ hg --config extensions.strip= strip -r . --no-backup
503 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
509 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 $ hg id -r . --traceback
510 $ hg id -r . --traceback
505 90d5d3ba2fc4 tip
511 90d5d3ba2fc4 tip
506
512
507 Test upgrade / downgrade
513 Test upgrade / downgrade
508 ========================
514 ========================
509
515
510 downgrading
516 downgrading
511
517
512 $ cat << EOF >> .hg/hgrc
518 $ cat << EOF >> .hg/hgrc
513 > [format]
519 > [format]
514 > use-persistent-nodemap=no
520 > use-persistent-nodemap=no
515 > EOF
521 > EOF
516 $ hg debugformat -v
522 $ hg debugformat -v
517 format-variant repo config default
523 format-variant repo config default
518 fncache: yes yes yes
524 fncache: yes yes yes
519 dotencode: yes yes yes
525 dotencode: yes yes yes
520 generaldelta: yes yes yes
526 generaldelta: yes yes yes
521 exp-sharesafe: no no no
527 exp-sharesafe: no no no
522 sparserevlog: yes yes yes
528 sparserevlog: yes yes yes
523 sidedata: no no no
529 sidedata: no no no
524 persistent-nodemap: yes no no
530 persistent-nodemap: yes no no
525 copies-sdc: no no no
531 copies-sdc: no no no
526 plain-cl-delta: yes yes yes
532 plain-cl-delta: yes yes yes
527 compression: zlib zlib zlib
533 compression: zlib zlib zlib
528 compression-level: default default default
534 compression-level: default default default
529 $ hg debugupgraderepo --run --no-backup --quiet
535 $ hg debugupgraderepo --run --no-backup --quiet
530 upgrade will perform the following actions:
536 upgrade will perform the following actions:
531
537
532 requirements
538 requirements
533 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
539 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
534 removed: persistent-nodemap
540 removed: persistent-nodemap
535
541
536 processed revlogs:
542 processed revlogs:
537 - all-filelogs
543 - all-filelogs
538 - changelog
544 - changelog
539 - manifest
545 - manifest
540
546
541 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
547 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
542 [1]
548 [1]
543 $ hg debugnodemap --metadata
549 $ hg debugnodemap --metadata
544
550
545
551
546 upgrading
552 upgrading
547
553
548 $ cat << EOF >> .hg/hgrc
554 $ cat << EOF >> .hg/hgrc
549 > [format]
555 > [format]
550 > use-persistent-nodemap=yes
556 > use-persistent-nodemap=yes
551 > EOF
557 > EOF
552 $ hg debugformat -v
558 $ hg debugformat -v
553 format-variant repo config default
559 format-variant repo config default
554 fncache: yes yes yes
560 fncache: yes yes yes
555 dotencode: yes yes yes
561 dotencode: yes yes yes
556 generaldelta: yes yes yes
562 generaldelta: yes yes yes
557 exp-sharesafe: no no no
563 exp-sharesafe: no no no
558 sparserevlog: yes yes yes
564 sparserevlog: yes yes yes
559 sidedata: no no no
565 sidedata: no no no
560 persistent-nodemap: no yes no
566 persistent-nodemap: no yes no
561 copies-sdc: no no no
567 copies-sdc: no no no
562 plain-cl-delta: yes yes yes
568 plain-cl-delta: yes yes yes
563 compression: zlib zlib zlib
569 compression: zlib zlib zlib
564 compression-level: default default default
570 compression-level: default default default
565 $ hg debugupgraderepo --run --no-backup --quiet
571 $ hg debugupgraderepo --run --no-backup --quiet
566 upgrade will perform the following actions:
572 upgrade will perform the following actions:
567
573
568 requirements
574 requirements
569 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
575 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
570 added: persistent-nodemap
576 added: persistent-nodemap
571
577
572 processed revlogs:
578 processed revlogs:
573 - all-filelogs
579 - all-filelogs
574 - changelog
580 - changelog
575 - manifest
581 - manifest
576
582
577 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
583 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
578 00changelog-*.nd (glob)
584 00changelog-*.nd (glob)
579 00changelog.n
585 00changelog.n
580 00manifest-*.nd (glob)
586 00manifest-*.nd (glob)
581 00manifest.n
587 00manifest.n
582
588
583 $ hg debugnodemap --metadata
589 $ hg debugnodemap --metadata
584 uid: * (glob)
590 uid: * (glob)
585 tip-rev: 5005
591 tip-rev: 5005
586 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
592 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
587 data-length: 121088
593 data-length: 121088
588 data-unused: 0
594 data-unused: 0
589 data-unused: 0.000%
595 data-unused: 0.000%
590
596
591 Running unrelated upgrade
597 Running unrelated upgrade
592
598
593 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
599 $ hg debugupgraderepo --run --no-backup --quiet --optimize re-delta-all
594 upgrade will perform the following actions:
600 upgrade will perform the following actions:
595
601
596 requirements
602 requirements
597 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, sparserevlog, store
603 preserved: dotencode, fncache, generaldelta, persistent-nodemap, revlogv1, sparserevlog, store
598
604
599 optimisations: re-delta-all
605 optimisations: re-delta-all
600
606
601 processed revlogs:
607 processed revlogs:
602 - all-filelogs
608 - all-filelogs
603 - changelog
609 - changelog
604 - manifest
610 - manifest
605
611
606 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
612 $ ls -1 .hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
607 00changelog-*.nd (glob)
613 00changelog-*.nd (glob)
608 00changelog.n
614 00changelog.n
609 00manifest-*.nd (glob)
615 00manifest-*.nd (glob)
610 00manifest.n
616 00manifest.n
611
617
612 $ hg debugnodemap --metadata
618 $ hg debugnodemap --metadata
613 uid: * (glob)
619 uid: * (glob)
614 tip-rev: 5005
620 tip-rev: 5005
615 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
621 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
616 data-length: 121088
622 data-length: 121088
617 data-unused: 0
623 data-unused: 0
618 data-unused: 0.000%
624 data-unused: 0.000%
619
625
620 Persistent nodemap and local/streaming clone
626 Persistent nodemap and local/streaming clone
621 ============================================
627 ============================================
622
628
623 $ cd ..
629 $ cd ..
624
630
625 standard clone
631 standard clone
626 --------------
632 --------------
627
633
628 The persistent nodemap should exist after a streaming clone
634 The persistent nodemap should exist after a streaming clone
629
635
630 $ hg clone --pull --quiet -U test-repo standard-clone
636 $ hg clone --pull --quiet -U test-repo standard-clone
631 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
637 $ ls -1 standard-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
632 00changelog-*.nd (glob)
638 00changelog-*.nd (glob)
633 00changelog.n
639 00changelog.n
634 00manifest-*.nd (glob)
640 00manifest-*.nd (glob)
635 00manifest.n
641 00manifest.n
636 $ hg -R standard-clone debugnodemap --metadata
642 $ hg -R standard-clone debugnodemap --metadata
637 uid: * (glob)
643 uid: * (glob)
638 tip-rev: 5005
644 tip-rev: 5005
639 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
645 tip-node: 90d5d3ba2fc47db50f712570487cb261a68c8ffe
640 data-length: 121088
646 data-length: 121088
641 data-unused: 0
647 data-unused: 0
642 data-unused: 0.000%
648 data-unused: 0.000%
643
649
644
650
645 local clone
651 local clone
646 ------------
652 ------------
647
653
648 The persistent nodemap should exist after a streaming clone
654 The persistent nodemap should exist after a streaming clone
649
655
650 $ hg clone -U test-repo local-clone
656 $ hg clone -U test-repo local-clone
651 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
657 $ ls -1 local-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
652 [1]
658 [1]
653 $ hg -R local-clone debugnodemap --metadata
659 $ hg -R local-clone debugnodemap --metadata
654
660
655 stream clone
661 stream clone
656 ------------
662 ------------
657
663
658 The persistent nodemap should exist after a streaming clone
664 The persistent nodemap should exist after a streaming clone
659
665
660 $ hg clone -U --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
666 $ hg clone -U --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
661 adding [s] 00manifest.n (70 bytes)
667 adding [s] 00manifest.n (70 bytes)
662 adding [s] 00manifest.i (313 KB)
668 adding [s] 00manifest.i (313 KB)
663 adding [s] 00manifest.d (452 KB)
669 adding [s] 00manifest.d (452 KB)
664 adding [s] 00changelog.n (70 bytes)
670 adding [s] 00changelog.n (70 bytes)
665 adding [s] 00changelog.i (313 KB)
671 adding [s] 00changelog.i (313 KB)
666 adding [s] 00changelog.d (360 KB)
672 adding [s] 00changelog.d (360 KB)
667 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
673 $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
668 [1]
674 [1]
669 $ hg -R stream-clone debugnodemap --metadata
675 $ hg -R stream-clone debugnodemap --metadata
General Comments 0
You need to be logged in to leave comments. Login now