##// END OF EJS Templates
share: rename share-safe warning config...
Pulkit Goyal -
r47051:2eb5fe13 default
parent child Browse files
Show More
@@ -1,2578 +1,2583 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.exchange-heads is False, the discovery will not start with
705 # If discovery.exchange-heads is False, the discovery will not start with
706 # remote head fetching and local head querying.
706 # remote head fetching and local head querying.
707 coreconfigitem(
707 coreconfigitem(
708 b'devel',
708 b'devel',
709 b'discovery.exchange-heads',
709 b'discovery.exchange-heads',
710 default=True,
710 default=True,
711 )
711 )
712 # If discovery.grow-sample is False, the sample size used in set discovery will
712 # If discovery.grow-sample is False, the sample size used in set discovery will
713 # not be increased through the process
713 # not be increased through the process
714 coreconfigitem(
714 coreconfigitem(
715 b'devel',
715 b'devel',
716 b'discovery.grow-sample',
716 b'discovery.grow-sample',
717 default=True,
717 default=True,
718 )
718 )
719 # discovery.grow-sample.rate control the rate at which the sample grow
719 # discovery.grow-sample.rate control the rate at which the sample grow
720 coreconfigitem(
720 coreconfigitem(
721 b'devel',
721 b'devel',
722 b'discovery.grow-sample.rate',
722 b'discovery.grow-sample.rate',
723 default=1.05,
723 default=1.05,
724 )
724 )
725 # If discovery.randomize is False, random sampling during discovery are
725 # If discovery.randomize is False, random sampling during discovery are
726 # deterministic. It is meant for integration tests.
726 # deterministic. It is meant for integration tests.
727 coreconfigitem(
727 coreconfigitem(
728 b'devel',
728 b'devel',
729 b'discovery.randomize',
729 b'discovery.randomize',
730 default=True,
730 default=True,
731 )
731 )
732 _registerdiffopts(section=b'diff')
732 _registerdiffopts(section=b'diff')
733 coreconfigitem(
733 coreconfigitem(
734 b'email',
734 b'email',
735 b'bcc',
735 b'bcc',
736 default=None,
736 default=None,
737 )
737 )
738 coreconfigitem(
738 coreconfigitem(
739 b'email',
739 b'email',
740 b'cc',
740 b'cc',
741 default=None,
741 default=None,
742 )
742 )
743 coreconfigitem(
743 coreconfigitem(
744 b'email',
744 b'email',
745 b'charsets',
745 b'charsets',
746 default=list,
746 default=list,
747 )
747 )
748 coreconfigitem(
748 coreconfigitem(
749 b'email',
749 b'email',
750 b'from',
750 b'from',
751 default=None,
751 default=None,
752 )
752 )
753 coreconfigitem(
753 coreconfigitem(
754 b'email',
754 b'email',
755 b'method',
755 b'method',
756 default=b'smtp',
756 default=b'smtp',
757 )
757 )
758 coreconfigitem(
758 coreconfigitem(
759 b'email',
759 b'email',
760 b'reply-to',
760 b'reply-to',
761 default=None,
761 default=None,
762 )
762 )
763 coreconfigitem(
763 coreconfigitem(
764 b'email',
764 b'email',
765 b'to',
765 b'to',
766 default=None,
766 default=None,
767 )
767 )
768 coreconfigitem(
768 coreconfigitem(
769 b'experimental',
769 b'experimental',
770 b'archivemetatemplate',
770 b'archivemetatemplate',
771 default=dynamicdefault,
771 default=dynamicdefault,
772 )
772 )
773 coreconfigitem(
773 coreconfigitem(
774 b'experimental',
774 b'experimental',
775 b'auto-publish',
775 b'auto-publish',
776 default=b'publish',
776 default=b'publish',
777 )
777 )
778 coreconfigitem(
778 coreconfigitem(
779 b'experimental',
779 b'experimental',
780 b'bundle-phases',
780 b'bundle-phases',
781 default=False,
781 default=False,
782 )
782 )
783 coreconfigitem(
783 coreconfigitem(
784 b'experimental',
784 b'experimental',
785 b'bundle2-advertise',
785 b'bundle2-advertise',
786 default=True,
786 default=True,
787 )
787 )
788 coreconfigitem(
788 coreconfigitem(
789 b'experimental',
789 b'experimental',
790 b'bundle2-output-capture',
790 b'bundle2-output-capture',
791 default=False,
791 default=False,
792 )
792 )
793 coreconfigitem(
793 coreconfigitem(
794 b'experimental',
794 b'experimental',
795 b'bundle2.pushback',
795 b'bundle2.pushback',
796 default=False,
796 default=False,
797 )
797 )
798 coreconfigitem(
798 coreconfigitem(
799 b'experimental',
799 b'experimental',
800 b'bundle2lazylocking',
800 b'bundle2lazylocking',
801 default=False,
801 default=False,
802 )
802 )
803 coreconfigitem(
803 coreconfigitem(
804 b'experimental',
804 b'experimental',
805 b'bundlecomplevel',
805 b'bundlecomplevel',
806 default=None,
806 default=None,
807 )
807 )
808 coreconfigitem(
808 coreconfigitem(
809 b'experimental',
809 b'experimental',
810 b'bundlecomplevel.bzip2',
810 b'bundlecomplevel.bzip2',
811 default=None,
811 default=None,
812 )
812 )
813 coreconfigitem(
813 coreconfigitem(
814 b'experimental',
814 b'experimental',
815 b'bundlecomplevel.gzip',
815 b'bundlecomplevel.gzip',
816 default=None,
816 default=None,
817 )
817 )
818 coreconfigitem(
818 coreconfigitem(
819 b'experimental',
819 b'experimental',
820 b'bundlecomplevel.none',
820 b'bundlecomplevel.none',
821 default=None,
821 default=None,
822 )
822 )
823 coreconfigitem(
823 coreconfigitem(
824 b'experimental',
824 b'experimental',
825 b'bundlecomplevel.zstd',
825 b'bundlecomplevel.zstd',
826 default=None,
826 default=None,
827 )
827 )
828 coreconfigitem(
828 coreconfigitem(
829 b'experimental',
829 b'experimental',
830 b'changegroup3',
830 b'changegroup3',
831 default=False,
831 default=False,
832 )
832 )
833 coreconfigitem(
833 coreconfigitem(
834 b'experimental',
834 b'experimental',
835 b'cleanup-as-archived',
835 b'cleanup-as-archived',
836 default=False,
836 default=False,
837 )
837 )
838 coreconfigitem(
838 coreconfigitem(
839 b'experimental',
839 b'experimental',
840 b'clientcompressionengines',
840 b'clientcompressionengines',
841 default=list,
841 default=list,
842 )
842 )
843 coreconfigitem(
843 coreconfigitem(
844 b'experimental',
844 b'experimental',
845 b'copytrace',
845 b'copytrace',
846 default=b'on',
846 default=b'on',
847 )
847 )
848 coreconfigitem(
848 coreconfigitem(
849 b'experimental',
849 b'experimental',
850 b'copytrace.movecandidateslimit',
850 b'copytrace.movecandidateslimit',
851 default=100,
851 default=100,
852 )
852 )
853 coreconfigitem(
853 coreconfigitem(
854 b'experimental',
854 b'experimental',
855 b'copytrace.sourcecommitlimit',
855 b'copytrace.sourcecommitlimit',
856 default=100,
856 default=100,
857 )
857 )
858 coreconfigitem(
858 coreconfigitem(
859 b'experimental',
859 b'experimental',
860 b'copies.read-from',
860 b'copies.read-from',
861 default=b"filelog-only",
861 default=b"filelog-only",
862 )
862 )
863 coreconfigitem(
863 coreconfigitem(
864 b'experimental',
864 b'experimental',
865 b'copies.write-to',
865 b'copies.write-to',
866 default=b'filelog-only',
866 default=b'filelog-only',
867 )
867 )
868 coreconfigitem(
868 coreconfigitem(
869 b'experimental',
869 b'experimental',
870 b'crecordtest',
870 b'crecordtest',
871 default=None,
871 default=None,
872 )
872 )
873 coreconfigitem(
873 coreconfigitem(
874 b'experimental',
874 b'experimental',
875 b'directaccess',
875 b'directaccess',
876 default=False,
876 default=False,
877 )
877 )
878 coreconfigitem(
878 coreconfigitem(
879 b'experimental',
879 b'experimental',
880 b'directaccess.revnums',
880 b'directaccess.revnums',
881 default=False,
881 default=False,
882 )
882 )
883 coreconfigitem(
883 coreconfigitem(
884 b'experimental',
884 b'experimental',
885 b'editortmpinhg',
885 b'editortmpinhg',
886 default=False,
886 default=False,
887 )
887 )
888 coreconfigitem(
888 coreconfigitem(
889 b'experimental',
889 b'experimental',
890 b'evolution',
890 b'evolution',
891 default=list,
891 default=list,
892 )
892 )
893 coreconfigitem(
893 coreconfigitem(
894 b'experimental',
894 b'experimental',
895 b'evolution.allowdivergence',
895 b'evolution.allowdivergence',
896 default=False,
896 default=False,
897 alias=[(b'experimental', b'allowdivergence')],
897 alias=[(b'experimental', b'allowdivergence')],
898 )
898 )
899 coreconfigitem(
899 coreconfigitem(
900 b'experimental',
900 b'experimental',
901 b'evolution.allowunstable',
901 b'evolution.allowunstable',
902 default=None,
902 default=None,
903 )
903 )
904 coreconfigitem(
904 coreconfigitem(
905 b'experimental',
905 b'experimental',
906 b'evolution.createmarkers',
906 b'evolution.createmarkers',
907 default=None,
907 default=None,
908 )
908 )
909 coreconfigitem(
909 coreconfigitem(
910 b'experimental',
910 b'experimental',
911 b'evolution.effect-flags',
911 b'evolution.effect-flags',
912 default=True,
912 default=True,
913 alias=[(b'experimental', b'effect-flags')],
913 alias=[(b'experimental', b'effect-flags')],
914 )
914 )
915 coreconfigitem(
915 coreconfigitem(
916 b'experimental',
916 b'experimental',
917 b'evolution.exchange',
917 b'evolution.exchange',
918 default=None,
918 default=None,
919 )
919 )
920 coreconfigitem(
920 coreconfigitem(
921 b'experimental',
921 b'experimental',
922 b'evolution.bundle-obsmarker',
922 b'evolution.bundle-obsmarker',
923 default=False,
923 default=False,
924 )
924 )
925 coreconfigitem(
925 coreconfigitem(
926 b'experimental',
926 b'experimental',
927 b'evolution.bundle-obsmarker:mandatory',
927 b'evolution.bundle-obsmarker:mandatory',
928 default=True,
928 default=True,
929 )
929 )
930 coreconfigitem(
930 coreconfigitem(
931 b'experimental',
931 b'experimental',
932 b'log.topo',
932 b'log.topo',
933 default=False,
933 default=False,
934 )
934 )
935 coreconfigitem(
935 coreconfigitem(
936 b'experimental',
936 b'experimental',
937 b'evolution.report-instabilities',
937 b'evolution.report-instabilities',
938 default=True,
938 default=True,
939 )
939 )
940 coreconfigitem(
940 coreconfigitem(
941 b'experimental',
941 b'experimental',
942 b'evolution.track-operation',
942 b'evolution.track-operation',
943 default=True,
943 default=True,
944 )
944 )
945 # repo-level config to exclude a revset visibility
945 # repo-level config to exclude a revset visibility
946 #
946 #
947 # The target use case is to use `share` to expose different subset of the same
947 # The target use case is to use `share` to expose different subset of the same
948 # repository, especially server side. See also `server.view`.
948 # repository, especially server side. See also `server.view`.
949 coreconfigitem(
949 coreconfigitem(
950 b'experimental',
950 b'experimental',
951 b'extra-filter-revs',
951 b'extra-filter-revs',
952 default=None,
952 default=None,
953 )
953 )
954 coreconfigitem(
954 coreconfigitem(
955 b'experimental',
955 b'experimental',
956 b'maxdeltachainspan',
956 b'maxdeltachainspan',
957 default=-1,
957 default=-1,
958 )
958 )
959 # tracks files which were undeleted (merge might delete them but we explicitly
959 # tracks files which were undeleted (merge might delete them but we explicitly
960 # kept/undeleted them) and creates new filenodes for them
960 # kept/undeleted them) and creates new filenodes for them
961 coreconfigitem(
961 coreconfigitem(
962 b'experimental',
962 b'experimental',
963 b'merge-track-salvaged',
963 b'merge-track-salvaged',
964 default=False,
964 default=False,
965 )
965 )
966 coreconfigitem(
966 coreconfigitem(
967 b'experimental',
967 b'experimental',
968 b'mergetempdirprefix',
968 b'mergetempdirprefix',
969 default=None,
969 default=None,
970 )
970 )
971 coreconfigitem(
971 coreconfigitem(
972 b'experimental',
972 b'experimental',
973 b'mmapindexthreshold',
973 b'mmapindexthreshold',
974 default=None,
974 default=None,
975 )
975 )
976 coreconfigitem(
976 coreconfigitem(
977 b'experimental',
977 b'experimental',
978 b'narrow',
978 b'narrow',
979 default=False,
979 default=False,
980 )
980 )
981 coreconfigitem(
981 coreconfigitem(
982 b'experimental',
982 b'experimental',
983 b'nonnormalparanoidcheck',
983 b'nonnormalparanoidcheck',
984 default=False,
984 default=False,
985 )
985 )
986 coreconfigitem(
986 coreconfigitem(
987 b'experimental',
987 b'experimental',
988 b'exportableenviron',
988 b'exportableenviron',
989 default=list,
989 default=list,
990 )
990 )
991 coreconfigitem(
991 coreconfigitem(
992 b'experimental',
992 b'experimental',
993 b'extendedheader.index',
993 b'extendedheader.index',
994 default=None,
994 default=None,
995 )
995 )
996 coreconfigitem(
996 coreconfigitem(
997 b'experimental',
997 b'experimental',
998 b'extendedheader.similarity',
998 b'extendedheader.similarity',
999 default=False,
999 default=False,
1000 )
1000 )
1001 coreconfigitem(
1001 coreconfigitem(
1002 b'experimental',
1002 b'experimental',
1003 b'graphshorten',
1003 b'graphshorten',
1004 default=False,
1004 default=False,
1005 )
1005 )
1006 coreconfigitem(
1006 coreconfigitem(
1007 b'experimental',
1007 b'experimental',
1008 b'graphstyle.parent',
1008 b'graphstyle.parent',
1009 default=dynamicdefault,
1009 default=dynamicdefault,
1010 )
1010 )
1011 coreconfigitem(
1011 coreconfigitem(
1012 b'experimental',
1012 b'experimental',
1013 b'graphstyle.missing',
1013 b'graphstyle.missing',
1014 default=dynamicdefault,
1014 default=dynamicdefault,
1015 )
1015 )
1016 coreconfigitem(
1016 coreconfigitem(
1017 b'experimental',
1017 b'experimental',
1018 b'graphstyle.grandparent',
1018 b'graphstyle.grandparent',
1019 default=dynamicdefault,
1019 default=dynamicdefault,
1020 )
1020 )
1021 coreconfigitem(
1021 coreconfigitem(
1022 b'experimental',
1022 b'experimental',
1023 b'hook-track-tags',
1023 b'hook-track-tags',
1024 default=False,
1024 default=False,
1025 )
1025 )
1026 coreconfigitem(
1026 coreconfigitem(
1027 b'experimental',
1027 b'experimental',
1028 b'httppeer.advertise-v2',
1028 b'httppeer.advertise-v2',
1029 default=False,
1029 default=False,
1030 )
1030 )
1031 coreconfigitem(
1031 coreconfigitem(
1032 b'experimental',
1032 b'experimental',
1033 b'httppeer.v2-encoder-order',
1033 b'httppeer.v2-encoder-order',
1034 default=None,
1034 default=None,
1035 )
1035 )
1036 coreconfigitem(
1036 coreconfigitem(
1037 b'experimental',
1037 b'experimental',
1038 b'httppostargs',
1038 b'httppostargs',
1039 default=False,
1039 default=False,
1040 )
1040 )
1041 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1041 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1042 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1042 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1043
1043
1044 coreconfigitem(
1044 coreconfigitem(
1045 b'experimental',
1045 b'experimental',
1046 b'obsmarkers-exchange-debug',
1046 b'obsmarkers-exchange-debug',
1047 default=False,
1047 default=False,
1048 )
1048 )
1049 coreconfigitem(
1049 coreconfigitem(
1050 b'experimental',
1050 b'experimental',
1051 b'remotenames',
1051 b'remotenames',
1052 default=False,
1052 default=False,
1053 )
1053 )
1054 coreconfigitem(
1054 coreconfigitem(
1055 b'experimental',
1055 b'experimental',
1056 b'removeemptydirs',
1056 b'removeemptydirs',
1057 default=True,
1057 default=True,
1058 )
1058 )
1059 coreconfigitem(
1059 coreconfigitem(
1060 b'experimental',
1060 b'experimental',
1061 b'revert.interactive.select-to-keep',
1061 b'revert.interactive.select-to-keep',
1062 default=False,
1062 default=False,
1063 )
1063 )
1064 coreconfigitem(
1064 coreconfigitem(
1065 b'experimental',
1065 b'experimental',
1066 b'revisions.prefixhexnode',
1066 b'revisions.prefixhexnode',
1067 default=False,
1067 default=False,
1068 )
1068 )
1069 coreconfigitem(
1069 coreconfigitem(
1070 b'experimental',
1070 b'experimental',
1071 b'revlogv2',
1071 b'revlogv2',
1072 default=None,
1072 default=None,
1073 )
1073 )
1074 coreconfigitem(
1074 coreconfigitem(
1075 b'experimental',
1075 b'experimental',
1076 b'revisions.disambiguatewithin',
1076 b'revisions.disambiguatewithin',
1077 default=None,
1077 default=None,
1078 )
1078 )
1079 coreconfigitem(
1079 coreconfigitem(
1080 b'experimental',
1080 b'experimental',
1081 b'rust.index',
1081 b'rust.index',
1082 default=False,
1082 default=False,
1083 )
1083 )
1084 coreconfigitem(
1084 coreconfigitem(
1085 b'experimental',
1085 b'experimental',
1086 b'server.filesdata.recommended-batch-size',
1086 b'server.filesdata.recommended-batch-size',
1087 default=50000,
1087 default=50000,
1088 )
1088 )
1089 coreconfigitem(
1089 coreconfigitem(
1090 b'experimental',
1090 b'experimental',
1091 b'server.manifestdata.recommended-batch-size',
1091 b'server.manifestdata.recommended-batch-size',
1092 default=100000,
1092 default=100000,
1093 )
1093 )
1094 coreconfigitem(
1094 coreconfigitem(
1095 b'experimental',
1095 b'experimental',
1096 b'server.stream-narrow-clones',
1096 b'server.stream-narrow-clones',
1097 default=False,
1097 default=False,
1098 )
1098 )
1099 coreconfigitem(
1099 coreconfigitem(
1100 b'experimental',
1100 b'experimental',
1101 b'sharesafe-warn-outdated-shares',
1102 default=True,
1103 )
1104 coreconfigitem(
1105 b'experimental',
1106 b'single-head-per-branch',
1101 b'single-head-per-branch',
1107 default=False,
1102 default=False,
1108 )
1103 )
1109 coreconfigitem(
1104 coreconfigitem(
1110 b'experimental',
1105 b'experimental',
1111 b'single-head-per-branch:account-closed-heads',
1106 b'single-head-per-branch:account-closed-heads',
1112 default=False,
1107 default=False,
1113 )
1108 )
1114 coreconfigitem(
1109 coreconfigitem(
1115 b'experimental',
1110 b'experimental',
1116 b'single-head-per-branch:public-changes-only',
1111 b'single-head-per-branch:public-changes-only',
1117 default=False,
1112 default=False,
1118 )
1113 )
1119 coreconfigitem(
1114 coreconfigitem(
1120 b'experimental',
1115 b'experimental',
1121 b'sshserver.support-v2',
1116 b'sshserver.support-v2',
1122 default=False,
1117 default=False,
1123 )
1118 )
1124 coreconfigitem(
1119 coreconfigitem(
1125 b'experimental',
1120 b'experimental',
1126 b'sparse-read',
1121 b'sparse-read',
1127 default=False,
1122 default=False,
1128 )
1123 )
1129 coreconfigitem(
1124 coreconfigitem(
1130 b'experimental',
1125 b'experimental',
1131 b'sparse-read.density-threshold',
1126 b'sparse-read.density-threshold',
1132 default=0.50,
1127 default=0.50,
1133 )
1128 )
1134 coreconfigitem(
1129 coreconfigitem(
1135 b'experimental',
1130 b'experimental',
1136 b'sparse-read.min-gap-size',
1131 b'sparse-read.min-gap-size',
1137 default=b'65K',
1132 default=b'65K',
1138 )
1133 )
1139 coreconfigitem(
1134 coreconfigitem(
1140 b'experimental',
1135 b'experimental',
1141 b'treemanifest',
1136 b'treemanifest',
1142 default=False,
1137 default=False,
1143 )
1138 )
1144 coreconfigitem(
1139 coreconfigitem(
1145 b'experimental',
1140 b'experimental',
1146 b'update.atomic-file',
1141 b'update.atomic-file',
1147 default=False,
1142 default=False,
1148 )
1143 )
1149 coreconfigitem(
1144 coreconfigitem(
1150 b'experimental',
1145 b'experimental',
1151 b'sshpeer.advertise-v2',
1146 b'sshpeer.advertise-v2',
1152 default=False,
1147 default=False,
1153 )
1148 )
1154 coreconfigitem(
1149 coreconfigitem(
1155 b'experimental',
1150 b'experimental',
1156 b'web.apiserver',
1151 b'web.apiserver',
1157 default=False,
1152 default=False,
1158 )
1153 )
1159 coreconfigitem(
1154 coreconfigitem(
1160 b'experimental',
1155 b'experimental',
1161 b'web.api.http-v2',
1156 b'web.api.http-v2',
1162 default=False,
1157 default=False,
1163 )
1158 )
1164 coreconfigitem(
1159 coreconfigitem(
1165 b'experimental',
1160 b'experimental',
1166 b'web.api.debugreflect',
1161 b'web.api.debugreflect',
1167 default=False,
1162 default=False,
1168 )
1163 )
1169 coreconfigitem(
1164 coreconfigitem(
1170 b'experimental',
1165 b'experimental',
1171 b'worker.wdir-get-thread-safe',
1166 b'worker.wdir-get-thread-safe',
1172 default=False,
1167 default=False,
1173 )
1168 )
1174 coreconfigitem(
1169 coreconfigitem(
1175 b'experimental',
1170 b'experimental',
1176 b'worker.repository-upgrade',
1171 b'worker.repository-upgrade',
1177 default=False,
1172 default=False,
1178 )
1173 )
1179 coreconfigitem(
1174 coreconfigitem(
1180 b'experimental',
1175 b'experimental',
1181 b'xdiff',
1176 b'xdiff',
1182 default=False,
1177 default=False,
1183 )
1178 )
1184 coreconfigitem(
1179 coreconfigitem(
1185 b'extensions',
1180 b'extensions',
1186 b'.*',
1181 b'.*',
1187 default=None,
1182 default=None,
1188 generic=True,
1183 generic=True,
1189 )
1184 )
1190 coreconfigitem(
1185 coreconfigitem(
1191 b'extdata',
1186 b'extdata',
1192 b'.*',
1187 b'.*',
1193 default=None,
1188 default=None,
1194 generic=True,
1189 generic=True,
1195 )
1190 )
1196 coreconfigitem(
1191 coreconfigitem(
1197 b'format',
1192 b'format',
1198 b'bookmarks-in-store',
1193 b'bookmarks-in-store',
1199 default=False,
1194 default=False,
1200 )
1195 )
1201 coreconfigitem(
1196 coreconfigitem(
1202 b'format',
1197 b'format',
1203 b'chunkcachesize',
1198 b'chunkcachesize',
1204 default=None,
1199 default=None,
1205 experimental=True,
1200 experimental=True,
1206 )
1201 )
1207 coreconfigitem(
1202 coreconfigitem(
1208 b'format',
1203 b'format',
1209 b'dotencode',
1204 b'dotencode',
1210 default=True,
1205 default=True,
1211 )
1206 )
1212 coreconfigitem(
1207 coreconfigitem(
1213 b'format',
1208 b'format',
1214 b'generaldelta',
1209 b'generaldelta',
1215 default=False,
1210 default=False,
1216 experimental=True,
1211 experimental=True,
1217 )
1212 )
1218 coreconfigitem(
1213 coreconfigitem(
1219 b'format',
1214 b'format',
1220 b'manifestcachesize',
1215 b'manifestcachesize',
1221 default=None,
1216 default=None,
1222 experimental=True,
1217 experimental=True,
1223 )
1218 )
1224 coreconfigitem(
1219 coreconfigitem(
1225 b'format',
1220 b'format',
1226 b'maxchainlen',
1221 b'maxchainlen',
1227 default=dynamicdefault,
1222 default=dynamicdefault,
1228 experimental=True,
1223 experimental=True,
1229 )
1224 )
1230 coreconfigitem(
1225 coreconfigitem(
1231 b'format',
1226 b'format',
1232 b'obsstore-version',
1227 b'obsstore-version',
1233 default=None,
1228 default=None,
1234 )
1229 )
1235 coreconfigitem(
1230 coreconfigitem(
1236 b'format',
1231 b'format',
1237 b'sparse-revlog',
1232 b'sparse-revlog',
1238 default=True,
1233 default=True,
1239 )
1234 )
1240 coreconfigitem(
1235 coreconfigitem(
1241 b'format',
1236 b'format',
1242 b'revlog-compression',
1237 b'revlog-compression',
1243 default=lambda: [b'zlib'],
1238 default=lambda: [b'zlib'],
1244 alias=[(b'experimental', b'format.compression')],
1239 alias=[(b'experimental', b'format.compression')],
1245 )
1240 )
1246 coreconfigitem(
1241 coreconfigitem(
1247 b'format',
1242 b'format',
1248 b'usefncache',
1243 b'usefncache',
1249 default=True,
1244 default=True,
1250 )
1245 )
1251 coreconfigitem(
1246 coreconfigitem(
1252 b'format',
1247 b'format',
1253 b'usegeneraldelta',
1248 b'usegeneraldelta',
1254 default=True,
1249 default=True,
1255 )
1250 )
1256 coreconfigitem(
1251 coreconfigitem(
1257 b'format',
1252 b'format',
1258 b'usestore',
1253 b'usestore',
1259 default=True,
1254 default=True,
1260 )
1255 )
1261 coreconfigitem(
1256 coreconfigitem(
1262 b'format',
1257 b'format',
1263 b'use-persistent-nodemap',
1258 b'use-persistent-nodemap',
1264 default=False,
1259 default=False,
1265 )
1260 )
1266 coreconfigitem(
1261 coreconfigitem(
1267 b'format',
1262 b'format',
1268 b'exp-use-copies-side-data-changeset',
1263 b'exp-use-copies-side-data-changeset',
1269 default=False,
1264 default=False,
1270 experimental=True,
1265 experimental=True,
1271 )
1266 )
1272 coreconfigitem(
1267 coreconfigitem(
1273 b'format',
1268 b'format',
1274 b'exp-use-side-data',
1269 b'exp-use-side-data',
1275 default=False,
1270 default=False,
1276 experimental=True,
1271 experimental=True,
1277 )
1272 )
1278 coreconfigitem(
1273 coreconfigitem(
1279 b'format',
1274 b'format',
1280 b'exp-share-safe',
1275 b'exp-share-safe',
1281 default=False,
1276 default=False,
1282 experimental=True,
1277 experimental=True,
1283 )
1278 )
1284 coreconfigitem(
1279 coreconfigitem(
1285 b'format',
1280 b'format',
1286 b'internal-phase',
1281 b'internal-phase',
1287 default=False,
1282 default=False,
1288 experimental=True,
1283 experimental=True,
1289 )
1284 )
1290 coreconfigitem(
1285 coreconfigitem(
1291 b'fsmonitor',
1286 b'fsmonitor',
1292 b'warn_when_unused',
1287 b'warn_when_unused',
1293 default=True,
1288 default=True,
1294 )
1289 )
1295 coreconfigitem(
1290 coreconfigitem(
1296 b'fsmonitor',
1291 b'fsmonitor',
1297 b'warn_update_file_count',
1292 b'warn_update_file_count',
1298 default=50000,
1293 default=50000,
1299 )
1294 )
1300 coreconfigitem(
1295 coreconfigitem(
1301 b'fsmonitor',
1296 b'fsmonitor',
1302 b'warn_update_file_count_rust',
1297 b'warn_update_file_count_rust',
1303 default=400000,
1298 default=400000,
1304 )
1299 )
1305 coreconfigitem(
1300 coreconfigitem(
1306 b'help',
1301 b'help',
1307 br'hidden-command\..*',
1302 br'hidden-command\..*',
1308 default=False,
1303 default=False,
1309 generic=True,
1304 generic=True,
1310 )
1305 )
1311 coreconfigitem(
1306 coreconfigitem(
1312 b'help',
1307 b'help',
1313 br'hidden-topic\..*',
1308 br'hidden-topic\..*',
1314 default=False,
1309 default=False,
1315 generic=True,
1310 generic=True,
1316 )
1311 )
1317 coreconfigitem(
1312 coreconfigitem(
1318 b'hooks',
1313 b'hooks',
1319 b'.*',
1314 b'.*',
1320 default=dynamicdefault,
1315 default=dynamicdefault,
1321 generic=True,
1316 generic=True,
1322 )
1317 )
1323 coreconfigitem(
1318 coreconfigitem(
1324 b'hgweb-paths',
1319 b'hgweb-paths',
1325 b'.*',
1320 b'.*',
1326 default=list,
1321 default=list,
1327 generic=True,
1322 generic=True,
1328 )
1323 )
1329 coreconfigitem(
1324 coreconfigitem(
1330 b'hostfingerprints',
1325 b'hostfingerprints',
1331 b'.*',
1326 b'.*',
1332 default=list,
1327 default=list,
1333 generic=True,
1328 generic=True,
1334 )
1329 )
1335 coreconfigitem(
1330 coreconfigitem(
1336 b'hostsecurity',
1331 b'hostsecurity',
1337 b'ciphers',
1332 b'ciphers',
1338 default=None,
1333 default=None,
1339 )
1334 )
1340 coreconfigitem(
1335 coreconfigitem(
1341 b'hostsecurity',
1336 b'hostsecurity',
1342 b'minimumprotocol',
1337 b'minimumprotocol',
1343 default=dynamicdefault,
1338 default=dynamicdefault,
1344 )
1339 )
1345 coreconfigitem(
1340 coreconfigitem(
1346 b'hostsecurity',
1341 b'hostsecurity',
1347 b'.*:minimumprotocol$',
1342 b'.*:minimumprotocol$',
1348 default=dynamicdefault,
1343 default=dynamicdefault,
1349 generic=True,
1344 generic=True,
1350 )
1345 )
1351 coreconfigitem(
1346 coreconfigitem(
1352 b'hostsecurity',
1347 b'hostsecurity',
1353 b'.*:ciphers$',
1348 b'.*:ciphers$',
1354 default=dynamicdefault,
1349 default=dynamicdefault,
1355 generic=True,
1350 generic=True,
1356 )
1351 )
1357 coreconfigitem(
1352 coreconfigitem(
1358 b'hostsecurity',
1353 b'hostsecurity',
1359 b'.*:fingerprints$',
1354 b'.*:fingerprints$',
1360 default=list,
1355 default=list,
1361 generic=True,
1356 generic=True,
1362 )
1357 )
1363 coreconfigitem(
1358 coreconfigitem(
1364 b'hostsecurity',
1359 b'hostsecurity',
1365 b'.*:verifycertsfile$',
1360 b'.*:verifycertsfile$',
1366 default=None,
1361 default=None,
1367 generic=True,
1362 generic=True,
1368 )
1363 )
1369
1364
1370 coreconfigitem(
1365 coreconfigitem(
1371 b'http_proxy',
1366 b'http_proxy',
1372 b'always',
1367 b'always',
1373 default=False,
1368 default=False,
1374 )
1369 )
1375 coreconfigitem(
1370 coreconfigitem(
1376 b'http_proxy',
1371 b'http_proxy',
1377 b'host',
1372 b'host',
1378 default=None,
1373 default=None,
1379 )
1374 )
1380 coreconfigitem(
1375 coreconfigitem(
1381 b'http_proxy',
1376 b'http_proxy',
1382 b'no',
1377 b'no',
1383 default=list,
1378 default=list,
1384 )
1379 )
1385 coreconfigitem(
1380 coreconfigitem(
1386 b'http_proxy',
1381 b'http_proxy',
1387 b'passwd',
1382 b'passwd',
1388 default=None,
1383 default=None,
1389 )
1384 )
1390 coreconfigitem(
1385 coreconfigitem(
1391 b'http_proxy',
1386 b'http_proxy',
1392 b'user',
1387 b'user',
1393 default=None,
1388 default=None,
1394 )
1389 )
1395
1390
1396 coreconfigitem(
1391 coreconfigitem(
1397 b'http',
1392 b'http',
1398 b'timeout',
1393 b'timeout',
1399 default=None,
1394 default=None,
1400 )
1395 )
1401
1396
1402 coreconfigitem(
1397 coreconfigitem(
1403 b'logtoprocess',
1398 b'logtoprocess',
1404 b'commandexception',
1399 b'commandexception',
1405 default=None,
1400 default=None,
1406 )
1401 )
1407 coreconfigitem(
1402 coreconfigitem(
1408 b'logtoprocess',
1403 b'logtoprocess',
1409 b'commandfinish',
1404 b'commandfinish',
1410 default=None,
1405 default=None,
1411 )
1406 )
1412 coreconfigitem(
1407 coreconfigitem(
1413 b'logtoprocess',
1408 b'logtoprocess',
1414 b'command',
1409 b'command',
1415 default=None,
1410 default=None,
1416 )
1411 )
1417 coreconfigitem(
1412 coreconfigitem(
1418 b'logtoprocess',
1413 b'logtoprocess',
1419 b'develwarn',
1414 b'develwarn',
1420 default=None,
1415 default=None,
1421 )
1416 )
1422 coreconfigitem(
1417 coreconfigitem(
1423 b'logtoprocess',
1418 b'logtoprocess',
1424 b'uiblocked',
1419 b'uiblocked',
1425 default=None,
1420 default=None,
1426 )
1421 )
1427 coreconfigitem(
1422 coreconfigitem(
1428 b'merge',
1423 b'merge',
1429 b'checkunknown',
1424 b'checkunknown',
1430 default=b'abort',
1425 default=b'abort',
1431 )
1426 )
1432 coreconfigitem(
1427 coreconfigitem(
1433 b'merge',
1428 b'merge',
1434 b'checkignored',
1429 b'checkignored',
1435 default=b'abort',
1430 default=b'abort',
1436 )
1431 )
1437 coreconfigitem(
1432 coreconfigitem(
1438 b'experimental',
1433 b'experimental',
1439 b'merge.checkpathconflicts',
1434 b'merge.checkpathconflicts',
1440 default=False,
1435 default=False,
1441 )
1436 )
1442 coreconfigitem(
1437 coreconfigitem(
1443 b'merge',
1438 b'merge',
1444 b'followcopies',
1439 b'followcopies',
1445 default=True,
1440 default=True,
1446 )
1441 )
1447 coreconfigitem(
1442 coreconfigitem(
1448 b'merge',
1443 b'merge',
1449 b'on-failure',
1444 b'on-failure',
1450 default=b'continue',
1445 default=b'continue',
1451 )
1446 )
1452 coreconfigitem(
1447 coreconfigitem(
1453 b'merge',
1448 b'merge',
1454 b'preferancestor',
1449 b'preferancestor',
1455 default=lambda: [b'*'],
1450 default=lambda: [b'*'],
1456 experimental=True,
1451 experimental=True,
1457 )
1452 )
1458 coreconfigitem(
1453 coreconfigitem(
1459 b'merge',
1454 b'merge',
1460 b'strict-capability-check',
1455 b'strict-capability-check',
1461 default=False,
1456 default=False,
1462 )
1457 )
1463 coreconfigitem(
1458 coreconfigitem(
1464 b'merge-tools',
1459 b'merge-tools',
1465 b'.*',
1460 b'.*',
1466 default=None,
1461 default=None,
1467 generic=True,
1462 generic=True,
1468 )
1463 )
1469 coreconfigitem(
1464 coreconfigitem(
1470 b'merge-tools',
1465 b'merge-tools',
1471 br'.*\.args$',
1466 br'.*\.args$',
1472 default=b"$local $base $other",
1467 default=b"$local $base $other",
1473 generic=True,
1468 generic=True,
1474 priority=-1,
1469 priority=-1,
1475 )
1470 )
1476 coreconfigitem(
1471 coreconfigitem(
1477 b'merge-tools',
1472 b'merge-tools',
1478 br'.*\.binary$',
1473 br'.*\.binary$',
1479 default=False,
1474 default=False,
1480 generic=True,
1475 generic=True,
1481 priority=-1,
1476 priority=-1,
1482 )
1477 )
1483 coreconfigitem(
1478 coreconfigitem(
1484 b'merge-tools',
1479 b'merge-tools',
1485 br'.*\.check$',
1480 br'.*\.check$',
1486 default=list,
1481 default=list,
1487 generic=True,
1482 generic=True,
1488 priority=-1,
1483 priority=-1,
1489 )
1484 )
1490 coreconfigitem(
1485 coreconfigitem(
1491 b'merge-tools',
1486 b'merge-tools',
1492 br'.*\.checkchanged$',
1487 br'.*\.checkchanged$',
1493 default=False,
1488 default=False,
1494 generic=True,
1489 generic=True,
1495 priority=-1,
1490 priority=-1,
1496 )
1491 )
1497 coreconfigitem(
1492 coreconfigitem(
1498 b'merge-tools',
1493 b'merge-tools',
1499 br'.*\.executable$',
1494 br'.*\.executable$',
1500 default=dynamicdefault,
1495 default=dynamicdefault,
1501 generic=True,
1496 generic=True,
1502 priority=-1,
1497 priority=-1,
1503 )
1498 )
1504 coreconfigitem(
1499 coreconfigitem(
1505 b'merge-tools',
1500 b'merge-tools',
1506 br'.*\.fixeol$',
1501 br'.*\.fixeol$',
1507 default=False,
1502 default=False,
1508 generic=True,
1503 generic=True,
1509 priority=-1,
1504 priority=-1,
1510 )
1505 )
1511 coreconfigitem(
1506 coreconfigitem(
1512 b'merge-tools',
1507 b'merge-tools',
1513 br'.*\.gui$',
1508 br'.*\.gui$',
1514 default=False,
1509 default=False,
1515 generic=True,
1510 generic=True,
1516 priority=-1,
1511 priority=-1,
1517 )
1512 )
1518 coreconfigitem(
1513 coreconfigitem(
1519 b'merge-tools',
1514 b'merge-tools',
1520 br'.*\.mergemarkers$',
1515 br'.*\.mergemarkers$',
1521 default=b'basic',
1516 default=b'basic',
1522 generic=True,
1517 generic=True,
1523 priority=-1,
1518 priority=-1,
1524 )
1519 )
1525 coreconfigitem(
1520 coreconfigitem(
1526 b'merge-tools',
1521 b'merge-tools',
1527 br'.*\.mergemarkertemplate$',
1522 br'.*\.mergemarkertemplate$',
1528 default=dynamicdefault, # take from command-templates.mergemarker
1523 default=dynamicdefault, # take from command-templates.mergemarker
1529 generic=True,
1524 generic=True,
1530 priority=-1,
1525 priority=-1,
1531 )
1526 )
1532 coreconfigitem(
1527 coreconfigitem(
1533 b'merge-tools',
1528 b'merge-tools',
1534 br'.*\.priority$',
1529 br'.*\.priority$',
1535 default=0,
1530 default=0,
1536 generic=True,
1531 generic=True,
1537 priority=-1,
1532 priority=-1,
1538 )
1533 )
1539 coreconfigitem(
1534 coreconfigitem(
1540 b'merge-tools',
1535 b'merge-tools',
1541 br'.*\.premerge$',
1536 br'.*\.premerge$',
1542 default=dynamicdefault,
1537 default=dynamicdefault,
1543 generic=True,
1538 generic=True,
1544 priority=-1,
1539 priority=-1,
1545 )
1540 )
1546 coreconfigitem(
1541 coreconfigitem(
1547 b'merge-tools',
1542 b'merge-tools',
1548 br'.*\.symlink$',
1543 br'.*\.symlink$',
1549 default=False,
1544 default=False,
1550 generic=True,
1545 generic=True,
1551 priority=-1,
1546 priority=-1,
1552 )
1547 )
1553 coreconfigitem(
1548 coreconfigitem(
1554 b'pager',
1549 b'pager',
1555 b'attend-.*',
1550 b'attend-.*',
1556 default=dynamicdefault,
1551 default=dynamicdefault,
1557 generic=True,
1552 generic=True,
1558 )
1553 )
1559 coreconfigitem(
1554 coreconfigitem(
1560 b'pager',
1555 b'pager',
1561 b'ignore',
1556 b'ignore',
1562 default=list,
1557 default=list,
1563 )
1558 )
1564 coreconfigitem(
1559 coreconfigitem(
1565 b'pager',
1560 b'pager',
1566 b'pager',
1561 b'pager',
1567 default=dynamicdefault,
1562 default=dynamicdefault,
1568 )
1563 )
1569 coreconfigitem(
1564 coreconfigitem(
1570 b'patch',
1565 b'patch',
1571 b'eol',
1566 b'eol',
1572 default=b'strict',
1567 default=b'strict',
1573 )
1568 )
1574 coreconfigitem(
1569 coreconfigitem(
1575 b'patch',
1570 b'patch',
1576 b'fuzz',
1571 b'fuzz',
1577 default=2,
1572 default=2,
1578 )
1573 )
1579 coreconfigitem(
1574 coreconfigitem(
1580 b'paths',
1575 b'paths',
1581 b'default',
1576 b'default',
1582 default=None,
1577 default=None,
1583 )
1578 )
1584 coreconfigitem(
1579 coreconfigitem(
1585 b'paths',
1580 b'paths',
1586 b'default-push',
1581 b'default-push',
1587 default=None,
1582 default=None,
1588 )
1583 )
1589 coreconfigitem(
1584 coreconfigitem(
1590 b'paths',
1585 b'paths',
1591 b'.*',
1586 b'.*',
1592 default=None,
1587 default=None,
1593 generic=True,
1588 generic=True,
1594 )
1589 )
1595 coreconfigitem(
1590 coreconfigitem(
1596 b'phases',
1591 b'phases',
1597 b'checksubrepos',
1592 b'checksubrepos',
1598 default=b'follow',
1593 default=b'follow',
1599 )
1594 )
1600 coreconfigitem(
1595 coreconfigitem(
1601 b'phases',
1596 b'phases',
1602 b'new-commit',
1597 b'new-commit',
1603 default=b'draft',
1598 default=b'draft',
1604 )
1599 )
1605 coreconfigitem(
1600 coreconfigitem(
1606 b'phases',
1601 b'phases',
1607 b'publish',
1602 b'publish',
1608 default=True,
1603 default=True,
1609 )
1604 )
1610 coreconfigitem(
1605 coreconfigitem(
1611 b'profiling',
1606 b'profiling',
1612 b'enabled',
1607 b'enabled',
1613 default=False,
1608 default=False,
1614 )
1609 )
1615 coreconfigitem(
1610 coreconfigitem(
1616 b'profiling',
1611 b'profiling',
1617 b'format',
1612 b'format',
1618 default=b'text',
1613 default=b'text',
1619 )
1614 )
1620 coreconfigitem(
1615 coreconfigitem(
1621 b'profiling',
1616 b'profiling',
1622 b'freq',
1617 b'freq',
1623 default=1000,
1618 default=1000,
1624 )
1619 )
1625 coreconfigitem(
1620 coreconfigitem(
1626 b'profiling',
1621 b'profiling',
1627 b'limit',
1622 b'limit',
1628 default=30,
1623 default=30,
1629 )
1624 )
1630 coreconfigitem(
1625 coreconfigitem(
1631 b'profiling',
1626 b'profiling',
1632 b'nested',
1627 b'nested',
1633 default=0,
1628 default=0,
1634 )
1629 )
1635 coreconfigitem(
1630 coreconfigitem(
1636 b'profiling',
1631 b'profiling',
1637 b'output',
1632 b'output',
1638 default=None,
1633 default=None,
1639 )
1634 )
1640 coreconfigitem(
1635 coreconfigitem(
1641 b'profiling',
1636 b'profiling',
1642 b'showmax',
1637 b'showmax',
1643 default=0.999,
1638 default=0.999,
1644 )
1639 )
1645 coreconfigitem(
1640 coreconfigitem(
1646 b'profiling',
1641 b'profiling',
1647 b'showmin',
1642 b'showmin',
1648 default=dynamicdefault,
1643 default=dynamicdefault,
1649 )
1644 )
1650 coreconfigitem(
1645 coreconfigitem(
1651 b'profiling',
1646 b'profiling',
1652 b'showtime',
1647 b'showtime',
1653 default=True,
1648 default=True,
1654 )
1649 )
1655 coreconfigitem(
1650 coreconfigitem(
1656 b'profiling',
1651 b'profiling',
1657 b'sort',
1652 b'sort',
1658 default=b'inlinetime',
1653 default=b'inlinetime',
1659 )
1654 )
1660 coreconfigitem(
1655 coreconfigitem(
1661 b'profiling',
1656 b'profiling',
1662 b'statformat',
1657 b'statformat',
1663 default=b'hotpath',
1658 default=b'hotpath',
1664 )
1659 )
1665 coreconfigitem(
1660 coreconfigitem(
1666 b'profiling',
1661 b'profiling',
1667 b'time-track',
1662 b'time-track',
1668 default=dynamicdefault,
1663 default=dynamicdefault,
1669 )
1664 )
1670 coreconfigitem(
1665 coreconfigitem(
1671 b'profiling',
1666 b'profiling',
1672 b'type',
1667 b'type',
1673 default=b'stat',
1668 default=b'stat',
1674 )
1669 )
1675 coreconfigitem(
1670 coreconfigitem(
1676 b'progress',
1671 b'progress',
1677 b'assume-tty',
1672 b'assume-tty',
1678 default=False,
1673 default=False,
1679 )
1674 )
1680 coreconfigitem(
1675 coreconfigitem(
1681 b'progress',
1676 b'progress',
1682 b'changedelay',
1677 b'changedelay',
1683 default=1,
1678 default=1,
1684 )
1679 )
1685 coreconfigitem(
1680 coreconfigitem(
1686 b'progress',
1681 b'progress',
1687 b'clear-complete',
1682 b'clear-complete',
1688 default=True,
1683 default=True,
1689 )
1684 )
1690 coreconfigitem(
1685 coreconfigitem(
1691 b'progress',
1686 b'progress',
1692 b'debug',
1687 b'debug',
1693 default=False,
1688 default=False,
1694 )
1689 )
1695 coreconfigitem(
1690 coreconfigitem(
1696 b'progress',
1691 b'progress',
1697 b'delay',
1692 b'delay',
1698 default=3,
1693 default=3,
1699 )
1694 )
1700 coreconfigitem(
1695 coreconfigitem(
1701 b'progress',
1696 b'progress',
1702 b'disable',
1697 b'disable',
1703 default=False,
1698 default=False,
1704 )
1699 )
1705 coreconfigitem(
1700 coreconfigitem(
1706 b'progress',
1701 b'progress',
1707 b'estimateinterval',
1702 b'estimateinterval',
1708 default=60.0,
1703 default=60.0,
1709 )
1704 )
1710 coreconfigitem(
1705 coreconfigitem(
1711 b'progress',
1706 b'progress',
1712 b'format',
1707 b'format',
1713 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1708 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1714 )
1709 )
1715 coreconfigitem(
1710 coreconfigitem(
1716 b'progress',
1711 b'progress',
1717 b'refresh',
1712 b'refresh',
1718 default=0.1,
1713 default=0.1,
1719 )
1714 )
1720 coreconfigitem(
1715 coreconfigitem(
1721 b'progress',
1716 b'progress',
1722 b'width',
1717 b'width',
1723 default=dynamicdefault,
1718 default=dynamicdefault,
1724 )
1719 )
1725 coreconfigitem(
1720 coreconfigitem(
1726 b'pull',
1721 b'pull',
1727 b'confirm',
1722 b'confirm',
1728 default=False,
1723 default=False,
1729 )
1724 )
1730 coreconfigitem(
1725 coreconfigitem(
1731 b'push',
1726 b'push',
1732 b'pushvars.server',
1727 b'pushvars.server',
1733 default=False,
1728 default=False,
1734 )
1729 )
1735 coreconfigitem(
1730 coreconfigitem(
1736 b'rewrite',
1731 b'rewrite',
1737 b'backup-bundle',
1732 b'backup-bundle',
1738 default=True,
1733 default=True,
1739 alias=[(b'ui', b'history-editing-backup')],
1734 alias=[(b'ui', b'history-editing-backup')],
1740 )
1735 )
1741 coreconfigitem(
1736 coreconfigitem(
1742 b'rewrite',
1737 b'rewrite',
1743 b'update-timestamp',
1738 b'update-timestamp',
1744 default=False,
1739 default=False,
1745 )
1740 )
1746 coreconfigitem(
1741 coreconfigitem(
1747 b'rewrite',
1742 b'rewrite',
1748 b'empty-successor',
1743 b'empty-successor',
1749 default=b'skip',
1744 default=b'skip',
1750 experimental=True,
1745 experimental=True,
1751 )
1746 )
1752 coreconfigitem(
1747 coreconfigitem(
1753 b'storage',
1748 b'storage',
1754 b'new-repo-backend',
1749 b'new-repo-backend',
1755 default=b'revlogv1',
1750 default=b'revlogv1',
1756 experimental=True,
1751 experimental=True,
1757 )
1752 )
1758 coreconfigitem(
1753 coreconfigitem(
1759 b'storage',
1754 b'storage',
1760 b'revlog.optimize-delta-parent-choice',
1755 b'revlog.optimize-delta-parent-choice',
1761 default=True,
1756 default=True,
1762 alias=[(b'format', b'aggressivemergedeltas')],
1757 alias=[(b'format', b'aggressivemergedeltas')],
1763 )
1758 )
1764 # experimental as long as rust is experimental (or a C version is implemented)
1759 # experimental as long as rust is experimental (or a C version is implemented)
1765 coreconfigitem(
1760 coreconfigitem(
1766 b'storage',
1761 b'storage',
1767 b'revlog.persistent-nodemap.mmap',
1762 b'revlog.persistent-nodemap.mmap',
1768 default=True,
1763 default=True,
1769 )
1764 )
1770 # experimental as long as format.use-persistent-nodemap is.
1765 # experimental as long as format.use-persistent-nodemap is.
1771 coreconfigitem(
1766 coreconfigitem(
1772 b'storage',
1767 b'storage',
1773 b'revlog.persistent-nodemap.slow-path',
1768 b'revlog.persistent-nodemap.slow-path',
1774 default=b"abort",
1769 default=b"abort",
1775 )
1770 )
1776
1771
1777 coreconfigitem(
1772 coreconfigitem(
1778 b'storage',
1773 b'storage',
1779 b'revlog.reuse-external-delta',
1774 b'revlog.reuse-external-delta',
1780 default=True,
1775 default=True,
1781 )
1776 )
1782 coreconfigitem(
1777 coreconfigitem(
1783 b'storage',
1778 b'storage',
1784 b'revlog.reuse-external-delta-parent',
1779 b'revlog.reuse-external-delta-parent',
1785 default=None,
1780 default=None,
1786 )
1781 )
1787 coreconfigitem(
1782 coreconfigitem(
1788 b'storage',
1783 b'storage',
1789 b'revlog.zlib.level',
1784 b'revlog.zlib.level',
1790 default=None,
1785 default=None,
1791 )
1786 )
1792 coreconfigitem(
1787 coreconfigitem(
1793 b'storage',
1788 b'storage',
1794 b'revlog.zstd.level',
1789 b'revlog.zstd.level',
1795 default=None,
1790 default=None,
1796 )
1791 )
1797 coreconfigitem(
1792 coreconfigitem(
1798 b'server',
1793 b'server',
1799 b'bookmarks-pushkey-compat',
1794 b'bookmarks-pushkey-compat',
1800 default=True,
1795 default=True,
1801 )
1796 )
1802 coreconfigitem(
1797 coreconfigitem(
1803 b'server',
1798 b'server',
1804 b'bundle1',
1799 b'bundle1',
1805 default=True,
1800 default=True,
1806 )
1801 )
1807 coreconfigitem(
1802 coreconfigitem(
1808 b'server',
1803 b'server',
1809 b'bundle1gd',
1804 b'bundle1gd',
1810 default=None,
1805 default=None,
1811 )
1806 )
1812 coreconfigitem(
1807 coreconfigitem(
1813 b'server',
1808 b'server',
1814 b'bundle1.pull',
1809 b'bundle1.pull',
1815 default=None,
1810 default=None,
1816 )
1811 )
1817 coreconfigitem(
1812 coreconfigitem(
1818 b'server',
1813 b'server',
1819 b'bundle1gd.pull',
1814 b'bundle1gd.pull',
1820 default=None,
1815 default=None,
1821 )
1816 )
1822 coreconfigitem(
1817 coreconfigitem(
1823 b'server',
1818 b'server',
1824 b'bundle1.push',
1819 b'bundle1.push',
1825 default=None,
1820 default=None,
1826 )
1821 )
1827 coreconfigitem(
1822 coreconfigitem(
1828 b'server',
1823 b'server',
1829 b'bundle1gd.push',
1824 b'bundle1gd.push',
1830 default=None,
1825 default=None,
1831 )
1826 )
1832 coreconfigitem(
1827 coreconfigitem(
1833 b'server',
1828 b'server',
1834 b'bundle2.stream',
1829 b'bundle2.stream',
1835 default=True,
1830 default=True,
1836 alias=[(b'experimental', b'bundle2.stream')],
1831 alias=[(b'experimental', b'bundle2.stream')],
1837 )
1832 )
1838 coreconfigitem(
1833 coreconfigitem(
1839 b'server',
1834 b'server',
1840 b'compressionengines',
1835 b'compressionengines',
1841 default=list,
1836 default=list,
1842 )
1837 )
1843 coreconfigitem(
1838 coreconfigitem(
1844 b'server',
1839 b'server',
1845 b'concurrent-push-mode',
1840 b'concurrent-push-mode',
1846 default=b'check-related',
1841 default=b'check-related',
1847 )
1842 )
1848 coreconfigitem(
1843 coreconfigitem(
1849 b'server',
1844 b'server',
1850 b'disablefullbundle',
1845 b'disablefullbundle',
1851 default=False,
1846 default=False,
1852 )
1847 )
1853 coreconfigitem(
1848 coreconfigitem(
1854 b'server',
1849 b'server',
1855 b'maxhttpheaderlen',
1850 b'maxhttpheaderlen',
1856 default=1024,
1851 default=1024,
1857 )
1852 )
1858 coreconfigitem(
1853 coreconfigitem(
1859 b'server',
1854 b'server',
1860 b'pullbundle',
1855 b'pullbundle',
1861 default=False,
1856 default=False,
1862 )
1857 )
1863 coreconfigitem(
1858 coreconfigitem(
1864 b'server',
1859 b'server',
1865 b'preferuncompressed',
1860 b'preferuncompressed',
1866 default=False,
1861 default=False,
1867 )
1862 )
1868 coreconfigitem(
1863 coreconfigitem(
1869 b'server',
1864 b'server',
1870 b'streamunbundle',
1865 b'streamunbundle',
1871 default=False,
1866 default=False,
1872 )
1867 )
1873 coreconfigitem(
1868 coreconfigitem(
1874 b'server',
1869 b'server',
1875 b'uncompressed',
1870 b'uncompressed',
1876 default=True,
1871 default=True,
1877 )
1872 )
1878 coreconfigitem(
1873 coreconfigitem(
1879 b'server',
1874 b'server',
1880 b'uncompressedallowsecret',
1875 b'uncompressedallowsecret',
1881 default=False,
1876 default=False,
1882 )
1877 )
1883 coreconfigitem(
1878 coreconfigitem(
1884 b'server',
1879 b'server',
1885 b'view',
1880 b'view',
1886 default=b'served',
1881 default=b'served',
1887 )
1882 )
1888 coreconfigitem(
1883 coreconfigitem(
1889 b'server',
1884 b'server',
1890 b'validate',
1885 b'validate',
1891 default=False,
1886 default=False,
1892 )
1887 )
1893 coreconfigitem(
1888 coreconfigitem(
1894 b'server',
1889 b'server',
1895 b'zliblevel',
1890 b'zliblevel',
1896 default=-1,
1891 default=-1,
1897 )
1892 )
1898 coreconfigitem(
1893 coreconfigitem(
1899 b'server',
1894 b'server',
1900 b'zstdlevel',
1895 b'zstdlevel',
1901 default=3,
1896 default=3,
1902 )
1897 )
1903 coreconfigitem(
1898 coreconfigitem(
1904 b'share',
1899 b'share',
1905 b'pool',
1900 b'pool',
1906 default=None,
1901 default=None,
1907 )
1902 )
1908 coreconfigitem(
1903 coreconfigitem(
1909 b'share',
1904 b'share',
1910 b'poolnaming',
1905 b'poolnaming',
1911 default=b'identity',
1906 default=b'identity',
1912 )
1907 )
1913 coreconfigitem(
1908 coreconfigitem(
1914 b'share',
1909 b'share',
1915 b'safe-mismatch.source-not-safe',
1910 b'safe-mismatch.source-not-safe',
1916 default=b'abort',
1911 default=b'abort',
1917 )
1912 )
1918 coreconfigitem(
1913 coreconfigitem(
1919 b'share',
1914 b'share',
1920 b'safe-mismatch.source-safe',
1915 b'safe-mismatch.source-safe',
1921 default=b'abort',
1916 default=b'abort',
1922 )
1917 )
1923 coreconfigitem(
1918 coreconfigitem(
1919 b'share',
1920 b'safe-mismatch.source-not-safe.warn',
1921 default=True,
1922 )
1923 coreconfigitem(
1924 b'share',
1925 b'safe-mismatch.source-safe.warn',
1926 default=True,
1927 )
1928 coreconfigitem(
1924 b'shelve',
1929 b'shelve',
1925 b'maxbackups',
1930 b'maxbackups',
1926 default=10,
1931 default=10,
1927 )
1932 )
1928 coreconfigitem(
1933 coreconfigitem(
1929 b'smtp',
1934 b'smtp',
1930 b'host',
1935 b'host',
1931 default=None,
1936 default=None,
1932 )
1937 )
1933 coreconfigitem(
1938 coreconfigitem(
1934 b'smtp',
1939 b'smtp',
1935 b'local_hostname',
1940 b'local_hostname',
1936 default=None,
1941 default=None,
1937 )
1942 )
1938 coreconfigitem(
1943 coreconfigitem(
1939 b'smtp',
1944 b'smtp',
1940 b'password',
1945 b'password',
1941 default=None,
1946 default=None,
1942 )
1947 )
1943 coreconfigitem(
1948 coreconfigitem(
1944 b'smtp',
1949 b'smtp',
1945 b'port',
1950 b'port',
1946 default=dynamicdefault,
1951 default=dynamicdefault,
1947 )
1952 )
1948 coreconfigitem(
1953 coreconfigitem(
1949 b'smtp',
1954 b'smtp',
1950 b'tls',
1955 b'tls',
1951 default=b'none',
1956 default=b'none',
1952 )
1957 )
1953 coreconfigitem(
1958 coreconfigitem(
1954 b'smtp',
1959 b'smtp',
1955 b'username',
1960 b'username',
1956 default=None,
1961 default=None,
1957 )
1962 )
1958 coreconfigitem(
1963 coreconfigitem(
1959 b'sparse',
1964 b'sparse',
1960 b'missingwarning',
1965 b'missingwarning',
1961 default=True,
1966 default=True,
1962 experimental=True,
1967 experimental=True,
1963 )
1968 )
1964 coreconfigitem(
1969 coreconfigitem(
1965 b'subrepos',
1970 b'subrepos',
1966 b'allowed',
1971 b'allowed',
1967 default=dynamicdefault, # to make backporting simpler
1972 default=dynamicdefault, # to make backporting simpler
1968 )
1973 )
1969 coreconfigitem(
1974 coreconfigitem(
1970 b'subrepos',
1975 b'subrepos',
1971 b'hg:allowed',
1976 b'hg:allowed',
1972 default=dynamicdefault,
1977 default=dynamicdefault,
1973 )
1978 )
1974 coreconfigitem(
1979 coreconfigitem(
1975 b'subrepos',
1980 b'subrepos',
1976 b'git:allowed',
1981 b'git:allowed',
1977 default=dynamicdefault,
1982 default=dynamicdefault,
1978 )
1983 )
1979 coreconfigitem(
1984 coreconfigitem(
1980 b'subrepos',
1985 b'subrepos',
1981 b'svn:allowed',
1986 b'svn:allowed',
1982 default=dynamicdefault,
1987 default=dynamicdefault,
1983 )
1988 )
1984 coreconfigitem(
1989 coreconfigitem(
1985 b'templates',
1990 b'templates',
1986 b'.*',
1991 b'.*',
1987 default=None,
1992 default=None,
1988 generic=True,
1993 generic=True,
1989 )
1994 )
1990 coreconfigitem(
1995 coreconfigitem(
1991 b'templateconfig',
1996 b'templateconfig',
1992 b'.*',
1997 b'.*',
1993 default=dynamicdefault,
1998 default=dynamicdefault,
1994 generic=True,
1999 generic=True,
1995 )
2000 )
1996 coreconfigitem(
2001 coreconfigitem(
1997 b'trusted',
2002 b'trusted',
1998 b'groups',
2003 b'groups',
1999 default=list,
2004 default=list,
2000 )
2005 )
2001 coreconfigitem(
2006 coreconfigitem(
2002 b'trusted',
2007 b'trusted',
2003 b'users',
2008 b'users',
2004 default=list,
2009 default=list,
2005 )
2010 )
2006 coreconfigitem(
2011 coreconfigitem(
2007 b'ui',
2012 b'ui',
2008 b'_usedassubrepo',
2013 b'_usedassubrepo',
2009 default=False,
2014 default=False,
2010 )
2015 )
2011 coreconfigitem(
2016 coreconfigitem(
2012 b'ui',
2017 b'ui',
2013 b'allowemptycommit',
2018 b'allowemptycommit',
2014 default=False,
2019 default=False,
2015 )
2020 )
2016 coreconfigitem(
2021 coreconfigitem(
2017 b'ui',
2022 b'ui',
2018 b'archivemeta',
2023 b'archivemeta',
2019 default=True,
2024 default=True,
2020 )
2025 )
2021 coreconfigitem(
2026 coreconfigitem(
2022 b'ui',
2027 b'ui',
2023 b'askusername',
2028 b'askusername',
2024 default=False,
2029 default=False,
2025 )
2030 )
2026 coreconfigitem(
2031 coreconfigitem(
2027 b'ui',
2032 b'ui',
2028 b'available-memory',
2033 b'available-memory',
2029 default=None,
2034 default=None,
2030 )
2035 )
2031
2036
2032 coreconfigitem(
2037 coreconfigitem(
2033 b'ui',
2038 b'ui',
2034 b'clonebundlefallback',
2039 b'clonebundlefallback',
2035 default=False,
2040 default=False,
2036 )
2041 )
2037 coreconfigitem(
2042 coreconfigitem(
2038 b'ui',
2043 b'ui',
2039 b'clonebundleprefers',
2044 b'clonebundleprefers',
2040 default=list,
2045 default=list,
2041 )
2046 )
2042 coreconfigitem(
2047 coreconfigitem(
2043 b'ui',
2048 b'ui',
2044 b'clonebundles',
2049 b'clonebundles',
2045 default=True,
2050 default=True,
2046 )
2051 )
2047 coreconfigitem(
2052 coreconfigitem(
2048 b'ui',
2053 b'ui',
2049 b'color',
2054 b'color',
2050 default=b'auto',
2055 default=b'auto',
2051 )
2056 )
2052 coreconfigitem(
2057 coreconfigitem(
2053 b'ui',
2058 b'ui',
2054 b'commitsubrepos',
2059 b'commitsubrepos',
2055 default=False,
2060 default=False,
2056 )
2061 )
2057 coreconfigitem(
2062 coreconfigitem(
2058 b'ui',
2063 b'ui',
2059 b'debug',
2064 b'debug',
2060 default=False,
2065 default=False,
2061 )
2066 )
2062 coreconfigitem(
2067 coreconfigitem(
2063 b'ui',
2068 b'ui',
2064 b'debugger',
2069 b'debugger',
2065 default=None,
2070 default=None,
2066 )
2071 )
2067 coreconfigitem(
2072 coreconfigitem(
2068 b'ui',
2073 b'ui',
2069 b'editor',
2074 b'editor',
2070 default=dynamicdefault,
2075 default=dynamicdefault,
2071 )
2076 )
2072 coreconfigitem(
2077 coreconfigitem(
2073 b'ui',
2078 b'ui',
2074 b'detailed-exit-code',
2079 b'detailed-exit-code',
2075 default=False,
2080 default=False,
2076 experimental=True,
2081 experimental=True,
2077 )
2082 )
2078 coreconfigitem(
2083 coreconfigitem(
2079 b'ui',
2084 b'ui',
2080 b'fallbackencoding',
2085 b'fallbackencoding',
2081 default=None,
2086 default=None,
2082 )
2087 )
2083 coreconfigitem(
2088 coreconfigitem(
2084 b'ui',
2089 b'ui',
2085 b'forcecwd',
2090 b'forcecwd',
2086 default=None,
2091 default=None,
2087 )
2092 )
2088 coreconfigitem(
2093 coreconfigitem(
2089 b'ui',
2094 b'ui',
2090 b'forcemerge',
2095 b'forcemerge',
2091 default=None,
2096 default=None,
2092 )
2097 )
2093 coreconfigitem(
2098 coreconfigitem(
2094 b'ui',
2099 b'ui',
2095 b'formatdebug',
2100 b'formatdebug',
2096 default=False,
2101 default=False,
2097 )
2102 )
2098 coreconfigitem(
2103 coreconfigitem(
2099 b'ui',
2104 b'ui',
2100 b'formatjson',
2105 b'formatjson',
2101 default=False,
2106 default=False,
2102 )
2107 )
2103 coreconfigitem(
2108 coreconfigitem(
2104 b'ui',
2109 b'ui',
2105 b'formatted',
2110 b'formatted',
2106 default=None,
2111 default=None,
2107 )
2112 )
2108 coreconfigitem(
2113 coreconfigitem(
2109 b'ui',
2114 b'ui',
2110 b'interactive',
2115 b'interactive',
2111 default=None,
2116 default=None,
2112 )
2117 )
2113 coreconfigitem(
2118 coreconfigitem(
2114 b'ui',
2119 b'ui',
2115 b'interface',
2120 b'interface',
2116 default=None,
2121 default=None,
2117 )
2122 )
2118 coreconfigitem(
2123 coreconfigitem(
2119 b'ui',
2124 b'ui',
2120 b'interface.chunkselector',
2125 b'interface.chunkselector',
2121 default=None,
2126 default=None,
2122 )
2127 )
2123 coreconfigitem(
2128 coreconfigitem(
2124 b'ui',
2129 b'ui',
2125 b'large-file-limit',
2130 b'large-file-limit',
2126 default=10000000,
2131 default=10000000,
2127 )
2132 )
2128 coreconfigitem(
2133 coreconfigitem(
2129 b'ui',
2134 b'ui',
2130 b'logblockedtimes',
2135 b'logblockedtimes',
2131 default=False,
2136 default=False,
2132 )
2137 )
2133 coreconfigitem(
2138 coreconfigitem(
2134 b'ui',
2139 b'ui',
2135 b'merge',
2140 b'merge',
2136 default=None,
2141 default=None,
2137 )
2142 )
2138 coreconfigitem(
2143 coreconfigitem(
2139 b'ui',
2144 b'ui',
2140 b'mergemarkers',
2145 b'mergemarkers',
2141 default=b'basic',
2146 default=b'basic',
2142 )
2147 )
2143 coreconfigitem(
2148 coreconfigitem(
2144 b'ui',
2149 b'ui',
2145 b'message-output',
2150 b'message-output',
2146 default=b'stdio',
2151 default=b'stdio',
2147 )
2152 )
2148 coreconfigitem(
2153 coreconfigitem(
2149 b'ui',
2154 b'ui',
2150 b'nontty',
2155 b'nontty',
2151 default=False,
2156 default=False,
2152 )
2157 )
2153 coreconfigitem(
2158 coreconfigitem(
2154 b'ui',
2159 b'ui',
2155 b'origbackuppath',
2160 b'origbackuppath',
2156 default=None,
2161 default=None,
2157 )
2162 )
2158 coreconfigitem(
2163 coreconfigitem(
2159 b'ui',
2164 b'ui',
2160 b'paginate',
2165 b'paginate',
2161 default=True,
2166 default=True,
2162 )
2167 )
2163 coreconfigitem(
2168 coreconfigitem(
2164 b'ui',
2169 b'ui',
2165 b'patch',
2170 b'patch',
2166 default=None,
2171 default=None,
2167 )
2172 )
2168 coreconfigitem(
2173 coreconfigitem(
2169 b'ui',
2174 b'ui',
2170 b'portablefilenames',
2175 b'portablefilenames',
2171 default=b'warn',
2176 default=b'warn',
2172 )
2177 )
2173 coreconfigitem(
2178 coreconfigitem(
2174 b'ui',
2179 b'ui',
2175 b'promptecho',
2180 b'promptecho',
2176 default=False,
2181 default=False,
2177 )
2182 )
2178 coreconfigitem(
2183 coreconfigitem(
2179 b'ui',
2184 b'ui',
2180 b'quiet',
2185 b'quiet',
2181 default=False,
2186 default=False,
2182 )
2187 )
2183 coreconfigitem(
2188 coreconfigitem(
2184 b'ui',
2189 b'ui',
2185 b'quietbookmarkmove',
2190 b'quietbookmarkmove',
2186 default=False,
2191 default=False,
2187 )
2192 )
2188 coreconfigitem(
2193 coreconfigitem(
2189 b'ui',
2194 b'ui',
2190 b'relative-paths',
2195 b'relative-paths',
2191 default=b'legacy',
2196 default=b'legacy',
2192 )
2197 )
2193 coreconfigitem(
2198 coreconfigitem(
2194 b'ui',
2199 b'ui',
2195 b'remotecmd',
2200 b'remotecmd',
2196 default=b'hg',
2201 default=b'hg',
2197 )
2202 )
2198 coreconfigitem(
2203 coreconfigitem(
2199 b'ui',
2204 b'ui',
2200 b'report_untrusted',
2205 b'report_untrusted',
2201 default=True,
2206 default=True,
2202 )
2207 )
2203 coreconfigitem(
2208 coreconfigitem(
2204 b'ui',
2209 b'ui',
2205 b'rollback',
2210 b'rollback',
2206 default=True,
2211 default=True,
2207 )
2212 )
2208 coreconfigitem(
2213 coreconfigitem(
2209 b'ui',
2214 b'ui',
2210 b'signal-safe-lock',
2215 b'signal-safe-lock',
2211 default=True,
2216 default=True,
2212 )
2217 )
2213 coreconfigitem(
2218 coreconfigitem(
2214 b'ui',
2219 b'ui',
2215 b'slash',
2220 b'slash',
2216 default=False,
2221 default=False,
2217 )
2222 )
2218 coreconfigitem(
2223 coreconfigitem(
2219 b'ui',
2224 b'ui',
2220 b'ssh',
2225 b'ssh',
2221 default=b'ssh',
2226 default=b'ssh',
2222 )
2227 )
2223 coreconfigitem(
2228 coreconfigitem(
2224 b'ui',
2229 b'ui',
2225 b'ssherrorhint',
2230 b'ssherrorhint',
2226 default=None,
2231 default=None,
2227 )
2232 )
2228 coreconfigitem(
2233 coreconfigitem(
2229 b'ui',
2234 b'ui',
2230 b'statuscopies',
2235 b'statuscopies',
2231 default=False,
2236 default=False,
2232 )
2237 )
2233 coreconfigitem(
2238 coreconfigitem(
2234 b'ui',
2239 b'ui',
2235 b'strict',
2240 b'strict',
2236 default=False,
2241 default=False,
2237 )
2242 )
2238 coreconfigitem(
2243 coreconfigitem(
2239 b'ui',
2244 b'ui',
2240 b'style',
2245 b'style',
2241 default=b'',
2246 default=b'',
2242 )
2247 )
2243 coreconfigitem(
2248 coreconfigitem(
2244 b'ui',
2249 b'ui',
2245 b'supportcontact',
2250 b'supportcontact',
2246 default=None,
2251 default=None,
2247 )
2252 )
2248 coreconfigitem(
2253 coreconfigitem(
2249 b'ui',
2254 b'ui',
2250 b'textwidth',
2255 b'textwidth',
2251 default=78,
2256 default=78,
2252 )
2257 )
2253 coreconfigitem(
2258 coreconfigitem(
2254 b'ui',
2259 b'ui',
2255 b'timeout',
2260 b'timeout',
2256 default=b'600',
2261 default=b'600',
2257 )
2262 )
2258 coreconfigitem(
2263 coreconfigitem(
2259 b'ui',
2264 b'ui',
2260 b'timeout.warn',
2265 b'timeout.warn',
2261 default=0,
2266 default=0,
2262 )
2267 )
2263 coreconfigitem(
2268 coreconfigitem(
2264 b'ui',
2269 b'ui',
2265 b'timestamp-output',
2270 b'timestamp-output',
2266 default=False,
2271 default=False,
2267 )
2272 )
2268 coreconfigitem(
2273 coreconfigitem(
2269 b'ui',
2274 b'ui',
2270 b'traceback',
2275 b'traceback',
2271 default=False,
2276 default=False,
2272 )
2277 )
2273 coreconfigitem(
2278 coreconfigitem(
2274 b'ui',
2279 b'ui',
2275 b'tweakdefaults',
2280 b'tweakdefaults',
2276 default=False,
2281 default=False,
2277 )
2282 )
2278 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2283 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2279 coreconfigitem(
2284 coreconfigitem(
2280 b'ui',
2285 b'ui',
2281 b'verbose',
2286 b'verbose',
2282 default=False,
2287 default=False,
2283 )
2288 )
2284 coreconfigitem(
2289 coreconfigitem(
2285 b'verify',
2290 b'verify',
2286 b'skipflags',
2291 b'skipflags',
2287 default=None,
2292 default=None,
2288 )
2293 )
2289 coreconfigitem(
2294 coreconfigitem(
2290 b'web',
2295 b'web',
2291 b'allowbz2',
2296 b'allowbz2',
2292 default=False,
2297 default=False,
2293 )
2298 )
2294 coreconfigitem(
2299 coreconfigitem(
2295 b'web',
2300 b'web',
2296 b'allowgz',
2301 b'allowgz',
2297 default=False,
2302 default=False,
2298 )
2303 )
2299 coreconfigitem(
2304 coreconfigitem(
2300 b'web',
2305 b'web',
2301 b'allow-pull',
2306 b'allow-pull',
2302 alias=[(b'web', b'allowpull')],
2307 alias=[(b'web', b'allowpull')],
2303 default=True,
2308 default=True,
2304 )
2309 )
2305 coreconfigitem(
2310 coreconfigitem(
2306 b'web',
2311 b'web',
2307 b'allow-push',
2312 b'allow-push',
2308 alias=[(b'web', b'allow_push')],
2313 alias=[(b'web', b'allow_push')],
2309 default=list,
2314 default=list,
2310 )
2315 )
2311 coreconfigitem(
2316 coreconfigitem(
2312 b'web',
2317 b'web',
2313 b'allowzip',
2318 b'allowzip',
2314 default=False,
2319 default=False,
2315 )
2320 )
2316 coreconfigitem(
2321 coreconfigitem(
2317 b'web',
2322 b'web',
2318 b'archivesubrepos',
2323 b'archivesubrepos',
2319 default=False,
2324 default=False,
2320 )
2325 )
2321 coreconfigitem(
2326 coreconfigitem(
2322 b'web',
2327 b'web',
2323 b'cache',
2328 b'cache',
2324 default=True,
2329 default=True,
2325 )
2330 )
2326 coreconfigitem(
2331 coreconfigitem(
2327 b'web',
2332 b'web',
2328 b'comparisoncontext',
2333 b'comparisoncontext',
2329 default=5,
2334 default=5,
2330 )
2335 )
2331 coreconfigitem(
2336 coreconfigitem(
2332 b'web',
2337 b'web',
2333 b'contact',
2338 b'contact',
2334 default=None,
2339 default=None,
2335 )
2340 )
2336 coreconfigitem(
2341 coreconfigitem(
2337 b'web',
2342 b'web',
2338 b'deny_push',
2343 b'deny_push',
2339 default=list,
2344 default=list,
2340 )
2345 )
2341 coreconfigitem(
2346 coreconfigitem(
2342 b'web',
2347 b'web',
2343 b'guessmime',
2348 b'guessmime',
2344 default=False,
2349 default=False,
2345 )
2350 )
2346 coreconfigitem(
2351 coreconfigitem(
2347 b'web',
2352 b'web',
2348 b'hidden',
2353 b'hidden',
2349 default=False,
2354 default=False,
2350 )
2355 )
2351 coreconfigitem(
2356 coreconfigitem(
2352 b'web',
2357 b'web',
2353 b'labels',
2358 b'labels',
2354 default=list,
2359 default=list,
2355 )
2360 )
2356 coreconfigitem(
2361 coreconfigitem(
2357 b'web',
2362 b'web',
2358 b'logoimg',
2363 b'logoimg',
2359 default=b'hglogo.png',
2364 default=b'hglogo.png',
2360 )
2365 )
2361 coreconfigitem(
2366 coreconfigitem(
2362 b'web',
2367 b'web',
2363 b'logourl',
2368 b'logourl',
2364 default=b'https://mercurial-scm.org/',
2369 default=b'https://mercurial-scm.org/',
2365 )
2370 )
2366 coreconfigitem(
2371 coreconfigitem(
2367 b'web',
2372 b'web',
2368 b'accesslog',
2373 b'accesslog',
2369 default=b'-',
2374 default=b'-',
2370 )
2375 )
2371 coreconfigitem(
2376 coreconfigitem(
2372 b'web',
2377 b'web',
2373 b'address',
2378 b'address',
2374 default=b'',
2379 default=b'',
2375 )
2380 )
2376 coreconfigitem(
2381 coreconfigitem(
2377 b'web',
2382 b'web',
2378 b'allow-archive',
2383 b'allow-archive',
2379 alias=[(b'web', b'allow_archive')],
2384 alias=[(b'web', b'allow_archive')],
2380 default=list,
2385 default=list,
2381 )
2386 )
2382 coreconfigitem(
2387 coreconfigitem(
2383 b'web',
2388 b'web',
2384 b'allow_read',
2389 b'allow_read',
2385 default=list,
2390 default=list,
2386 )
2391 )
2387 coreconfigitem(
2392 coreconfigitem(
2388 b'web',
2393 b'web',
2389 b'baseurl',
2394 b'baseurl',
2390 default=None,
2395 default=None,
2391 )
2396 )
2392 coreconfigitem(
2397 coreconfigitem(
2393 b'web',
2398 b'web',
2394 b'cacerts',
2399 b'cacerts',
2395 default=None,
2400 default=None,
2396 )
2401 )
2397 coreconfigitem(
2402 coreconfigitem(
2398 b'web',
2403 b'web',
2399 b'certificate',
2404 b'certificate',
2400 default=None,
2405 default=None,
2401 )
2406 )
2402 coreconfigitem(
2407 coreconfigitem(
2403 b'web',
2408 b'web',
2404 b'collapse',
2409 b'collapse',
2405 default=False,
2410 default=False,
2406 )
2411 )
2407 coreconfigitem(
2412 coreconfigitem(
2408 b'web',
2413 b'web',
2409 b'csp',
2414 b'csp',
2410 default=None,
2415 default=None,
2411 )
2416 )
2412 coreconfigitem(
2417 coreconfigitem(
2413 b'web',
2418 b'web',
2414 b'deny_read',
2419 b'deny_read',
2415 default=list,
2420 default=list,
2416 )
2421 )
2417 coreconfigitem(
2422 coreconfigitem(
2418 b'web',
2423 b'web',
2419 b'descend',
2424 b'descend',
2420 default=True,
2425 default=True,
2421 )
2426 )
2422 coreconfigitem(
2427 coreconfigitem(
2423 b'web',
2428 b'web',
2424 b'description',
2429 b'description',
2425 default=b"",
2430 default=b"",
2426 )
2431 )
2427 coreconfigitem(
2432 coreconfigitem(
2428 b'web',
2433 b'web',
2429 b'encoding',
2434 b'encoding',
2430 default=lambda: encoding.encoding,
2435 default=lambda: encoding.encoding,
2431 )
2436 )
2432 coreconfigitem(
2437 coreconfigitem(
2433 b'web',
2438 b'web',
2434 b'errorlog',
2439 b'errorlog',
2435 default=b'-',
2440 default=b'-',
2436 )
2441 )
2437 coreconfigitem(
2442 coreconfigitem(
2438 b'web',
2443 b'web',
2439 b'ipv6',
2444 b'ipv6',
2440 default=False,
2445 default=False,
2441 )
2446 )
2442 coreconfigitem(
2447 coreconfigitem(
2443 b'web',
2448 b'web',
2444 b'maxchanges',
2449 b'maxchanges',
2445 default=10,
2450 default=10,
2446 )
2451 )
2447 coreconfigitem(
2452 coreconfigitem(
2448 b'web',
2453 b'web',
2449 b'maxfiles',
2454 b'maxfiles',
2450 default=10,
2455 default=10,
2451 )
2456 )
2452 coreconfigitem(
2457 coreconfigitem(
2453 b'web',
2458 b'web',
2454 b'maxshortchanges',
2459 b'maxshortchanges',
2455 default=60,
2460 default=60,
2456 )
2461 )
2457 coreconfigitem(
2462 coreconfigitem(
2458 b'web',
2463 b'web',
2459 b'motd',
2464 b'motd',
2460 default=b'',
2465 default=b'',
2461 )
2466 )
2462 coreconfigitem(
2467 coreconfigitem(
2463 b'web',
2468 b'web',
2464 b'name',
2469 b'name',
2465 default=dynamicdefault,
2470 default=dynamicdefault,
2466 )
2471 )
2467 coreconfigitem(
2472 coreconfigitem(
2468 b'web',
2473 b'web',
2469 b'port',
2474 b'port',
2470 default=8000,
2475 default=8000,
2471 )
2476 )
2472 coreconfigitem(
2477 coreconfigitem(
2473 b'web',
2478 b'web',
2474 b'prefix',
2479 b'prefix',
2475 default=b'',
2480 default=b'',
2476 )
2481 )
2477 coreconfigitem(
2482 coreconfigitem(
2478 b'web',
2483 b'web',
2479 b'push_ssl',
2484 b'push_ssl',
2480 default=True,
2485 default=True,
2481 )
2486 )
2482 coreconfigitem(
2487 coreconfigitem(
2483 b'web',
2488 b'web',
2484 b'refreshinterval',
2489 b'refreshinterval',
2485 default=20,
2490 default=20,
2486 )
2491 )
2487 coreconfigitem(
2492 coreconfigitem(
2488 b'web',
2493 b'web',
2489 b'server-header',
2494 b'server-header',
2490 default=None,
2495 default=None,
2491 )
2496 )
2492 coreconfigitem(
2497 coreconfigitem(
2493 b'web',
2498 b'web',
2494 b'static',
2499 b'static',
2495 default=None,
2500 default=None,
2496 )
2501 )
2497 coreconfigitem(
2502 coreconfigitem(
2498 b'web',
2503 b'web',
2499 b'staticurl',
2504 b'staticurl',
2500 default=None,
2505 default=None,
2501 )
2506 )
2502 coreconfigitem(
2507 coreconfigitem(
2503 b'web',
2508 b'web',
2504 b'stripes',
2509 b'stripes',
2505 default=1,
2510 default=1,
2506 )
2511 )
2507 coreconfigitem(
2512 coreconfigitem(
2508 b'web',
2513 b'web',
2509 b'style',
2514 b'style',
2510 default=b'paper',
2515 default=b'paper',
2511 )
2516 )
2512 coreconfigitem(
2517 coreconfigitem(
2513 b'web',
2518 b'web',
2514 b'templates',
2519 b'templates',
2515 default=None,
2520 default=None,
2516 )
2521 )
2517 coreconfigitem(
2522 coreconfigitem(
2518 b'web',
2523 b'web',
2519 b'view',
2524 b'view',
2520 default=b'served',
2525 default=b'served',
2521 experimental=True,
2526 experimental=True,
2522 )
2527 )
2523 coreconfigitem(
2528 coreconfigitem(
2524 b'worker',
2529 b'worker',
2525 b'backgroundclose',
2530 b'backgroundclose',
2526 default=dynamicdefault,
2531 default=dynamicdefault,
2527 )
2532 )
2528 # Windows defaults to a limit of 512 open files. A buffer of 128
2533 # Windows defaults to a limit of 512 open files. A buffer of 128
2529 # should give us enough headway.
2534 # should give us enough headway.
2530 coreconfigitem(
2535 coreconfigitem(
2531 b'worker',
2536 b'worker',
2532 b'backgroundclosemaxqueue',
2537 b'backgroundclosemaxqueue',
2533 default=384,
2538 default=384,
2534 )
2539 )
2535 coreconfigitem(
2540 coreconfigitem(
2536 b'worker',
2541 b'worker',
2537 b'backgroundcloseminfilecount',
2542 b'backgroundcloseminfilecount',
2538 default=2048,
2543 default=2048,
2539 )
2544 )
2540 coreconfigitem(
2545 coreconfigitem(
2541 b'worker',
2546 b'worker',
2542 b'backgroundclosethreadcount',
2547 b'backgroundclosethreadcount',
2543 default=4,
2548 default=4,
2544 )
2549 )
2545 coreconfigitem(
2550 coreconfigitem(
2546 b'worker',
2551 b'worker',
2547 b'enabled',
2552 b'enabled',
2548 default=True,
2553 default=True,
2549 )
2554 )
2550 coreconfigitem(
2555 coreconfigitem(
2551 b'worker',
2556 b'worker',
2552 b'numcpus',
2557 b'numcpus',
2553 default=None,
2558 default=None,
2554 )
2559 )
2555
2560
2556 # Rebase related configuration moved to core because other extension are doing
2561 # Rebase related configuration moved to core because other extension are doing
2557 # strange things. For example, shelve import the extensions to reuse some bit
2562 # strange things. For example, shelve import the extensions to reuse some bit
2558 # without formally loading it.
2563 # without formally loading it.
2559 coreconfigitem(
2564 coreconfigitem(
2560 b'commands',
2565 b'commands',
2561 b'rebase.requiredest',
2566 b'rebase.requiredest',
2562 default=False,
2567 default=False,
2563 )
2568 )
2564 coreconfigitem(
2569 coreconfigitem(
2565 b'experimental',
2570 b'experimental',
2566 b'rebaseskipobsolete',
2571 b'rebaseskipobsolete',
2567 default=True,
2572 default=True,
2568 )
2573 )
2569 coreconfigitem(
2574 coreconfigitem(
2570 b'rebase',
2575 b'rebase',
2571 b'singletransaction',
2576 b'singletransaction',
2572 default=False,
2577 default=False,
2573 )
2578 )
2574 coreconfigitem(
2579 coreconfigitem(
2575 b'rebase',
2580 b'rebase',
2576 b'experimental.inmemory',
2581 b'experimental.inmemory',
2577 default=False,
2582 default=False,
2578 )
2583 )
@@ -1,3021 +1,3031 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 not using a version of Mercurial compiled
907 implemented in Rust, so people not using a version of Mercurial compiled
908 with the Rust part might actually suffer some slowdown. For this reason,
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
909 Such version will by default refuse to access such repositories. That
910 behavior can be controlled by configuration. Check
910 behavior can be controlled by configuration. Check
911 :hg:`help config.storage.revlog.persistent-nodemap.slowpath` for details.
911 :hg:`help config.storage.revlog.persistent-nodemap.slowpath` for details.
912
912
913 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.
914
914
915 Disabled by default.
915 Disabled by default.
916
916
917 ``usestore``
917 ``usestore``
918 Enable or disable the "store" repository format which improves
918 Enable or disable the "store" repository format which improves
919 compatibility with systems that fold case or otherwise mangle
919 compatibility with systems that fold case or otherwise mangle
920 filenames. Disabling this option will allow you to store longer filenames
920 filenames. Disabling this option will allow you to store longer filenames
921 in some situations at the expense of compatibility.
921 in some situations at the expense of compatibility.
922
922
923 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.
924
924
925 Enabled by default.
925 Enabled by default.
926
926
927 ``sparse-revlog``
927 ``sparse-revlog``
928 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
928 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
929 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
930 smaller store. For repositories with many revisions, it also helps
930 smaller store. For repositories with many revisions, it also helps
931 performance (by using shortened delta chains.)
931 performance (by using shortened delta chains.)
932
932
933 Repositories with this on-disk format require Mercurial version 4.7
933 Repositories with this on-disk format require Mercurial version 4.7
934
934
935 Enabled by default.
935 Enabled by default.
936
936
937 ``revlog-compression``
937 ``revlog-compression``
938 Compression algorithm used by revlog. Supported values are `zlib` and
938 Compression algorithm used by revlog. Supported values are `zlib` and
939 `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
940 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
941 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
941 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
942 can be specified, the first available one will be used.
942 can be specified, the first available one will be used.
943
943
944 On some systems, the Mercurial installation may lack `zstd` support.
944 On some systems, the Mercurial installation may lack `zstd` support.
945
945
946 Default is `zlib`.
946 Default is `zlib`.
947
947
948 ``bookmarks-in-store``
948 ``bookmarks-in-store``
949 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
950 using `hg share` regardless of the `-B` option.
950 using `hg share` regardless of the `-B` option.
951
951
952 Repositories with this on-disk format require Mercurial version 5.1.
952 Repositories with this on-disk format require Mercurial version 5.1.
953
953
954 Disabled by default.
954 Disabled by default.
955
955
956
956
957 ``graph``
957 ``graph``
958 ---------
958 ---------
959
959
960 Web graph view configuration. This section let you change graph
960 Web graph view configuration. This section let you change graph
961 elements display properties by branches, for instance to make the
961 elements display properties by branches, for instance to make the
962 ``default`` branch stand out.
962 ``default`` branch stand out.
963
963
964 Each line has the following format::
964 Each line has the following format::
965
965
966 <branch>.<argument> = <value>
966 <branch>.<argument> = <value>
967
967
968 where ``<branch>`` is the name of the branch being
968 where ``<branch>`` is the name of the branch being
969 customized. Example::
969 customized. Example::
970
970
971 [graph]
971 [graph]
972 # 2px width
972 # 2px width
973 default.width = 2
973 default.width = 2
974 # red color
974 # red color
975 default.color = FF0000
975 default.color = FF0000
976
976
977 Supported arguments:
977 Supported arguments:
978
978
979 ``width``
979 ``width``
980 Set branch edges width in pixels.
980 Set branch edges width in pixels.
981
981
982 ``color``
982 ``color``
983 Set branch edges color in hexadecimal RGB notation.
983 Set branch edges color in hexadecimal RGB notation.
984
984
985 ``hooks``
985 ``hooks``
986 ---------
986 ---------
987
987
988 Commands or Python functions that get automatically executed by
988 Commands or Python functions that get automatically executed by
989 various actions such as starting or finishing a commit. Multiple
989 various actions such as starting or finishing a commit. Multiple
990 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
991 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
992 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
993 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
994 and setting the priority. The default priority is 0.
994 and setting the priority. The default priority is 0.
995
995
996 Example ``.hg/hgrc``::
996 Example ``.hg/hgrc``::
997
997
998 [hooks]
998 [hooks]
999 # update working directory after adding changesets
999 # update working directory after adding changesets
1000 changegroup.update = hg update
1000 changegroup.update = hg update
1001 # do not use the site-wide hook
1001 # do not use the site-wide hook
1002 incoming =
1002 incoming =
1003 incoming.email = /my/email/hook
1003 incoming.email = /my/email/hook
1004 incoming.autobuild = /my/build/hook
1004 incoming.autobuild = /my/build/hook
1005 # force autobuild hook to run before other incoming hooks
1005 # force autobuild hook to run before other incoming hooks
1006 priority.incoming.autobuild = 1
1006 priority.incoming.autobuild = 1
1007
1007
1008 Most hooks are run with environment variables set that give useful
1008 Most hooks are run with environment variables set that give useful
1009 additional information. For each hook below, the environment variables
1009 additional information. For each hook below, the environment variables
1010 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
1011 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1011 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1012 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
1013 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
1014 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1014 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1015
1015
1016 .. container:: windows
1016 .. container:: windows
1017
1017
1018 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1018 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1019 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1019 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1020 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1020 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1021 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
1022 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
1023 double quotes after processing.
1023 double quotes after processing.
1024
1024
1025 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
1026 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::
1027
1027
1028 [hooks]
1028 [hooks]
1029 incoming.autobuild = /my/build/hook
1029 incoming.autobuild = /my/build/hook
1030 # enable translation to cmd.exe syntax for autobuild hook
1030 # enable translation to cmd.exe syntax for autobuild hook
1031 tonative.incoming.autobuild = True
1031 tonative.incoming.autobuild = True
1032
1032
1033 ``changegroup``
1033 ``changegroup``
1034 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
1035 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``.
1036 The URL from which changes came is in ``$HG_URL``.
1036 The URL from which changes came is in ``$HG_URL``.
1037
1037
1038 ``commit``
1038 ``commit``
1039 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
1040 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1040 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1041 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1041 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1042
1042
1043 ``incoming``
1043 ``incoming``
1044 Run after a changeset has been pulled, pushed, or unbundled into
1044 Run after a changeset has been pulled, pushed, or unbundled into
1045 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
1046 ``$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``.
1047
1047
1048 ``outgoing``
1048 ``outgoing``
1049 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
1050 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
1051 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1051 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1052
1052
1053 ``post-<command>``
1053 ``post-<command>``
1054 Run after successful invocations of the associated command. The
1054 Run after successful invocations of the associated command. The
1055 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
1056 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1056 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1057 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1057 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1058 the python data internally passed to <command>. ``$HG_OPTS`` is a
1058 the python data internally passed to <command>. ``$HG_OPTS`` is a
1059 dictionary of options (with unspecified options set to their defaults).
1059 dictionary of options (with unspecified options set to their defaults).
1060 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1060 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1061
1061
1062 ``fail-<command>``
1062 ``fail-<command>``
1063 Run after a failed invocation of an associated command. The contents
1063 Run after a failed invocation of an associated command. The contents
1064 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
1065 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1065 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1066 string representations of the python data internally passed to
1066 string representations of the python data internally passed to
1067 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1067 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1068 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.
1069 Hook failure is ignored.
1069 Hook failure is ignored.
1070
1070
1071 ``pre-<command>``
1071 ``pre-<command>``
1072 Run before executing the associated command. The contents of the
1072 Run before executing the associated command. The contents of the
1073 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1073 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1074 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1074 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1075 representations of the data internally passed to <command>. ``$HG_OPTS``
1075 representations of the data internally passed to <command>. ``$HG_OPTS``
1076 is a dictionary of options (with unspecified options set to their
1076 is a dictionary of options (with unspecified options set to their
1077 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
1078 failure, the command doesn't execute and Mercurial returns the failure
1078 failure, the command doesn't execute and Mercurial returns the failure
1079 code.
1079 code.
1080
1080
1081 ``prechangegroup``
1081 ``prechangegroup``
1082 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
1083 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
1084 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
1085 will come is in ``$HG_URL``.
1085 will come is in ``$HG_URL``.
1086
1086
1087 ``precommit``
1087 ``precommit``
1088 Run before starting a local commit. Exit status 0 allows the
1088 Run before starting a local commit. Exit status 0 allows the
1089 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.
1090 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1090 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1091
1091
1092 ``prelistkeys``
1092 ``prelistkeys``
1093 Run before listing pushkeys (like bookmarks) in the
1093 Run before listing pushkeys (like bookmarks) in the
1094 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
1095 in ``$HG_NAMESPACE``.
1095 in ``$HG_NAMESPACE``.
1096
1096
1097 ``preoutgoing``
1097 ``preoutgoing``
1098 Run before collecting changes to send from the local repository to
1098 Run before collecting changes to send from the local repository to
1099 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
1100 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
1101 local pull, push (outbound) or bundle commands), but not completely,
1101 local pull, push (outbound) or bundle commands), but not completely,
1102 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
1103 ``$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
1104 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1104 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1105 is happening on behalf of a repository on same system.
1105 is happening on behalf of a repository on same system.
1106
1106
1107 ``prepushkey``
1107 ``prepushkey``
1108 Run before a pushkey (like a bookmark) is added to the
1108 Run before a pushkey (like a bookmark) is added to the
1109 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
1110 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``,
1111 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
1112 ``$HG_NEW``.
1112 ``$HG_NEW``.
1113
1113
1114 ``pretag``
1114 ``pretag``
1115 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
1116 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
1117 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
1118 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``.
1119
1119
1120 ``pretxnopen``
1120 ``pretxnopen``
1121 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
1122 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
1123 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
1124 transaction from being opened.
1124 transaction from being opened.
1125
1125
1126 ``pretxnclose``
1126 ``pretxnclose``
1127 Run right before the transaction is actually finalized. Any repository change
1127 Run right before the transaction is actually finalized. Any repository change
1128 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
1129 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
1130 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
1131 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
1132 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
1133 vary according the transaction type. New changesets will add ``$HG_NODE``
1133 vary according the transaction type. New changesets will add ``$HG_NODE``
1134 (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
1135 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1135 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1136 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``
1137 respectively, etc.
1137 respectively, etc.
1138
1138
1139 ``pretxnclose-bookmark``
1139 ``pretxnclose-bookmark``
1140 Run right before a bookmark change is actually finalized. Any repository
1140 Run right before a bookmark change is actually finalized. Any repository
1141 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
1142 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
1143 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.
1144 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
1145 bookmark location will be available in ``$HG_NODE`` while the previous
1145 bookmark location will be available in ``$HG_NODE`` while the previous
1146 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
1147 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``
1148 will be empty.
1148 will be empty.
1149 In addition, the reason for the transaction opening will be in
1149 In addition, the reason for the transaction opening will be in
1150 ``$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
1151 ``HG_TXNID``.
1151 ``HG_TXNID``.
1152
1152
1153 ``pretxnclose-phase``
1153 ``pretxnclose-phase``
1154 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
1155 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
1156 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
1157 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
1158 multiple times, once for each revision affected by a phase change.
1158 multiple times, once for each revision affected by a phase change.
1159 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``
1160 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``
1161 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
1162 ``$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
1163 ``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
1164 the ``$HG_OLDPHASE`` entry will be empty.
1164 the ``$HG_OLDPHASE`` entry will be empty.
1165
1165
1166 ``txnclose``
1166 ``txnclose``
1167 Run after any repository transaction has been committed. At this
1167 Run after any repository transaction has been committed. At this
1168 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
1169 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
1170 details about available variables.
1170 details about available variables.
1171
1171
1172 ``txnclose-bookmark``
1172 ``txnclose-bookmark``
1173 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
1174 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
1175 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1175 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1176 about available variables.
1176 about available variables.
1177
1177
1178 ``txnclose-phase``
1178 ``txnclose-phase``
1179 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
1180 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
1181 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
1182 available variables.
1182 available variables.
1183
1183
1184 ``txnabort``
1184 ``txnabort``
1185 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`
1186 for details about available variables.
1186 for details about available variables.
1187
1187
1188 ``pretxnchangegroup``
1188 ``pretxnchangegroup``
1189 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
1190 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
1191 program. This allows validation of incoming changes before accepting them.
1191 program. This allows validation of incoming changes before accepting them.
1192 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
1193 ``$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
1194 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
1195 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``.
1196
1196
1197 ``pretxncommit``
1197 ``pretxncommit``
1198 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
1199 committed. The changeset is visible to the hook program. This allows
1199 committed. The changeset is visible to the hook program. This allows
1200 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
1201 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
1202 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
1203 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1203 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1204
1204
1205 ``preupdate``
1205 ``preupdate``
1206 Run before updating the working directory. Exit status 0 allows
1206 Run before updating the working directory. Exit status 0 allows
1207 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.
1208 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
1209 merge, the ID of second new parent is in ``$HG_PARENT2``.
1209 merge, the ID of second new parent is in ``$HG_PARENT2``.
1210
1210
1211 ``listkeys``
1211 ``listkeys``
1212 Run after listing pushkeys (like bookmarks) in the repository. The
1212 Run after listing pushkeys (like bookmarks) in the repository. The
1213 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1213 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1214 dictionary containing the keys and values.
1214 dictionary containing the keys and values.
1215
1215
1216 ``pushkey``
1216 ``pushkey``
1217 Run after a pushkey (like a bookmark) is added to the
1217 Run after a pushkey (like a bookmark) is added to the
1218 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
1219 ``$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
1220 value is in ``$HG_NEW``.
1220 value is in ``$HG_NEW``.
1221
1221
1222 ``tag``
1222 ``tag``
1223 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``.
1224 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
1225 the repository if ``$HG_LOCAL=0``.
1225 the repository if ``$HG_LOCAL=0``.
1226
1226
1227 ``update``
1227 ``update``
1228 Run after updating the working directory. The changeset ID of first
1228 Run after updating the working directory. The changeset ID of first
1229 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
1230 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
1231 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``.
1232
1232
1233 .. note::
1233 .. note::
1234
1234
1235 It is generally better to use standard hooks rather than the
1235 It is generally better to use standard hooks rather than the
1236 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
1237 called in the appropriate contexts for influencing transactions.
1237 called in the appropriate contexts for influencing transactions.
1238 Also, hooks like "commit" will be called in all contexts that
1238 Also, hooks like "commit" will be called in all contexts that
1239 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.
1240
1240
1241 .. note::
1241 .. note::
1242
1242
1243 Environment variables with empty values may not be passed to
1243 Environment variables with empty values may not be passed to
1244 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1244 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1245 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
1246 changesets, while it will not be available at all under Windows.
1246 changesets, while it will not be available at all under Windows.
1247
1247
1248 The syntax for Python hooks is as follows::
1248 The syntax for Python hooks is as follows::
1249
1249
1250 hookname = python:modulename.submodule.callable
1250 hookname = python:modulename.submodule.callable
1251 hookname = python:/path/to/python/module.py:callable
1251 hookname = python:/path/to/python/module.py:callable
1252
1252
1253 Python hooks are run within the Mercurial process. Each hook is
1253 Python hooks are run within the Mercurial process. Each hook is
1254 called with at least three keyword arguments: a ui object (keyword
1254 called with at least three keyword arguments: a ui object (keyword
1255 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1255 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1256 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
1257 environment variables above are passed as keyword arguments, with no
1257 environment variables above are passed as keyword arguments, with no
1258 ``HG_`` prefix, and names in lower case.
1258 ``HG_`` prefix, and names in lower case.
1259
1259
1260 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
1261 is treated as a failure.
1261 is treated as a failure.
1262
1262
1263
1263
1264 ``hostfingerprints``
1264 ``hostfingerprints``
1265 --------------------
1265 --------------------
1266
1266
1267 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1267 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1268
1268
1269 Fingerprints of the certificates of known HTTPS servers.
1269 Fingerprints of the certificates of known HTTPS servers.
1270
1270
1271 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
1272 only succeed if the servers certificate matches the fingerprint.
1272 only succeed if the servers certificate matches the fingerprint.
1273 This is very similar to how ssh known hosts works.
1273 This is very similar to how ssh known hosts works.
1274
1274
1275 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.
1276 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
1277 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
1278 to a new certificate.
1278 to a new certificate.
1279
1279
1280 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.
1281
1281
1282 For example::
1282 For example::
1283
1283
1284 [hostfingerprints]
1284 [hostfingerprints]
1285 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
1286 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
1287
1287
1288 ``hostsecurity``
1288 ``hostsecurity``
1289 ----------------
1289 ----------------
1290
1290
1291 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
1292 other machines.
1292 other machines.
1293
1293
1294 The following options control default behavior for all hosts.
1294 The following options control default behavior for all hosts.
1295
1295
1296 ``ciphers``
1296 ``ciphers``
1297 Defines the cryptographic ciphers to use for connections.
1297 Defines the cryptographic ciphers to use for connections.
1298
1298
1299 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
1300 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.
1301
1301
1302 This setting is for advanced users only. Setting to incorrect values
1302 This setting is for advanced users only. Setting to incorrect values
1303 can significantly lower connection security or decrease performance.
1303 can significantly lower connection security or decrease performance.
1304 You have been warned.
1304 You have been warned.
1305
1305
1306 This option requires Python 2.7.
1306 This option requires Python 2.7.
1307
1307
1308 ``minimumprotocol``
1308 ``minimumprotocol``
1309 Defines the minimum channel encryption protocol to use.
1309 Defines the minimum channel encryption protocol to use.
1310
1310
1311 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
1312 is used.
1312 is used.
1313
1313
1314 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1314 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1315
1315
1316 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
1317 old versions of Python only support up to TLS 1.0.
1317 old versions of Python only support up to TLS 1.0.
1318
1318
1319 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
1320 ``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
1321 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
1322 a server does not support TLS 1.1+.
1322 a server does not support TLS 1.1+.
1323
1323
1324 Options in the ``[hostsecurity]`` section can have the form
1324 Options in the ``[hostsecurity]`` section can have the form
1325 ``hostname``:``setting``. This allows multiple settings to be defined on a
1325 ``hostname``:``setting``. This allows multiple settings to be defined on a
1326 per-host basis.
1326 per-host basis.
1327
1327
1328 The following per-host settings can be defined.
1328 The following per-host settings can be defined.
1329
1329
1330 ``ciphers``
1330 ``ciphers``
1331 This behaves like ``ciphers`` as described above except it only applies
1331 This behaves like ``ciphers`` as described above except it only applies
1332 to the host on which it is defined.
1332 to the host on which it is defined.
1333
1333
1334 ``fingerprints``
1334 ``fingerprints``
1335 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
1336 the form ``algorithm``:``fingerprint``. e.g.
1336 the form ``algorithm``:``fingerprint``. e.g.
1337 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1337 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1338 In addition, colons (``:``) can appear in the fingerprint part.
1338 In addition, colons (``:``) can appear in the fingerprint part.
1339
1339
1340 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1340 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1341 ``sha512``.
1341 ``sha512``.
1342
1342
1343 Use of ``sha256`` or ``sha512`` is preferred.
1343 Use of ``sha256`` or ``sha512`` is preferred.
1344
1344
1345 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
1346 host and Mercurial will require the remote certificate to match one
1346 host and Mercurial will require the remote certificate to match one
1347 of the fingerprints specified. This means if the server updates its
1347 of the fingerprints specified. This means if the server updates its
1348 certificate, Mercurial will abort until a new fingerprint is defined.
1348 certificate, Mercurial will abort until a new fingerprint is defined.
1349 This can provide stronger security than traditional CA-based validation
1349 This can provide stronger security than traditional CA-based validation
1350 at the expense of convenience.
1350 at the expense of convenience.
1351
1351
1352 This option takes precedence over ``verifycertsfile``.
1352 This option takes precedence over ``verifycertsfile``.
1353
1353
1354 ``minimumprotocol``
1354 ``minimumprotocol``
1355 This behaves like ``minimumprotocol`` as described above except it
1355 This behaves like ``minimumprotocol`` as described above except it
1356 only applies to the host on which it is defined.
1356 only applies to the host on which it is defined.
1357
1357
1358 ``verifycertsfile``
1358 ``verifycertsfile``
1359 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
1360 verify the server certificate. Environment variables and ``~user``
1360 verify the server certificate. Environment variables and ``~user``
1361 constructs are expanded in the filename.
1361 constructs are expanded in the filename.
1362
1362
1363 The server certificate or the certificate's certificate authority (CA)
1363 The server certificate or the certificate's certificate authority (CA)
1364 must match a certificate from this file or certificate verification
1364 must match a certificate from this file or certificate verification
1365 will fail and connections to the server will be refused.
1365 will fail and connections to the server will be refused.
1366
1366
1367 If defined, only certificates provided by this file will be used:
1367 If defined, only certificates provided by this file will be used:
1368 ``web.cacerts`` and any system/default certificates will not be
1368 ``web.cacerts`` and any system/default certificates will not be
1369 used.
1369 used.
1370
1370
1371 This option has no effect if the per-host ``fingerprints`` option
1371 This option has no effect if the per-host ``fingerprints`` option
1372 is set.
1372 is set.
1373
1373
1374 The format of the file is as follows::
1374 The format of the file is as follows::
1375
1375
1376 -----BEGIN CERTIFICATE-----
1376 -----BEGIN CERTIFICATE-----
1377 ... (certificate in base64 PEM encoding) ...
1377 ... (certificate in base64 PEM encoding) ...
1378 -----END CERTIFICATE-----
1378 -----END CERTIFICATE-----
1379 -----BEGIN CERTIFICATE-----
1379 -----BEGIN CERTIFICATE-----
1380 ... (certificate in base64 PEM encoding) ...
1380 ... (certificate in base64 PEM encoding) ...
1381 -----END CERTIFICATE-----
1381 -----END CERTIFICATE-----
1382
1382
1383 For example::
1383 For example::
1384
1384
1385 [hostsecurity]
1385 [hostsecurity]
1386 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1386 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
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
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
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
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
1389 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1389 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1390
1390
1391 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
1392 when connecting to ``hg.example.com``::
1392 when connecting to ``hg.example.com``::
1393
1393
1394 [hostsecurity]
1394 [hostsecurity]
1395 minimumprotocol = tls1.2
1395 minimumprotocol = tls1.2
1396 hg.example.com:minimumprotocol = tls1.1
1396 hg.example.com:minimumprotocol = tls1.1
1397
1397
1398 ``http_proxy``
1398 ``http_proxy``
1399 --------------
1399 --------------
1400
1400
1401 Used to access web-based Mercurial repositories through a HTTP
1401 Used to access web-based Mercurial repositories through a HTTP
1402 proxy.
1402 proxy.
1403
1403
1404 ``host``
1404 ``host``
1405 Host name and (optional) port of the proxy server, for example
1405 Host name and (optional) port of the proxy server, for example
1406 "myproxy:8000".
1406 "myproxy:8000".
1407
1407
1408 ``no``
1408 ``no``
1409 Optional. Comma-separated list of host names that should bypass
1409 Optional. Comma-separated list of host names that should bypass
1410 the proxy.
1410 the proxy.
1411
1411
1412 ``passwd``
1412 ``passwd``
1413 Optional. Password to authenticate with at the proxy server.
1413 Optional. Password to authenticate with at the proxy server.
1414
1414
1415 ``user``
1415 ``user``
1416 Optional. User name to authenticate with at the proxy server.
1416 Optional. User name to authenticate with at the proxy server.
1417
1417
1418 ``always``
1418 ``always``
1419 Optional. Always use the proxy, even for localhost and any entries
1419 Optional. Always use the proxy, even for localhost and any entries
1420 in ``http_proxy.no``. (default: False)
1420 in ``http_proxy.no``. (default: False)
1421
1421
1422 ``http``
1422 ``http``
1423 ----------
1423 ----------
1424
1424
1425 Used to configure access to Mercurial repositories via HTTP.
1425 Used to configure access to Mercurial repositories via HTTP.
1426
1426
1427 ``timeout``
1427 ``timeout``
1428 If set, blocking operations will timeout after that many seconds.
1428 If set, blocking operations will timeout after that many seconds.
1429 (default: None)
1429 (default: None)
1430
1430
1431 ``merge``
1431 ``merge``
1432 ---------
1432 ---------
1433
1433
1434 This section specifies behavior during merges and updates.
1434 This section specifies behavior during merges and updates.
1435
1435
1436 ``checkignored``
1436 ``checkignored``
1437 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
1438 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
1439 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1439 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1440 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
1441 ``.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
1442 ``.orig``. (default: ``abort``)
1442 ``.orig``. (default: ``abort``)
1443
1443
1444 ``checkunknown``
1444 ``checkunknown``
1445 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
1446 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
1447 different contents. Similar to ``merge.checkignored``, except for files that
1447 different contents. Similar to ``merge.checkignored``, except for files that
1448 are not ignored. (default: ``abort``)
1448 are not ignored. (default: ``abort``)
1449
1449
1450 ``on-failure``
1450 ``on-failure``
1451 When set to ``continue`` (the default), the merge process attempts to
1451 When set to ``continue`` (the default), the merge process attempts to
1452 merge all unresolved files using the merge chosen tool, regardless of
1452 merge all unresolved files using the merge chosen tool, regardless of
1453 whether previous file merge attempts during the process succeeded or not.
1453 whether previous file merge attempts during the process succeeded or not.
1454 Setting this to ``prompt`` will prompt after any merge failure continue
1454 Setting this to ``prompt`` will prompt after any merge failure continue
1455 or halt the merge process. Setting this to ``halt`` will automatically
1455 or halt the merge process. Setting this to ``halt`` will automatically
1456 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
1457 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
1458 halted, the repository is left in a normal ``unresolved`` merge state.
1458 halted, the repository is left in a normal ``unresolved`` merge state.
1459 (default: ``continue``)
1459 (default: ``continue``)
1460
1460
1461 ``strict-capability-check``
1461 ``strict-capability-check``
1462 Whether capabilities of internal merge tools are checked strictly
1462 Whether capabilities of internal merge tools are checked strictly
1463 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.
1464 (default: False)
1464 (default: False)
1465
1465
1466 ``merge-patterns``
1466 ``merge-patterns``
1467 ------------------
1467 ------------------
1468
1468
1469 This section specifies merge tools to associate with particular file
1469 This section specifies merge tools to associate with particular file
1470 patterns. Tools matched here will take precedence over the default
1470 patterns. Tools matched here will take precedence over the default
1471 merge tool. Patterns are globs by default, rooted at the repository
1471 merge tool. Patterns are globs by default, rooted at the repository
1472 root.
1472 root.
1473
1473
1474 Example::
1474 Example::
1475
1475
1476 [merge-patterns]
1476 [merge-patterns]
1477 **.c = kdiff3
1477 **.c = kdiff3
1478 **.jpg = myimgmerge
1478 **.jpg = myimgmerge
1479
1479
1480 ``merge-tools``
1480 ``merge-tools``
1481 ---------------
1481 ---------------
1482
1482
1483 This section configures external merge tools to use for file-level
1483 This section configures external merge tools to use for file-level
1484 merges. This section has likely been preconfigured at install time.
1484 merges. This section has likely been preconfigured at install time.
1485 Use :hg:`config merge-tools` to check the existing configuration.
1485 Use :hg:`config merge-tools` to check the existing configuration.
1486 Also see :hg:`help merge-tools` for more details.
1486 Also see :hg:`help merge-tools` for more details.
1487
1487
1488 Example ``~/.hgrc``::
1488 Example ``~/.hgrc``::
1489
1489
1490 [merge-tools]
1490 [merge-tools]
1491 # Override stock tool location
1491 # Override stock tool location
1492 kdiff3.executable = ~/bin/kdiff3
1492 kdiff3.executable = ~/bin/kdiff3
1493 # Specify command line
1493 # Specify command line
1494 kdiff3.args = $base $local $other -o $output
1494 kdiff3.args = $base $local $other -o $output
1495 # Give higher priority
1495 # Give higher priority
1496 kdiff3.priority = 1
1496 kdiff3.priority = 1
1497
1497
1498 # Changing the priority of preconfigured tool
1498 # Changing the priority of preconfigured tool
1499 meld.priority = 0
1499 meld.priority = 0
1500
1500
1501 # Disable a preconfigured tool
1501 # Disable a preconfigured tool
1502 vimdiff.disabled = yes
1502 vimdiff.disabled = yes
1503
1503
1504 # Define new tool
1504 # Define new tool
1505 myHtmlTool.args = -m $local $other $base $output
1505 myHtmlTool.args = -m $local $other $base $output
1506 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1506 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1507 myHtmlTool.priority = 1
1507 myHtmlTool.priority = 1
1508
1508
1509 Supported arguments:
1509 Supported arguments:
1510
1510
1511 ``priority``
1511 ``priority``
1512 The priority in which to evaluate this tool.
1512 The priority in which to evaluate this tool.
1513 (default: 0)
1513 (default: 0)
1514
1514
1515 ``executable``
1515 ``executable``
1516 Either just the name of the executable or its pathname.
1516 Either just the name of the executable or its pathname.
1517
1517
1518 .. container:: windows
1518 .. container:: windows
1519
1519
1520 On Windows, the path can use environment variables with ${ProgramFiles}
1520 On Windows, the path can use environment variables with ${ProgramFiles}
1521 syntax.
1521 syntax.
1522
1522
1523 (default: the tool name)
1523 (default: the tool name)
1524
1524
1525 ``args``
1525 ``args``
1526 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
1527 files being merged as well as the output file through these
1527 files being merged as well as the output file through these
1528 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1528 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1529
1529
1530 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
1531 being performed. During an update or merge, ``$local`` represents the original
1531 being performed. During an update or merge, ``$local`` represents the original
1532 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
1533 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
1534 destination of the rebase, and ``$other`` represents the commit being rebased.
1534 destination of the rebase, and ``$other`` represents the commit being rebased.
1535
1535
1536 Some operations define custom labels to assist with identifying the revisions,
1536 Some operations define custom labels to assist with identifying the revisions,
1537 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1537 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1538 labels are not available, these will be ``local``, ``other``, and ``base``,
1538 labels are not available, these will be ``local``, ``other``, and ``base``,
1539 respectively.
1539 respectively.
1540 (default: ``$local $base $other``)
1540 (default: ``$local $base $other``)
1541
1541
1542 ``premerge``
1542 ``premerge``
1543 Attempt to run internal non-interactive 3-way merge tool before
1543 Attempt to run internal non-interactive 3-way merge tool before
1544 launching external tool. Options are ``true``, ``false``, ``keep``,
1544 launching external tool. Options are ``true``, ``false``, ``keep``,
1545 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1545 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1546 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``
1547 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
1548 marker (see internal :merge3 in :hg:`help merge-tools`). The
1548 marker (see internal :merge3 in :hg:`help merge-tools`). The
1549 ``keep-mergediff`` option is similar but uses a different marker style
1549 ``keep-mergediff`` option is similar but uses a different marker style
1550 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1550 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1551
1551
1552 ``binary``
1552 ``binary``
1553 This tool can merge binary files. (default: False, unless tool
1553 This tool can merge binary files. (default: False, unless tool
1554 was selected by file pattern match)
1554 was selected by file pattern match)
1555
1555
1556 ``symlink``
1556 ``symlink``
1557 This tool can merge symlinks. (default: False)
1557 This tool can merge symlinks. (default: False)
1558
1558
1559 ``check``
1559 ``check``
1560 A list of merge success-checking options:
1560 A list of merge success-checking options:
1561
1561
1562 ``changed``
1562 ``changed``
1563 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.
1564 ``conflicts``
1564 ``conflicts``
1565 Check whether there are conflicts even though the tool reported success.
1565 Check whether there are conflicts even though the tool reported success.
1566 ``prompt``
1566 ``prompt``
1567 Always prompt for merge success, regardless of success reported by tool.
1567 Always prompt for merge success, regardless of success reported by tool.
1568
1568
1569 ``fixeol``
1569 ``fixeol``
1570 Attempt to fix up EOL changes caused by the merge tool.
1570 Attempt to fix up EOL changes caused by the merge tool.
1571 (default: False)
1571 (default: False)
1572
1572
1573 ``gui``
1573 ``gui``
1574 This tool requires a graphical interface to run. (default: False)
1574 This tool requires a graphical interface to run. (default: False)
1575
1575
1576 ``mergemarkers``
1576 ``mergemarkers``
1577 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1577 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1578 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1578 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1579 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1579 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1580 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
1581 the corresponding option in the ``[ui]`` section is ``detailed``.
1581 the corresponding option in the ``[ui]`` section is ``detailed``.
1582 (default: ``basic``)
1582 (default: ``basic``)
1583
1583
1584 ``mergemarkertemplate``
1584 ``mergemarkertemplate``
1585 This setting can be used to override ``mergemarker`` from the
1585 This setting can be used to override ``mergemarker`` from the
1586 ``[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
1587 ``$label``-prefixed variables and to the conflict markers that are generated
1587 ``$label``-prefixed variables and to the conflict markers that are generated
1588 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1588 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1589 in ``[ui]`` for more information.
1589 in ``[ui]`` for more information.
1590
1590
1591 .. container:: windows
1591 .. container:: windows
1592
1592
1593 ``regkey``
1593 ``regkey``
1594 Windows registry key which describes install location of this
1594 Windows registry key which describes install location of this
1595 tool. Mercurial will search for this key first under
1595 tool. Mercurial will search for this key first under
1596 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1596 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1597 (default: None)
1597 (default: None)
1598
1598
1599 ``regkeyalt``
1599 ``regkeyalt``
1600 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
1601 found. The alternate key uses the same ``regname`` and ``regappend``
1601 found. The alternate key uses the same ``regname`` and ``regappend``
1602 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
1603 is to search for 32bit applications on 64bit operating systems.
1603 is to search for 32bit applications on 64bit operating systems.
1604 (default: None)
1604 (default: None)
1605
1605
1606 ``regname``
1606 ``regname``
1607 Name of value to read from specified registry key.
1607 Name of value to read from specified registry key.
1608 (default: the unnamed (default) value)
1608 (default: the unnamed (default) value)
1609
1609
1610 ``regappend``
1610 ``regappend``
1611 String to append to the value read from the registry, typically
1611 String to append to the value read from the registry, typically
1612 the executable name of the tool.
1612 the executable name of the tool.
1613 (default: None)
1613 (default: None)
1614
1614
1615 ``pager``
1615 ``pager``
1616 ---------
1616 ---------
1617
1617
1618 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
1619 :hg:`help pager` for details.
1619 :hg:`help pager` for details.
1620
1620
1621 ``pager``
1621 ``pager``
1622 Define the external tool used as pager.
1622 Define the external tool used as pager.
1623
1623
1624 If no pager is set, Mercurial uses the environment variable $PAGER.
1624 If no pager is set, Mercurial uses the environment variable $PAGER.
1625 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
1626 used, typically `less` on Unix and `more` on Windows. Example::
1626 used, typically `less` on Unix and `more` on Windows. Example::
1627
1627
1628 [pager]
1628 [pager]
1629 pager = less -FRX
1629 pager = less -FRX
1630
1630
1631 ``ignore``
1631 ``ignore``
1632 List of commands to disable the pager for. Example::
1632 List of commands to disable the pager for. Example::
1633
1633
1634 [pager]
1634 [pager]
1635 ignore = version, help, update
1635 ignore = version, help, update
1636
1636
1637 ``patch``
1637 ``patch``
1638 ---------
1638 ---------
1639
1639
1640 Settings used when applying patches, for instance through the 'import'
1640 Settings used when applying patches, for instance through the 'import'
1641 command or with Mercurial Queues extension.
1641 command or with Mercurial Queues extension.
1642
1642
1643 ``eol``
1643 ``eol``
1644 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
1645 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
1646 lines are ignored when patching and the result line endings are
1646 lines are ignored when patching and the result line endings are
1647 normalized to either LF (Unix) or CRLF (Windows). When set to
1647 normalized to either LF (Unix) or CRLF (Windows). When set to
1648 ``auto``, end of lines are again ignored while patching but line
1648 ``auto``, end of lines are again ignored while patching but line
1649 endings in patched files are normalized to their original setting
1649 endings in patched files are normalized to their original setting
1650 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
1651 of line, patch line endings are preserved.
1651 of line, patch line endings are preserved.
1652 (default: strict)
1652 (default: strict)
1653
1653
1654 ``fuzz``
1654 ``fuzz``
1655 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
1656 controls how much context the patcher is allowed to ignore when
1656 controls how much context the patcher is allowed to ignore when
1657 trying to apply a patch.
1657 trying to apply a patch.
1658 (default: 2)
1658 (default: 2)
1659
1659
1660 ``paths``
1660 ``paths``
1661 ---------
1661 ---------
1662
1662
1663 Assigns symbolic names and behavior to repositories.
1663 Assigns symbolic names and behavior to repositories.
1664
1664
1665 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
1666 location of the repository. Example::
1666 location of the repository. Example::
1667
1667
1668 [paths]
1668 [paths]
1669 my_server = https://example.com/my_repo
1669 my_server = https://example.com/my_repo
1670 local_path = /home/me/repo
1670 local_path = /home/me/repo
1671
1671
1672 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
1673 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``:
1674 :hg:`push local_path`.
1674 :hg:`push local_path`.
1675
1675
1676 Options containing colons (``:``) denote sub-options that can influence
1676 Options containing colons (``:``) denote sub-options that can influence
1677 behavior for that specific path. Example::
1677 behavior for that specific path. Example::
1678
1678
1679 [paths]
1679 [paths]
1680 my_server = https://example.com/my_path
1680 my_server = https://example.com/my_path
1681 my_server:pushurl = ssh://example.com/my_path
1681 my_server:pushurl = ssh://example.com/my_path
1682
1682
1683 The following sub-options can be defined:
1683 The following sub-options can be defined:
1684
1684
1685 ``pushurl``
1685 ``pushurl``
1686 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
1687 defined by the path's main entry is used.
1687 defined by the path's main entry is used.
1688
1688
1689 ``pushrev``
1689 ``pushrev``
1690 A revset defining which revisions to push by default.
1690 A revset defining which revisions to push by default.
1691
1691
1692 When :hg:`push` is executed without a ``-r`` argument, the revset
1692 When :hg:`push` is executed without a ``-r`` argument, the revset
1693 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.
1694
1694
1695 For example, a value of ``.`` will push the working directory's
1695 For example, a value of ``.`` will push the working directory's
1696 revision by default.
1696 revision by default.
1697
1697
1698 Revsets specifying bookmarks will not result in the bookmark being
1698 Revsets specifying bookmarks will not result in the bookmark being
1699 pushed.
1699 pushed.
1700
1700
1701 The following special named paths exist:
1701 The following special named paths exist:
1702
1702
1703 ``default``
1703 ``default``
1704 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.
1705
1705
1706 :hg:`clone` will automatically define this path to the location the
1706 :hg:`clone` will automatically define this path to the location the
1707 repository was cloned from.
1707 repository was cloned from.
1708
1708
1709 ``default-push``
1709 ``default-push``
1710 (deprecated) The URL or directory for the default :hg:`push` location.
1710 (deprecated) The URL or directory for the default :hg:`push` location.
1711 ``default:pushurl`` should be used instead.
1711 ``default:pushurl`` should be used instead.
1712
1712
1713 ``phases``
1713 ``phases``
1714 ----------
1714 ----------
1715
1715
1716 Specifies default handling of phases. See :hg:`help phases` for more
1716 Specifies default handling of phases. See :hg:`help phases` for more
1717 information about working with phases.
1717 information about working with phases.
1718
1718
1719 ``publish``
1719 ``publish``
1720 Controls draft phase behavior when working as a server. When true,
1720 Controls draft phase behavior when working as a server. When true,
1721 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
1722 pulled or cloned changesets are set to public in the client.
1722 pulled or cloned changesets are set to public in the client.
1723 (default: True)
1723 (default: True)
1724
1724
1725 ``new-commit``
1725 ``new-commit``
1726 Phase of newly-created commits.
1726 Phase of newly-created commits.
1727 (default: draft)
1727 (default: draft)
1728
1728
1729 ``checksubrepos``
1729 ``checksubrepos``
1730 Check the phase of the current revision of each subrepository. Allowed
1730 Check the phase of the current revision of each subrepository. Allowed
1731 values are "ignore", "follow" and "abort". For settings other than
1731 values are "ignore", "follow" and "abort". For settings other than
1732 "ignore", the phase of the current revision of each subrepository is
1732 "ignore", the phase of the current revision of each subrepository is
1733 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
1734 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
1735 "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
1736 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
1737 used for the parent repository commit (if set to "follow").
1737 used for the parent repository commit (if set to "follow").
1738 (default: follow)
1738 (default: follow)
1739
1739
1740
1740
1741 ``profiling``
1741 ``profiling``
1742 -------------
1742 -------------
1743
1743
1744 Specifies profiling type, format, and file output. Two profilers are
1744 Specifies profiling type, format, and file output. Two profilers are
1745 supported: an instrumenting profiler (named ``ls``), and a sampling
1745 supported: an instrumenting profiler (named ``ls``), and a sampling
1746 profiler (named ``stat``).
1746 profiler (named ``stat``).
1747
1747
1748 In this section description, 'profiling data' stands for the raw data
1748 In this section description, 'profiling data' stands for the raw data
1749 collected during profiling, while 'profiling report' stands for a
1749 collected during profiling, while 'profiling report' stands for a
1750 statistical text report generated from the profiling data.
1750 statistical text report generated from the profiling data.
1751
1751
1752 ``enabled``
1752 ``enabled``
1753 Enable the profiler.
1753 Enable the profiler.
1754 (default: false)
1754 (default: false)
1755
1755
1756 This is equivalent to passing ``--profile`` on the command line.
1756 This is equivalent to passing ``--profile`` on the command line.
1757
1757
1758 ``type``
1758 ``type``
1759 The type of profiler to use.
1759 The type of profiler to use.
1760 (default: stat)
1760 (default: stat)
1761
1761
1762 ``ls``
1762 ``ls``
1763 Use Python's built-in instrumenting profiler. This profiler
1763 Use Python's built-in instrumenting profiler. This profiler
1764 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
1765 first line of a function. This restriction makes it difficult to
1765 first line of a function. This restriction makes it difficult to
1766 identify the expensive parts of a non-trivial function.
1766 identify the expensive parts of a non-trivial function.
1767 ``stat``
1767 ``stat``
1768 Use a statistical profiler, statprof. This profiler is most
1768 Use a statistical profiler, statprof. This profiler is most
1769 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
1770 seconds.
1770 seconds.
1771
1771
1772 ``format``
1772 ``format``
1773 Profiling format. Specific to the ``ls`` instrumenting profiler.
1773 Profiling format. Specific to the ``ls`` instrumenting profiler.
1774 (default: text)
1774 (default: text)
1775
1775
1776 ``text``
1776 ``text``
1777 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
1778 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
1779 not kept.
1779 not kept.
1780 ``kcachegrind``
1780 ``kcachegrind``
1781 Format profiling data for kcachegrind use: when saving to a
1781 Format profiling data for kcachegrind use: when saving to a
1782 file, the generated file can directly be loaded into
1782 file, the generated file can directly be loaded into
1783 kcachegrind.
1783 kcachegrind.
1784
1784
1785 ``statformat``
1785 ``statformat``
1786 Profiling format for the ``stat`` profiler.
1786 Profiling format for the ``stat`` profiler.
1787 (default: hotpath)
1787 (default: hotpath)
1788
1788
1789 ``hotpath``
1789 ``hotpath``
1790 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
1791 most time was spent).
1791 most time was spent).
1792 ``bymethod``
1792 ``bymethod``
1793 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.
1794 ``byline``
1794 ``byline``
1795 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.
1796 ``json``
1796 ``json``
1797 Render profiling data as JSON.
1797 Render profiling data as JSON.
1798
1798
1799 ``frequency``
1799 ``frequency``
1800 Sampling frequency. Specific to the ``stat`` sampling profiler.
1800 Sampling frequency. Specific to the ``stat`` sampling profiler.
1801 (default: 1000)
1801 (default: 1000)
1802
1802
1803 ``output``
1803 ``output``
1804 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
1805 file exists, it is replaced. (default: None, data is printed on
1805 file exists, it is replaced. (default: None, data is printed on
1806 stderr)
1806 stderr)
1807
1807
1808 ``sort``
1808 ``sort``
1809 Sort field. Specific to the ``ls`` instrumenting profiler.
1809 Sort field. Specific to the ``ls`` instrumenting profiler.
1810 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1810 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1811 ``inlinetime``.
1811 ``inlinetime``.
1812 (default: inlinetime)
1812 (default: inlinetime)
1813
1813
1814 ``time-track``
1814 ``time-track``
1815 Control if the stat profiler track ``cpu`` or ``real`` time.
1815 Control if the stat profiler track ``cpu`` or ``real`` time.
1816 (default: ``cpu`` on Windows, otherwise ``real``)
1816 (default: ``cpu`` on Windows, otherwise ``real``)
1817
1817
1818 ``limit``
1818 ``limit``
1819 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1819 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1820 (default: 30)
1820 (default: 30)
1821
1821
1822 ``nested``
1822 ``nested``
1823 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.
1824 This can help explain the difference between Total and Inline.
1824 This can help explain the difference between Total and Inline.
1825 Specific to the ``ls`` instrumenting profiler.
1825 Specific to the ``ls`` instrumenting profiler.
1826 (default: 0)
1826 (default: 0)
1827
1827
1828 ``showmin``
1828 ``showmin``
1829 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.
1830 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
1831 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1831 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1832
1832
1833 Only used by the ``stat`` profiler.
1833 Only used by the ``stat`` profiler.
1834
1834
1835 For the ``hotpath`` format, default is ``0.05``.
1835 For the ``hotpath`` format, default is ``0.05``.
1836 For the ``chrome`` format, default is ``0.005``.
1836 For the ``chrome`` format, default is ``0.005``.
1837
1837
1838 The option is unused on other formats.
1838 The option is unused on other formats.
1839
1839
1840 ``showmax``
1840 ``showmax``
1841 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
1842 display. Values format is the same as ``showmin``.
1842 display. Values format is the same as ``showmin``.
1843
1843
1844 Only used by the ``stat`` profiler.
1844 Only used by the ``stat`` profiler.
1845
1845
1846 For the ``chrome`` format, default is ``0.999``.
1846 For the ``chrome`` format, default is ``0.999``.
1847
1847
1848 The option is unused on other formats.
1848 The option is unused on other formats.
1849
1849
1850 ``showtime``
1850 ``showtime``
1851 Show time taken as absolute durations, in addition to percentages.
1851 Show time taken as absolute durations, in addition to percentages.
1852 Only used by the ``hotpath`` format.
1852 Only used by the ``hotpath`` format.
1853 (default: true)
1853 (default: true)
1854
1854
1855 ``progress``
1855 ``progress``
1856 ------------
1856 ------------
1857
1857
1858 Mercurial commands can draw progress bars that are as informative as
1858 Mercurial commands can draw progress bars that are as informative as
1859 possible. Some progress bars only offer indeterminate information, while others
1859 possible. Some progress bars only offer indeterminate information, while others
1860 have a definite end point.
1860 have a definite end point.
1861
1861
1862 ``debug``
1862 ``debug``
1863 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)
1864
1864
1865 ``delay``
1865 ``delay``
1866 Number of seconds (float) before showing the progress bar. (default: 3)
1866 Number of seconds (float) before showing the progress bar. (default: 3)
1867
1867
1868 ``changedelay``
1868 ``changedelay``
1869 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,
1870 that value will be used instead. (default: 1)
1870 that value will be used instead. (default: 1)
1871
1871
1872 ``estimateinterval``
1872 ``estimateinterval``
1873 Maximum sampling interval in seconds for speed and estimated time
1873 Maximum sampling interval in seconds for speed and estimated time
1874 calculation. (default: 60)
1874 calculation. (default: 60)
1875
1875
1876 ``refresh``
1876 ``refresh``
1877 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)
1878
1878
1879 ``format``
1879 ``format``
1880 Format of the progress bar.
1880 Format of the progress bar.
1881
1881
1882 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1882 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1883 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1883 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1884 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
1885 ``-<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
1886 first num characters.
1886 first num characters.
1887
1887
1888 (default: topic bar number estimate)
1888 (default: topic bar number estimate)
1889
1889
1890 ``width``
1890 ``width``
1891 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,
1892 term width) will be used).
1892 term width) will be used).
1893
1893
1894 ``clear-complete``
1894 ``clear-complete``
1895 Clear the progress bar after it's done. (default: True)
1895 Clear the progress bar after it's done. (default: True)
1896
1896
1897 ``disable``
1897 ``disable``
1898 If true, don't show a progress bar.
1898 If true, don't show a progress bar.
1899
1899
1900 ``assume-tty``
1900 ``assume-tty``
1901 If true, ALWAYS show a progress bar, unless disable is given.
1901 If true, ALWAYS show a progress bar, unless disable is given.
1902
1902
1903 ``rebase``
1903 ``rebase``
1904 ----------
1904 ----------
1905
1905
1906 ``evolution.allowdivergence``
1906 ``evolution.allowdivergence``
1907 Default to False, when True allow creating divergence when performing
1907 Default to False, when True allow creating divergence when performing
1908 rebase of obsolete changesets.
1908 rebase of obsolete changesets.
1909
1909
1910 ``revsetalias``
1910 ``revsetalias``
1911 ---------------
1911 ---------------
1912
1912
1913 Alias definitions for revsets. See :hg:`help revsets` for details.
1913 Alias definitions for revsets. See :hg:`help revsets` for details.
1914
1914
1915 ``rewrite``
1915 ``rewrite``
1916 -----------
1916 -----------
1917
1917
1918 ``backup-bundle``
1918 ``backup-bundle``
1919 Whether to save stripped changesets to a bundle file. (default: True)
1919 Whether to save stripped changesets to a bundle file. (default: True)
1920
1920
1921 ``update-timestamp``
1921 ``update-timestamp``
1922 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
1923 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
1924 current version.
1924 current version.
1925
1925
1926 ``empty-successor``
1926 ``empty-successor``
1927
1927
1928 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
1929 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
1930 ``keep``, the empty successor is created and kept.
1930 ``keep``, the empty successor is created and kept.
1931
1931
1932 Currently, only the rebase and absorb commands consider this configuration.
1932 Currently, only the rebase and absorb commands consider this configuration.
1933 (EXPERIMENTAL)
1933 (EXPERIMENTAL)
1934
1934
1935 ``share``
1935 ``share``
1936 ---------
1936 ---------
1937
1937
1938 ``safe-mismatch.source-safe``
1938 ``safe-mismatch.source-safe``
1939
1939
1940 Controls what happens when the shared repository does not use the
1940 Controls what happens when the shared repository does not use the
1941 share-safe mechanism but its source repository does.
1941 share-safe mechanism but its source repository does.
1942
1942
1943 Possible values are `abort` (default), `allow`, `upgrade-abort` and
1943 Possible values are `abort` (default), `allow`, `upgrade-abort` and
1944 `upgrade-abort`.
1944 `upgrade-abort`.
1945 `abort`: Disallows running any command and aborts
1945 `abort`: Disallows running any command and aborts
1946 `allow`: Respects the feature presence in the share source
1946 `allow`: Respects the feature presence in the share source
1947 `upgrade-abort`: tries to upgrade the share to use share-safe;
1947 `upgrade-abort`: tries to upgrade the share to use share-safe;
1948 if it fails, aborts
1948 if it fails, aborts
1949 `upgrade-allow`: tries to upgrade the share; if it fails, continue by
1949 `upgrade-allow`: tries to upgrade the share; if it fails, continue by
1950 respecting the share source setting
1950 respecting the share source setting
1951
1951
1952 ``safe-mismatch.source-not-safe``
1952 ``safe-mismatch.source-not-safe``
1953
1953
1954 Controls what happens when the shared repository uses the share-safe
1954 Controls what happens when the shared repository uses the share-safe
1955 mechanism but its source does not.
1955 mechanism but its source does not.
1956
1956
1957 Possible values are `abort` (default), `allow`, `downgrade-abort` and
1957 Possible values are `abort` (default), `allow`, `downgrade-abort` and
1958 `downgrade-abort`.
1958 `downgrade-abort`.
1959 `abort`: Disallows running any command and aborts
1959 `abort`: Disallows running any command and aborts
1960 `allow`: Respects the feature presence in the share source
1960 `allow`: Respects the feature presence in the share source
1961 `downgrade-abort`: tries to downgrade the share to not use share-safe;
1961 `downgrade-abort`: tries to downgrade the share to not use share-safe;
1962 if it fails, aborts
1962 if it fails, aborts
1963 `downgrade-allow`: tries to downgrade the share to not use share-safe;
1963 `downgrade-allow`: tries to downgrade the share to not use share-safe;
1964 if it fails, continue by respecting the shared
1964 if it fails, continue by respecting the shared
1965 source setting
1965 source setting
1966
1966
1967
1967
1968 ``safe-mismatch.source-safe.warn``
1969 Shows a warning on operations if the shared repository does not use
1970 share-safe, but the source repository does.
1971 (default: True)
1972
1973 ``safe-mismatch.source-not-safe.warn``
1974 Shows a warning on operations if the shared repository uses share-safe,
1975 but the source repository does not.
1976 (default: True)
1977
1968 ``storage``
1978 ``storage``
1969 -----------
1979 -----------
1970
1980
1971 Control the strategy Mercurial uses internally to store history. Options in this
1981 Control the strategy Mercurial uses internally to store history. Options in this
1972 category impact performance and repository size.
1982 category impact performance and repository size.
1973
1983
1974 ``revlog.optimize-delta-parent-choice``
1984 ``revlog.optimize-delta-parent-choice``
1975 When storing a merge revision, both parents will be equally considered as
1985 When storing a merge revision, both parents will be equally considered as
1976 a possible delta base. This results in better delta selection and improved
1986 a possible delta base. This results in better delta selection and improved
1977 revlog compression. This option is enabled by default.
1987 revlog compression. This option is enabled by default.
1978
1988
1979 Turning this option off can result in large increase of repository size for
1989 Turning this option off can result in large increase of repository size for
1980 repository with many merges.
1990 repository with many merges.
1981
1991
1982 ``revlog.persistent-nodemap.mmap``
1992 ``revlog.persistent-nodemap.mmap``
1983 Whether to use the Operating System "memory mapping" feature (when
1993 Whether to use the Operating System "memory mapping" feature (when
1984 possible) to access the persistent nodemap data. This improve performance
1994 possible) to access the persistent nodemap data. This improve performance
1985 and reduce memory pressure.
1995 and reduce memory pressure.
1986
1996
1987 Default to True.
1997 Default to True.
1988
1998
1989 For details on the "persistent-nodemap" feature, see:
1999 For details on the "persistent-nodemap" feature, see:
1990 :hg:`help config format.use-persistent-nodemap`.
2000 :hg:`help config format.use-persistent-nodemap`.
1991
2001
1992 ``revlog.persistent-nodemap.slow-path``
2002 ``revlog.persistent-nodemap.slow-path``
1993 Control the behavior of Merucrial when using a repository with "persistent"
2003 Control the behavior of Merucrial when using a repository with "persistent"
1994 nodemap with an installation of Mercurial without a fast implementation for
2004 nodemap with an installation of Mercurial without a fast implementation for
1995 the feature:
2005 the feature:
1996
2006
1997 ``allow``: Silently use the slower implementation to access the repository.
2007 ``allow``: Silently use the slower implementation to access the repository.
1998 ``warn``: Warn, but use the slower implementation to access the repository.
2008 ``warn``: Warn, but use the slower implementation to access the repository.
1999 ``abort``: Prevent access to such repositories. (This is the default)
2009 ``abort``: Prevent access to such repositories. (This is the default)
2000
2010
2001 For details on the "persistent-nodemap" feature, see:
2011 For details on the "persistent-nodemap" feature, see:
2002 :hg:`help config format.use-persistent-nodemap`.
2012 :hg:`help config format.use-persistent-nodemap`.
2003
2013
2004 ``revlog.reuse-external-delta-parent``
2014 ``revlog.reuse-external-delta-parent``
2005 Control the order in which delta parents are considered when adding new
2015 Control the order in which delta parents are considered when adding new
2006 revisions from an external source.
2016 revisions from an external source.
2007 (typically: apply bundle from `hg pull` or `hg push`).
2017 (typically: apply bundle from `hg pull` or `hg push`).
2008
2018
2009 New revisions are usually provided as a delta against other revisions. By
2019 New revisions are usually provided as a delta against other revisions. By
2010 default, Mercurial will try to reuse this delta first, therefore using the
2020 default, Mercurial will try to reuse this delta first, therefore using the
2011 same "delta parent" as the source. Directly using delta's from the source
2021 same "delta parent" as the source. Directly using delta's from the source
2012 reduces CPU usage and usually speeds up operation. However, in some case,
2022 reduces CPU usage and usually speeds up operation. However, in some case,
2013 the source might have sub-optimal delta bases and forcing their reevaluation
2023 the source might have sub-optimal delta bases and forcing their reevaluation
2014 is useful. For example, pushes from an old client could have sub-optimal
2024 is useful. For example, pushes from an old client could have sub-optimal
2015 delta's parent that the server want to optimize. (lack of general delta, bad
2025 delta's parent that the server want to optimize. (lack of general delta, bad
2016 parents, choice, lack of sparse-revlog, etc).
2026 parents, choice, lack of sparse-revlog, etc).
2017
2027
2018 This option is enabled by default. Turning it off will ensure bad delta
2028 This option is enabled by default. Turning it off will ensure bad delta
2019 parent choices from older client do not propagate to this repository, at
2029 parent choices from older client do not propagate to this repository, at
2020 the cost of a small increase in CPU consumption.
2030 the cost of a small increase in CPU consumption.
2021
2031
2022 Note: this option only control the order in which delta parents are
2032 Note: this option only control the order in which delta parents are
2023 considered. Even when disabled, the existing delta from the source will be
2033 considered. Even when disabled, the existing delta from the source will be
2024 reused if the same delta parent is selected.
2034 reused if the same delta parent is selected.
2025
2035
2026 ``revlog.reuse-external-delta``
2036 ``revlog.reuse-external-delta``
2027 Control the reuse of delta from external source.
2037 Control the reuse of delta from external source.
2028 (typically: apply bundle from `hg pull` or `hg push`).
2038 (typically: apply bundle from `hg pull` or `hg push`).
2029
2039
2030 New revisions are usually provided as a delta against another revision. By
2040 New revisions are usually provided as a delta against another revision. By
2031 default, Mercurial will not recompute the same delta again, trusting
2041 default, Mercurial will not recompute the same delta again, trusting
2032 externally provided deltas. There have been rare cases of small adjustment
2042 externally provided deltas. There have been rare cases of small adjustment
2033 to the diffing algorithm in the past. So in some rare case, recomputing
2043 to the diffing algorithm in the past. So in some rare case, recomputing
2034 delta provided by ancient clients can provides better results. Disabling
2044 delta provided by ancient clients can provides better results. Disabling
2035 this option means going through a full delta recomputation for all incoming
2045 this option means going through a full delta recomputation for all incoming
2036 revisions. It means a large increase in CPU usage and will slow operations
2046 revisions. It means a large increase in CPU usage and will slow operations
2037 down.
2047 down.
2038
2048
2039 This option is enabled by default. When disabled, it also disables the
2049 This option is enabled by default. When disabled, it also disables the
2040 related ``storage.revlog.reuse-external-delta-parent`` option.
2050 related ``storage.revlog.reuse-external-delta-parent`` option.
2041
2051
2042 ``revlog.zlib.level``
2052 ``revlog.zlib.level``
2043 Zlib compression level used when storing data into the repository. Accepted
2053 Zlib compression level used when storing data into the repository. Accepted
2044 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2054 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2045 default value is 6.
2055 default value is 6.
2046
2056
2047
2057
2048 ``revlog.zstd.level``
2058 ``revlog.zstd.level``
2049 zstd compression level used when storing data into the repository. Accepted
2059 zstd compression level used when storing data into the repository. Accepted
2050 Value range from 1 (lowest compression) to 22 (highest compression).
2060 Value range from 1 (lowest compression) to 22 (highest compression).
2051 (default 3)
2061 (default 3)
2052
2062
2053 ``server``
2063 ``server``
2054 ----------
2064 ----------
2055
2065
2056 Controls generic server settings.
2066 Controls generic server settings.
2057
2067
2058 ``bookmarks-pushkey-compat``
2068 ``bookmarks-pushkey-compat``
2059 Trigger pushkey hook when being pushed bookmark updates. This config exist
2069 Trigger pushkey hook when being pushed bookmark updates. This config exist
2060 for compatibility purpose (default to True)
2070 for compatibility purpose (default to True)
2061
2071
2062 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2072 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2063 movement we recommend you migrate them to ``txnclose-bookmark`` and
2073 movement we recommend you migrate them to ``txnclose-bookmark`` and
2064 ``pretxnclose-bookmark``.
2074 ``pretxnclose-bookmark``.
2065
2075
2066 ``compressionengines``
2076 ``compressionengines``
2067 List of compression engines and their relative priority to advertise
2077 List of compression engines and their relative priority to advertise
2068 to clients.
2078 to clients.
2069
2079
2070 The order of compression engines determines their priority, the first
2080 The order of compression engines determines their priority, the first
2071 having the highest priority. If a compression engine is not listed
2081 having the highest priority. If a compression engine is not listed
2072 here, it won't be advertised to clients.
2082 here, it won't be advertised to clients.
2073
2083
2074 If not set (the default), built-in defaults are used. Run
2084 If not set (the default), built-in defaults are used. Run
2075 :hg:`debuginstall` to list available compression engines and their
2085 :hg:`debuginstall` to list available compression engines and their
2076 default wire protocol priority.
2086 default wire protocol priority.
2077
2087
2078 Older Mercurial clients only support zlib compression and this setting
2088 Older Mercurial clients only support zlib compression and this setting
2079 has no effect for legacy clients.
2089 has no effect for legacy clients.
2080
2090
2081 ``uncompressed``
2091 ``uncompressed``
2082 Whether to allow clients to clone a repository using the
2092 Whether to allow clients to clone a repository using the
2083 uncompressed streaming protocol. This transfers about 40% more
2093 uncompressed streaming protocol. This transfers about 40% more
2084 data than a regular clone, but uses less memory and CPU on both
2094 data than a regular clone, but uses less memory and CPU on both
2085 server and client. Over a LAN (100 Mbps or better) or a very fast
2095 server and client. Over a LAN (100 Mbps or better) or a very fast
2086 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2096 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2087 regular clone. Over most WAN connections (anything slower than
2097 regular clone. Over most WAN connections (anything slower than
2088 about 6 Mbps), uncompressed streaming is slower, because of the
2098 about 6 Mbps), uncompressed streaming is slower, because of the
2089 extra data transfer overhead. This mode will also temporarily hold
2099 extra data transfer overhead. This mode will also temporarily hold
2090 the write lock while determining what data to transfer.
2100 the write lock while determining what data to transfer.
2091 (default: True)
2101 (default: True)
2092
2102
2093 ``uncompressedallowsecret``
2103 ``uncompressedallowsecret``
2094 Whether to allow stream clones when the repository contains secret
2104 Whether to allow stream clones when the repository contains secret
2095 changesets. (default: False)
2105 changesets. (default: False)
2096
2106
2097 ``preferuncompressed``
2107 ``preferuncompressed``
2098 When set, clients will try to use the uncompressed streaming
2108 When set, clients will try to use the uncompressed streaming
2099 protocol. (default: False)
2109 protocol. (default: False)
2100
2110
2101 ``disablefullbundle``
2111 ``disablefullbundle``
2102 When set, servers will refuse attempts to do pull-based clones.
2112 When set, servers will refuse attempts to do pull-based clones.
2103 If this option is set, ``preferuncompressed`` and/or clone bundles
2113 If this option is set, ``preferuncompressed`` and/or clone bundles
2104 are highly recommended. Partial clones will still be allowed.
2114 are highly recommended. Partial clones will still be allowed.
2105 (default: False)
2115 (default: False)
2106
2116
2107 ``streamunbundle``
2117 ``streamunbundle``
2108 When set, servers will apply data sent from the client directly,
2118 When set, servers will apply data sent from the client directly,
2109 otherwise it will be written to a temporary file first. This option
2119 otherwise it will be written to a temporary file first. This option
2110 effectively prevents concurrent pushes.
2120 effectively prevents concurrent pushes.
2111
2121
2112 ``pullbundle``
2122 ``pullbundle``
2113 When set, the server will check pullbundle.manifest for bundles
2123 When set, the server will check pullbundle.manifest for bundles
2114 covering the requested heads and common nodes. The first matching
2124 covering the requested heads and common nodes. The first matching
2115 entry will be streamed to the client.
2125 entry will be streamed to the client.
2116
2126
2117 For HTTP transport, the stream will still use zlib compression
2127 For HTTP transport, the stream will still use zlib compression
2118 for older clients.
2128 for older clients.
2119
2129
2120 ``concurrent-push-mode``
2130 ``concurrent-push-mode``
2121 Level of allowed race condition between two pushing clients.
2131 Level of allowed race condition between two pushing clients.
2122
2132
2123 - 'strict': push is abort if another client touched the repository
2133 - 'strict': push is abort if another client touched the repository
2124 while the push was preparing.
2134 while the push was preparing.
2125 - 'check-related': push is only aborted if it affects head that got also
2135 - 'check-related': push is only aborted if it affects head that got also
2126 affected while the push was preparing. (default since 5.4)
2136 affected while the push was preparing. (default since 5.4)
2127
2137
2128 'check-related' only takes effect for compatible clients (version
2138 'check-related' only takes effect for compatible clients (version
2129 4.3 and later). Older clients will use 'strict'.
2139 4.3 and later). Older clients will use 'strict'.
2130
2140
2131 ``validate``
2141 ``validate``
2132 Whether to validate the completeness of pushed changesets by
2142 Whether to validate the completeness of pushed changesets by
2133 checking that all new file revisions specified in manifests are
2143 checking that all new file revisions specified in manifests are
2134 present. (default: False)
2144 present. (default: False)
2135
2145
2136 ``maxhttpheaderlen``
2146 ``maxhttpheaderlen``
2137 Instruct HTTP clients not to send request headers longer than this
2147 Instruct HTTP clients not to send request headers longer than this
2138 many bytes. (default: 1024)
2148 many bytes. (default: 1024)
2139
2149
2140 ``bundle1``
2150 ``bundle1``
2141 Whether to allow clients to push and pull using the legacy bundle1
2151 Whether to allow clients to push and pull using the legacy bundle1
2142 exchange format. (default: True)
2152 exchange format. (default: True)
2143
2153
2144 ``bundle1gd``
2154 ``bundle1gd``
2145 Like ``bundle1`` but only used if the repository is using the
2155 Like ``bundle1`` but only used if the repository is using the
2146 *generaldelta* storage format. (default: True)
2156 *generaldelta* storage format. (default: True)
2147
2157
2148 ``bundle1.push``
2158 ``bundle1.push``
2149 Whether to allow clients to push using the legacy bundle1 exchange
2159 Whether to allow clients to push using the legacy bundle1 exchange
2150 format. (default: True)
2160 format. (default: True)
2151
2161
2152 ``bundle1gd.push``
2162 ``bundle1gd.push``
2153 Like ``bundle1.push`` but only used if the repository is using the
2163 Like ``bundle1.push`` but only used if the repository is using the
2154 *generaldelta* storage format. (default: True)
2164 *generaldelta* storage format. (default: True)
2155
2165
2156 ``bundle1.pull``
2166 ``bundle1.pull``
2157 Whether to allow clients to pull using the legacy bundle1 exchange
2167 Whether to allow clients to pull using the legacy bundle1 exchange
2158 format. (default: True)
2168 format. (default: True)
2159
2169
2160 ``bundle1gd.pull``
2170 ``bundle1gd.pull``
2161 Like ``bundle1.pull`` but only used if the repository is using the
2171 Like ``bundle1.pull`` but only used if the repository is using the
2162 *generaldelta* storage format. (default: True)
2172 *generaldelta* storage format. (default: True)
2163
2173
2164 Large repositories using the *generaldelta* storage format should
2174 Large repositories using the *generaldelta* storage format should
2165 consider setting this option because converting *generaldelta*
2175 consider setting this option because converting *generaldelta*
2166 repositories to the exchange format required by the bundle1 data
2176 repositories to the exchange format required by the bundle1 data
2167 format can consume a lot of CPU.
2177 format can consume a lot of CPU.
2168
2178
2169 ``bundle2.stream``
2179 ``bundle2.stream``
2170 Whether to allow clients to pull using the bundle2 streaming protocol.
2180 Whether to allow clients to pull using the bundle2 streaming protocol.
2171 (default: True)
2181 (default: True)
2172
2182
2173 ``zliblevel``
2183 ``zliblevel``
2174 Integer between ``-1`` and ``9`` that controls the zlib compression level
2184 Integer between ``-1`` and ``9`` that controls the zlib compression level
2175 for wire protocol commands that send zlib compressed output (notably the
2185 for wire protocol commands that send zlib compressed output (notably the
2176 commands that send repository history data).
2186 commands that send repository history data).
2177
2187
2178 The default (``-1``) uses the default zlib compression level, which is
2188 The default (``-1``) uses the default zlib compression level, which is
2179 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2189 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2180 maximum compression.
2190 maximum compression.
2181
2191
2182 Setting this option allows server operators to make trade-offs between
2192 Setting this option allows server operators to make trade-offs between
2183 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2193 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2184 but sends more bytes to clients.
2194 but sends more bytes to clients.
2185
2195
2186 This option only impacts the HTTP server.
2196 This option only impacts the HTTP server.
2187
2197
2188 ``zstdlevel``
2198 ``zstdlevel``
2189 Integer between ``1`` and ``22`` that controls the zstd compression level
2199 Integer between ``1`` and ``22`` that controls the zstd compression level
2190 for wire protocol commands. ``1`` is the minimal amount of compression and
2200 for wire protocol commands. ``1`` is the minimal amount of compression and
2191 ``22`` is the highest amount of compression.
2201 ``22`` is the highest amount of compression.
2192
2202
2193 The default (``3``) should be significantly faster than zlib while likely
2203 The default (``3``) should be significantly faster than zlib while likely
2194 delivering better compression ratios.
2204 delivering better compression ratios.
2195
2205
2196 This option only impacts the HTTP server.
2206 This option only impacts the HTTP server.
2197
2207
2198 See also ``server.zliblevel``.
2208 See also ``server.zliblevel``.
2199
2209
2200 ``view``
2210 ``view``
2201 Repository filter used when exchanging revisions with the peer.
2211 Repository filter used when exchanging revisions with the peer.
2202
2212
2203 The default view (``served``) excludes secret and hidden changesets.
2213 The default view (``served``) excludes secret and hidden changesets.
2204 Another useful value is ``immutable`` (no draft, secret or hidden
2214 Another useful value is ``immutable`` (no draft, secret or hidden
2205 changesets). (EXPERIMENTAL)
2215 changesets). (EXPERIMENTAL)
2206
2216
2207 ``smtp``
2217 ``smtp``
2208 --------
2218 --------
2209
2219
2210 Configuration for extensions that need to send email messages.
2220 Configuration for extensions that need to send email messages.
2211
2221
2212 ``host``
2222 ``host``
2213 Host name of mail server, e.g. "mail.example.com".
2223 Host name of mail server, e.g. "mail.example.com".
2214
2224
2215 ``port``
2225 ``port``
2216 Optional. Port to connect to on mail server. (default: 465 if
2226 Optional. Port to connect to on mail server. (default: 465 if
2217 ``tls`` is smtps; 25 otherwise)
2227 ``tls`` is smtps; 25 otherwise)
2218
2228
2219 ``tls``
2229 ``tls``
2220 Optional. Method to enable TLS when connecting to mail server: starttls,
2230 Optional. Method to enable TLS when connecting to mail server: starttls,
2221 smtps or none. (default: none)
2231 smtps or none. (default: none)
2222
2232
2223 ``username``
2233 ``username``
2224 Optional. User name for authenticating with the SMTP server.
2234 Optional. User name for authenticating with the SMTP server.
2225 (default: None)
2235 (default: None)
2226
2236
2227 ``password``
2237 ``password``
2228 Optional. Password for authenticating with the SMTP server. If not
2238 Optional. Password for authenticating with the SMTP server. If not
2229 specified, interactive sessions will prompt the user for a
2239 specified, interactive sessions will prompt the user for a
2230 password; non-interactive sessions will fail. (default: None)
2240 password; non-interactive sessions will fail. (default: None)
2231
2241
2232 ``local_hostname``
2242 ``local_hostname``
2233 Optional. The hostname that the sender can use to identify
2243 Optional. The hostname that the sender can use to identify
2234 itself to the MTA.
2244 itself to the MTA.
2235
2245
2236
2246
2237 ``subpaths``
2247 ``subpaths``
2238 ------------
2248 ------------
2239
2249
2240 Subrepository source URLs can go stale if a remote server changes name
2250 Subrepository source URLs can go stale if a remote server changes name
2241 or becomes temporarily unavailable. This section lets you define
2251 or becomes temporarily unavailable. This section lets you define
2242 rewrite rules of the form::
2252 rewrite rules of the form::
2243
2253
2244 <pattern> = <replacement>
2254 <pattern> = <replacement>
2245
2255
2246 where ``pattern`` is a regular expression matching a subrepository
2256 where ``pattern`` is a regular expression matching a subrepository
2247 source URL and ``replacement`` is the replacement string used to
2257 source URL and ``replacement`` is the replacement string used to
2248 rewrite it. Groups can be matched in ``pattern`` and referenced in
2258 rewrite it. Groups can be matched in ``pattern`` and referenced in
2249 ``replacements``. For instance::
2259 ``replacements``. For instance::
2250
2260
2251 http://server/(.*)-hg/ = http://hg.server/\1/
2261 http://server/(.*)-hg/ = http://hg.server/\1/
2252
2262
2253 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2263 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2254
2264
2255 Relative subrepository paths are first made absolute, and the
2265 Relative subrepository paths are first made absolute, and the
2256 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2266 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2257 doesn't match the full path, an attempt is made to apply it on the
2267 doesn't match the full path, an attempt is made to apply it on the
2258 relative path alone. The rules are applied in definition order.
2268 relative path alone. The rules are applied in definition order.
2259
2269
2260 ``subrepos``
2270 ``subrepos``
2261 ------------
2271 ------------
2262
2272
2263 This section contains options that control the behavior of the
2273 This section contains options that control the behavior of the
2264 subrepositories feature. See also :hg:`help subrepos`.
2274 subrepositories feature. See also :hg:`help subrepos`.
2265
2275
2266 Security note: auditing in Mercurial is known to be insufficient to
2276 Security note: auditing in Mercurial is known to be insufficient to
2267 prevent clone-time code execution with carefully constructed Git
2277 prevent clone-time code execution with carefully constructed Git
2268 subrepos. It is unknown if a similar detect is present in Subversion
2278 subrepos. It is unknown if a similar detect is present in Subversion
2269 subrepos. Both Git and Subversion subrepos are disabled by default
2279 subrepos. Both Git and Subversion subrepos are disabled by default
2270 out of security concerns. These subrepo types can be enabled using
2280 out of security concerns. These subrepo types can be enabled using
2271 the respective options below.
2281 the respective options below.
2272
2282
2273 ``allowed``
2283 ``allowed``
2274 Whether subrepositories are allowed in the working directory.
2284 Whether subrepositories are allowed in the working directory.
2275
2285
2276 When false, commands involving subrepositories (like :hg:`update`)
2286 When false, commands involving subrepositories (like :hg:`update`)
2277 will fail for all subrepository types.
2287 will fail for all subrepository types.
2278 (default: true)
2288 (default: true)
2279
2289
2280 ``hg:allowed``
2290 ``hg:allowed``
2281 Whether Mercurial subrepositories are allowed in the working
2291 Whether Mercurial subrepositories are allowed in the working
2282 directory. This option only has an effect if ``subrepos.allowed``
2292 directory. This option only has an effect if ``subrepos.allowed``
2283 is true.
2293 is true.
2284 (default: true)
2294 (default: true)
2285
2295
2286 ``git:allowed``
2296 ``git:allowed``
2287 Whether Git subrepositories are allowed in the working directory.
2297 Whether Git subrepositories are allowed in the working directory.
2288 This option only has an effect if ``subrepos.allowed`` is true.
2298 This option only has an effect if ``subrepos.allowed`` is true.
2289
2299
2290 See the security note above before enabling Git subrepos.
2300 See the security note above before enabling Git subrepos.
2291 (default: false)
2301 (default: false)
2292
2302
2293 ``svn:allowed``
2303 ``svn:allowed``
2294 Whether Subversion subrepositories are allowed in the working
2304 Whether Subversion subrepositories are allowed in the working
2295 directory. This option only has an effect if ``subrepos.allowed``
2305 directory. This option only has an effect if ``subrepos.allowed``
2296 is true.
2306 is true.
2297
2307
2298 See the security note above before enabling Subversion subrepos.
2308 See the security note above before enabling Subversion subrepos.
2299 (default: false)
2309 (default: false)
2300
2310
2301 ``templatealias``
2311 ``templatealias``
2302 -----------------
2312 -----------------
2303
2313
2304 Alias definitions for templates. See :hg:`help templates` for details.
2314 Alias definitions for templates. See :hg:`help templates` for details.
2305
2315
2306 ``templates``
2316 ``templates``
2307 -------------
2317 -------------
2308
2318
2309 Use the ``[templates]`` section to define template strings.
2319 Use the ``[templates]`` section to define template strings.
2310 See :hg:`help templates` for details.
2320 See :hg:`help templates` for details.
2311
2321
2312 ``trusted``
2322 ``trusted``
2313 -----------
2323 -----------
2314
2324
2315 Mercurial will not use the settings in the
2325 Mercurial will not use the settings in the
2316 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2326 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2317 user or to a trusted group, as various hgrc features allow arbitrary
2327 user or to a trusted group, as various hgrc features allow arbitrary
2318 commands to be run. This issue is often encountered when configuring
2328 commands to be run. This issue is often encountered when configuring
2319 hooks or extensions for shared repositories or servers. However,
2329 hooks or extensions for shared repositories or servers. However,
2320 the web interface will use some safe settings from the ``[web]``
2330 the web interface will use some safe settings from the ``[web]``
2321 section.
2331 section.
2322
2332
2323 This section specifies what users and groups are trusted. The
2333 This section specifies what users and groups are trusted. The
2324 current user is always trusted. To trust everybody, list a user or a
2334 current user is always trusted. To trust everybody, list a user or a
2325 group with name ``*``. These settings must be placed in an
2335 group with name ``*``. These settings must be placed in an
2326 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2336 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2327 user or service running Mercurial.
2337 user or service running Mercurial.
2328
2338
2329 ``users``
2339 ``users``
2330 Comma-separated list of trusted users.
2340 Comma-separated list of trusted users.
2331
2341
2332 ``groups``
2342 ``groups``
2333 Comma-separated list of trusted groups.
2343 Comma-separated list of trusted groups.
2334
2344
2335
2345
2336 ``ui``
2346 ``ui``
2337 ------
2347 ------
2338
2348
2339 User interface controls.
2349 User interface controls.
2340
2350
2341 ``archivemeta``
2351 ``archivemeta``
2342 Whether to include the .hg_archival.txt file containing meta data
2352 Whether to include the .hg_archival.txt file containing meta data
2343 (hashes for the repository base and for tip) in archives created
2353 (hashes for the repository base and for tip) in archives created
2344 by the :hg:`archive` command or downloaded via hgweb.
2354 by the :hg:`archive` command or downloaded via hgweb.
2345 (default: True)
2355 (default: True)
2346
2356
2347 ``askusername``
2357 ``askusername``
2348 Whether to prompt for a username when committing. If True, and
2358 Whether to prompt for a username when committing. If True, and
2349 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2359 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2350 be prompted to enter a username. If no username is entered, the
2360 be prompted to enter a username. If no username is entered, the
2351 default ``USER@HOST`` is used instead.
2361 default ``USER@HOST`` is used instead.
2352 (default: False)
2362 (default: False)
2353
2363
2354 ``clonebundles``
2364 ``clonebundles``
2355 Whether the "clone bundles" feature is enabled.
2365 Whether the "clone bundles" feature is enabled.
2356
2366
2357 When enabled, :hg:`clone` may download and apply a server-advertised
2367 When enabled, :hg:`clone` may download and apply a server-advertised
2358 bundle file from a URL instead of using the normal exchange mechanism.
2368 bundle file from a URL instead of using the normal exchange mechanism.
2359
2369
2360 This can likely result in faster and more reliable clones.
2370 This can likely result in faster and more reliable clones.
2361
2371
2362 (default: True)
2372 (default: True)
2363
2373
2364 ``clonebundlefallback``
2374 ``clonebundlefallback``
2365 Whether failure to apply an advertised "clone bundle" from a server
2375 Whether failure to apply an advertised "clone bundle" from a server
2366 should result in fallback to a regular clone.
2376 should result in fallback to a regular clone.
2367
2377
2368 This is disabled by default because servers advertising "clone
2378 This is disabled by default because servers advertising "clone
2369 bundles" often do so to reduce server load. If advertised bundles
2379 bundles" often do so to reduce server load. If advertised bundles
2370 start mass failing and clients automatically fall back to a regular
2380 start mass failing and clients automatically fall back to a regular
2371 clone, this would add significant and unexpected load to the server
2381 clone, this would add significant and unexpected load to the server
2372 since the server is expecting clone operations to be offloaded to
2382 since the server is expecting clone operations to be offloaded to
2373 pre-generated bundles. Failing fast (the default behavior) ensures
2383 pre-generated bundles. Failing fast (the default behavior) ensures
2374 clients don't overwhelm the server when "clone bundle" application
2384 clients don't overwhelm the server when "clone bundle" application
2375 fails.
2385 fails.
2376
2386
2377 (default: False)
2387 (default: False)
2378
2388
2379 ``clonebundleprefers``
2389 ``clonebundleprefers``
2380 Defines preferences for which "clone bundles" to use.
2390 Defines preferences for which "clone bundles" to use.
2381
2391
2382 Servers advertising "clone bundles" may advertise multiple available
2392 Servers advertising "clone bundles" may advertise multiple available
2383 bundles. Each bundle may have different attributes, such as the bundle
2393 bundles. Each bundle may have different attributes, such as the bundle
2384 type and compression format. This option is used to prefer a particular
2394 type and compression format. This option is used to prefer a particular
2385 bundle over another.
2395 bundle over another.
2386
2396
2387 The following keys are defined by Mercurial:
2397 The following keys are defined by Mercurial:
2388
2398
2389 BUNDLESPEC
2399 BUNDLESPEC
2390 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2400 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2391 e.g. ``gzip-v2`` or ``bzip2-v1``.
2401 e.g. ``gzip-v2`` or ``bzip2-v1``.
2392
2402
2393 COMPRESSION
2403 COMPRESSION
2394 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2404 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2395
2405
2396 Server operators may define custom keys.
2406 Server operators may define custom keys.
2397
2407
2398 Example values: ``COMPRESSION=bzip2``,
2408 Example values: ``COMPRESSION=bzip2``,
2399 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2409 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2400
2410
2401 By default, the first bundle advertised by the server is used.
2411 By default, the first bundle advertised by the server is used.
2402
2412
2403 ``color``
2413 ``color``
2404 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2414 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2405 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2415 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2406 seems possible. See :hg:`help color` for details.
2416 seems possible. See :hg:`help color` for details.
2407
2417
2408 ``commitsubrepos``
2418 ``commitsubrepos``
2409 Whether to commit modified subrepositories when committing the
2419 Whether to commit modified subrepositories when committing the
2410 parent repository. If False and one subrepository has uncommitted
2420 parent repository. If False and one subrepository has uncommitted
2411 changes, abort the commit.
2421 changes, abort the commit.
2412 (default: False)
2422 (default: False)
2413
2423
2414 ``debug``
2424 ``debug``
2415 Print debugging information. (default: False)
2425 Print debugging information. (default: False)
2416
2426
2417 ``editor``
2427 ``editor``
2418 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2428 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2419
2429
2420 ``fallbackencoding``
2430 ``fallbackencoding``
2421 Encoding to try if it's not possible to decode the changelog using
2431 Encoding to try if it's not possible to decode the changelog using
2422 UTF-8. (default: ISO-8859-1)
2432 UTF-8. (default: ISO-8859-1)
2423
2433
2424 ``graphnodetemplate``
2434 ``graphnodetemplate``
2425 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2435 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2426
2436
2427 ``ignore``
2437 ``ignore``
2428 A file to read per-user ignore patterns from. This file should be
2438 A file to read per-user ignore patterns from. This file should be
2429 in the same format as a repository-wide .hgignore file. Filenames
2439 in the same format as a repository-wide .hgignore file. Filenames
2430 are relative to the repository root. This option supports hook syntax,
2440 are relative to the repository root. This option supports hook syntax,
2431 so if you want to specify multiple ignore files, you can do so by
2441 so if you want to specify multiple ignore files, you can do so by
2432 setting something like ``ignore.other = ~/.hgignore2``. For details
2442 setting something like ``ignore.other = ~/.hgignore2``. For details
2433 of the ignore file format, see the ``hgignore(5)`` man page.
2443 of the ignore file format, see the ``hgignore(5)`` man page.
2434
2444
2435 ``interactive``
2445 ``interactive``
2436 Allow to prompt the user. (default: True)
2446 Allow to prompt the user. (default: True)
2437
2447
2438 ``interface``
2448 ``interface``
2439 Select the default interface for interactive features (default: text).
2449 Select the default interface for interactive features (default: text).
2440 Possible values are 'text' and 'curses'.
2450 Possible values are 'text' and 'curses'.
2441
2451
2442 ``interface.chunkselector``
2452 ``interface.chunkselector``
2443 Select the interface for change recording (e.g. :hg:`commit -i`).
2453 Select the interface for change recording (e.g. :hg:`commit -i`).
2444 Possible values are 'text' and 'curses'.
2454 Possible values are 'text' and 'curses'.
2445 This config overrides the interface specified by ui.interface.
2455 This config overrides the interface specified by ui.interface.
2446
2456
2447 ``large-file-limit``
2457 ``large-file-limit``
2448 Largest file size that gives no memory use warning.
2458 Largest file size that gives no memory use warning.
2449 Possible values are integers or 0 to disable the check.
2459 Possible values are integers or 0 to disable the check.
2450 (default: 10000000)
2460 (default: 10000000)
2451
2461
2452 ``logtemplate``
2462 ``logtemplate``
2453 (DEPRECATED) Use ``command-templates.log`` instead.
2463 (DEPRECATED) Use ``command-templates.log`` instead.
2454
2464
2455 ``merge``
2465 ``merge``
2456 The conflict resolution program to use during a manual merge.
2466 The conflict resolution program to use during a manual merge.
2457 For more information on merge tools see :hg:`help merge-tools`.
2467 For more information on merge tools see :hg:`help merge-tools`.
2458 For configuring merge tools see the ``[merge-tools]`` section.
2468 For configuring merge tools see the ``[merge-tools]`` section.
2459
2469
2460 ``mergemarkers``
2470 ``mergemarkers``
2461 Sets the merge conflict marker label styling. The ``detailed`` style
2471 Sets the merge conflict marker label styling. The ``detailed`` style
2462 uses the ``command-templates.mergemarker`` setting to style the labels.
2472 uses the ``command-templates.mergemarker`` setting to style the labels.
2463 The ``basic`` style just uses 'local' and 'other' as the marker label.
2473 The ``basic`` style just uses 'local' and 'other' as the marker label.
2464 One of ``basic`` or ``detailed``.
2474 One of ``basic`` or ``detailed``.
2465 (default: ``basic``)
2475 (default: ``basic``)
2466
2476
2467 ``mergemarkertemplate``
2477 ``mergemarkertemplate``
2468 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2478 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2469
2479
2470 ``message-output``
2480 ``message-output``
2471 Where to write status and error messages. (default: ``stdio``)
2481 Where to write status and error messages. (default: ``stdio``)
2472
2482
2473 ``channel``
2483 ``channel``
2474 Use separate channel for structured output. (Command-server only)
2484 Use separate channel for structured output. (Command-server only)
2475 ``stderr``
2485 ``stderr``
2476 Everything to stderr.
2486 Everything to stderr.
2477 ``stdio``
2487 ``stdio``
2478 Status to stdout, and error to stderr.
2488 Status to stdout, and error to stderr.
2479
2489
2480 ``origbackuppath``
2490 ``origbackuppath``
2481 The path to a directory used to store generated .orig files. If the path is
2491 The path to a directory used to store generated .orig files. If the path is
2482 not a directory, one will be created. If set, files stored in this
2492 not a directory, one will be created. If set, files stored in this
2483 directory have the same name as the original file and do not have a .orig
2493 directory have the same name as the original file and do not have a .orig
2484 suffix.
2494 suffix.
2485
2495
2486 ``paginate``
2496 ``paginate``
2487 Control the pagination of command output (default: True). See :hg:`help pager`
2497 Control the pagination of command output (default: True). See :hg:`help pager`
2488 for details.
2498 for details.
2489
2499
2490 ``patch``
2500 ``patch``
2491 An optional external tool that ``hg import`` and some extensions
2501 An optional external tool that ``hg import`` and some extensions
2492 will use for applying patches. By default Mercurial uses an
2502 will use for applying patches. By default Mercurial uses an
2493 internal patch utility. The external tool must work as the common
2503 internal patch utility. The external tool must work as the common
2494 Unix ``patch`` program. In particular, it must accept a ``-p``
2504 Unix ``patch`` program. In particular, it must accept a ``-p``
2495 argument to strip patch headers, a ``-d`` argument to specify the
2505 argument to strip patch headers, a ``-d`` argument to specify the
2496 current directory, a file name to patch, and a patch file to take
2506 current directory, a file name to patch, and a patch file to take
2497 from stdin.
2507 from stdin.
2498
2508
2499 It is possible to specify a patch tool together with extra
2509 It is possible to specify a patch tool together with extra
2500 arguments. For example, setting this option to ``patch --merge``
2510 arguments. For example, setting this option to ``patch --merge``
2501 will use the ``patch`` program with its 2-way merge option.
2511 will use the ``patch`` program with its 2-way merge option.
2502
2512
2503 ``portablefilenames``
2513 ``portablefilenames``
2504 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2514 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2505 (default: ``warn``)
2515 (default: ``warn``)
2506
2516
2507 ``warn``
2517 ``warn``
2508 Print a warning message on POSIX platforms, if a file with a non-portable
2518 Print a warning message on POSIX platforms, if a file with a non-portable
2509 filename is added (e.g. a file with a name that can't be created on
2519 filename is added (e.g. a file with a name that can't be created on
2510 Windows because it contains reserved parts like ``AUX``, reserved
2520 Windows because it contains reserved parts like ``AUX``, reserved
2511 characters like ``:``, or would cause a case collision with an existing
2521 characters like ``:``, or would cause a case collision with an existing
2512 file).
2522 file).
2513
2523
2514 ``ignore``
2524 ``ignore``
2515 Don't print a warning.
2525 Don't print a warning.
2516
2526
2517 ``abort``
2527 ``abort``
2518 The command is aborted.
2528 The command is aborted.
2519
2529
2520 ``true``
2530 ``true``
2521 Alias for ``warn``.
2531 Alias for ``warn``.
2522
2532
2523 ``false``
2533 ``false``
2524 Alias for ``ignore``.
2534 Alias for ``ignore``.
2525
2535
2526 .. container:: windows
2536 .. container:: windows
2527
2537
2528 On Windows, this configuration option is ignored and the command aborted.
2538 On Windows, this configuration option is ignored and the command aborted.
2529
2539
2530 ``pre-merge-tool-output-template``
2540 ``pre-merge-tool-output-template``
2531 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2541 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2532
2542
2533 ``quiet``
2543 ``quiet``
2534 Reduce the amount of output printed.
2544 Reduce the amount of output printed.
2535 (default: False)
2545 (default: False)
2536
2546
2537 ``relative-paths``
2547 ``relative-paths``
2538 Prefer relative paths in the UI.
2548 Prefer relative paths in the UI.
2539
2549
2540 ``remotecmd``
2550 ``remotecmd``
2541 Remote command to use for clone/push/pull operations.
2551 Remote command to use for clone/push/pull operations.
2542 (default: ``hg``)
2552 (default: ``hg``)
2543
2553
2544 ``report_untrusted``
2554 ``report_untrusted``
2545 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2555 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2546 trusted user or group.
2556 trusted user or group.
2547 (default: True)
2557 (default: True)
2548
2558
2549 ``slash``
2559 ``slash``
2550 (Deprecated. Use ``slashpath`` template filter instead.)
2560 (Deprecated. Use ``slashpath`` template filter instead.)
2551
2561
2552 Display paths using a slash (``/``) as the path separator. This
2562 Display paths using a slash (``/``) as the path separator. This
2553 only makes a difference on systems where the default path
2563 only makes a difference on systems where the default path
2554 separator is not the slash character (e.g. Windows uses the
2564 separator is not the slash character (e.g. Windows uses the
2555 backslash character (``\``)).
2565 backslash character (``\``)).
2556 (default: False)
2566 (default: False)
2557
2567
2558 ``statuscopies``
2568 ``statuscopies``
2559 Display copies in the status command.
2569 Display copies in the status command.
2560
2570
2561 ``ssh``
2571 ``ssh``
2562 Command to use for SSH connections. (default: ``ssh``)
2572 Command to use for SSH connections. (default: ``ssh``)
2563
2573
2564 ``ssherrorhint``
2574 ``ssherrorhint``
2565 A hint shown to the user in the case of SSH error (e.g.
2575 A hint shown to the user in the case of SSH error (e.g.
2566 ``Please see http://company/internalwiki/ssh.html``)
2576 ``Please see http://company/internalwiki/ssh.html``)
2567
2577
2568 ``strict``
2578 ``strict``
2569 Require exact command names, instead of allowing unambiguous
2579 Require exact command names, instead of allowing unambiguous
2570 abbreviations. (default: False)
2580 abbreviations. (default: False)
2571
2581
2572 ``style``
2582 ``style``
2573 Name of style to use for command output.
2583 Name of style to use for command output.
2574
2584
2575 ``supportcontact``
2585 ``supportcontact``
2576 A URL where users should report a Mercurial traceback. Use this if you are a
2586 A URL where users should report a Mercurial traceback. Use this if you are a
2577 large organisation with its own Mercurial deployment process and crash
2587 large organisation with its own Mercurial deployment process and crash
2578 reports should be addressed to your internal support.
2588 reports should be addressed to your internal support.
2579
2589
2580 ``textwidth``
2590 ``textwidth``
2581 Maximum width of help text. A longer line generated by ``hg help`` or
2591 Maximum width of help text. A longer line generated by ``hg help`` or
2582 ``hg subcommand --help`` will be broken after white space to get this
2592 ``hg subcommand --help`` will be broken after white space to get this
2583 width or the terminal width, whichever comes first.
2593 width or the terminal width, whichever comes first.
2584 A non-positive value will disable this and the terminal width will be
2594 A non-positive value will disable this and the terminal width will be
2585 used. (default: 78)
2595 used. (default: 78)
2586
2596
2587 ``timeout``
2597 ``timeout``
2588 The timeout used when a lock is held (in seconds), a negative value
2598 The timeout used when a lock is held (in seconds), a negative value
2589 means no timeout. (default: 600)
2599 means no timeout. (default: 600)
2590
2600
2591 ``timeout.warn``
2601 ``timeout.warn``
2592 Time (in seconds) before a warning is printed about held lock. A negative
2602 Time (in seconds) before a warning is printed about held lock. A negative
2593 value means no warning. (default: 0)
2603 value means no warning. (default: 0)
2594
2604
2595 ``traceback``
2605 ``traceback``
2596 Mercurial always prints a traceback when an unknown exception
2606 Mercurial always prints a traceback when an unknown exception
2597 occurs. Setting this to True will make Mercurial print a traceback
2607 occurs. Setting this to True will make Mercurial print a traceback
2598 on all exceptions, even those recognized by Mercurial (such as
2608 on all exceptions, even those recognized by Mercurial (such as
2599 IOError or MemoryError). (default: False)
2609 IOError or MemoryError). (default: False)
2600
2610
2601 ``tweakdefaults``
2611 ``tweakdefaults``
2602
2612
2603 By default Mercurial's behavior changes very little from release
2613 By default Mercurial's behavior changes very little from release
2604 to release, but over time the recommended config settings
2614 to release, but over time the recommended config settings
2605 shift. Enable this config to opt in to get automatic tweaks to
2615 shift. Enable this config to opt in to get automatic tweaks to
2606 Mercurial's behavior over time. This config setting will have no
2616 Mercurial's behavior over time. This config setting will have no
2607 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2617 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2608 not include ``tweakdefaults``. (default: False)
2618 not include ``tweakdefaults``. (default: False)
2609
2619
2610 It currently means::
2620 It currently means::
2611
2621
2612 .. tweakdefaultsmarker
2622 .. tweakdefaultsmarker
2613
2623
2614 ``username``
2624 ``username``
2615 The committer of a changeset created when running "commit".
2625 The committer of a changeset created when running "commit".
2616 Typically a person's name and email address, e.g. ``Fred Widget
2626 Typically a person's name and email address, e.g. ``Fred Widget
2617 <fred@example.com>``. Environment variables in the
2627 <fred@example.com>``. Environment variables in the
2618 username are expanded.
2628 username are expanded.
2619
2629
2620 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2630 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2621 hgrc is empty, e.g. if the system admin set ``username =`` in the
2631 hgrc is empty, e.g. if the system admin set ``username =`` in the
2622 system hgrc, it has to be specified manually or in a different
2632 system hgrc, it has to be specified manually or in a different
2623 hgrc file)
2633 hgrc file)
2624
2634
2625 ``verbose``
2635 ``verbose``
2626 Increase the amount of output printed. (default: False)
2636 Increase the amount of output printed. (default: False)
2627
2637
2628
2638
2629 ``command-templates``
2639 ``command-templates``
2630 ---------------------
2640 ---------------------
2631
2641
2632 Templates used for customizing the output of commands.
2642 Templates used for customizing the output of commands.
2633
2643
2634 ``graphnode``
2644 ``graphnode``
2635 The template used to print changeset nodes in an ASCII revision graph.
2645 The template used to print changeset nodes in an ASCII revision graph.
2636 (default: ``{graphnode}``)
2646 (default: ``{graphnode}``)
2637
2647
2638 ``log``
2648 ``log``
2639 Template string for commands that print changesets.
2649 Template string for commands that print changesets.
2640
2650
2641 ``mergemarker``
2651 ``mergemarker``
2642 The template used to print the commit description next to each conflict
2652 The template used to print the commit description next to each conflict
2643 marker during merge conflicts. See :hg:`help templates` for the template
2653 marker during merge conflicts. See :hg:`help templates` for the template
2644 format.
2654 format.
2645
2655
2646 Defaults to showing the hash, tags, branches, bookmarks, author, and
2656 Defaults to showing the hash, tags, branches, bookmarks, author, and
2647 the first line of the commit description.
2657 the first line of the commit description.
2648
2658
2649 If you use non-ASCII characters in names for tags, branches, bookmarks,
2659 If you use non-ASCII characters in names for tags, branches, bookmarks,
2650 authors, and/or commit descriptions, you must pay attention to encodings of
2660 authors, and/or commit descriptions, you must pay attention to encodings of
2651 managed files. At template expansion, non-ASCII characters use the encoding
2661 managed files. At template expansion, non-ASCII characters use the encoding
2652 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2662 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2653 environment variables that govern your locale. If the encoding of the merge
2663 environment variables that govern your locale. If the encoding of the merge
2654 markers is different from the encoding of the merged files,
2664 markers is different from the encoding of the merged files,
2655 serious problems may occur.
2665 serious problems may occur.
2656
2666
2657 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2667 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2658
2668
2659 ``oneline-summary``
2669 ``oneline-summary``
2660 A template used by `hg rebase` and other commands for showing a one-line
2670 A template used by `hg rebase` and other commands for showing a one-line
2661 summary of a commit. If the template configured here is longer than one
2671 summary of a commit. If the template configured here is longer than one
2662 line, then only the first line is used.
2672 line, then only the first line is used.
2663
2673
2664 The template can be overridden per command by defining a template in
2674 The template can be overridden per command by defining a template in
2665 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2675 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2666
2676
2667 ``pre-merge-tool-output``
2677 ``pre-merge-tool-output``
2668 A template that is printed before executing an external merge tool. This can
2678 A template that is printed before executing an external merge tool. This can
2669 be used to print out additional context that might be useful to have during
2679 be used to print out additional context that might be useful to have during
2670 the conflict resolution, such as the description of the various commits
2680 the conflict resolution, such as the description of the various commits
2671 involved or bookmarks/tags.
2681 involved or bookmarks/tags.
2672
2682
2673 Additional information is available in the ``local`, ``base``, and ``other``
2683 Additional information is available in the ``local`, ``base``, and ``other``
2674 dicts. For example: ``{local.label}``, ``{base.name}``, or
2684 dicts. For example: ``{local.label}``, ``{base.name}``, or
2675 ``{other.islink}``.
2685 ``{other.islink}``.
2676
2686
2677
2687
2678 ``web``
2688 ``web``
2679 -------
2689 -------
2680
2690
2681 Web interface configuration. The settings in this section apply to
2691 Web interface configuration. The settings in this section apply to
2682 both the builtin webserver (started by :hg:`serve`) and the script you
2692 both the builtin webserver (started by :hg:`serve`) and the script you
2683 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2693 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2684 and WSGI).
2694 and WSGI).
2685
2695
2686 The Mercurial webserver does no authentication (it does not prompt for
2696 The Mercurial webserver does no authentication (it does not prompt for
2687 usernames and passwords to validate *who* users are), but it does do
2697 usernames and passwords to validate *who* users are), but it does do
2688 authorization (it grants or denies access for *authenticated users*
2698 authorization (it grants or denies access for *authenticated users*
2689 based on settings in this section). You must either configure your
2699 based on settings in this section). You must either configure your
2690 webserver to do authentication for you, or disable the authorization
2700 webserver to do authentication for you, or disable the authorization
2691 checks.
2701 checks.
2692
2702
2693 For a quick setup in a trusted environment, e.g., a private LAN, where
2703 For a quick setup in a trusted environment, e.g., a private LAN, where
2694 you want it to accept pushes from anybody, you can use the following
2704 you want it to accept pushes from anybody, you can use the following
2695 command line::
2705 command line::
2696
2706
2697 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2707 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2698
2708
2699 Note that this will allow anybody to push anything to the server and
2709 Note that this will allow anybody to push anything to the server and
2700 that this should not be used for public servers.
2710 that this should not be used for public servers.
2701
2711
2702 The full set of options is:
2712 The full set of options is:
2703
2713
2704 ``accesslog``
2714 ``accesslog``
2705 Where to output the access log. (default: stdout)
2715 Where to output the access log. (default: stdout)
2706
2716
2707 ``address``
2717 ``address``
2708 Interface address to bind to. (default: all)
2718 Interface address to bind to. (default: all)
2709
2719
2710 ``allow-archive``
2720 ``allow-archive``
2711 List of archive format (bz2, gz, zip) allowed for downloading.
2721 List of archive format (bz2, gz, zip) allowed for downloading.
2712 (default: empty)
2722 (default: empty)
2713
2723
2714 ``allowbz2``
2724 ``allowbz2``
2715 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2725 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2716 revisions.
2726 revisions.
2717 (default: False)
2727 (default: False)
2718
2728
2719 ``allowgz``
2729 ``allowgz``
2720 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2730 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2721 revisions.
2731 revisions.
2722 (default: False)
2732 (default: False)
2723
2733
2724 ``allow-pull``
2734 ``allow-pull``
2725 Whether to allow pulling from the repository. (default: True)
2735 Whether to allow pulling from the repository. (default: True)
2726
2736
2727 ``allow-push``
2737 ``allow-push``
2728 Whether to allow pushing to the repository. If empty or not set,
2738 Whether to allow pushing to the repository. If empty or not set,
2729 pushing is not allowed. If the special value ``*``, any remote
2739 pushing is not allowed. If the special value ``*``, any remote
2730 user can push, including unauthenticated users. Otherwise, the
2740 user can push, including unauthenticated users. Otherwise, the
2731 remote user must have been authenticated, and the authenticated
2741 remote user must have been authenticated, and the authenticated
2732 user name must be present in this list. The contents of the
2742 user name must be present in this list. The contents of the
2733 allow-push list are examined after the deny_push list.
2743 allow-push list are examined after the deny_push list.
2734
2744
2735 ``allow_read``
2745 ``allow_read``
2736 If the user has not already been denied repository access due to
2746 If the user has not already been denied repository access due to
2737 the contents of deny_read, this list determines whether to grant
2747 the contents of deny_read, this list determines whether to grant
2738 repository access to the user. If this list is not empty, and the
2748 repository access to the user. If this list is not empty, and the
2739 user is unauthenticated or not present in the list, then access is
2749 user is unauthenticated or not present in the list, then access is
2740 denied for the user. If the list is empty or not set, then access
2750 denied for the user. If the list is empty or not set, then access
2741 is permitted to all users by default. Setting allow_read to the
2751 is permitted to all users by default. Setting allow_read to the
2742 special value ``*`` is equivalent to it not being set (i.e. access
2752 special value ``*`` is equivalent to it not being set (i.e. access
2743 is permitted to all users). The contents of the allow_read list are
2753 is permitted to all users). The contents of the allow_read list are
2744 examined after the deny_read list.
2754 examined after the deny_read list.
2745
2755
2746 ``allowzip``
2756 ``allowzip``
2747 (DEPRECATED) Whether to allow .zip downloading of repository
2757 (DEPRECATED) Whether to allow .zip downloading of repository
2748 revisions. This feature creates temporary files.
2758 revisions. This feature creates temporary files.
2749 (default: False)
2759 (default: False)
2750
2760
2751 ``archivesubrepos``
2761 ``archivesubrepos``
2752 Whether to recurse into subrepositories when archiving.
2762 Whether to recurse into subrepositories when archiving.
2753 (default: False)
2763 (default: False)
2754
2764
2755 ``baseurl``
2765 ``baseurl``
2756 Base URL to use when publishing URLs in other locations, so
2766 Base URL to use when publishing URLs in other locations, so
2757 third-party tools like email notification hooks can construct
2767 third-party tools like email notification hooks can construct
2758 URLs. Example: ``http://hgserver/repos/``.
2768 URLs. Example: ``http://hgserver/repos/``.
2759
2769
2760 ``cacerts``
2770 ``cacerts``
2761 Path to file containing a list of PEM encoded certificate
2771 Path to file containing a list of PEM encoded certificate
2762 authority certificates. Environment variables and ``~user``
2772 authority certificates. Environment variables and ``~user``
2763 constructs are expanded in the filename. If specified on the
2773 constructs are expanded in the filename. If specified on the
2764 client, then it will verify the identity of remote HTTPS servers
2774 client, then it will verify the identity of remote HTTPS servers
2765 with these certificates.
2775 with these certificates.
2766
2776
2767 To disable SSL verification temporarily, specify ``--insecure`` from
2777 To disable SSL verification temporarily, specify ``--insecure`` from
2768 command line.
2778 command line.
2769
2779
2770 You can use OpenSSL's CA certificate file if your platform has
2780 You can use OpenSSL's CA certificate file if your platform has
2771 one. On most Linux systems this will be
2781 one. On most Linux systems this will be
2772 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2782 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2773 generate this file manually. The form must be as follows::
2783 generate this file manually. The form must be as follows::
2774
2784
2775 -----BEGIN CERTIFICATE-----
2785 -----BEGIN CERTIFICATE-----
2776 ... (certificate in base64 PEM encoding) ...
2786 ... (certificate in base64 PEM encoding) ...
2777 -----END CERTIFICATE-----
2787 -----END CERTIFICATE-----
2778 -----BEGIN CERTIFICATE-----
2788 -----BEGIN CERTIFICATE-----
2779 ... (certificate in base64 PEM encoding) ...
2789 ... (certificate in base64 PEM encoding) ...
2780 -----END CERTIFICATE-----
2790 -----END CERTIFICATE-----
2781
2791
2782 ``cache``
2792 ``cache``
2783 Whether to support caching in hgweb. (default: True)
2793 Whether to support caching in hgweb. (default: True)
2784
2794
2785 ``certificate``
2795 ``certificate``
2786 Certificate to use when running :hg:`serve`.
2796 Certificate to use when running :hg:`serve`.
2787
2797
2788 ``collapse``
2798 ``collapse``
2789 With ``descend`` enabled, repositories in subdirectories are shown at
2799 With ``descend`` enabled, repositories in subdirectories are shown at
2790 a single level alongside repositories in the current path. With
2800 a single level alongside repositories in the current path. With
2791 ``collapse`` also enabled, repositories residing at a deeper level than
2801 ``collapse`` also enabled, repositories residing at a deeper level than
2792 the current path are grouped behind navigable directory entries that
2802 the current path are grouped behind navigable directory entries that
2793 lead to the locations of these repositories. In effect, this setting
2803 lead to the locations of these repositories. In effect, this setting
2794 collapses each collection of repositories found within a subdirectory
2804 collapses each collection of repositories found within a subdirectory
2795 into a single entry for that subdirectory. (default: False)
2805 into a single entry for that subdirectory. (default: False)
2796
2806
2797 ``comparisoncontext``
2807 ``comparisoncontext``
2798 Number of lines of context to show in side-by-side file comparison. If
2808 Number of lines of context to show in side-by-side file comparison. If
2799 negative or the value ``full``, whole files are shown. (default: 5)
2809 negative or the value ``full``, whole files are shown. (default: 5)
2800
2810
2801 This setting can be overridden by a ``context`` request parameter to the
2811 This setting can be overridden by a ``context`` request parameter to the
2802 ``comparison`` command, taking the same values.
2812 ``comparison`` command, taking the same values.
2803
2813
2804 ``contact``
2814 ``contact``
2805 Name or email address of the person in charge of the repository.
2815 Name or email address of the person in charge of the repository.
2806 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2816 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2807
2817
2808 ``csp``
2818 ``csp``
2809 Send a ``Content-Security-Policy`` HTTP header with this value.
2819 Send a ``Content-Security-Policy`` HTTP header with this value.
2810
2820
2811 The value may contain a special string ``%nonce%``, which will be replaced
2821 The value may contain a special string ``%nonce%``, which will be replaced
2812 by a randomly-generated one-time use value. If the value contains
2822 by a randomly-generated one-time use value. If the value contains
2813 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2823 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2814 one-time property of the nonce. This nonce will also be inserted into
2824 one-time property of the nonce. This nonce will also be inserted into
2815 ``<script>`` elements containing inline JavaScript.
2825 ``<script>`` elements containing inline JavaScript.
2816
2826
2817 Note: lots of HTML content sent by the server is derived from repository
2827 Note: lots of HTML content sent by the server is derived from repository
2818 data. Please consider the potential for malicious repository data to
2828 data. Please consider the potential for malicious repository data to
2819 "inject" itself into generated HTML content as part of your security
2829 "inject" itself into generated HTML content as part of your security
2820 threat model.
2830 threat model.
2821
2831
2822 ``deny_push``
2832 ``deny_push``
2823 Whether to deny pushing to the repository. If empty or not set,
2833 Whether to deny pushing to the repository. If empty or not set,
2824 push is not denied. If the special value ``*``, all remote users are
2834 push is not denied. If the special value ``*``, all remote users are
2825 denied push. Otherwise, unauthenticated users are all denied, and
2835 denied push. Otherwise, unauthenticated users are all denied, and
2826 any authenticated user name present in this list is also denied. The
2836 any authenticated user name present in this list is also denied. The
2827 contents of the deny_push list are examined before the allow-push list.
2837 contents of the deny_push list are examined before the allow-push list.
2828
2838
2829 ``deny_read``
2839 ``deny_read``
2830 Whether to deny reading/viewing of the repository. If this list is
2840 Whether to deny reading/viewing of the repository. If this list is
2831 not empty, unauthenticated users are all denied, and any
2841 not empty, unauthenticated users are all denied, and any
2832 authenticated user name present in this list is also denied access to
2842 authenticated user name present in this list is also denied access to
2833 the repository. If set to the special value ``*``, all remote users
2843 the repository. If set to the special value ``*``, all remote users
2834 are denied access (rarely needed ;). If deny_read is empty or not set,
2844 are denied access (rarely needed ;). If deny_read is empty or not set,
2835 the determination of repository access depends on the presence and
2845 the determination of repository access depends on the presence and
2836 content of the allow_read list (see description). If both
2846 content of the allow_read list (see description). If both
2837 deny_read and allow_read are empty or not set, then access is
2847 deny_read and allow_read are empty or not set, then access is
2838 permitted to all users by default. If the repository is being
2848 permitted to all users by default. If the repository is being
2839 served via hgwebdir, denied users will not be able to see it in
2849 served via hgwebdir, denied users will not be able to see it in
2840 the list of repositories. The contents of the deny_read list have
2850 the list of repositories. The contents of the deny_read list have
2841 priority over (are examined before) the contents of the allow_read
2851 priority over (are examined before) the contents of the allow_read
2842 list.
2852 list.
2843
2853
2844 ``descend``
2854 ``descend``
2845 hgwebdir indexes will not descend into subdirectories. Only repositories
2855 hgwebdir indexes will not descend into subdirectories. Only repositories
2846 directly in the current path will be shown (other repositories are still
2856 directly in the current path will be shown (other repositories are still
2847 available from the index corresponding to their containing path).
2857 available from the index corresponding to their containing path).
2848
2858
2849 ``description``
2859 ``description``
2850 Textual description of the repository's purpose or contents.
2860 Textual description of the repository's purpose or contents.
2851 (default: "unknown")
2861 (default: "unknown")
2852
2862
2853 ``encoding``
2863 ``encoding``
2854 Character encoding name. (default: the current locale charset)
2864 Character encoding name. (default: the current locale charset)
2855 Example: "UTF-8".
2865 Example: "UTF-8".
2856
2866
2857 ``errorlog``
2867 ``errorlog``
2858 Where to output the error log. (default: stderr)
2868 Where to output the error log. (default: stderr)
2859
2869
2860 ``guessmime``
2870 ``guessmime``
2861 Control MIME types for raw download of file content.
2871 Control MIME types for raw download of file content.
2862 Set to True to let hgweb guess the content type from the file
2872 Set to True to let hgweb guess the content type from the file
2863 extension. This will serve HTML files as ``text/html`` and might
2873 extension. This will serve HTML files as ``text/html`` and might
2864 allow cross-site scripting attacks when serving untrusted
2874 allow cross-site scripting attacks when serving untrusted
2865 repositories. (default: False)
2875 repositories. (default: False)
2866
2876
2867 ``hidden``
2877 ``hidden``
2868 Whether to hide the repository in the hgwebdir index.
2878 Whether to hide the repository in the hgwebdir index.
2869 (default: False)
2879 (default: False)
2870
2880
2871 ``ipv6``
2881 ``ipv6``
2872 Whether to use IPv6. (default: False)
2882 Whether to use IPv6. (default: False)
2873
2883
2874 ``labels``
2884 ``labels``
2875 List of string *labels* associated with the repository.
2885 List of string *labels* associated with the repository.
2876
2886
2877 Labels are exposed as a template keyword and can be used to customize
2887 Labels are exposed as a template keyword and can be used to customize
2878 output. e.g. the ``index`` template can group or filter repositories
2888 output. e.g. the ``index`` template can group or filter repositories
2879 by labels and the ``summary`` template can display additional content
2889 by labels and the ``summary`` template can display additional content
2880 if a specific label is present.
2890 if a specific label is present.
2881
2891
2882 ``logoimg``
2892 ``logoimg``
2883 File name of the logo image that some templates display on each page.
2893 File name of the logo image that some templates display on each page.
2884 The file name is relative to ``staticurl``. That is, the full path to
2894 The file name is relative to ``staticurl``. That is, the full path to
2885 the logo image is "staticurl/logoimg".
2895 the logo image is "staticurl/logoimg".
2886 If unset, ``hglogo.png`` will be used.
2896 If unset, ``hglogo.png`` will be used.
2887
2897
2888 ``logourl``
2898 ``logourl``
2889 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2899 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2890 will be used.
2900 will be used.
2891
2901
2892 ``maxchanges``
2902 ``maxchanges``
2893 Maximum number of changes to list on the changelog. (default: 10)
2903 Maximum number of changes to list on the changelog. (default: 10)
2894
2904
2895 ``maxfiles``
2905 ``maxfiles``
2896 Maximum number of files to list per changeset. (default: 10)
2906 Maximum number of files to list per changeset. (default: 10)
2897
2907
2898 ``maxshortchanges``
2908 ``maxshortchanges``
2899 Maximum number of changes to list on the shortlog, graph or filelog
2909 Maximum number of changes to list on the shortlog, graph or filelog
2900 pages. (default: 60)
2910 pages. (default: 60)
2901
2911
2902 ``name``
2912 ``name``
2903 Repository name to use in the web interface.
2913 Repository name to use in the web interface.
2904 (default: current working directory)
2914 (default: current working directory)
2905
2915
2906 ``port``
2916 ``port``
2907 Port to listen on. (default: 8000)
2917 Port to listen on. (default: 8000)
2908
2918
2909 ``prefix``
2919 ``prefix``
2910 Prefix path to serve from. (default: '' (server root))
2920 Prefix path to serve from. (default: '' (server root))
2911
2921
2912 ``push_ssl``
2922 ``push_ssl``
2913 Whether to require that inbound pushes be transported over SSL to
2923 Whether to require that inbound pushes be transported over SSL to
2914 prevent password sniffing. (default: True)
2924 prevent password sniffing. (default: True)
2915
2925
2916 ``refreshinterval``
2926 ``refreshinterval``
2917 How frequently directory listings re-scan the filesystem for new
2927 How frequently directory listings re-scan the filesystem for new
2918 repositories, in seconds. This is relevant when wildcards are used
2928 repositories, in seconds. This is relevant when wildcards are used
2919 to define paths. Depending on how much filesystem traversal is
2929 to define paths. Depending on how much filesystem traversal is
2920 required, refreshing may negatively impact performance.
2930 required, refreshing may negatively impact performance.
2921
2931
2922 Values less than or equal to 0 always refresh.
2932 Values less than or equal to 0 always refresh.
2923 (default: 20)
2933 (default: 20)
2924
2934
2925 ``server-header``
2935 ``server-header``
2926 Value for HTTP ``Server`` response header.
2936 Value for HTTP ``Server`` response header.
2927
2937
2928 ``static``
2938 ``static``
2929 Directory where static files are served from.
2939 Directory where static files are served from.
2930
2940
2931 ``staticurl``
2941 ``staticurl``
2932 Base URL to use for static files. If unset, static files (e.g. the
2942 Base URL to use for static files. If unset, static files (e.g. the
2933 hgicon.png favicon) will be served by the CGI script itself. Use
2943 hgicon.png favicon) will be served by the CGI script itself. Use
2934 this setting to serve them directly with the HTTP server.
2944 this setting to serve them directly with the HTTP server.
2935 Example: ``http://hgserver/static/``.
2945 Example: ``http://hgserver/static/``.
2936
2946
2937 ``stripes``
2947 ``stripes``
2938 How many lines a "zebra stripe" should span in multi-line output.
2948 How many lines a "zebra stripe" should span in multi-line output.
2939 Set to 0 to disable. (default: 1)
2949 Set to 0 to disable. (default: 1)
2940
2950
2941 ``style``
2951 ``style``
2942 Which template map style to use. The available options are the names of
2952 Which template map style to use. The available options are the names of
2943 subdirectories in the HTML templates path. (default: ``paper``)
2953 subdirectories in the HTML templates path. (default: ``paper``)
2944 Example: ``monoblue``.
2954 Example: ``monoblue``.
2945
2955
2946 ``templates``
2956 ``templates``
2947 Where to find the HTML templates. The default path to the HTML templates
2957 Where to find the HTML templates. The default path to the HTML templates
2948 can be obtained from ``hg debuginstall``.
2958 can be obtained from ``hg debuginstall``.
2949
2959
2950 ``websub``
2960 ``websub``
2951 ----------
2961 ----------
2952
2962
2953 Web substitution filter definition. You can use this section to
2963 Web substitution filter definition. You can use this section to
2954 define a set of regular expression substitution patterns which
2964 define a set of regular expression substitution patterns which
2955 let you automatically modify the hgweb server output.
2965 let you automatically modify the hgweb server output.
2956
2966
2957 The default hgweb templates only apply these substitution patterns
2967 The default hgweb templates only apply these substitution patterns
2958 on the revision description fields. You can apply them anywhere
2968 on the revision description fields. You can apply them anywhere
2959 you want when you create your own templates by adding calls to the
2969 you want when you create your own templates by adding calls to the
2960 "websub" filter (usually after calling the "escape" filter).
2970 "websub" filter (usually after calling the "escape" filter).
2961
2971
2962 This can be used, for example, to convert issue references to links
2972 This can be used, for example, to convert issue references to links
2963 to your issue tracker, or to convert "markdown-like" syntax into
2973 to your issue tracker, or to convert "markdown-like" syntax into
2964 HTML (see the examples below).
2974 HTML (see the examples below).
2965
2975
2966 Each entry in this section names a substitution filter.
2976 Each entry in this section names a substitution filter.
2967 The value of each entry defines the substitution expression itself.
2977 The value of each entry defines the substitution expression itself.
2968 The websub expressions follow the old interhg extension syntax,
2978 The websub expressions follow the old interhg extension syntax,
2969 which in turn imitates the Unix sed replacement syntax::
2979 which in turn imitates the Unix sed replacement syntax::
2970
2980
2971 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2981 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2972
2982
2973 You can use any separator other than "/". The final "i" is optional
2983 You can use any separator other than "/". The final "i" is optional
2974 and indicates that the search must be case insensitive.
2984 and indicates that the search must be case insensitive.
2975
2985
2976 Examples::
2986 Examples::
2977
2987
2978 [websub]
2988 [websub]
2979 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2989 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2980 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2990 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2981 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2991 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2982
2992
2983 ``worker``
2993 ``worker``
2984 ----------
2994 ----------
2985
2995
2986 Parallel master/worker configuration. We currently perform working
2996 Parallel master/worker configuration. We currently perform working
2987 directory updates in parallel on Unix-like systems, which greatly
2997 directory updates in parallel on Unix-like systems, which greatly
2988 helps performance.
2998 helps performance.
2989
2999
2990 ``enabled``
3000 ``enabled``
2991 Whether to enable workers code to be used.
3001 Whether to enable workers code to be used.
2992 (default: true)
3002 (default: true)
2993
3003
2994 ``numcpus``
3004 ``numcpus``
2995 Number of CPUs to use for parallel operations. A zero or
3005 Number of CPUs to use for parallel operations. A zero or
2996 negative value is treated as ``use the default``.
3006 negative value is treated as ``use the default``.
2997 (default: 4 or the number of CPUs on the system, whichever is larger)
3007 (default: 4 or the number of CPUs on the system, whichever is larger)
2998
3008
2999 ``backgroundclose``
3009 ``backgroundclose``
3000 Whether to enable closing file handles on background threads during certain
3010 Whether to enable closing file handles on background threads during certain
3001 operations. Some platforms aren't very efficient at closing file
3011 operations. Some platforms aren't very efficient at closing file
3002 handles that have been written or appended to. By performing file closing
3012 handles that have been written or appended to. By performing file closing
3003 on background threads, file write rate can increase substantially.
3013 on background threads, file write rate can increase substantially.
3004 (default: true on Windows, false elsewhere)
3014 (default: true on Windows, false elsewhere)
3005
3015
3006 ``backgroundcloseminfilecount``
3016 ``backgroundcloseminfilecount``
3007 Minimum number of files required to trigger background file closing.
3017 Minimum number of files required to trigger background file closing.
3008 Operations not writing this many files won't start background close
3018 Operations not writing this many files won't start background close
3009 threads.
3019 threads.
3010 (default: 2048)
3020 (default: 2048)
3011
3021
3012 ``backgroundclosemaxqueue``
3022 ``backgroundclosemaxqueue``
3013 The maximum number of opened file handles waiting to be closed in the
3023 The maximum number of opened file handles waiting to be closed in the
3014 background. This option only has an effect if ``backgroundclose`` is
3024 background. This option only has an effect if ``backgroundclose`` is
3015 enabled.
3025 enabled.
3016 (default: 384)
3026 (default: 384)
3017
3027
3018 ``backgroundclosethreadcount``
3028 ``backgroundclosethreadcount``
3019 Number of threads to process background file closes. Only relevant if
3029 Number of threads to process background file closes. Only relevant if
3020 ``backgroundclose`` is enabled.
3030 ``backgroundclose`` is enabled.
3021 (default: 4)
3031 (default: 4)
@@ -1,3684 +1,3692 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 mismatch_warn = ui.configbool(
579 b'share', b'safe-mismatch.source-not-safe.warn'
580 )
578 mismatch_config = ui.config(
581 mismatch_config = ui.config(
579 b'share', b'safe-mismatch.source-not-safe'
582 b'share', b'safe-mismatch.source-not-safe'
580 )
583 )
581 if mismatch_config in (
584 if mismatch_config in (
582 b'downgrade-allow',
585 b'downgrade-allow',
583 b'allow',
586 b'allow',
584 b'downgrade-abort',
587 b'downgrade-abort',
585 ):
588 ):
586 # prevent cyclic import localrepo -> upgrade -> localrepo
589 # prevent cyclic import localrepo -> upgrade -> localrepo
587 from . import upgrade
590 from . import upgrade
588
591
589 upgrade.downgrade_share_to_non_safe(
592 upgrade.downgrade_share_to_non_safe(
590 ui,
593 ui,
591 hgvfs,
594 hgvfs,
592 sharedvfs,
595 sharedvfs,
593 requirements,
596 requirements,
594 mismatch_config,
597 mismatch_config,
598 mismatch_warn,
595 )
599 )
596 elif mismatch_config == b'abort':
600 elif mismatch_config == b'abort':
597 raise error.Abort(
601 raise error.Abort(
598 _(
602 _(
599 b"share source does not support exp-sharesafe requirement"
603 b"share source does not support exp-sharesafe requirement"
600 )
604 )
601 )
605 )
602 else:
606 else:
603 hint = _(
607 hint = _(
604 "run `hg help config.share.safe-mismatch.source-not-safe`"
608 "run `hg help config.share.safe-mismatch.source-not-safe`"
605 )
609 )
606 raise error.Abort(
610 raise error.Abort(
607 _(
611 _(
608 b"share-safe mismatch with source.\nUnrecognized"
612 b"share-safe mismatch with source.\nUnrecognized"
609 b" value '%s' of `share.safe-mismatch.source-not-safe`"
613 b" value '%s' of `share.safe-mismatch.source-not-safe`"
610 b" set."
614 b" set."
611 )
615 )
612 % mismatch_config,
616 % mismatch_config,
613 hint=hint,
617 hint=hint,
614 )
618 )
615 else:
619 else:
616 requirements |= _readrequires(storevfs, False)
620 requirements |= _readrequires(storevfs, False)
617 elif shared:
621 elif shared:
618 sourcerequires = _readrequires(sharedvfs, False)
622 sourcerequires = _readrequires(sharedvfs, False)
619 if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires:
623 if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires:
620 mismatch_config = ui.config(b'share', b'safe-mismatch.source-safe')
624 mismatch_config = ui.config(b'share', b'safe-mismatch.source-safe')
625 mismatch_warn = ui.configbool(
626 b'share', b'safe-mismatch.source-safe.warn'
627 )
621 if mismatch_config in (
628 if mismatch_config in (
622 b'upgrade-allow',
629 b'upgrade-allow',
623 b'allow',
630 b'allow',
624 b'upgrade-abort',
631 b'upgrade-abort',
625 ):
632 ):
626 # prevent cyclic import localrepo -> upgrade -> localrepo
633 # prevent cyclic import localrepo -> upgrade -> localrepo
627 from . import upgrade
634 from . import upgrade
628
635
629 upgrade.upgrade_share_to_safe(
636 upgrade.upgrade_share_to_safe(
630 ui,
637 ui,
631 hgvfs,
638 hgvfs,
632 storevfs,
639 storevfs,
633 requirements,
640 requirements,
634 mismatch_config,
641 mismatch_config,
642 mismatch_warn,
635 )
643 )
636 elif mismatch_config == b'abort':
644 elif mismatch_config == b'abort':
637 raise error.Abort(
645 raise error.Abort(
638 _(
646 _(
639 b'version mismatch: source uses share-safe'
647 b'version mismatch: source uses share-safe'
640 b' functionality while the current share does not'
648 b' functionality while the current share does not'
641 )
649 )
642 )
650 )
643 else:
651 else:
644 hint = _("run `hg help config.share.safe-mismatch.source-safe`")
652 hint = _("run `hg help config.share.safe-mismatch.source-safe`")
645 raise error.Abort(
653 raise error.Abort(
646 _(
654 _(
647 b"share-safe mismatch with source.\nUnrecognized"
655 b"share-safe mismatch with source.\nUnrecognized"
648 b" value '%s' of `share.safe-mismatch.source-safe` set."
656 b" value '%s' of `share.safe-mismatch.source-safe` set."
649 )
657 )
650 % mismatch_config,
658 % mismatch_config,
651 hint=hint,
659 hint=hint,
652 )
660 )
653
661
654 # The .hg/hgrc file may load extensions or contain config options
662 # The .hg/hgrc file may load extensions or contain config options
655 # that influence repository construction. Attempt to load it and
663 # that influence repository construction. Attempt to load it and
656 # process any new extensions that it may have pulled in.
664 # process any new extensions that it may have pulled in.
657 if loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs):
665 if loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs):
658 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
666 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
659 extensions.loadall(ui)
667 extensions.loadall(ui)
660 extensions.populateui(ui)
668 extensions.populateui(ui)
661
669
662 # Set of module names of extensions loaded for this repository.
670 # Set of module names of extensions loaded for this repository.
663 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
671 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
664
672
665 supportedrequirements = gathersupportedrequirements(ui)
673 supportedrequirements = gathersupportedrequirements(ui)
666
674
667 # We first validate the requirements are known.
675 # We first validate the requirements are known.
668 ensurerequirementsrecognized(requirements, supportedrequirements)
676 ensurerequirementsrecognized(requirements, supportedrequirements)
669
677
670 # Then we validate that the known set is reasonable to use together.
678 # Then we validate that the known set is reasonable to use together.
671 ensurerequirementscompatible(ui, requirements)
679 ensurerequirementscompatible(ui, requirements)
672
680
673 # TODO there are unhandled edge cases related to opening repositories with
681 # TODO there are unhandled edge cases related to opening repositories with
674 # shared storage. If storage is shared, we should also test for requirements
682 # shared storage. If storage is shared, we should also test for requirements
675 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
683 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
676 # that repo, as that repo may load extensions needed to open it. This is a
684 # that repo, as that repo may load extensions needed to open it. This is a
677 # bit complicated because we don't want the other hgrc to overwrite settings
685 # bit complicated because we don't want the other hgrc to overwrite settings
678 # in this hgrc.
686 # in this hgrc.
679 #
687 #
680 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
688 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
681 # file when sharing repos. But if a requirement is added after the share is
689 # file when sharing repos. But if a requirement is added after the share is
682 # performed, thereby introducing a new requirement for the opener, we may
690 # performed, thereby introducing a new requirement for the opener, we may
683 # will not see that and could encounter a run-time error interacting with
691 # will not see that and could encounter a run-time error interacting with
684 # that shared store since it has an unknown-to-us requirement.
692 # that shared store since it has an unknown-to-us requirement.
685
693
686 # At this point, we know we should be capable of opening the repository.
694 # At this point, we know we should be capable of opening the repository.
687 # Now get on with doing that.
695 # Now get on with doing that.
688
696
689 features = set()
697 features = set()
690
698
691 # The "store" part of the repository holds versioned data. How it is
699 # The "store" part of the repository holds versioned data. How it is
692 # accessed is determined by various requirements. If `shared` or
700 # accessed is determined by various requirements. If `shared` or
693 # `relshared` requirements are present, this indicates current repository
701 # `relshared` requirements are present, this indicates current repository
694 # is a share and store exists in path mentioned in `.hg/sharedpath`
702 # is a share and store exists in path mentioned in `.hg/sharedpath`
695 if shared:
703 if shared:
696 storebasepath = sharedvfs.base
704 storebasepath = sharedvfs.base
697 cachepath = sharedvfs.join(b'cache')
705 cachepath = sharedvfs.join(b'cache')
698 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
706 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
699 else:
707 else:
700 storebasepath = hgvfs.base
708 storebasepath = hgvfs.base
701 cachepath = hgvfs.join(b'cache')
709 cachepath = hgvfs.join(b'cache')
702 wcachepath = hgvfs.join(b'wcache')
710 wcachepath = hgvfs.join(b'wcache')
703
711
704 # The store has changed over time and the exact layout is dictated by
712 # The store has changed over time and the exact layout is dictated by
705 # requirements. The store interface abstracts differences across all
713 # requirements. The store interface abstracts differences across all
706 # of them.
714 # of them.
707 store = makestore(
715 store = makestore(
708 requirements,
716 requirements,
709 storebasepath,
717 storebasepath,
710 lambda base: vfsmod.vfs(base, cacheaudited=True),
718 lambda base: vfsmod.vfs(base, cacheaudited=True),
711 )
719 )
712 hgvfs.createmode = store.createmode
720 hgvfs.createmode = store.createmode
713
721
714 storevfs = store.vfs
722 storevfs = store.vfs
715 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
723 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
716
724
717 # The cache vfs is used to manage cache files.
725 # The cache vfs is used to manage cache files.
718 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
726 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
719 cachevfs.createmode = store.createmode
727 cachevfs.createmode = store.createmode
720 # The cache vfs is used to manage cache files related to the working copy
728 # The cache vfs is used to manage cache files related to the working copy
721 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
729 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
722 wcachevfs.createmode = store.createmode
730 wcachevfs.createmode = store.createmode
723
731
724 # Now resolve the type for the repository object. We do this by repeatedly
732 # Now resolve the type for the repository object. We do this by repeatedly
725 # calling a factory function to produces types for specific aspects of the
733 # calling a factory function to produces types for specific aspects of the
726 # repo's operation. The aggregate returned types are used as base classes
734 # repo's operation. The aggregate returned types are used as base classes
727 # for a dynamically-derived type, which will represent our new repository.
735 # for a dynamically-derived type, which will represent our new repository.
728
736
729 bases = []
737 bases = []
730 extrastate = {}
738 extrastate = {}
731
739
732 for iface, fn in REPO_INTERFACES:
740 for iface, fn in REPO_INTERFACES:
733 # We pass all potentially useful state to give extensions tons of
741 # We pass all potentially useful state to give extensions tons of
734 # flexibility.
742 # flexibility.
735 typ = fn()(
743 typ = fn()(
736 ui=ui,
744 ui=ui,
737 intents=intents,
745 intents=intents,
738 requirements=requirements,
746 requirements=requirements,
739 features=features,
747 features=features,
740 wdirvfs=wdirvfs,
748 wdirvfs=wdirvfs,
741 hgvfs=hgvfs,
749 hgvfs=hgvfs,
742 store=store,
750 store=store,
743 storevfs=storevfs,
751 storevfs=storevfs,
744 storeoptions=storevfs.options,
752 storeoptions=storevfs.options,
745 cachevfs=cachevfs,
753 cachevfs=cachevfs,
746 wcachevfs=wcachevfs,
754 wcachevfs=wcachevfs,
747 extensionmodulenames=extensionmodulenames,
755 extensionmodulenames=extensionmodulenames,
748 extrastate=extrastate,
756 extrastate=extrastate,
749 baseclasses=bases,
757 baseclasses=bases,
750 )
758 )
751
759
752 if not isinstance(typ, type):
760 if not isinstance(typ, type):
753 raise error.ProgrammingError(
761 raise error.ProgrammingError(
754 b'unable to construct type for %s' % iface
762 b'unable to construct type for %s' % iface
755 )
763 )
756
764
757 bases.append(typ)
765 bases.append(typ)
758
766
759 # type() allows you to use characters in type names that wouldn't be
767 # type() allows you to use characters in type names that wouldn't be
760 # recognized as Python symbols in source code. We abuse that to add
768 # recognized as Python symbols in source code. We abuse that to add
761 # rich information about our constructed repo.
769 # rich information about our constructed repo.
762 name = pycompat.sysstr(
770 name = pycompat.sysstr(
763 b'derivedrepo:%s<%s>' % (wdirvfs.base, b','.join(sorted(requirements)))
771 b'derivedrepo:%s<%s>' % (wdirvfs.base, b','.join(sorted(requirements)))
764 )
772 )
765
773
766 cls = type(name, tuple(bases), {})
774 cls = type(name, tuple(bases), {})
767
775
768 return cls(
776 return cls(
769 baseui=baseui,
777 baseui=baseui,
770 ui=ui,
778 ui=ui,
771 origroot=path,
779 origroot=path,
772 wdirvfs=wdirvfs,
780 wdirvfs=wdirvfs,
773 hgvfs=hgvfs,
781 hgvfs=hgvfs,
774 requirements=requirements,
782 requirements=requirements,
775 supportedrequirements=supportedrequirements,
783 supportedrequirements=supportedrequirements,
776 sharedpath=storebasepath,
784 sharedpath=storebasepath,
777 store=store,
785 store=store,
778 cachevfs=cachevfs,
786 cachevfs=cachevfs,
779 wcachevfs=wcachevfs,
787 wcachevfs=wcachevfs,
780 features=features,
788 features=features,
781 intents=intents,
789 intents=intents,
782 )
790 )
783
791
784
792
785 def loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs=None):
793 def loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs=None):
786 """Load hgrc files/content into a ui instance.
794 """Load hgrc files/content into a ui instance.
787
795
788 This is called during repository opening to load any additional
796 This is called during repository opening to load any additional
789 config files or settings relevant to the current repository.
797 config files or settings relevant to the current repository.
790
798
791 Returns a bool indicating whether any additional configs were loaded.
799 Returns a bool indicating whether any additional configs were loaded.
792
800
793 Extensions should monkeypatch this function to modify how per-repo
801 Extensions should monkeypatch this function to modify how per-repo
794 configs are loaded. For example, an extension may wish to pull in
802 configs are loaded. For example, an extension may wish to pull in
795 configs from alternate files or sources.
803 configs from alternate files or sources.
796
804
797 sharedvfs is vfs object pointing to source repo if the current one is a
805 sharedvfs is vfs object pointing to source repo if the current one is a
798 shared one
806 shared one
799 """
807 """
800 if not rcutil.use_repo_hgrc():
808 if not rcutil.use_repo_hgrc():
801 return False
809 return False
802
810
803 ret = False
811 ret = False
804 # first load config from shared source if we has to
812 # first load config from shared source if we has to
805 if requirementsmod.SHARESAFE_REQUIREMENT in requirements and sharedvfs:
813 if requirementsmod.SHARESAFE_REQUIREMENT in requirements and sharedvfs:
806 try:
814 try:
807 ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
815 ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
808 ret = True
816 ret = True
809 except IOError:
817 except IOError:
810 pass
818 pass
811
819
812 try:
820 try:
813 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
821 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
814 ret = True
822 ret = True
815 except IOError:
823 except IOError:
816 pass
824 pass
817
825
818 try:
826 try:
819 ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
827 ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
820 ret = True
828 ret = True
821 except IOError:
829 except IOError:
822 pass
830 pass
823
831
824 return ret
832 return ret
825
833
826
834
827 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
835 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
828 """Perform additional actions after .hg/hgrc is loaded.
836 """Perform additional actions after .hg/hgrc is loaded.
829
837
830 This function is called during repository loading immediately after
838 This function is called during repository loading immediately after
831 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
839 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
832
840
833 The function can be used to validate configs, automatically add
841 The function can be used to validate configs, automatically add
834 options (including extensions) based on requirements, etc.
842 options (including extensions) based on requirements, etc.
835 """
843 """
836
844
837 # Map of requirements to list of extensions to load automatically when
845 # Map of requirements to list of extensions to load automatically when
838 # requirement is present.
846 # requirement is present.
839 autoextensions = {
847 autoextensions = {
840 b'git': [b'git'],
848 b'git': [b'git'],
841 b'largefiles': [b'largefiles'],
849 b'largefiles': [b'largefiles'],
842 b'lfs': [b'lfs'],
850 b'lfs': [b'lfs'],
843 }
851 }
844
852
845 for requirement, names in sorted(autoextensions.items()):
853 for requirement, names in sorted(autoextensions.items()):
846 if requirement not in requirements:
854 if requirement not in requirements:
847 continue
855 continue
848
856
849 for name in names:
857 for name in names:
850 if not ui.hasconfig(b'extensions', name):
858 if not ui.hasconfig(b'extensions', name):
851 ui.setconfig(b'extensions', name, b'', source=b'autoload')
859 ui.setconfig(b'extensions', name, b'', source=b'autoload')
852
860
853
861
854 def gathersupportedrequirements(ui):
862 def gathersupportedrequirements(ui):
855 """Determine the complete set of recognized requirements."""
863 """Determine the complete set of recognized requirements."""
856 # Start with all requirements supported by this file.
864 # Start with all requirements supported by this file.
857 supported = set(localrepository._basesupported)
865 supported = set(localrepository._basesupported)
858
866
859 # Execute ``featuresetupfuncs`` entries if they belong to an extension
867 # Execute ``featuresetupfuncs`` entries if they belong to an extension
860 # relevant to this ui instance.
868 # relevant to this ui instance.
861 modules = {m.__name__ for n, m in extensions.extensions(ui)}
869 modules = {m.__name__ for n, m in extensions.extensions(ui)}
862
870
863 for fn in featuresetupfuncs:
871 for fn in featuresetupfuncs:
864 if fn.__module__ in modules:
872 if fn.__module__ in modules:
865 fn(ui, supported)
873 fn(ui, supported)
866
874
867 # Add derived requirements from registered compression engines.
875 # Add derived requirements from registered compression engines.
868 for name in util.compengines:
876 for name in util.compengines:
869 engine = util.compengines[name]
877 engine = util.compengines[name]
870 if engine.available() and engine.revlogheader():
878 if engine.available() and engine.revlogheader():
871 supported.add(b'exp-compression-%s' % name)
879 supported.add(b'exp-compression-%s' % name)
872 if engine.name() == b'zstd':
880 if engine.name() == b'zstd':
873 supported.add(b'revlog-compression-zstd')
881 supported.add(b'revlog-compression-zstd')
874
882
875 return supported
883 return supported
876
884
877
885
878 def ensurerequirementsrecognized(requirements, supported):
886 def ensurerequirementsrecognized(requirements, supported):
879 """Validate that a set of local requirements is recognized.
887 """Validate that a set of local requirements is recognized.
880
888
881 Receives a set of requirements. Raises an ``error.RepoError`` if there
889 Receives a set of requirements. Raises an ``error.RepoError`` if there
882 exists any requirement in that set that currently loaded code doesn't
890 exists any requirement in that set that currently loaded code doesn't
883 recognize.
891 recognize.
884
892
885 Returns a set of supported requirements.
893 Returns a set of supported requirements.
886 """
894 """
887 missing = set()
895 missing = set()
888
896
889 for requirement in requirements:
897 for requirement in requirements:
890 if requirement in supported:
898 if requirement in supported:
891 continue
899 continue
892
900
893 if not requirement or not requirement[0:1].isalnum():
901 if not requirement or not requirement[0:1].isalnum():
894 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
902 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
895
903
896 missing.add(requirement)
904 missing.add(requirement)
897
905
898 if missing:
906 if missing:
899 raise error.RequirementError(
907 raise error.RequirementError(
900 _(b'repository requires features unknown to this Mercurial: %s')
908 _(b'repository requires features unknown to this Mercurial: %s')
901 % b' '.join(sorted(missing)),
909 % b' '.join(sorted(missing)),
902 hint=_(
910 hint=_(
903 b'see https://mercurial-scm.org/wiki/MissingRequirement '
911 b'see https://mercurial-scm.org/wiki/MissingRequirement '
904 b'for more information'
912 b'for more information'
905 ),
913 ),
906 )
914 )
907
915
908
916
909 def ensurerequirementscompatible(ui, requirements):
917 def ensurerequirementscompatible(ui, requirements):
910 """Validates that a set of recognized requirements is mutually compatible.
918 """Validates that a set of recognized requirements is mutually compatible.
911
919
912 Some requirements may not be compatible with others or require
920 Some requirements may not be compatible with others or require
913 config options that aren't enabled. This function is called during
921 config options that aren't enabled. This function is called during
914 repository opening to ensure that the set of requirements needed
922 repository opening to ensure that the set of requirements needed
915 to open a repository is sane and compatible with config options.
923 to open a repository is sane and compatible with config options.
916
924
917 Extensions can monkeypatch this function to perform additional
925 Extensions can monkeypatch this function to perform additional
918 checking.
926 checking.
919
927
920 ``error.RepoError`` should be raised on failure.
928 ``error.RepoError`` should be raised on failure.
921 """
929 """
922 if (
930 if (
923 requirementsmod.SPARSE_REQUIREMENT in requirements
931 requirementsmod.SPARSE_REQUIREMENT in requirements
924 and not sparse.enabled
932 and not sparse.enabled
925 ):
933 ):
926 raise error.RepoError(
934 raise error.RepoError(
927 _(
935 _(
928 b'repository is using sparse feature but '
936 b'repository is using sparse feature but '
929 b'sparse is not enabled; enable the '
937 b'sparse is not enabled; enable the '
930 b'"sparse" extensions to access'
938 b'"sparse" extensions to access'
931 )
939 )
932 )
940 )
933
941
934
942
935 def makestore(requirements, path, vfstype):
943 def makestore(requirements, path, vfstype):
936 """Construct a storage object for a repository."""
944 """Construct a storage object for a repository."""
937 if b'store' in requirements:
945 if b'store' in requirements:
938 if b'fncache' in requirements:
946 if b'fncache' in requirements:
939 return storemod.fncachestore(
947 return storemod.fncachestore(
940 path, vfstype, b'dotencode' in requirements
948 path, vfstype, b'dotencode' in requirements
941 )
949 )
942
950
943 return storemod.encodedstore(path, vfstype)
951 return storemod.encodedstore(path, vfstype)
944
952
945 return storemod.basicstore(path, vfstype)
953 return storemod.basicstore(path, vfstype)
946
954
947
955
948 def resolvestorevfsoptions(ui, requirements, features):
956 def resolvestorevfsoptions(ui, requirements, features):
949 """Resolve the options to pass to the store vfs opener.
957 """Resolve the options to pass to the store vfs opener.
950
958
951 The returned dict is used to influence behavior of the storage layer.
959 The returned dict is used to influence behavior of the storage layer.
952 """
960 """
953 options = {}
961 options = {}
954
962
955 if requirementsmod.TREEMANIFEST_REQUIREMENT in requirements:
963 if requirementsmod.TREEMANIFEST_REQUIREMENT in requirements:
956 options[b'treemanifest'] = True
964 options[b'treemanifest'] = True
957
965
958 # experimental config: format.manifestcachesize
966 # experimental config: format.manifestcachesize
959 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
967 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
960 if manifestcachesize is not None:
968 if manifestcachesize is not None:
961 options[b'manifestcachesize'] = manifestcachesize
969 options[b'manifestcachesize'] = manifestcachesize
962
970
963 # In the absence of another requirement superseding a revlog-related
971 # In the absence of another requirement superseding a revlog-related
964 # requirement, we have to assume the repo is using revlog version 0.
972 # requirement, we have to assume the repo is using revlog version 0.
965 # This revlog format is super old and we don't bother trying to parse
973 # This revlog format is super old and we don't bother trying to parse
966 # opener options for it because those options wouldn't do anything
974 # opener options for it because those options wouldn't do anything
967 # meaningful on such old repos.
975 # meaningful on such old repos.
968 if (
976 if (
969 b'revlogv1' in requirements
977 b'revlogv1' in requirements
970 or requirementsmod.REVLOGV2_REQUIREMENT in requirements
978 or requirementsmod.REVLOGV2_REQUIREMENT in requirements
971 ):
979 ):
972 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
980 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
973 else: # explicitly mark repo as using revlogv0
981 else: # explicitly mark repo as using revlogv0
974 options[b'revlogv0'] = True
982 options[b'revlogv0'] = True
975
983
976 if requirementsmod.COPIESSDC_REQUIREMENT in requirements:
984 if requirementsmod.COPIESSDC_REQUIREMENT in requirements:
977 options[b'copies-storage'] = b'changeset-sidedata'
985 options[b'copies-storage'] = b'changeset-sidedata'
978 else:
986 else:
979 writecopiesto = ui.config(b'experimental', b'copies.write-to')
987 writecopiesto = ui.config(b'experimental', b'copies.write-to')
980 copiesextramode = (b'changeset-only', b'compatibility')
988 copiesextramode = (b'changeset-only', b'compatibility')
981 if writecopiesto in copiesextramode:
989 if writecopiesto in copiesextramode:
982 options[b'copies-storage'] = b'extra'
990 options[b'copies-storage'] = b'extra'
983
991
984 return options
992 return options
985
993
986
994
987 def resolverevlogstorevfsoptions(ui, requirements, features):
995 def resolverevlogstorevfsoptions(ui, requirements, features):
988 """Resolve opener options specific to revlogs."""
996 """Resolve opener options specific to revlogs."""
989
997
990 options = {}
998 options = {}
991 options[b'flagprocessors'] = {}
999 options[b'flagprocessors'] = {}
992
1000
993 if b'revlogv1' in requirements:
1001 if b'revlogv1' in requirements:
994 options[b'revlogv1'] = True
1002 options[b'revlogv1'] = True
995 if requirementsmod.REVLOGV2_REQUIREMENT in requirements:
1003 if requirementsmod.REVLOGV2_REQUIREMENT in requirements:
996 options[b'revlogv2'] = True
1004 options[b'revlogv2'] = True
997
1005
998 if b'generaldelta' in requirements:
1006 if b'generaldelta' in requirements:
999 options[b'generaldelta'] = True
1007 options[b'generaldelta'] = True
1000
1008
1001 # experimental config: format.chunkcachesize
1009 # experimental config: format.chunkcachesize
1002 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
1010 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
1003 if chunkcachesize is not None:
1011 if chunkcachesize is not None:
1004 options[b'chunkcachesize'] = chunkcachesize
1012 options[b'chunkcachesize'] = chunkcachesize
1005
1013
1006 deltabothparents = ui.configbool(
1014 deltabothparents = ui.configbool(
1007 b'storage', b'revlog.optimize-delta-parent-choice'
1015 b'storage', b'revlog.optimize-delta-parent-choice'
1008 )
1016 )
1009 options[b'deltabothparents'] = deltabothparents
1017 options[b'deltabothparents'] = deltabothparents
1010
1018
1011 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
1019 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
1012 lazydeltabase = False
1020 lazydeltabase = False
1013 if lazydelta:
1021 if lazydelta:
1014 lazydeltabase = ui.configbool(
1022 lazydeltabase = ui.configbool(
1015 b'storage', b'revlog.reuse-external-delta-parent'
1023 b'storage', b'revlog.reuse-external-delta-parent'
1016 )
1024 )
1017 if lazydeltabase is None:
1025 if lazydeltabase is None:
1018 lazydeltabase = not scmutil.gddeltaconfig(ui)
1026 lazydeltabase = not scmutil.gddeltaconfig(ui)
1019 options[b'lazydelta'] = lazydelta
1027 options[b'lazydelta'] = lazydelta
1020 options[b'lazydeltabase'] = lazydeltabase
1028 options[b'lazydeltabase'] = lazydeltabase
1021
1029
1022 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
1030 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
1023 if 0 <= chainspan:
1031 if 0 <= chainspan:
1024 options[b'maxdeltachainspan'] = chainspan
1032 options[b'maxdeltachainspan'] = chainspan
1025
1033
1026 mmapindexthreshold = ui.configbytes(b'experimental', b'mmapindexthreshold')
1034 mmapindexthreshold = ui.configbytes(b'experimental', b'mmapindexthreshold')
1027 if mmapindexthreshold is not None:
1035 if mmapindexthreshold is not None:
1028 options[b'mmapindexthreshold'] = mmapindexthreshold
1036 options[b'mmapindexthreshold'] = mmapindexthreshold
1029
1037
1030 withsparseread = ui.configbool(b'experimental', b'sparse-read')
1038 withsparseread = ui.configbool(b'experimental', b'sparse-read')
1031 srdensitythres = float(
1039 srdensitythres = float(
1032 ui.config(b'experimental', b'sparse-read.density-threshold')
1040 ui.config(b'experimental', b'sparse-read.density-threshold')
1033 )
1041 )
1034 srmingapsize = ui.configbytes(b'experimental', b'sparse-read.min-gap-size')
1042 srmingapsize = ui.configbytes(b'experimental', b'sparse-read.min-gap-size')
1035 options[b'with-sparse-read'] = withsparseread
1043 options[b'with-sparse-read'] = withsparseread
1036 options[b'sparse-read-density-threshold'] = srdensitythres
1044 options[b'sparse-read-density-threshold'] = srdensitythres
1037 options[b'sparse-read-min-gap-size'] = srmingapsize
1045 options[b'sparse-read-min-gap-size'] = srmingapsize
1038
1046
1039 sparserevlog = requirementsmod.SPARSEREVLOG_REQUIREMENT in requirements
1047 sparserevlog = requirementsmod.SPARSEREVLOG_REQUIREMENT in requirements
1040 options[b'sparse-revlog'] = sparserevlog
1048 options[b'sparse-revlog'] = sparserevlog
1041 if sparserevlog:
1049 if sparserevlog:
1042 options[b'generaldelta'] = True
1050 options[b'generaldelta'] = True
1043
1051
1044 sidedata = requirementsmod.SIDEDATA_REQUIREMENT in requirements
1052 sidedata = requirementsmod.SIDEDATA_REQUIREMENT in requirements
1045 options[b'side-data'] = sidedata
1053 options[b'side-data'] = sidedata
1046
1054
1047 maxchainlen = None
1055 maxchainlen = None
1048 if sparserevlog:
1056 if sparserevlog:
1049 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
1057 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
1050 # experimental config: format.maxchainlen
1058 # experimental config: format.maxchainlen
1051 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
1059 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
1052 if maxchainlen is not None:
1060 if maxchainlen is not None:
1053 options[b'maxchainlen'] = maxchainlen
1061 options[b'maxchainlen'] = maxchainlen
1054
1062
1055 for r in requirements:
1063 for r in requirements:
1056 # we allow multiple compression engine requirement to co-exist because
1064 # we allow multiple compression engine requirement to co-exist because
1057 # strickly speaking, revlog seems to support mixed compression style.
1065 # strickly speaking, revlog seems to support mixed compression style.
1058 #
1066 #
1059 # The compression used for new entries will be "the last one"
1067 # The compression used for new entries will be "the last one"
1060 prefix = r.startswith
1068 prefix = r.startswith
1061 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
1069 if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
1062 options[b'compengine'] = r.split(b'-', 2)[2]
1070 options[b'compengine'] = r.split(b'-', 2)[2]
1063
1071
1064 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
1072 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
1065 if options[b'zlib.level'] is not None:
1073 if options[b'zlib.level'] is not None:
1066 if not (0 <= options[b'zlib.level'] <= 9):
1074 if not (0 <= options[b'zlib.level'] <= 9):
1067 msg = _(b'invalid value for `storage.revlog.zlib.level` config: %d')
1075 msg = _(b'invalid value for `storage.revlog.zlib.level` config: %d')
1068 raise error.Abort(msg % options[b'zlib.level'])
1076 raise error.Abort(msg % options[b'zlib.level'])
1069 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
1077 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
1070 if options[b'zstd.level'] is not None:
1078 if options[b'zstd.level'] is not None:
1071 if not (0 <= options[b'zstd.level'] <= 22):
1079 if not (0 <= options[b'zstd.level'] <= 22):
1072 msg = _(b'invalid value for `storage.revlog.zstd.level` config: %d')
1080 msg = _(b'invalid value for `storage.revlog.zstd.level` config: %d')
1073 raise error.Abort(msg % options[b'zstd.level'])
1081 raise error.Abort(msg % options[b'zstd.level'])
1074
1082
1075 if requirementsmod.NARROW_REQUIREMENT in requirements:
1083 if requirementsmod.NARROW_REQUIREMENT in requirements:
1076 options[b'enableellipsis'] = True
1084 options[b'enableellipsis'] = True
1077
1085
1078 if ui.configbool(b'experimental', b'rust.index'):
1086 if ui.configbool(b'experimental', b'rust.index'):
1079 options[b'rust.index'] = True
1087 options[b'rust.index'] = True
1080 if requirementsmod.NODEMAP_REQUIREMENT in requirements:
1088 if requirementsmod.NODEMAP_REQUIREMENT in requirements:
1081 slow_path = ui.config(
1089 slow_path = ui.config(
1082 b'storage', b'revlog.persistent-nodemap.slow-path'
1090 b'storage', b'revlog.persistent-nodemap.slow-path'
1083 )
1091 )
1084 if slow_path not in (b'allow', b'warn', b'abort'):
1092 if slow_path not in (b'allow', b'warn', b'abort'):
1085 default = ui.config_default(
1093 default = ui.config_default(
1086 b'storage', b'revlog.persistent-nodemap.slow-path'
1094 b'storage', b'revlog.persistent-nodemap.slow-path'
1087 )
1095 )
1088 msg = _(
1096 msg = _(
1089 b'unknown value for config '
1097 b'unknown value for config '
1090 b'"storage.revlog.persistent-nodemap.slow-path": "%s"\n'
1098 b'"storage.revlog.persistent-nodemap.slow-path": "%s"\n'
1091 )
1099 )
1092 ui.warn(msg % slow_path)
1100 ui.warn(msg % slow_path)
1093 if not ui.quiet:
1101 if not ui.quiet:
1094 ui.warn(_(b'falling back to default value: %s\n') % default)
1102 ui.warn(_(b'falling back to default value: %s\n') % default)
1095 slow_path = default
1103 slow_path = default
1096
1104
1097 msg = _(
1105 msg = _(
1098 b"accessing `persistent-nodemap` repository without associated "
1106 b"accessing `persistent-nodemap` repository without associated "
1099 b"fast implementation."
1107 b"fast implementation."
1100 )
1108 )
1101 hint = _(
1109 hint = _(
1102 b"check `hg help config.format.use-persistent-nodemap` "
1110 b"check `hg help config.format.use-persistent-nodemap` "
1103 b"for details"
1111 b"for details"
1104 )
1112 )
1105 if not revlog.HAS_FAST_PERSISTENT_NODEMAP:
1113 if not revlog.HAS_FAST_PERSISTENT_NODEMAP:
1106 if slow_path == b'warn':
1114 if slow_path == b'warn':
1107 msg = b"warning: " + msg + b'\n'
1115 msg = b"warning: " + msg + b'\n'
1108 ui.warn(msg)
1116 ui.warn(msg)
1109 if not ui.quiet:
1117 if not ui.quiet:
1110 hint = b'(' + hint + b')\n'
1118 hint = b'(' + hint + b')\n'
1111 ui.warn(hint)
1119 ui.warn(hint)
1112 if slow_path == b'abort':
1120 if slow_path == b'abort':
1113 raise error.Abort(msg, hint=hint)
1121 raise error.Abort(msg, hint=hint)
1114 options[b'persistent-nodemap'] = True
1122 options[b'persistent-nodemap'] = True
1115 if ui.configbool(b'storage', b'revlog.persistent-nodemap.mmap'):
1123 if ui.configbool(b'storage', b'revlog.persistent-nodemap.mmap'):
1116 options[b'persistent-nodemap.mmap'] = True
1124 options[b'persistent-nodemap.mmap'] = True
1117 if ui.configbool(b'devel', b'persistent-nodemap'):
1125 if ui.configbool(b'devel', b'persistent-nodemap'):
1118 options[b'devel-force-nodemap'] = True
1126 options[b'devel-force-nodemap'] = True
1119
1127
1120 return options
1128 return options
1121
1129
1122
1130
1123 def makemain(**kwargs):
1131 def makemain(**kwargs):
1124 """Produce a type conforming to ``ilocalrepositorymain``."""
1132 """Produce a type conforming to ``ilocalrepositorymain``."""
1125 return localrepository
1133 return localrepository
1126
1134
1127
1135
1128 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1136 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1129 class revlogfilestorage(object):
1137 class revlogfilestorage(object):
1130 """File storage when using revlogs."""
1138 """File storage when using revlogs."""
1131
1139
1132 def file(self, path):
1140 def file(self, path):
1133 if path[0] == b'/':
1141 if path[0] == b'/':
1134 path = path[1:]
1142 path = path[1:]
1135
1143
1136 return filelog.filelog(self.svfs, path)
1144 return filelog.filelog(self.svfs, path)
1137
1145
1138
1146
1139 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1147 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
1140 class revlognarrowfilestorage(object):
1148 class revlognarrowfilestorage(object):
1141 """File storage when using revlogs and narrow files."""
1149 """File storage when using revlogs and narrow files."""
1142
1150
1143 def file(self, path):
1151 def file(self, path):
1144 if path[0] == b'/':
1152 if path[0] == b'/':
1145 path = path[1:]
1153 path = path[1:]
1146
1154
1147 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
1155 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
1148
1156
1149
1157
1150 def makefilestorage(requirements, features, **kwargs):
1158 def makefilestorage(requirements, features, **kwargs):
1151 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
1159 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
1152 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
1160 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
1153 features.add(repository.REPO_FEATURE_STREAM_CLONE)
1161 features.add(repository.REPO_FEATURE_STREAM_CLONE)
1154
1162
1155 if requirementsmod.NARROW_REQUIREMENT in requirements:
1163 if requirementsmod.NARROW_REQUIREMENT in requirements:
1156 return revlognarrowfilestorage
1164 return revlognarrowfilestorage
1157 else:
1165 else:
1158 return revlogfilestorage
1166 return revlogfilestorage
1159
1167
1160
1168
1161 # List of repository interfaces and factory functions for them. Each
1169 # List of repository interfaces and factory functions for them. Each
1162 # will be called in order during ``makelocalrepository()`` to iteratively
1170 # will be called in order during ``makelocalrepository()`` to iteratively
1163 # derive the final type for a local repository instance. We capture the
1171 # derive the final type for a local repository instance. We capture the
1164 # function as a lambda so we don't hold a reference and the module-level
1172 # function as a lambda so we don't hold a reference and the module-level
1165 # functions can be wrapped.
1173 # functions can be wrapped.
1166 REPO_INTERFACES = [
1174 REPO_INTERFACES = [
1167 (repository.ilocalrepositorymain, lambda: makemain),
1175 (repository.ilocalrepositorymain, lambda: makemain),
1168 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
1176 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
1169 ]
1177 ]
1170
1178
1171
1179
1172 @interfaceutil.implementer(repository.ilocalrepositorymain)
1180 @interfaceutil.implementer(repository.ilocalrepositorymain)
1173 class localrepository(object):
1181 class localrepository(object):
1174 """Main class for representing local repositories.
1182 """Main class for representing local repositories.
1175
1183
1176 All local repositories are instances of this class.
1184 All local repositories are instances of this class.
1177
1185
1178 Constructed on its own, instances of this class are not usable as
1186 Constructed on its own, instances of this class are not usable as
1179 repository objects. To obtain a usable repository object, call
1187 repository objects. To obtain a usable repository object, call
1180 ``hg.repository()``, ``localrepo.instance()``, or
1188 ``hg.repository()``, ``localrepo.instance()``, or
1181 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
1189 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
1182 ``instance()`` adds support for creating new repositories.
1190 ``instance()`` adds support for creating new repositories.
1183 ``hg.repository()`` adds more extension integration, including calling
1191 ``hg.repository()`` adds more extension integration, including calling
1184 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
1192 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
1185 used.
1193 used.
1186 """
1194 """
1187
1195
1188 # obsolete experimental requirements:
1196 # obsolete experimental requirements:
1189 # - manifestv2: An experimental new manifest format that allowed
1197 # - manifestv2: An experimental new manifest format that allowed
1190 # for stem compression of long paths. Experiment ended up not
1198 # for stem compression of long paths. Experiment ended up not
1191 # being successful (repository sizes went up due to worse delta
1199 # being successful (repository sizes went up due to worse delta
1192 # chains), and the code was deleted in 4.6.
1200 # chains), and the code was deleted in 4.6.
1193 supportedformats = {
1201 supportedformats = {
1194 b'revlogv1',
1202 b'revlogv1',
1195 b'generaldelta',
1203 b'generaldelta',
1196 requirementsmod.TREEMANIFEST_REQUIREMENT,
1204 requirementsmod.TREEMANIFEST_REQUIREMENT,
1197 requirementsmod.COPIESSDC_REQUIREMENT,
1205 requirementsmod.COPIESSDC_REQUIREMENT,
1198 requirementsmod.REVLOGV2_REQUIREMENT,
1206 requirementsmod.REVLOGV2_REQUIREMENT,
1199 requirementsmod.SIDEDATA_REQUIREMENT,
1207 requirementsmod.SIDEDATA_REQUIREMENT,
1200 requirementsmod.SPARSEREVLOG_REQUIREMENT,
1208 requirementsmod.SPARSEREVLOG_REQUIREMENT,
1201 requirementsmod.NODEMAP_REQUIREMENT,
1209 requirementsmod.NODEMAP_REQUIREMENT,
1202 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
1210 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
1203 requirementsmod.SHARESAFE_REQUIREMENT,
1211 requirementsmod.SHARESAFE_REQUIREMENT,
1204 }
1212 }
1205 _basesupported = supportedformats | {
1213 _basesupported = supportedformats | {
1206 b'store',
1214 b'store',
1207 b'fncache',
1215 b'fncache',
1208 requirementsmod.SHARED_REQUIREMENT,
1216 requirementsmod.SHARED_REQUIREMENT,
1209 requirementsmod.RELATIVE_SHARED_REQUIREMENT,
1217 requirementsmod.RELATIVE_SHARED_REQUIREMENT,
1210 b'dotencode',
1218 b'dotencode',
1211 requirementsmod.SPARSE_REQUIREMENT,
1219 requirementsmod.SPARSE_REQUIREMENT,
1212 requirementsmod.INTERNAL_PHASE_REQUIREMENT,
1220 requirementsmod.INTERNAL_PHASE_REQUIREMENT,
1213 }
1221 }
1214
1222
1215 # list of prefix for file which can be written without 'wlock'
1223 # list of prefix for file which can be written without 'wlock'
1216 # Extensions should extend this list when needed
1224 # Extensions should extend this list when needed
1217 _wlockfreeprefix = {
1225 _wlockfreeprefix = {
1218 # We migh consider requiring 'wlock' for the next
1226 # We migh consider requiring 'wlock' for the next
1219 # two, but pretty much all the existing code assume
1227 # two, but pretty much all the existing code assume
1220 # wlock is not needed so we keep them excluded for
1228 # wlock is not needed so we keep them excluded for
1221 # now.
1229 # now.
1222 b'hgrc',
1230 b'hgrc',
1223 b'requires',
1231 b'requires',
1224 # XXX cache is a complicatged business someone
1232 # XXX cache is a complicatged business someone
1225 # should investigate this in depth at some point
1233 # should investigate this in depth at some point
1226 b'cache/',
1234 b'cache/',
1227 # XXX shouldn't be dirstate covered by the wlock?
1235 # XXX shouldn't be dirstate covered by the wlock?
1228 b'dirstate',
1236 b'dirstate',
1229 # XXX bisect was still a bit too messy at the time
1237 # XXX bisect was still a bit too messy at the time
1230 # this changeset was introduced. Someone should fix
1238 # this changeset was introduced. Someone should fix
1231 # the remainig bit and drop this line
1239 # the remainig bit and drop this line
1232 b'bisect.state',
1240 b'bisect.state',
1233 }
1241 }
1234
1242
1235 def __init__(
1243 def __init__(
1236 self,
1244 self,
1237 baseui,
1245 baseui,
1238 ui,
1246 ui,
1239 origroot,
1247 origroot,
1240 wdirvfs,
1248 wdirvfs,
1241 hgvfs,
1249 hgvfs,
1242 requirements,
1250 requirements,
1243 supportedrequirements,
1251 supportedrequirements,
1244 sharedpath,
1252 sharedpath,
1245 store,
1253 store,
1246 cachevfs,
1254 cachevfs,
1247 wcachevfs,
1255 wcachevfs,
1248 features,
1256 features,
1249 intents=None,
1257 intents=None,
1250 ):
1258 ):
1251 """Create a new local repository instance.
1259 """Create a new local repository instance.
1252
1260
1253 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
1261 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
1254 or ``localrepo.makelocalrepository()`` for obtaining a new repository
1262 or ``localrepo.makelocalrepository()`` for obtaining a new repository
1255 object.
1263 object.
1256
1264
1257 Arguments:
1265 Arguments:
1258
1266
1259 baseui
1267 baseui
1260 ``ui.ui`` instance that ``ui`` argument was based off of.
1268 ``ui.ui`` instance that ``ui`` argument was based off of.
1261
1269
1262 ui
1270 ui
1263 ``ui.ui`` instance for use by the repository.
1271 ``ui.ui`` instance for use by the repository.
1264
1272
1265 origroot
1273 origroot
1266 ``bytes`` path to working directory root of this repository.
1274 ``bytes`` path to working directory root of this repository.
1267
1275
1268 wdirvfs
1276 wdirvfs
1269 ``vfs.vfs`` rooted at the working directory.
1277 ``vfs.vfs`` rooted at the working directory.
1270
1278
1271 hgvfs
1279 hgvfs
1272 ``vfs.vfs`` rooted at .hg/
1280 ``vfs.vfs`` rooted at .hg/
1273
1281
1274 requirements
1282 requirements
1275 ``set`` of bytestrings representing repository opening requirements.
1283 ``set`` of bytestrings representing repository opening requirements.
1276
1284
1277 supportedrequirements
1285 supportedrequirements
1278 ``set`` of bytestrings representing repository requirements that we
1286 ``set`` of bytestrings representing repository requirements that we
1279 know how to open. May be a supetset of ``requirements``.
1287 know how to open. May be a supetset of ``requirements``.
1280
1288
1281 sharedpath
1289 sharedpath
1282 ``bytes`` Defining path to storage base directory. Points to a
1290 ``bytes`` Defining path to storage base directory. Points to a
1283 ``.hg/`` directory somewhere.
1291 ``.hg/`` directory somewhere.
1284
1292
1285 store
1293 store
1286 ``store.basicstore`` (or derived) instance providing access to
1294 ``store.basicstore`` (or derived) instance providing access to
1287 versioned storage.
1295 versioned storage.
1288
1296
1289 cachevfs
1297 cachevfs
1290 ``vfs.vfs`` used for cache files.
1298 ``vfs.vfs`` used for cache files.
1291
1299
1292 wcachevfs
1300 wcachevfs
1293 ``vfs.vfs`` used for cache files related to the working copy.
1301 ``vfs.vfs`` used for cache files related to the working copy.
1294
1302
1295 features
1303 features
1296 ``set`` of bytestrings defining features/capabilities of this
1304 ``set`` of bytestrings defining features/capabilities of this
1297 instance.
1305 instance.
1298
1306
1299 intents
1307 intents
1300 ``set`` of system strings indicating what this repo will be used
1308 ``set`` of system strings indicating what this repo will be used
1301 for.
1309 for.
1302 """
1310 """
1303 self.baseui = baseui
1311 self.baseui = baseui
1304 self.ui = ui
1312 self.ui = ui
1305 self.origroot = origroot
1313 self.origroot = origroot
1306 # vfs rooted at working directory.
1314 # vfs rooted at working directory.
1307 self.wvfs = wdirvfs
1315 self.wvfs = wdirvfs
1308 self.root = wdirvfs.base
1316 self.root = wdirvfs.base
1309 # vfs rooted at .hg/. Used to access most non-store paths.
1317 # vfs rooted at .hg/. Used to access most non-store paths.
1310 self.vfs = hgvfs
1318 self.vfs = hgvfs
1311 self.path = hgvfs.base
1319 self.path = hgvfs.base
1312 self.requirements = requirements
1320 self.requirements = requirements
1313 self.supported = supportedrequirements
1321 self.supported = supportedrequirements
1314 self.sharedpath = sharedpath
1322 self.sharedpath = sharedpath
1315 self.store = store
1323 self.store = store
1316 self.cachevfs = cachevfs
1324 self.cachevfs = cachevfs
1317 self.wcachevfs = wcachevfs
1325 self.wcachevfs = wcachevfs
1318 self.features = features
1326 self.features = features
1319
1327
1320 self.filtername = None
1328 self.filtername = None
1321
1329
1322 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1330 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1323 b'devel', b'check-locks'
1331 b'devel', b'check-locks'
1324 ):
1332 ):
1325 self.vfs.audit = self._getvfsward(self.vfs.audit)
1333 self.vfs.audit = self._getvfsward(self.vfs.audit)
1326 # A list of callback to shape the phase if no data were found.
1334 # A list of callback to shape the phase if no data were found.
1327 # Callback are in the form: func(repo, roots) --> processed root.
1335 # Callback are in the form: func(repo, roots) --> processed root.
1328 # This list it to be filled by extension during repo setup
1336 # This list it to be filled by extension during repo setup
1329 self._phasedefaults = []
1337 self._phasedefaults = []
1330
1338
1331 color.setup(self.ui)
1339 color.setup(self.ui)
1332
1340
1333 self.spath = self.store.path
1341 self.spath = self.store.path
1334 self.svfs = self.store.vfs
1342 self.svfs = self.store.vfs
1335 self.sjoin = self.store.join
1343 self.sjoin = self.store.join
1336 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1344 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
1337 b'devel', b'check-locks'
1345 b'devel', b'check-locks'
1338 ):
1346 ):
1339 if util.safehasattr(self.svfs, b'vfs'): # this is filtervfs
1347 if util.safehasattr(self.svfs, b'vfs'): # this is filtervfs
1340 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1348 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1341 else: # standard vfs
1349 else: # standard vfs
1342 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1350 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1343
1351
1344 self._dirstatevalidatewarned = False
1352 self._dirstatevalidatewarned = False
1345
1353
1346 self._branchcaches = branchmap.BranchMapCache()
1354 self._branchcaches = branchmap.BranchMapCache()
1347 self._revbranchcache = None
1355 self._revbranchcache = None
1348 self._filterpats = {}
1356 self._filterpats = {}
1349 self._datafilters = {}
1357 self._datafilters = {}
1350 self._transref = self._lockref = self._wlockref = None
1358 self._transref = self._lockref = self._wlockref = None
1351
1359
1352 # A cache for various files under .hg/ that tracks file changes,
1360 # A cache for various files under .hg/ that tracks file changes,
1353 # (used by the filecache decorator)
1361 # (used by the filecache decorator)
1354 #
1362 #
1355 # Maps a property name to its util.filecacheentry
1363 # Maps a property name to its util.filecacheentry
1356 self._filecache = {}
1364 self._filecache = {}
1357
1365
1358 # hold sets of revision to be filtered
1366 # hold sets of revision to be filtered
1359 # should be cleared when something might have changed the filter value:
1367 # should be cleared when something might have changed the filter value:
1360 # - new changesets,
1368 # - new changesets,
1361 # - phase change,
1369 # - phase change,
1362 # - new obsolescence marker,
1370 # - new obsolescence marker,
1363 # - working directory parent change,
1371 # - working directory parent change,
1364 # - bookmark changes
1372 # - bookmark changes
1365 self.filteredrevcache = {}
1373 self.filteredrevcache = {}
1366
1374
1367 # post-dirstate-status hooks
1375 # post-dirstate-status hooks
1368 self._postdsstatus = []
1376 self._postdsstatus = []
1369
1377
1370 # generic mapping between names and nodes
1378 # generic mapping between names and nodes
1371 self.names = namespaces.namespaces()
1379 self.names = namespaces.namespaces()
1372
1380
1373 # Key to signature value.
1381 # Key to signature value.
1374 self._sparsesignaturecache = {}
1382 self._sparsesignaturecache = {}
1375 # Signature to cached matcher instance.
1383 # Signature to cached matcher instance.
1376 self._sparsematchercache = {}
1384 self._sparsematchercache = {}
1377
1385
1378 self._extrafilterid = repoview.extrafilter(ui)
1386 self._extrafilterid = repoview.extrafilter(ui)
1379
1387
1380 self.filecopiesmode = None
1388 self.filecopiesmode = None
1381 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1389 if requirementsmod.COPIESSDC_REQUIREMENT in self.requirements:
1382 self.filecopiesmode = b'changeset-sidedata'
1390 self.filecopiesmode = b'changeset-sidedata'
1383
1391
1384 def _getvfsward(self, origfunc):
1392 def _getvfsward(self, origfunc):
1385 """build a ward for self.vfs"""
1393 """build a ward for self.vfs"""
1386 rref = weakref.ref(self)
1394 rref = weakref.ref(self)
1387
1395
1388 def checkvfs(path, mode=None):
1396 def checkvfs(path, mode=None):
1389 ret = origfunc(path, mode=mode)
1397 ret = origfunc(path, mode=mode)
1390 repo = rref()
1398 repo = rref()
1391 if (
1399 if (
1392 repo is None
1400 repo is None
1393 or not util.safehasattr(repo, b'_wlockref')
1401 or not util.safehasattr(repo, b'_wlockref')
1394 or not util.safehasattr(repo, b'_lockref')
1402 or not util.safehasattr(repo, b'_lockref')
1395 ):
1403 ):
1396 return
1404 return
1397 if mode in (None, b'r', b'rb'):
1405 if mode in (None, b'r', b'rb'):
1398 return
1406 return
1399 if path.startswith(repo.path):
1407 if path.startswith(repo.path):
1400 # truncate name relative to the repository (.hg)
1408 # truncate name relative to the repository (.hg)
1401 path = path[len(repo.path) + 1 :]
1409 path = path[len(repo.path) + 1 :]
1402 if path.startswith(b'cache/'):
1410 if path.startswith(b'cache/'):
1403 msg = b'accessing cache with vfs instead of cachevfs: "%s"'
1411 msg = b'accessing cache with vfs instead of cachevfs: "%s"'
1404 repo.ui.develwarn(msg % path, stacklevel=3, config=b"cache-vfs")
1412 repo.ui.develwarn(msg % path, stacklevel=3, config=b"cache-vfs")
1405 # path prefixes covered by 'lock'
1413 # path prefixes covered by 'lock'
1406 vfs_path_prefixes = (
1414 vfs_path_prefixes = (
1407 b'journal.',
1415 b'journal.',
1408 b'undo.',
1416 b'undo.',
1409 b'strip-backup/',
1417 b'strip-backup/',
1410 b'cache/',
1418 b'cache/',
1411 )
1419 )
1412 if any(path.startswith(prefix) for prefix in vfs_path_prefixes):
1420 if any(path.startswith(prefix) for prefix in vfs_path_prefixes):
1413 if repo._currentlock(repo._lockref) is None:
1421 if repo._currentlock(repo._lockref) is None:
1414 repo.ui.develwarn(
1422 repo.ui.develwarn(
1415 b'write with no lock: "%s"' % path,
1423 b'write with no lock: "%s"' % path,
1416 stacklevel=3,
1424 stacklevel=3,
1417 config=b'check-locks',
1425 config=b'check-locks',
1418 )
1426 )
1419 elif repo._currentlock(repo._wlockref) is None:
1427 elif repo._currentlock(repo._wlockref) is None:
1420 # rest of vfs files are covered by 'wlock'
1428 # rest of vfs files are covered by 'wlock'
1421 #
1429 #
1422 # exclude special files
1430 # exclude special files
1423 for prefix in self._wlockfreeprefix:
1431 for prefix in self._wlockfreeprefix:
1424 if path.startswith(prefix):
1432 if path.startswith(prefix):
1425 return
1433 return
1426 repo.ui.develwarn(
1434 repo.ui.develwarn(
1427 b'write with no wlock: "%s"' % path,
1435 b'write with no wlock: "%s"' % path,
1428 stacklevel=3,
1436 stacklevel=3,
1429 config=b'check-locks',
1437 config=b'check-locks',
1430 )
1438 )
1431 return ret
1439 return ret
1432
1440
1433 return checkvfs
1441 return checkvfs
1434
1442
1435 def _getsvfsward(self, origfunc):
1443 def _getsvfsward(self, origfunc):
1436 """build a ward for self.svfs"""
1444 """build a ward for self.svfs"""
1437 rref = weakref.ref(self)
1445 rref = weakref.ref(self)
1438
1446
1439 def checksvfs(path, mode=None):
1447 def checksvfs(path, mode=None):
1440 ret = origfunc(path, mode=mode)
1448 ret = origfunc(path, mode=mode)
1441 repo = rref()
1449 repo = rref()
1442 if repo is None or not util.safehasattr(repo, b'_lockref'):
1450 if repo is None or not util.safehasattr(repo, b'_lockref'):
1443 return
1451 return
1444 if mode in (None, b'r', b'rb'):
1452 if mode in (None, b'r', b'rb'):
1445 return
1453 return
1446 if path.startswith(repo.sharedpath):
1454 if path.startswith(repo.sharedpath):
1447 # truncate name relative to the repository (.hg)
1455 # truncate name relative to the repository (.hg)
1448 path = path[len(repo.sharedpath) + 1 :]
1456 path = path[len(repo.sharedpath) + 1 :]
1449 if repo._currentlock(repo._lockref) is None:
1457 if repo._currentlock(repo._lockref) is None:
1450 repo.ui.develwarn(
1458 repo.ui.develwarn(
1451 b'write with no lock: "%s"' % path, stacklevel=4
1459 b'write with no lock: "%s"' % path, stacklevel=4
1452 )
1460 )
1453 return ret
1461 return ret
1454
1462
1455 return checksvfs
1463 return checksvfs
1456
1464
1457 def close(self):
1465 def close(self):
1458 self._writecaches()
1466 self._writecaches()
1459
1467
1460 def _writecaches(self):
1468 def _writecaches(self):
1461 if self._revbranchcache:
1469 if self._revbranchcache:
1462 self._revbranchcache.write()
1470 self._revbranchcache.write()
1463
1471
1464 def _restrictcapabilities(self, caps):
1472 def _restrictcapabilities(self, caps):
1465 if self.ui.configbool(b'experimental', b'bundle2-advertise'):
1473 if self.ui.configbool(b'experimental', b'bundle2-advertise'):
1466 caps = set(caps)
1474 caps = set(caps)
1467 capsblob = bundle2.encodecaps(
1475 capsblob = bundle2.encodecaps(
1468 bundle2.getrepocaps(self, role=b'client')
1476 bundle2.getrepocaps(self, role=b'client')
1469 )
1477 )
1470 caps.add(b'bundle2=' + urlreq.quote(capsblob))
1478 caps.add(b'bundle2=' + urlreq.quote(capsblob))
1471 return caps
1479 return caps
1472
1480
1473 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1481 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1474 # self -> auditor -> self._checknested -> self
1482 # self -> auditor -> self._checknested -> self
1475
1483
1476 @property
1484 @property
1477 def auditor(self):
1485 def auditor(self):
1478 # This is only used by context.workingctx.match in order to
1486 # This is only used by context.workingctx.match in order to
1479 # detect files in subrepos.
1487 # detect files in subrepos.
1480 return pathutil.pathauditor(self.root, callback=self._checknested)
1488 return pathutil.pathauditor(self.root, callback=self._checknested)
1481
1489
1482 @property
1490 @property
1483 def nofsauditor(self):
1491 def nofsauditor(self):
1484 # This is only used by context.basectx.match in order to detect
1492 # This is only used by context.basectx.match in order to detect
1485 # files in subrepos.
1493 # files in subrepos.
1486 return pathutil.pathauditor(
1494 return pathutil.pathauditor(
1487 self.root, callback=self._checknested, realfs=False, cached=True
1495 self.root, callback=self._checknested, realfs=False, cached=True
1488 )
1496 )
1489
1497
1490 def _checknested(self, path):
1498 def _checknested(self, path):
1491 """Determine if path is a legal nested repository."""
1499 """Determine if path is a legal nested repository."""
1492 if not path.startswith(self.root):
1500 if not path.startswith(self.root):
1493 return False
1501 return False
1494 subpath = path[len(self.root) + 1 :]
1502 subpath = path[len(self.root) + 1 :]
1495 normsubpath = util.pconvert(subpath)
1503 normsubpath = util.pconvert(subpath)
1496
1504
1497 # XXX: Checking against the current working copy is wrong in
1505 # XXX: Checking against the current working copy is wrong in
1498 # the sense that it can reject things like
1506 # the sense that it can reject things like
1499 #
1507 #
1500 # $ hg cat -r 10 sub/x.txt
1508 # $ hg cat -r 10 sub/x.txt
1501 #
1509 #
1502 # if sub/ is no longer a subrepository in the working copy
1510 # if sub/ is no longer a subrepository in the working copy
1503 # parent revision.
1511 # parent revision.
1504 #
1512 #
1505 # However, it can of course also allow things that would have
1513 # However, it can of course also allow things that would have
1506 # been rejected before, such as the above cat command if sub/
1514 # been rejected before, such as the above cat command if sub/
1507 # is a subrepository now, but was a normal directory before.
1515 # is a subrepository now, but was a normal directory before.
1508 # The old path auditor would have rejected by mistake since it
1516 # The old path auditor would have rejected by mistake since it
1509 # panics when it sees sub/.hg/.
1517 # panics when it sees sub/.hg/.
1510 #
1518 #
1511 # All in all, checking against the working copy seems sensible
1519 # All in all, checking against the working copy seems sensible
1512 # since we want to prevent access to nested repositories on
1520 # since we want to prevent access to nested repositories on
1513 # the filesystem *now*.
1521 # the filesystem *now*.
1514 ctx = self[None]
1522 ctx = self[None]
1515 parts = util.splitpath(subpath)
1523 parts = util.splitpath(subpath)
1516 while parts:
1524 while parts:
1517 prefix = b'/'.join(parts)
1525 prefix = b'/'.join(parts)
1518 if prefix in ctx.substate:
1526 if prefix in ctx.substate:
1519 if prefix == normsubpath:
1527 if prefix == normsubpath:
1520 return True
1528 return True
1521 else:
1529 else:
1522 sub = ctx.sub(prefix)
1530 sub = ctx.sub(prefix)
1523 return sub.checknested(subpath[len(prefix) + 1 :])
1531 return sub.checknested(subpath[len(prefix) + 1 :])
1524 else:
1532 else:
1525 parts.pop()
1533 parts.pop()
1526 return False
1534 return False
1527
1535
1528 def peer(self):
1536 def peer(self):
1529 return localpeer(self) # not cached to avoid reference cycle
1537 return localpeer(self) # not cached to avoid reference cycle
1530
1538
1531 def unfiltered(self):
1539 def unfiltered(self):
1532 """Return unfiltered version of the repository
1540 """Return unfiltered version of the repository
1533
1541
1534 Intended to be overwritten by filtered repo."""
1542 Intended to be overwritten by filtered repo."""
1535 return self
1543 return self
1536
1544
1537 def filtered(self, name, visibilityexceptions=None):
1545 def filtered(self, name, visibilityexceptions=None):
1538 """Return a filtered version of a repository
1546 """Return a filtered version of a repository
1539
1547
1540 The `name` parameter is the identifier of the requested view. This
1548 The `name` parameter is the identifier of the requested view. This
1541 will return a repoview object set "exactly" to the specified view.
1549 will return a repoview object set "exactly" to the specified view.
1542
1550
1543 This function does not apply recursive filtering to a repository. For
1551 This function does not apply recursive filtering to a repository. For
1544 example calling `repo.filtered("served")` will return a repoview using
1552 example calling `repo.filtered("served")` will return a repoview using
1545 the "served" view, regardless of the initial view used by `repo`.
1553 the "served" view, regardless of the initial view used by `repo`.
1546
1554
1547 In other word, there is always only one level of `repoview` "filtering".
1555 In other word, there is always only one level of `repoview` "filtering".
1548 """
1556 """
1549 if self._extrafilterid is not None and b'%' not in name:
1557 if self._extrafilterid is not None and b'%' not in name:
1550 name = name + b'%' + self._extrafilterid
1558 name = name + b'%' + self._extrafilterid
1551
1559
1552 cls = repoview.newtype(self.unfiltered().__class__)
1560 cls = repoview.newtype(self.unfiltered().__class__)
1553 return cls(self, name, visibilityexceptions)
1561 return cls(self, name, visibilityexceptions)
1554
1562
1555 @mixedrepostorecache(
1563 @mixedrepostorecache(
1556 (b'bookmarks', b'plain'),
1564 (b'bookmarks', b'plain'),
1557 (b'bookmarks.current', b'plain'),
1565 (b'bookmarks.current', b'plain'),
1558 (b'bookmarks', b''),
1566 (b'bookmarks', b''),
1559 (b'00changelog.i', b''),
1567 (b'00changelog.i', b''),
1560 )
1568 )
1561 def _bookmarks(self):
1569 def _bookmarks(self):
1562 # Since the multiple files involved in the transaction cannot be
1570 # Since the multiple files involved in the transaction cannot be
1563 # written atomically (with current repository format), there is a race
1571 # written atomically (with current repository format), there is a race
1564 # condition here.
1572 # condition here.
1565 #
1573 #
1566 # 1) changelog content A is read
1574 # 1) changelog content A is read
1567 # 2) outside transaction update changelog to content B
1575 # 2) outside transaction update changelog to content B
1568 # 3) outside transaction update bookmark file referring to content B
1576 # 3) outside transaction update bookmark file referring to content B
1569 # 4) bookmarks file content is read and filtered against changelog-A
1577 # 4) bookmarks file content is read and filtered against changelog-A
1570 #
1578 #
1571 # When this happens, bookmarks against nodes missing from A are dropped.
1579 # When this happens, bookmarks against nodes missing from A are dropped.
1572 #
1580 #
1573 # Having this happening during read is not great, but it become worse
1581 # Having this happening during read is not great, but it become worse
1574 # when this happen during write because the bookmarks to the "unknown"
1582 # when this happen during write because the bookmarks to the "unknown"
1575 # nodes will be dropped for good. However, writes happen within locks.
1583 # nodes will be dropped for good. However, writes happen within locks.
1576 # This locking makes it possible to have a race free consistent read.
1584 # This locking makes it possible to have a race free consistent read.
1577 # For this purpose data read from disc before locking are
1585 # For this purpose data read from disc before locking are
1578 # "invalidated" right after the locks are taken. This invalidations are
1586 # "invalidated" right after the locks are taken. This invalidations are
1579 # "light", the `filecache` mechanism keep the data in memory and will
1587 # "light", the `filecache` mechanism keep the data in memory and will
1580 # reuse them if the underlying files did not changed. Not parsing the
1588 # reuse them if the underlying files did not changed. Not parsing the
1581 # same data multiple times helps performances.
1589 # same data multiple times helps performances.
1582 #
1590 #
1583 # Unfortunately in the case describe above, the files tracked by the
1591 # Unfortunately in the case describe above, the files tracked by the
1584 # bookmarks file cache might not have changed, but the in-memory
1592 # bookmarks file cache might not have changed, but the in-memory
1585 # content is still "wrong" because we used an older changelog content
1593 # content is still "wrong" because we used an older changelog content
1586 # to process the on-disk data. So after locking, the changelog would be
1594 # to process the on-disk data. So after locking, the changelog would be
1587 # refreshed but `_bookmarks` would be preserved.
1595 # refreshed but `_bookmarks` would be preserved.
1588 # Adding `00changelog.i` to the list of tracked file is not
1596 # Adding `00changelog.i` to the list of tracked file is not
1589 # enough, because at the time we build the content for `_bookmarks` in
1597 # enough, because at the time we build the content for `_bookmarks` in
1590 # (4), the changelog file has already diverged from the content used
1598 # (4), the changelog file has already diverged from the content used
1591 # for loading `changelog` in (1)
1599 # for loading `changelog` in (1)
1592 #
1600 #
1593 # To prevent the issue, we force the changelog to be explicitly
1601 # To prevent the issue, we force the changelog to be explicitly
1594 # reloaded while computing `_bookmarks`. The data race can still happen
1602 # reloaded while computing `_bookmarks`. The data race can still happen
1595 # without the lock (with a narrower window), but it would no longer go
1603 # without the lock (with a narrower window), but it would no longer go
1596 # undetected during the lock time refresh.
1604 # undetected during the lock time refresh.
1597 #
1605 #
1598 # The new schedule is as follow
1606 # The new schedule is as follow
1599 #
1607 #
1600 # 1) filecache logic detect that `_bookmarks` needs to be computed
1608 # 1) filecache logic detect that `_bookmarks` needs to be computed
1601 # 2) cachestat for `bookmarks` and `changelog` are captured (for book)
1609 # 2) cachestat for `bookmarks` and `changelog` are captured (for book)
1602 # 3) We force `changelog` filecache to be tested
1610 # 3) We force `changelog` filecache to be tested
1603 # 4) cachestat for `changelog` are captured (for changelog)
1611 # 4) cachestat for `changelog` are captured (for changelog)
1604 # 5) `_bookmarks` is computed and cached
1612 # 5) `_bookmarks` is computed and cached
1605 #
1613 #
1606 # The step in (3) ensure we have a changelog at least as recent as the
1614 # The step in (3) ensure we have a changelog at least as recent as the
1607 # cache stat computed in (1). As a result at locking time:
1615 # cache stat computed in (1). As a result at locking time:
1608 # * if the changelog did not changed since (1) -> we can reuse the data
1616 # * if the changelog did not changed since (1) -> we can reuse the data
1609 # * otherwise -> the bookmarks get refreshed.
1617 # * otherwise -> the bookmarks get refreshed.
1610 self._refreshchangelog()
1618 self._refreshchangelog()
1611 return bookmarks.bmstore(self)
1619 return bookmarks.bmstore(self)
1612
1620
1613 def _refreshchangelog(self):
1621 def _refreshchangelog(self):
1614 """make sure the in memory changelog match the on-disk one"""
1622 """make sure the in memory changelog match the on-disk one"""
1615 if 'changelog' in vars(self) and self.currenttransaction() is None:
1623 if 'changelog' in vars(self) and self.currenttransaction() is None:
1616 del self.changelog
1624 del self.changelog
1617
1625
1618 @property
1626 @property
1619 def _activebookmark(self):
1627 def _activebookmark(self):
1620 return self._bookmarks.active
1628 return self._bookmarks.active
1621
1629
1622 # _phasesets depend on changelog. what we need is to call
1630 # _phasesets depend on changelog. what we need is to call
1623 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1631 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1624 # can't be easily expressed in filecache mechanism.
1632 # can't be easily expressed in filecache mechanism.
1625 @storecache(b'phaseroots', b'00changelog.i')
1633 @storecache(b'phaseroots', b'00changelog.i')
1626 def _phasecache(self):
1634 def _phasecache(self):
1627 return phases.phasecache(self, self._phasedefaults)
1635 return phases.phasecache(self, self._phasedefaults)
1628
1636
1629 @storecache(b'obsstore')
1637 @storecache(b'obsstore')
1630 def obsstore(self):
1638 def obsstore(self):
1631 return obsolete.makestore(self.ui, self)
1639 return obsolete.makestore(self.ui, self)
1632
1640
1633 @storecache(b'00changelog.i')
1641 @storecache(b'00changelog.i')
1634 def changelog(self):
1642 def changelog(self):
1635 # load dirstate before changelog to avoid race see issue6303
1643 # load dirstate before changelog to avoid race see issue6303
1636 self.dirstate.prefetch_parents()
1644 self.dirstate.prefetch_parents()
1637 return self.store.changelog(txnutil.mayhavepending(self.root))
1645 return self.store.changelog(txnutil.mayhavepending(self.root))
1638
1646
1639 @storecache(b'00manifest.i')
1647 @storecache(b'00manifest.i')
1640 def manifestlog(self):
1648 def manifestlog(self):
1641 return self.store.manifestlog(self, self._storenarrowmatch)
1649 return self.store.manifestlog(self, self._storenarrowmatch)
1642
1650
1643 @repofilecache(b'dirstate')
1651 @repofilecache(b'dirstate')
1644 def dirstate(self):
1652 def dirstate(self):
1645 return self._makedirstate()
1653 return self._makedirstate()
1646
1654
1647 def _makedirstate(self):
1655 def _makedirstate(self):
1648 """Extension point for wrapping the dirstate per-repo."""
1656 """Extension point for wrapping the dirstate per-repo."""
1649 sparsematchfn = lambda: sparse.matcher(self)
1657 sparsematchfn = lambda: sparse.matcher(self)
1650
1658
1651 return dirstate.dirstate(
1659 return dirstate.dirstate(
1652 self.vfs, self.ui, self.root, self._dirstatevalidate, sparsematchfn
1660 self.vfs, self.ui, self.root, self._dirstatevalidate, sparsematchfn
1653 )
1661 )
1654
1662
1655 def _dirstatevalidate(self, node):
1663 def _dirstatevalidate(self, node):
1656 try:
1664 try:
1657 self.changelog.rev(node)
1665 self.changelog.rev(node)
1658 return node
1666 return node
1659 except error.LookupError:
1667 except error.LookupError:
1660 if not self._dirstatevalidatewarned:
1668 if not self._dirstatevalidatewarned:
1661 self._dirstatevalidatewarned = True
1669 self._dirstatevalidatewarned = True
1662 self.ui.warn(
1670 self.ui.warn(
1663 _(b"warning: ignoring unknown working parent %s!\n")
1671 _(b"warning: ignoring unknown working parent %s!\n")
1664 % short(node)
1672 % short(node)
1665 )
1673 )
1666 return nullid
1674 return nullid
1667
1675
1668 @storecache(narrowspec.FILENAME)
1676 @storecache(narrowspec.FILENAME)
1669 def narrowpats(self):
1677 def narrowpats(self):
1670 """matcher patterns for this repository's narrowspec
1678 """matcher patterns for this repository's narrowspec
1671
1679
1672 A tuple of (includes, excludes).
1680 A tuple of (includes, excludes).
1673 """
1681 """
1674 return narrowspec.load(self)
1682 return narrowspec.load(self)
1675
1683
1676 @storecache(narrowspec.FILENAME)
1684 @storecache(narrowspec.FILENAME)
1677 def _storenarrowmatch(self):
1685 def _storenarrowmatch(self):
1678 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1686 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1679 return matchmod.always()
1687 return matchmod.always()
1680 include, exclude = self.narrowpats
1688 include, exclude = self.narrowpats
1681 return narrowspec.match(self.root, include=include, exclude=exclude)
1689 return narrowspec.match(self.root, include=include, exclude=exclude)
1682
1690
1683 @storecache(narrowspec.FILENAME)
1691 @storecache(narrowspec.FILENAME)
1684 def _narrowmatch(self):
1692 def _narrowmatch(self):
1685 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1693 if requirementsmod.NARROW_REQUIREMENT not in self.requirements:
1686 return matchmod.always()
1694 return matchmod.always()
1687 narrowspec.checkworkingcopynarrowspec(self)
1695 narrowspec.checkworkingcopynarrowspec(self)
1688 include, exclude = self.narrowpats
1696 include, exclude = self.narrowpats
1689 return narrowspec.match(self.root, include=include, exclude=exclude)
1697 return narrowspec.match(self.root, include=include, exclude=exclude)
1690
1698
1691 def narrowmatch(self, match=None, includeexact=False):
1699 def narrowmatch(self, match=None, includeexact=False):
1692 """matcher corresponding the the repo's narrowspec
1700 """matcher corresponding the the repo's narrowspec
1693
1701
1694 If `match` is given, then that will be intersected with the narrow
1702 If `match` is given, then that will be intersected with the narrow
1695 matcher.
1703 matcher.
1696
1704
1697 If `includeexact` is True, then any exact matches from `match` will
1705 If `includeexact` is True, then any exact matches from `match` will
1698 be included even if they're outside the narrowspec.
1706 be included even if they're outside the narrowspec.
1699 """
1707 """
1700 if match:
1708 if match:
1701 if includeexact and not self._narrowmatch.always():
1709 if includeexact and not self._narrowmatch.always():
1702 # do not exclude explicitly-specified paths so that they can
1710 # do not exclude explicitly-specified paths so that they can
1703 # be warned later on
1711 # be warned later on
1704 em = matchmod.exact(match.files())
1712 em = matchmod.exact(match.files())
1705 nm = matchmod.unionmatcher([self._narrowmatch, em])
1713 nm = matchmod.unionmatcher([self._narrowmatch, em])
1706 return matchmod.intersectmatchers(match, nm)
1714 return matchmod.intersectmatchers(match, nm)
1707 return matchmod.intersectmatchers(match, self._narrowmatch)
1715 return matchmod.intersectmatchers(match, self._narrowmatch)
1708 return self._narrowmatch
1716 return self._narrowmatch
1709
1717
1710 def setnarrowpats(self, newincludes, newexcludes):
1718 def setnarrowpats(self, newincludes, newexcludes):
1711 narrowspec.save(self, newincludes, newexcludes)
1719 narrowspec.save(self, newincludes, newexcludes)
1712 self.invalidate(clearfilecache=True)
1720 self.invalidate(clearfilecache=True)
1713
1721
1714 @unfilteredpropertycache
1722 @unfilteredpropertycache
1715 def _quick_access_changeid_null(self):
1723 def _quick_access_changeid_null(self):
1716 return {
1724 return {
1717 b'null': (nullrev, nullid),
1725 b'null': (nullrev, nullid),
1718 nullrev: (nullrev, nullid),
1726 nullrev: (nullrev, nullid),
1719 nullid: (nullrev, nullid),
1727 nullid: (nullrev, nullid),
1720 }
1728 }
1721
1729
1722 @unfilteredpropertycache
1730 @unfilteredpropertycache
1723 def _quick_access_changeid_wc(self):
1731 def _quick_access_changeid_wc(self):
1724 # also fast path access to the working copy parents
1732 # also fast path access to the working copy parents
1725 # however, only do it for filter that ensure wc is visible.
1733 # however, only do it for filter that ensure wc is visible.
1726 quick = self._quick_access_changeid_null.copy()
1734 quick = self._quick_access_changeid_null.copy()
1727 cl = self.unfiltered().changelog
1735 cl = self.unfiltered().changelog
1728 for node in self.dirstate.parents():
1736 for node in self.dirstate.parents():
1729 if node == nullid:
1737 if node == nullid:
1730 continue
1738 continue
1731 rev = cl.index.get_rev(node)
1739 rev = cl.index.get_rev(node)
1732 if rev is None:
1740 if rev is None:
1733 # unknown working copy parent case:
1741 # unknown working copy parent case:
1734 #
1742 #
1735 # skip the fast path and let higher code deal with it
1743 # skip the fast path and let higher code deal with it
1736 continue
1744 continue
1737 pair = (rev, node)
1745 pair = (rev, node)
1738 quick[rev] = pair
1746 quick[rev] = pair
1739 quick[node] = pair
1747 quick[node] = pair
1740 # also add the parents of the parents
1748 # also add the parents of the parents
1741 for r in cl.parentrevs(rev):
1749 for r in cl.parentrevs(rev):
1742 if r == nullrev:
1750 if r == nullrev:
1743 continue
1751 continue
1744 n = cl.node(r)
1752 n = cl.node(r)
1745 pair = (r, n)
1753 pair = (r, n)
1746 quick[r] = pair
1754 quick[r] = pair
1747 quick[n] = pair
1755 quick[n] = pair
1748 p1node = self.dirstate.p1()
1756 p1node = self.dirstate.p1()
1749 if p1node != nullid:
1757 if p1node != nullid:
1750 quick[b'.'] = quick[p1node]
1758 quick[b'.'] = quick[p1node]
1751 return quick
1759 return quick
1752
1760
1753 @unfilteredmethod
1761 @unfilteredmethod
1754 def _quick_access_changeid_invalidate(self):
1762 def _quick_access_changeid_invalidate(self):
1755 if '_quick_access_changeid_wc' in vars(self):
1763 if '_quick_access_changeid_wc' in vars(self):
1756 del self.__dict__['_quick_access_changeid_wc']
1764 del self.__dict__['_quick_access_changeid_wc']
1757
1765
1758 @property
1766 @property
1759 def _quick_access_changeid(self):
1767 def _quick_access_changeid(self):
1760 """an helper dictionnary for __getitem__ calls
1768 """an helper dictionnary for __getitem__ calls
1761
1769
1762 This contains a list of symbol we can recognise right away without
1770 This contains a list of symbol we can recognise right away without
1763 further processing.
1771 further processing.
1764 """
1772 """
1765 if self.filtername in repoview.filter_has_wc:
1773 if self.filtername in repoview.filter_has_wc:
1766 return self._quick_access_changeid_wc
1774 return self._quick_access_changeid_wc
1767 return self._quick_access_changeid_null
1775 return self._quick_access_changeid_null
1768
1776
1769 def __getitem__(self, changeid):
1777 def __getitem__(self, changeid):
1770 # dealing with special cases
1778 # dealing with special cases
1771 if changeid is None:
1779 if changeid is None:
1772 return context.workingctx(self)
1780 return context.workingctx(self)
1773 if isinstance(changeid, context.basectx):
1781 if isinstance(changeid, context.basectx):
1774 return changeid
1782 return changeid
1775
1783
1776 # dealing with multiple revisions
1784 # dealing with multiple revisions
1777 if isinstance(changeid, slice):
1785 if isinstance(changeid, slice):
1778 # wdirrev isn't contiguous so the slice shouldn't include it
1786 # wdirrev isn't contiguous so the slice shouldn't include it
1779 return [
1787 return [
1780 self[i]
1788 self[i]
1781 for i in pycompat.xrange(*changeid.indices(len(self)))
1789 for i in pycompat.xrange(*changeid.indices(len(self)))
1782 if i not in self.changelog.filteredrevs
1790 if i not in self.changelog.filteredrevs
1783 ]
1791 ]
1784
1792
1785 # dealing with some special values
1793 # dealing with some special values
1786 quick_access = self._quick_access_changeid.get(changeid)
1794 quick_access = self._quick_access_changeid.get(changeid)
1787 if quick_access is not None:
1795 if quick_access is not None:
1788 rev, node = quick_access
1796 rev, node = quick_access
1789 return context.changectx(self, rev, node, maybe_filtered=False)
1797 return context.changectx(self, rev, node, maybe_filtered=False)
1790 if changeid == b'tip':
1798 if changeid == b'tip':
1791 node = self.changelog.tip()
1799 node = self.changelog.tip()
1792 rev = self.changelog.rev(node)
1800 rev = self.changelog.rev(node)
1793 return context.changectx(self, rev, node)
1801 return context.changectx(self, rev, node)
1794
1802
1795 # dealing with arbitrary values
1803 # dealing with arbitrary values
1796 try:
1804 try:
1797 if isinstance(changeid, int):
1805 if isinstance(changeid, int):
1798 node = self.changelog.node(changeid)
1806 node = self.changelog.node(changeid)
1799 rev = changeid
1807 rev = changeid
1800 elif changeid == b'.':
1808 elif changeid == b'.':
1801 # this is a hack to delay/avoid loading obsmarkers
1809 # this is a hack to delay/avoid loading obsmarkers
1802 # when we know that '.' won't be hidden
1810 # when we know that '.' won't be hidden
1803 node = self.dirstate.p1()
1811 node = self.dirstate.p1()
1804 rev = self.unfiltered().changelog.rev(node)
1812 rev = self.unfiltered().changelog.rev(node)
1805 elif len(changeid) == 20:
1813 elif len(changeid) == 20:
1806 try:
1814 try:
1807 node = changeid
1815 node = changeid
1808 rev = self.changelog.rev(changeid)
1816 rev = self.changelog.rev(changeid)
1809 except error.FilteredLookupError:
1817 except error.FilteredLookupError:
1810 changeid = hex(changeid) # for the error message
1818 changeid = hex(changeid) # for the error message
1811 raise
1819 raise
1812 except LookupError:
1820 except LookupError:
1813 # check if it might have come from damaged dirstate
1821 # check if it might have come from damaged dirstate
1814 #
1822 #
1815 # XXX we could avoid the unfiltered if we had a recognizable
1823 # XXX we could avoid the unfiltered if we had a recognizable
1816 # exception for filtered changeset access
1824 # exception for filtered changeset access
1817 if (
1825 if (
1818 self.local()
1826 self.local()
1819 and changeid in self.unfiltered().dirstate.parents()
1827 and changeid in self.unfiltered().dirstate.parents()
1820 ):
1828 ):
1821 msg = _(b"working directory has unknown parent '%s'!")
1829 msg = _(b"working directory has unknown parent '%s'!")
1822 raise error.Abort(msg % short(changeid))
1830 raise error.Abort(msg % short(changeid))
1823 changeid = hex(changeid) # for the error message
1831 changeid = hex(changeid) # for the error message
1824 raise
1832 raise
1825
1833
1826 elif len(changeid) == 40:
1834 elif len(changeid) == 40:
1827 node = bin(changeid)
1835 node = bin(changeid)
1828 rev = self.changelog.rev(node)
1836 rev = self.changelog.rev(node)
1829 else:
1837 else:
1830 raise error.ProgrammingError(
1838 raise error.ProgrammingError(
1831 b"unsupported changeid '%s' of type %s"
1839 b"unsupported changeid '%s' of type %s"
1832 % (changeid, pycompat.bytestr(type(changeid)))
1840 % (changeid, pycompat.bytestr(type(changeid)))
1833 )
1841 )
1834
1842
1835 return context.changectx(self, rev, node)
1843 return context.changectx(self, rev, node)
1836
1844
1837 except (error.FilteredIndexError, error.FilteredLookupError):
1845 except (error.FilteredIndexError, error.FilteredLookupError):
1838 raise error.FilteredRepoLookupError(
1846 raise error.FilteredRepoLookupError(
1839 _(b"filtered revision '%s'") % pycompat.bytestr(changeid)
1847 _(b"filtered revision '%s'") % pycompat.bytestr(changeid)
1840 )
1848 )
1841 except (IndexError, LookupError):
1849 except (IndexError, LookupError):
1842 raise error.RepoLookupError(
1850 raise error.RepoLookupError(
1843 _(b"unknown revision '%s'") % pycompat.bytestr(changeid)
1851 _(b"unknown revision '%s'") % pycompat.bytestr(changeid)
1844 )
1852 )
1845 except error.WdirUnsupported:
1853 except error.WdirUnsupported:
1846 return context.workingctx(self)
1854 return context.workingctx(self)
1847
1855
1848 def __contains__(self, changeid):
1856 def __contains__(self, changeid):
1849 """True if the given changeid exists"""
1857 """True if the given changeid exists"""
1850 try:
1858 try:
1851 self[changeid]
1859 self[changeid]
1852 return True
1860 return True
1853 except error.RepoLookupError:
1861 except error.RepoLookupError:
1854 return False
1862 return False
1855
1863
1856 def __nonzero__(self):
1864 def __nonzero__(self):
1857 return True
1865 return True
1858
1866
1859 __bool__ = __nonzero__
1867 __bool__ = __nonzero__
1860
1868
1861 def __len__(self):
1869 def __len__(self):
1862 # no need to pay the cost of repoview.changelog
1870 # no need to pay the cost of repoview.changelog
1863 unfi = self.unfiltered()
1871 unfi = self.unfiltered()
1864 return len(unfi.changelog)
1872 return len(unfi.changelog)
1865
1873
1866 def __iter__(self):
1874 def __iter__(self):
1867 return iter(self.changelog)
1875 return iter(self.changelog)
1868
1876
1869 def revs(self, expr, *args):
1877 def revs(self, expr, *args):
1870 """Find revisions matching a revset.
1878 """Find revisions matching a revset.
1871
1879
1872 The revset is specified as a string ``expr`` that may contain
1880 The revset is specified as a string ``expr`` that may contain
1873 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1881 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1874
1882
1875 Revset aliases from the configuration are not expanded. To expand
1883 Revset aliases from the configuration are not expanded. To expand
1876 user aliases, consider calling ``scmutil.revrange()`` or
1884 user aliases, consider calling ``scmutil.revrange()`` or
1877 ``repo.anyrevs([expr], user=True)``.
1885 ``repo.anyrevs([expr], user=True)``.
1878
1886
1879 Returns a smartset.abstractsmartset, which is a list-like interface
1887 Returns a smartset.abstractsmartset, which is a list-like interface
1880 that contains integer revisions.
1888 that contains integer revisions.
1881 """
1889 """
1882 tree = revsetlang.spectree(expr, *args)
1890 tree = revsetlang.spectree(expr, *args)
1883 return revset.makematcher(tree)(self)
1891 return revset.makematcher(tree)(self)
1884
1892
1885 def set(self, expr, *args):
1893 def set(self, expr, *args):
1886 """Find revisions matching a revset and emit changectx instances.
1894 """Find revisions matching a revset and emit changectx instances.
1887
1895
1888 This is a convenience wrapper around ``revs()`` that iterates the
1896 This is a convenience wrapper around ``revs()`` that iterates the
1889 result and is a generator of changectx instances.
1897 result and is a generator of changectx instances.
1890
1898
1891 Revset aliases from the configuration are not expanded. To expand
1899 Revset aliases from the configuration are not expanded. To expand
1892 user aliases, consider calling ``scmutil.revrange()``.
1900 user aliases, consider calling ``scmutil.revrange()``.
1893 """
1901 """
1894 for r in self.revs(expr, *args):
1902 for r in self.revs(expr, *args):
1895 yield self[r]
1903 yield self[r]
1896
1904
1897 def anyrevs(self, specs, user=False, localalias=None):
1905 def anyrevs(self, specs, user=False, localalias=None):
1898 """Find revisions matching one of the given revsets.
1906 """Find revisions matching one of the given revsets.
1899
1907
1900 Revset aliases from the configuration are not expanded by default. To
1908 Revset aliases from the configuration are not expanded by default. To
1901 expand user aliases, specify ``user=True``. To provide some local
1909 expand user aliases, specify ``user=True``. To provide some local
1902 definitions overriding user aliases, set ``localalias`` to
1910 definitions overriding user aliases, set ``localalias`` to
1903 ``{name: definitionstring}``.
1911 ``{name: definitionstring}``.
1904 """
1912 """
1905 if specs == [b'null']:
1913 if specs == [b'null']:
1906 return revset.baseset([nullrev])
1914 return revset.baseset([nullrev])
1907 if specs == [b'.']:
1915 if specs == [b'.']:
1908 quick_data = self._quick_access_changeid.get(b'.')
1916 quick_data = self._quick_access_changeid.get(b'.')
1909 if quick_data is not None:
1917 if quick_data is not None:
1910 return revset.baseset([quick_data[0]])
1918 return revset.baseset([quick_data[0]])
1911 if user:
1919 if user:
1912 m = revset.matchany(
1920 m = revset.matchany(
1913 self.ui,
1921 self.ui,
1914 specs,
1922 specs,
1915 lookup=revset.lookupfn(self),
1923 lookup=revset.lookupfn(self),
1916 localalias=localalias,
1924 localalias=localalias,
1917 )
1925 )
1918 else:
1926 else:
1919 m = revset.matchany(None, specs, localalias=localalias)
1927 m = revset.matchany(None, specs, localalias=localalias)
1920 return m(self)
1928 return m(self)
1921
1929
1922 def url(self):
1930 def url(self):
1923 return b'file:' + self.root
1931 return b'file:' + self.root
1924
1932
1925 def hook(self, name, throw=False, **args):
1933 def hook(self, name, throw=False, **args):
1926 """Call a hook, passing this repo instance.
1934 """Call a hook, passing this repo instance.
1927
1935
1928 This a convenience method to aid invoking hooks. Extensions likely
1936 This a convenience method to aid invoking hooks. Extensions likely
1929 won't call this unless they have registered a custom hook or are
1937 won't call this unless they have registered a custom hook or are
1930 replacing code that is expected to call a hook.
1938 replacing code that is expected to call a hook.
1931 """
1939 """
1932 return hook.hook(self.ui, self, name, throw, **args)
1940 return hook.hook(self.ui, self, name, throw, **args)
1933
1941
1934 @filteredpropertycache
1942 @filteredpropertycache
1935 def _tagscache(self):
1943 def _tagscache(self):
1936 """Returns a tagscache object that contains various tags related
1944 """Returns a tagscache object that contains various tags related
1937 caches."""
1945 caches."""
1938
1946
1939 # This simplifies its cache management by having one decorated
1947 # This simplifies its cache management by having one decorated
1940 # function (this one) and the rest simply fetch things from it.
1948 # function (this one) and the rest simply fetch things from it.
1941 class tagscache(object):
1949 class tagscache(object):
1942 def __init__(self):
1950 def __init__(self):
1943 # These two define the set of tags for this repository. tags
1951 # These two define the set of tags for this repository. tags
1944 # maps tag name to node; tagtypes maps tag name to 'global' or
1952 # maps tag name to node; tagtypes maps tag name to 'global' or
1945 # 'local'. (Global tags are defined by .hgtags across all
1953 # 'local'. (Global tags are defined by .hgtags across all
1946 # heads, and local tags are defined in .hg/localtags.)
1954 # heads, and local tags are defined in .hg/localtags.)
1947 # They constitute the in-memory cache of tags.
1955 # They constitute the in-memory cache of tags.
1948 self.tags = self.tagtypes = None
1956 self.tags = self.tagtypes = None
1949
1957
1950 self.nodetagscache = self.tagslist = None
1958 self.nodetagscache = self.tagslist = None
1951
1959
1952 cache = tagscache()
1960 cache = tagscache()
1953 cache.tags, cache.tagtypes = self._findtags()
1961 cache.tags, cache.tagtypes = self._findtags()
1954
1962
1955 return cache
1963 return cache
1956
1964
1957 def tags(self):
1965 def tags(self):
1958 '''return a mapping of tag to node'''
1966 '''return a mapping of tag to node'''
1959 t = {}
1967 t = {}
1960 if self.changelog.filteredrevs:
1968 if self.changelog.filteredrevs:
1961 tags, tt = self._findtags()
1969 tags, tt = self._findtags()
1962 else:
1970 else:
1963 tags = self._tagscache.tags
1971 tags = self._tagscache.tags
1964 rev = self.changelog.rev
1972 rev = self.changelog.rev
1965 for k, v in pycompat.iteritems(tags):
1973 for k, v in pycompat.iteritems(tags):
1966 try:
1974 try:
1967 # ignore tags to unknown nodes
1975 # ignore tags to unknown nodes
1968 rev(v)
1976 rev(v)
1969 t[k] = v
1977 t[k] = v
1970 except (error.LookupError, ValueError):
1978 except (error.LookupError, ValueError):
1971 pass
1979 pass
1972 return t
1980 return t
1973
1981
1974 def _findtags(self):
1982 def _findtags(self):
1975 """Do the hard work of finding tags. Return a pair of dicts
1983 """Do the hard work of finding tags. Return a pair of dicts
1976 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1984 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1977 maps tag name to a string like \'global\' or \'local\'.
1985 maps tag name to a string like \'global\' or \'local\'.
1978 Subclasses or extensions are free to add their own tags, but
1986 Subclasses or extensions are free to add their own tags, but
1979 should be aware that the returned dicts will be retained for the
1987 should be aware that the returned dicts will be retained for the
1980 duration of the localrepo object."""
1988 duration of the localrepo object."""
1981
1989
1982 # XXX what tagtype should subclasses/extensions use? Currently
1990 # XXX what tagtype should subclasses/extensions use? Currently
1983 # mq and bookmarks add tags, but do not set the tagtype at all.
1991 # mq and bookmarks add tags, but do not set the tagtype at all.
1984 # Should each extension invent its own tag type? Should there
1992 # Should each extension invent its own tag type? Should there
1985 # be one tagtype for all such "virtual" tags? Or is the status
1993 # be one tagtype for all such "virtual" tags? Or is the status
1986 # quo fine?
1994 # quo fine?
1987
1995
1988 # map tag name to (node, hist)
1996 # map tag name to (node, hist)
1989 alltags = tagsmod.findglobaltags(self.ui, self)
1997 alltags = tagsmod.findglobaltags(self.ui, self)
1990 # map tag name to tag type
1998 # map tag name to tag type
1991 tagtypes = {tag: b'global' for tag in alltags}
1999 tagtypes = {tag: b'global' for tag in alltags}
1992
2000
1993 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
2001 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1994
2002
1995 # Build the return dicts. Have to re-encode tag names because
2003 # Build the return dicts. Have to re-encode tag names because
1996 # the tags module always uses UTF-8 (in order not to lose info
2004 # the tags module always uses UTF-8 (in order not to lose info
1997 # writing to the cache), but the rest of Mercurial wants them in
2005 # writing to the cache), but the rest of Mercurial wants them in
1998 # local encoding.
2006 # local encoding.
1999 tags = {}
2007 tags = {}
2000 for (name, (node, hist)) in pycompat.iteritems(alltags):
2008 for (name, (node, hist)) in pycompat.iteritems(alltags):
2001 if node != nullid:
2009 if node != nullid:
2002 tags[encoding.tolocal(name)] = node
2010 tags[encoding.tolocal(name)] = node
2003 tags[b'tip'] = self.changelog.tip()
2011 tags[b'tip'] = self.changelog.tip()
2004 tagtypes = {
2012 tagtypes = {
2005 encoding.tolocal(name): value
2013 encoding.tolocal(name): value
2006 for (name, value) in pycompat.iteritems(tagtypes)
2014 for (name, value) in pycompat.iteritems(tagtypes)
2007 }
2015 }
2008 return (tags, tagtypes)
2016 return (tags, tagtypes)
2009
2017
2010 def tagtype(self, tagname):
2018 def tagtype(self, tagname):
2011 """
2019 """
2012 return the type of the given tag. result can be:
2020 return the type of the given tag. result can be:
2013
2021
2014 'local' : a local tag
2022 'local' : a local tag
2015 'global' : a global tag
2023 'global' : a global tag
2016 None : tag does not exist
2024 None : tag does not exist
2017 """
2025 """
2018
2026
2019 return self._tagscache.tagtypes.get(tagname)
2027 return self._tagscache.tagtypes.get(tagname)
2020
2028
2021 def tagslist(self):
2029 def tagslist(self):
2022 '''return a list of tags ordered by revision'''
2030 '''return a list of tags ordered by revision'''
2023 if not self._tagscache.tagslist:
2031 if not self._tagscache.tagslist:
2024 l = []
2032 l = []
2025 for t, n in pycompat.iteritems(self.tags()):
2033 for t, n in pycompat.iteritems(self.tags()):
2026 l.append((self.changelog.rev(n), t, n))
2034 l.append((self.changelog.rev(n), t, n))
2027 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
2035 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
2028
2036
2029 return self._tagscache.tagslist
2037 return self._tagscache.tagslist
2030
2038
2031 def nodetags(self, node):
2039 def nodetags(self, node):
2032 '''return the tags associated with a node'''
2040 '''return the tags associated with a node'''
2033 if not self._tagscache.nodetagscache:
2041 if not self._tagscache.nodetagscache:
2034 nodetagscache = {}
2042 nodetagscache = {}
2035 for t, n in pycompat.iteritems(self._tagscache.tags):
2043 for t, n in pycompat.iteritems(self._tagscache.tags):
2036 nodetagscache.setdefault(n, []).append(t)
2044 nodetagscache.setdefault(n, []).append(t)
2037 for tags in pycompat.itervalues(nodetagscache):
2045 for tags in pycompat.itervalues(nodetagscache):
2038 tags.sort()
2046 tags.sort()
2039 self._tagscache.nodetagscache = nodetagscache
2047 self._tagscache.nodetagscache = nodetagscache
2040 return self._tagscache.nodetagscache.get(node, [])
2048 return self._tagscache.nodetagscache.get(node, [])
2041
2049
2042 def nodebookmarks(self, node):
2050 def nodebookmarks(self, node):
2043 """return the list of bookmarks pointing to the specified node"""
2051 """return the list of bookmarks pointing to the specified node"""
2044 return self._bookmarks.names(node)
2052 return self._bookmarks.names(node)
2045
2053
2046 def branchmap(self):
2054 def branchmap(self):
2047 """returns a dictionary {branch: [branchheads]} with branchheads
2055 """returns a dictionary {branch: [branchheads]} with branchheads
2048 ordered by increasing revision number"""
2056 ordered by increasing revision number"""
2049 return self._branchcaches[self]
2057 return self._branchcaches[self]
2050
2058
2051 @unfilteredmethod
2059 @unfilteredmethod
2052 def revbranchcache(self):
2060 def revbranchcache(self):
2053 if not self._revbranchcache:
2061 if not self._revbranchcache:
2054 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
2062 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
2055 return self._revbranchcache
2063 return self._revbranchcache
2056
2064
2057 def branchtip(self, branch, ignoremissing=False):
2065 def branchtip(self, branch, ignoremissing=False):
2058 """return the tip node for a given branch
2066 """return the tip node for a given branch
2059
2067
2060 If ignoremissing is True, then this method will not raise an error.
2068 If ignoremissing is True, then this method will not raise an error.
2061 This is helpful for callers that only expect None for a missing branch
2069 This is helpful for callers that only expect None for a missing branch
2062 (e.g. namespace).
2070 (e.g. namespace).
2063
2071
2064 """
2072 """
2065 try:
2073 try:
2066 return self.branchmap().branchtip(branch)
2074 return self.branchmap().branchtip(branch)
2067 except KeyError:
2075 except KeyError:
2068 if not ignoremissing:
2076 if not ignoremissing:
2069 raise error.RepoLookupError(_(b"unknown branch '%s'") % branch)
2077 raise error.RepoLookupError(_(b"unknown branch '%s'") % branch)
2070 else:
2078 else:
2071 pass
2079 pass
2072
2080
2073 def lookup(self, key):
2081 def lookup(self, key):
2074 node = scmutil.revsymbol(self, key).node()
2082 node = scmutil.revsymbol(self, key).node()
2075 if node is None:
2083 if node is None:
2076 raise error.RepoLookupError(_(b"unknown revision '%s'") % key)
2084 raise error.RepoLookupError(_(b"unknown revision '%s'") % key)
2077 return node
2085 return node
2078
2086
2079 def lookupbranch(self, key):
2087 def lookupbranch(self, key):
2080 if self.branchmap().hasbranch(key):
2088 if self.branchmap().hasbranch(key):
2081 return key
2089 return key
2082
2090
2083 return scmutil.revsymbol(self, key).branch()
2091 return scmutil.revsymbol(self, key).branch()
2084
2092
2085 def known(self, nodes):
2093 def known(self, nodes):
2086 cl = self.changelog
2094 cl = self.changelog
2087 get_rev = cl.index.get_rev
2095 get_rev = cl.index.get_rev
2088 filtered = cl.filteredrevs
2096 filtered = cl.filteredrevs
2089 result = []
2097 result = []
2090 for n in nodes:
2098 for n in nodes:
2091 r = get_rev(n)
2099 r = get_rev(n)
2092 resp = not (r is None or r in filtered)
2100 resp = not (r is None or r in filtered)
2093 result.append(resp)
2101 result.append(resp)
2094 return result
2102 return result
2095
2103
2096 def local(self):
2104 def local(self):
2097 return self
2105 return self
2098
2106
2099 def publishing(self):
2107 def publishing(self):
2100 # it's safe (and desirable) to trust the publish flag unconditionally
2108 # it's safe (and desirable) to trust the publish flag unconditionally
2101 # so that we don't finalize changes shared between users via ssh or nfs
2109 # so that we don't finalize changes shared between users via ssh or nfs
2102 return self.ui.configbool(b'phases', b'publish', untrusted=True)
2110 return self.ui.configbool(b'phases', b'publish', untrusted=True)
2103
2111
2104 def cancopy(self):
2112 def cancopy(self):
2105 # so statichttprepo's override of local() works
2113 # so statichttprepo's override of local() works
2106 if not self.local():
2114 if not self.local():
2107 return False
2115 return False
2108 if not self.publishing():
2116 if not self.publishing():
2109 return True
2117 return True
2110 # if publishing we can't copy if there is filtered content
2118 # if publishing we can't copy if there is filtered content
2111 return not self.filtered(b'visible').changelog.filteredrevs
2119 return not self.filtered(b'visible').changelog.filteredrevs
2112
2120
2113 def shared(self):
2121 def shared(self):
2114 '''the type of shared repository (None if not shared)'''
2122 '''the type of shared repository (None if not shared)'''
2115 if self.sharedpath != self.path:
2123 if self.sharedpath != self.path:
2116 return b'store'
2124 return b'store'
2117 return None
2125 return None
2118
2126
2119 def wjoin(self, f, *insidef):
2127 def wjoin(self, f, *insidef):
2120 return self.vfs.reljoin(self.root, f, *insidef)
2128 return self.vfs.reljoin(self.root, f, *insidef)
2121
2129
2122 def setparents(self, p1, p2=nullid):
2130 def setparents(self, p1, p2=nullid):
2123 self[None].setparents(p1, p2)
2131 self[None].setparents(p1, p2)
2124 self._quick_access_changeid_invalidate()
2132 self._quick_access_changeid_invalidate()
2125
2133
2126 def filectx(self, path, changeid=None, fileid=None, changectx=None):
2134 def filectx(self, path, changeid=None, fileid=None, changectx=None):
2127 """changeid must be a changeset revision, if specified.
2135 """changeid must be a changeset revision, if specified.
2128 fileid can be a file revision or node."""
2136 fileid can be a file revision or node."""
2129 return context.filectx(
2137 return context.filectx(
2130 self, path, changeid, fileid, changectx=changectx
2138 self, path, changeid, fileid, changectx=changectx
2131 )
2139 )
2132
2140
2133 def getcwd(self):
2141 def getcwd(self):
2134 return self.dirstate.getcwd()
2142 return self.dirstate.getcwd()
2135
2143
2136 def pathto(self, f, cwd=None):
2144 def pathto(self, f, cwd=None):
2137 return self.dirstate.pathto(f, cwd)
2145 return self.dirstate.pathto(f, cwd)
2138
2146
2139 def _loadfilter(self, filter):
2147 def _loadfilter(self, filter):
2140 if filter not in self._filterpats:
2148 if filter not in self._filterpats:
2141 l = []
2149 l = []
2142 for pat, cmd in self.ui.configitems(filter):
2150 for pat, cmd in self.ui.configitems(filter):
2143 if cmd == b'!':
2151 if cmd == b'!':
2144 continue
2152 continue
2145 mf = matchmod.match(self.root, b'', [pat])
2153 mf = matchmod.match(self.root, b'', [pat])
2146 fn = None
2154 fn = None
2147 params = cmd
2155 params = cmd
2148 for name, filterfn in pycompat.iteritems(self._datafilters):
2156 for name, filterfn in pycompat.iteritems(self._datafilters):
2149 if cmd.startswith(name):
2157 if cmd.startswith(name):
2150 fn = filterfn
2158 fn = filterfn
2151 params = cmd[len(name) :].lstrip()
2159 params = cmd[len(name) :].lstrip()
2152 break
2160 break
2153 if not fn:
2161 if not fn:
2154 fn = lambda s, c, **kwargs: procutil.filter(s, c)
2162 fn = lambda s, c, **kwargs: procutil.filter(s, c)
2155 fn.__name__ = 'commandfilter'
2163 fn.__name__ = 'commandfilter'
2156 # Wrap old filters not supporting keyword arguments
2164 # Wrap old filters not supporting keyword arguments
2157 if not pycompat.getargspec(fn)[2]:
2165 if not pycompat.getargspec(fn)[2]:
2158 oldfn = fn
2166 oldfn = fn
2159 fn = lambda s, c, oldfn=oldfn, **kwargs: oldfn(s, c)
2167 fn = lambda s, c, oldfn=oldfn, **kwargs: oldfn(s, c)
2160 fn.__name__ = 'compat-' + oldfn.__name__
2168 fn.__name__ = 'compat-' + oldfn.__name__
2161 l.append((mf, fn, params))
2169 l.append((mf, fn, params))
2162 self._filterpats[filter] = l
2170 self._filterpats[filter] = l
2163 return self._filterpats[filter]
2171 return self._filterpats[filter]
2164
2172
2165 def _filter(self, filterpats, filename, data):
2173 def _filter(self, filterpats, filename, data):
2166 for mf, fn, cmd in filterpats:
2174 for mf, fn, cmd in filterpats:
2167 if mf(filename):
2175 if mf(filename):
2168 self.ui.debug(
2176 self.ui.debug(
2169 b"filtering %s through %s\n"
2177 b"filtering %s through %s\n"
2170 % (filename, cmd or pycompat.sysbytes(fn.__name__))
2178 % (filename, cmd or pycompat.sysbytes(fn.__name__))
2171 )
2179 )
2172 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
2180 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
2173 break
2181 break
2174
2182
2175 return data
2183 return data
2176
2184
2177 @unfilteredpropertycache
2185 @unfilteredpropertycache
2178 def _encodefilterpats(self):
2186 def _encodefilterpats(self):
2179 return self._loadfilter(b'encode')
2187 return self._loadfilter(b'encode')
2180
2188
2181 @unfilteredpropertycache
2189 @unfilteredpropertycache
2182 def _decodefilterpats(self):
2190 def _decodefilterpats(self):
2183 return self._loadfilter(b'decode')
2191 return self._loadfilter(b'decode')
2184
2192
2185 def adddatafilter(self, name, filter):
2193 def adddatafilter(self, name, filter):
2186 self._datafilters[name] = filter
2194 self._datafilters[name] = filter
2187
2195
2188 def wread(self, filename):
2196 def wread(self, filename):
2189 if self.wvfs.islink(filename):
2197 if self.wvfs.islink(filename):
2190 data = self.wvfs.readlink(filename)
2198 data = self.wvfs.readlink(filename)
2191 else:
2199 else:
2192 data = self.wvfs.read(filename)
2200 data = self.wvfs.read(filename)
2193 return self._filter(self._encodefilterpats, filename, data)
2201 return self._filter(self._encodefilterpats, filename, data)
2194
2202
2195 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
2203 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
2196 """write ``data`` into ``filename`` in the working directory
2204 """write ``data`` into ``filename`` in the working directory
2197
2205
2198 This returns length of written (maybe decoded) data.
2206 This returns length of written (maybe decoded) data.
2199 """
2207 """
2200 data = self._filter(self._decodefilterpats, filename, data)
2208 data = self._filter(self._decodefilterpats, filename, data)
2201 if b'l' in flags:
2209 if b'l' in flags:
2202 self.wvfs.symlink(data, filename)
2210 self.wvfs.symlink(data, filename)
2203 else:
2211 else:
2204 self.wvfs.write(
2212 self.wvfs.write(
2205 filename, data, backgroundclose=backgroundclose, **kwargs
2213 filename, data, backgroundclose=backgroundclose, **kwargs
2206 )
2214 )
2207 if b'x' in flags:
2215 if b'x' in flags:
2208 self.wvfs.setflags(filename, False, True)
2216 self.wvfs.setflags(filename, False, True)
2209 else:
2217 else:
2210 self.wvfs.setflags(filename, False, False)
2218 self.wvfs.setflags(filename, False, False)
2211 return len(data)
2219 return len(data)
2212
2220
2213 def wwritedata(self, filename, data):
2221 def wwritedata(self, filename, data):
2214 return self._filter(self._decodefilterpats, filename, data)
2222 return self._filter(self._decodefilterpats, filename, data)
2215
2223
2216 def currenttransaction(self):
2224 def currenttransaction(self):
2217 """return the current transaction or None if non exists"""
2225 """return the current transaction or None if non exists"""
2218 if self._transref:
2226 if self._transref:
2219 tr = self._transref()
2227 tr = self._transref()
2220 else:
2228 else:
2221 tr = None
2229 tr = None
2222
2230
2223 if tr and tr.running():
2231 if tr and tr.running():
2224 return tr
2232 return tr
2225 return None
2233 return None
2226
2234
2227 def transaction(self, desc, report=None):
2235 def transaction(self, desc, report=None):
2228 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
2236 if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool(
2229 b'devel', b'check-locks'
2237 b'devel', b'check-locks'
2230 ):
2238 ):
2231 if self._currentlock(self._lockref) is None:
2239 if self._currentlock(self._lockref) is None:
2232 raise error.ProgrammingError(b'transaction requires locking')
2240 raise error.ProgrammingError(b'transaction requires locking')
2233 tr = self.currenttransaction()
2241 tr = self.currenttransaction()
2234 if tr is not None:
2242 if tr is not None:
2235 return tr.nest(name=desc)
2243 return tr.nest(name=desc)
2236
2244
2237 # abort here if the journal already exists
2245 # abort here if the journal already exists
2238 if self.svfs.exists(b"journal"):
2246 if self.svfs.exists(b"journal"):
2239 raise error.RepoError(
2247 raise error.RepoError(
2240 _(b"abandoned transaction found"),
2248 _(b"abandoned transaction found"),
2241 hint=_(b"run 'hg recover' to clean up transaction"),
2249 hint=_(b"run 'hg recover' to clean up transaction"),
2242 )
2250 )
2243
2251
2244 idbase = b"%.40f#%f" % (random.random(), time.time())
2252 idbase = b"%.40f#%f" % (random.random(), time.time())
2245 ha = hex(hashutil.sha1(idbase).digest())
2253 ha = hex(hashutil.sha1(idbase).digest())
2246 txnid = b'TXN:' + ha
2254 txnid = b'TXN:' + ha
2247 self.hook(b'pretxnopen', throw=True, txnname=desc, txnid=txnid)
2255 self.hook(b'pretxnopen', throw=True, txnname=desc, txnid=txnid)
2248
2256
2249 self._writejournal(desc)
2257 self._writejournal(desc)
2250 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
2258 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
2251 if report:
2259 if report:
2252 rp = report
2260 rp = report
2253 else:
2261 else:
2254 rp = self.ui.warn
2262 rp = self.ui.warn
2255 vfsmap = {b'plain': self.vfs, b'store': self.svfs} # root of .hg/
2263 vfsmap = {b'plain': self.vfs, b'store': self.svfs} # root of .hg/
2256 # we must avoid cyclic reference between repo and transaction.
2264 # we must avoid cyclic reference between repo and transaction.
2257 reporef = weakref.ref(self)
2265 reporef = weakref.ref(self)
2258 # Code to track tag movement
2266 # Code to track tag movement
2259 #
2267 #
2260 # Since tags are all handled as file content, it is actually quite hard
2268 # Since tags are all handled as file content, it is actually quite hard
2261 # to track these movement from a code perspective. So we fallback to a
2269 # to track these movement from a code perspective. So we fallback to a
2262 # tracking at the repository level. One could envision to track changes
2270 # tracking at the repository level. One could envision to track changes
2263 # to the '.hgtags' file through changegroup apply but that fails to
2271 # to the '.hgtags' file through changegroup apply but that fails to
2264 # cope with case where transaction expose new heads without changegroup
2272 # cope with case where transaction expose new heads without changegroup
2265 # being involved (eg: phase movement).
2273 # being involved (eg: phase movement).
2266 #
2274 #
2267 # For now, We gate the feature behind a flag since this likely comes
2275 # For now, We gate the feature behind a flag since this likely comes
2268 # with performance impacts. The current code run more often than needed
2276 # with performance impacts. The current code run more often than needed
2269 # and do not use caches as much as it could. The current focus is on
2277 # and do not use caches as much as it could. The current focus is on
2270 # the behavior of the feature so we disable it by default. The flag
2278 # the behavior of the feature so we disable it by default. The flag
2271 # will be removed when we are happy with the performance impact.
2279 # will be removed when we are happy with the performance impact.
2272 #
2280 #
2273 # Once this feature is no longer experimental move the following
2281 # Once this feature is no longer experimental move the following
2274 # documentation to the appropriate help section:
2282 # documentation to the appropriate help section:
2275 #
2283 #
2276 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
2284 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
2277 # tags (new or changed or deleted tags). In addition the details of
2285 # tags (new or changed or deleted tags). In addition the details of
2278 # these changes are made available in a file at:
2286 # these changes are made available in a file at:
2279 # ``REPOROOT/.hg/changes/tags.changes``.
2287 # ``REPOROOT/.hg/changes/tags.changes``.
2280 # Make sure you check for HG_TAG_MOVED before reading that file as it
2288 # Make sure you check for HG_TAG_MOVED before reading that file as it
2281 # might exist from a previous transaction even if no tag were touched
2289 # might exist from a previous transaction even if no tag were touched
2282 # in this one. Changes are recorded in a line base format::
2290 # in this one. Changes are recorded in a line base format::
2283 #
2291 #
2284 # <action> <hex-node> <tag-name>\n
2292 # <action> <hex-node> <tag-name>\n
2285 #
2293 #
2286 # Actions are defined as follow:
2294 # Actions are defined as follow:
2287 # "-R": tag is removed,
2295 # "-R": tag is removed,
2288 # "+A": tag is added,
2296 # "+A": tag is added,
2289 # "-M": tag is moved (old value),
2297 # "-M": tag is moved (old value),
2290 # "+M": tag is moved (new value),
2298 # "+M": tag is moved (new value),
2291 tracktags = lambda x: None
2299 tracktags = lambda x: None
2292 # experimental config: experimental.hook-track-tags
2300 # experimental config: experimental.hook-track-tags
2293 shouldtracktags = self.ui.configbool(
2301 shouldtracktags = self.ui.configbool(
2294 b'experimental', b'hook-track-tags'
2302 b'experimental', b'hook-track-tags'
2295 )
2303 )
2296 if desc != b'strip' and shouldtracktags:
2304 if desc != b'strip' and shouldtracktags:
2297 oldheads = self.changelog.headrevs()
2305 oldheads = self.changelog.headrevs()
2298
2306
2299 def tracktags(tr2):
2307 def tracktags(tr2):
2300 repo = reporef()
2308 repo = reporef()
2301 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
2309 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
2302 newheads = repo.changelog.headrevs()
2310 newheads = repo.changelog.headrevs()
2303 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
2311 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
2304 # notes: we compare lists here.
2312 # notes: we compare lists here.
2305 # As we do it only once buiding set would not be cheaper
2313 # As we do it only once buiding set would not be cheaper
2306 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
2314 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
2307 if changes:
2315 if changes:
2308 tr2.hookargs[b'tag_moved'] = b'1'
2316 tr2.hookargs[b'tag_moved'] = b'1'
2309 with repo.vfs(
2317 with repo.vfs(
2310 b'changes/tags.changes', b'w', atomictemp=True
2318 b'changes/tags.changes', b'w', atomictemp=True
2311 ) as changesfile:
2319 ) as changesfile:
2312 # note: we do not register the file to the transaction
2320 # note: we do not register the file to the transaction
2313 # because we needs it to still exist on the transaction
2321 # because we needs it to still exist on the transaction
2314 # is close (for txnclose hooks)
2322 # is close (for txnclose hooks)
2315 tagsmod.writediff(changesfile, changes)
2323 tagsmod.writediff(changesfile, changes)
2316
2324
2317 def validate(tr2):
2325 def validate(tr2):
2318 """will run pre-closing hooks"""
2326 """will run pre-closing hooks"""
2319 # XXX the transaction API is a bit lacking here so we take a hacky
2327 # XXX the transaction API is a bit lacking here so we take a hacky
2320 # path for now
2328 # path for now
2321 #
2329 #
2322 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
2330 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
2323 # dict is copied before these run. In addition we needs the data
2331 # dict is copied before these run. In addition we needs the data
2324 # available to in memory hooks too.
2332 # available to in memory hooks too.
2325 #
2333 #
2326 # Moreover, we also need to make sure this runs before txnclose
2334 # Moreover, we also need to make sure this runs before txnclose
2327 # hooks and there is no "pending" mechanism that would execute
2335 # hooks and there is no "pending" mechanism that would execute
2328 # logic only if hooks are about to run.
2336 # logic only if hooks are about to run.
2329 #
2337 #
2330 # Fixing this limitation of the transaction is also needed to track
2338 # Fixing this limitation of the transaction is also needed to track
2331 # other families of changes (bookmarks, phases, obsolescence).
2339 # other families of changes (bookmarks, phases, obsolescence).
2332 #
2340 #
2333 # This will have to be fixed before we remove the experimental
2341 # This will have to be fixed before we remove the experimental
2334 # gating.
2342 # gating.
2335 tracktags(tr2)
2343 tracktags(tr2)
2336 repo = reporef()
2344 repo = reporef()
2337
2345
2338 singleheadopt = (b'experimental', b'single-head-per-branch')
2346 singleheadopt = (b'experimental', b'single-head-per-branch')
2339 singlehead = repo.ui.configbool(*singleheadopt)
2347 singlehead = repo.ui.configbool(*singleheadopt)
2340 if singlehead:
2348 if singlehead:
2341 singleheadsub = repo.ui.configsuboptions(*singleheadopt)[1]
2349 singleheadsub = repo.ui.configsuboptions(*singleheadopt)[1]
2342 accountclosed = singleheadsub.get(
2350 accountclosed = singleheadsub.get(
2343 b"account-closed-heads", False
2351 b"account-closed-heads", False
2344 )
2352 )
2345 if singleheadsub.get(b"public-changes-only", False):
2353 if singleheadsub.get(b"public-changes-only", False):
2346 filtername = b"immutable"
2354 filtername = b"immutable"
2347 else:
2355 else:
2348 filtername = b"visible"
2356 filtername = b"visible"
2349 scmutil.enforcesinglehead(
2357 scmutil.enforcesinglehead(
2350 repo, tr2, desc, accountclosed, filtername
2358 repo, tr2, desc, accountclosed, filtername
2351 )
2359 )
2352 if hook.hashook(repo.ui, b'pretxnclose-bookmark'):
2360 if hook.hashook(repo.ui, b'pretxnclose-bookmark'):
2353 for name, (old, new) in sorted(
2361 for name, (old, new) in sorted(
2354 tr.changes[b'bookmarks'].items()
2362 tr.changes[b'bookmarks'].items()
2355 ):
2363 ):
2356 args = tr.hookargs.copy()
2364 args = tr.hookargs.copy()
2357 args.update(bookmarks.preparehookargs(name, old, new))
2365 args.update(bookmarks.preparehookargs(name, old, new))
2358 repo.hook(
2366 repo.hook(
2359 b'pretxnclose-bookmark',
2367 b'pretxnclose-bookmark',
2360 throw=True,
2368 throw=True,
2361 **pycompat.strkwargs(args)
2369 **pycompat.strkwargs(args)
2362 )
2370 )
2363 if hook.hashook(repo.ui, b'pretxnclose-phase'):
2371 if hook.hashook(repo.ui, b'pretxnclose-phase'):
2364 cl = repo.unfiltered().changelog
2372 cl = repo.unfiltered().changelog
2365 for revs, (old, new) in tr.changes[b'phases']:
2373 for revs, (old, new) in tr.changes[b'phases']:
2366 for rev in revs:
2374 for rev in revs:
2367 args = tr.hookargs.copy()
2375 args = tr.hookargs.copy()
2368 node = hex(cl.node(rev))
2376 node = hex(cl.node(rev))
2369 args.update(phases.preparehookargs(node, old, new))
2377 args.update(phases.preparehookargs(node, old, new))
2370 repo.hook(
2378 repo.hook(
2371 b'pretxnclose-phase',
2379 b'pretxnclose-phase',
2372 throw=True,
2380 throw=True,
2373 **pycompat.strkwargs(args)
2381 **pycompat.strkwargs(args)
2374 )
2382 )
2375
2383
2376 repo.hook(
2384 repo.hook(
2377 b'pretxnclose', throw=True, **pycompat.strkwargs(tr.hookargs)
2385 b'pretxnclose', throw=True, **pycompat.strkwargs(tr.hookargs)
2378 )
2386 )
2379
2387
2380 def releasefn(tr, success):
2388 def releasefn(tr, success):
2381 repo = reporef()
2389 repo = reporef()
2382 if repo is None:
2390 if repo is None:
2383 # If the repo has been GC'd (and this release function is being
2391 # If the repo has been GC'd (and this release function is being
2384 # called from transaction.__del__), there's not much we can do,
2392 # called from transaction.__del__), there's not much we can do,
2385 # so just leave the unfinished transaction there and let the
2393 # so just leave the unfinished transaction there and let the
2386 # user run `hg recover`.
2394 # user run `hg recover`.
2387 return
2395 return
2388 if success:
2396 if success:
2389 # this should be explicitly invoked here, because
2397 # this should be explicitly invoked here, because
2390 # in-memory changes aren't written out at closing
2398 # in-memory changes aren't written out at closing
2391 # transaction, if tr.addfilegenerator (via
2399 # transaction, if tr.addfilegenerator (via
2392 # dirstate.write or so) isn't invoked while
2400 # dirstate.write or so) isn't invoked while
2393 # transaction running
2401 # transaction running
2394 repo.dirstate.write(None)
2402 repo.dirstate.write(None)
2395 else:
2403 else:
2396 # discard all changes (including ones already written
2404 # discard all changes (including ones already written
2397 # out) in this transaction
2405 # out) in this transaction
2398 narrowspec.restorebackup(self, b'journal.narrowspec')
2406 narrowspec.restorebackup(self, b'journal.narrowspec')
2399 narrowspec.restorewcbackup(self, b'journal.narrowspec.dirstate')
2407 narrowspec.restorewcbackup(self, b'journal.narrowspec.dirstate')
2400 repo.dirstate.restorebackup(None, b'journal.dirstate')
2408 repo.dirstate.restorebackup(None, b'journal.dirstate')
2401
2409
2402 repo.invalidate(clearfilecache=True)
2410 repo.invalidate(clearfilecache=True)
2403
2411
2404 tr = transaction.transaction(
2412 tr = transaction.transaction(
2405 rp,
2413 rp,
2406 self.svfs,
2414 self.svfs,
2407 vfsmap,
2415 vfsmap,
2408 b"journal",
2416 b"journal",
2409 b"undo",
2417 b"undo",
2410 aftertrans(renames),
2418 aftertrans(renames),
2411 self.store.createmode,
2419 self.store.createmode,
2412 validator=validate,
2420 validator=validate,
2413 releasefn=releasefn,
2421 releasefn=releasefn,
2414 checkambigfiles=_cachedfiles,
2422 checkambigfiles=_cachedfiles,
2415 name=desc,
2423 name=desc,
2416 )
2424 )
2417 tr.changes[b'origrepolen'] = len(self)
2425 tr.changes[b'origrepolen'] = len(self)
2418 tr.changes[b'obsmarkers'] = set()
2426 tr.changes[b'obsmarkers'] = set()
2419 tr.changes[b'phases'] = []
2427 tr.changes[b'phases'] = []
2420 tr.changes[b'bookmarks'] = {}
2428 tr.changes[b'bookmarks'] = {}
2421
2429
2422 tr.hookargs[b'txnid'] = txnid
2430 tr.hookargs[b'txnid'] = txnid
2423 tr.hookargs[b'txnname'] = desc
2431 tr.hookargs[b'txnname'] = desc
2424 tr.hookargs[b'changes'] = tr.changes
2432 tr.hookargs[b'changes'] = tr.changes
2425 # note: writing the fncache only during finalize mean that the file is
2433 # note: writing the fncache only during finalize mean that the file is
2426 # outdated when running hooks. As fncache is used for streaming clone,
2434 # outdated when running hooks. As fncache is used for streaming clone,
2427 # this is not expected to break anything that happen during the hooks.
2435 # this is not expected to break anything that happen during the hooks.
2428 tr.addfinalize(b'flush-fncache', self.store.write)
2436 tr.addfinalize(b'flush-fncache', self.store.write)
2429
2437
2430 def txnclosehook(tr2):
2438 def txnclosehook(tr2):
2431 """To be run if transaction is successful, will schedule a hook run"""
2439 """To be run if transaction is successful, will schedule a hook run"""
2432 # Don't reference tr2 in hook() so we don't hold a reference.
2440 # Don't reference tr2 in hook() so we don't hold a reference.
2433 # This reduces memory consumption when there are multiple
2441 # This reduces memory consumption when there are multiple
2434 # transactions per lock. This can likely go away if issue5045
2442 # transactions per lock. This can likely go away if issue5045
2435 # fixes the function accumulation.
2443 # fixes the function accumulation.
2436 hookargs = tr2.hookargs
2444 hookargs = tr2.hookargs
2437
2445
2438 def hookfunc(unused_success):
2446 def hookfunc(unused_success):
2439 repo = reporef()
2447 repo = reporef()
2440 if hook.hashook(repo.ui, b'txnclose-bookmark'):
2448 if hook.hashook(repo.ui, b'txnclose-bookmark'):
2441 bmchanges = sorted(tr.changes[b'bookmarks'].items())
2449 bmchanges = sorted(tr.changes[b'bookmarks'].items())
2442 for name, (old, new) in bmchanges:
2450 for name, (old, new) in bmchanges:
2443 args = tr.hookargs.copy()
2451 args = tr.hookargs.copy()
2444 args.update(bookmarks.preparehookargs(name, old, new))
2452 args.update(bookmarks.preparehookargs(name, old, new))
2445 repo.hook(
2453 repo.hook(
2446 b'txnclose-bookmark',
2454 b'txnclose-bookmark',
2447 throw=False,
2455 throw=False,
2448 **pycompat.strkwargs(args)
2456 **pycompat.strkwargs(args)
2449 )
2457 )
2450
2458
2451 if hook.hashook(repo.ui, b'txnclose-phase'):
2459 if hook.hashook(repo.ui, b'txnclose-phase'):
2452 cl = repo.unfiltered().changelog
2460 cl = repo.unfiltered().changelog
2453 phasemv = sorted(
2461 phasemv = sorted(
2454 tr.changes[b'phases'], key=lambda r: r[0][0]
2462 tr.changes[b'phases'], key=lambda r: r[0][0]
2455 )
2463 )
2456 for revs, (old, new) in phasemv:
2464 for revs, (old, new) in phasemv:
2457 for rev in revs:
2465 for rev in revs:
2458 args = tr.hookargs.copy()
2466 args = tr.hookargs.copy()
2459 node = hex(cl.node(rev))
2467 node = hex(cl.node(rev))
2460 args.update(phases.preparehookargs(node, old, new))
2468 args.update(phases.preparehookargs(node, old, new))
2461 repo.hook(
2469 repo.hook(
2462 b'txnclose-phase',
2470 b'txnclose-phase',
2463 throw=False,
2471 throw=False,
2464 **pycompat.strkwargs(args)
2472 **pycompat.strkwargs(args)
2465 )
2473 )
2466
2474
2467 repo.hook(
2475 repo.hook(
2468 b'txnclose', throw=False, **pycompat.strkwargs(hookargs)
2476 b'txnclose', throw=False, **pycompat.strkwargs(hookargs)
2469 )
2477 )
2470
2478
2471 reporef()._afterlock(hookfunc)
2479 reporef()._afterlock(hookfunc)
2472
2480
2473 tr.addfinalize(b'txnclose-hook', txnclosehook)
2481 tr.addfinalize(b'txnclose-hook', txnclosehook)
2474 # Include a leading "-" to make it happen before the transaction summary
2482 # Include a leading "-" to make it happen before the transaction summary
2475 # reports registered via scmutil.registersummarycallback() whose names
2483 # reports registered via scmutil.registersummarycallback() whose names
2476 # are 00-txnreport etc. That way, the caches will be warm when the
2484 # are 00-txnreport etc. That way, the caches will be warm when the
2477 # callbacks run.
2485 # callbacks run.
2478 tr.addpostclose(b'-warm-cache', self._buildcacheupdater(tr))
2486 tr.addpostclose(b'-warm-cache', self._buildcacheupdater(tr))
2479
2487
2480 def txnaborthook(tr2):
2488 def txnaborthook(tr2):
2481 """To be run if transaction is aborted"""
2489 """To be run if transaction is aborted"""
2482 reporef().hook(
2490 reporef().hook(
2483 b'txnabort', throw=False, **pycompat.strkwargs(tr2.hookargs)
2491 b'txnabort', throw=False, **pycompat.strkwargs(tr2.hookargs)
2484 )
2492 )
2485
2493
2486 tr.addabort(b'txnabort-hook', txnaborthook)
2494 tr.addabort(b'txnabort-hook', txnaborthook)
2487 # avoid eager cache invalidation. in-memory data should be identical
2495 # avoid eager cache invalidation. in-memory data should be identical
2488 # to stored data if transaction has no error.
2496 # to stored data if transaction has no error.
2489 tr.addpostclose(b'refresh-filecachestats', self._refreshfilecachestats)
2497 tr.addpostclose(b'refresh-filecachestats', self._refreshfilecachestats)
2490 self._transref = weakref.ref(tr)
2498 self._transref = weakref.ref(tr)
2491 scmutil.registersummarycallback(self, tr, desc)
2499 scmutil.registersummarycallback(self, tr, desc)
2492 return tr
2500 return tr
2493
2501
2494 def _journalfiles(self):
2502 def _journalfiles(self):
2495 return (
2503 return (
2496 (self.svfs, b'journal'),
2504 (self.svfs, b'journal'),
2497 (self.svfs, b'journal.narrowspec'),
2505 (self.svfs, b'journal.narrowspec'),
2498 (self.vfs, b'journal.narrowspec.dirstate'),
2506 (self.vfs, b'journal.narrowspec.dirstate'),
2499 (self.vfs, b'journal.dirstate'),
2507 (self.vfs, b'journal.dirstate'),
2500 (self.vfs, b'journal.branch'),
2508 (self.vfs, b'journal.branch'),
2501 (self.vfs, b'journal.desc'),
2509 (self.vfs, b'journal.desc'),
2502 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2510 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2503 (self.svfs, b'journal.phaseroots'),
2511 (self.svfs, b'journal.phaseroots'),
2504 )
2512 )
2505
2513
2506 def undofiles(self):
2514 def undofiles(self):
2507 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
2515 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
2508
2516
2509 @unfilteredmethod
2517 @unfilteredmethod
2510 def _writejournal(self, desc):
2518 def _writejournal(self, desc):
2511 self.dirstate.savebackup(None, b'journal.dirstate')
2519 self.dirstate.savebackup(None, b'journal.dirstate')
2512 narrowspec.savewcbackup(self, b'journal.narrowspec.dirstate')
2520 narrowspec.savewcbackup(self, b'journal.narrowspec.dirstate')
2513 narrowspec.savebackup(self, b'journal.narrowspec')
2521 narrowspec.savebackup(self, b'journal.narrowspec')
2514 self.vfs.write(
2522 self.vfs.write(
2515 b"journal.branch", encoding.fromlocal(self.dirstate.branch())
2523 b"journal.branch", encoding.fromlocal(self.dirstate.branch())
2516 )
2524 )
2517 self.vfs.write(b"journal.desc", b"%d\n%s\n" % (len(self), desc))
2525 self.vfs.write(b"journal.desc", b"%d\n%s\n" % (len(self), desc))
2518 bookmarksvfs = bookmarks.bookmarksvfs(self)
2526 bookmarksvfs = bookmarks.bookmarksvfs(self)
2519 bookmarksvfs.write(
2527 bookmarksvfs.write(
2520 b"journal.bookmarks", bookmarksvfs.tryread(b"bookmarks")
2528 b"journal.bookmarks", bookmarksvfs.tryread(b"bookmarks")
2521 )
2529 )
2522 self.svfs.write(b"journal.phaseroots", self.svfs.tryread(b"phaseroots"))
2530 self.svfs.write(b"journal.phaseroots", self.svfs.tryread(b"phaseroots"))
2523
2531
2524 def recover(self):
2532 def recover(self):
2525 with self.lock():
2533 with self.lock():
2526 if self.svfs.exists(b"journal"):
2534 if self.svfs.exists(b"journal"):
2527 self.ui.status(_(b"rolling back interrupted transaction\n"))
2535 self.ui.status(_(b"rolling back interrupted transaction\n"))
2528 vfsmap = {
2536 vfsmap = {
2529 b'': self.svfs,
2537 b'': self.svfs,
2530 b'plain': self.vfs,
2538 b'plain': self.vfs,
2531 }
2539 }
2532 transaction.rollback(
2540 transaction.rollback(
2533 self.svfs,
2541 self.svfs,
2534 vfsmap,
2542 vfsmap,
2535 b"journal",
2543 b"journal",
2536 self.ui.warn,
2544 self.ui.warn,
2537 checkambigfiles=_cachedfiles,
2545 checkambigfiles=_cachedfiles,
2538 )
2546 )
2539 self.invalidate()
2547 self.invalidate()
2540 return True
2548 return True
2541 else:
2549 else:
2542 self.ui.warn(_(b"no interrupted transaction available\n"))
2550 self.ui.warn(_(b"no interrupted transaction available\n"))
2543 return False
2551 return False
2544
2552
2545 def rollback(self, dryrun=False, force=False):
2553 def rollback(self, dryrun=False, force=False):
2546 wlock = lock = dsguard = None
2554 wlock = lock = dsguard = None
2547 try:
2555 try:
2548 wlock = self.wlock()
2556 wlock = self.wlock()
2549 lock = self.lock()
2557 lock = self.lock()
2550 if self.svfs.exists(b"undo"):
2558 if self.svfs.exists(b"undo"):
2551 dsguard = dirstateguard.dirstateguard(self, b'rollback')
2559 dsguard = dirstateguard.dirstateguard(self, b'rollback')
2552
2560
2553 return self._rollback(dryrun, force, dsguard)
2561 return self._rollback(dryrun, force, dsguard)
2554 else:
2562 else:
2555 self.ui.warn(_(b"no rollback information available\n"))
2563 self.ui.warn(_(b"no rollback information available\n"))
2556 return 1
2564 return 1
2557 finally:
2565 finally:
2558 release(dsguard, lock, wlock)
2566 release(dsguard, lock, wlock)
2559
2567
2560 @unfilteredmethod # Until we get smarter cache management
2568 @unfilteredmethod # Until we get smarter cache management
2561 def _rollback(self, dryrun, force, dsguard):
2569 def _rollback(self, dryrun, force, dsguard):
2562 ui = self.ui
2570 ui = self.ui
2563 try:
2571 try:
2564 args = self.vfs.read(b'undo.desc').splitlines()
2572 args = self.vfs.read(b'undo.desc').splitlines()
2565 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2573 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2566 if len(args) >= 3:
2574 if len(args) >= 3:
2567 detail = args[2]
2575 detail = args[2]
2568 oldtip = oldlen - 1
2576 oldtip = oldlen - 1
2569
2577
2570 if detail and ui.verbose:
2578 if detail and ui.verbose:
2571 msg = _(
2579 msg = _(
2572 b'repository tip rolled back to revision %d'
2580 b'repository tip rolled back to revision %d'
2573 b' (undo %s: %s)\n'
2581 b' (undo %s: %s)\n'
2574 ) % (oldtip, desc, detail)
2582 ) % (oldtip, desc, detail)
2575 else:
2583 else:
2576 msg = _(
2584 msg = _(
2577 b'repository tip rolled back to revision %d (undo %s)\n'
2585 b'repository tip rolled back to revision %d (undo %s)\n'
2578 ) % (oldtip, desc)
2586 ) % (oldtip, desc)
2579 except IOError:
2587 except IOError:
2580 msg = _(b'rolling back unknown transaction\n')
2588 msg = _(b'rolling back unknown transaction\n')
2581 desc = None
2589 desc = None
2582
2590
2583 if not force and self[b'.'] != self[b'tip'] and desc == b'commit':
2591 if not force and self[b'.'] != self[b'tip'] and desc == b'commit':
2584 raise error.Abort(
2592 raise error.Abort(
2585 _(
2593 _(
2586 b'rollback of last commit while not checked out '
2594 b'rollback of last commit while not checked out '
2587 b'may lose data'
2595 b'may lose data'
2588 ),
2596 ),
2589 hint=_(b'use -f to force'),
2597 hint=_(b'use -f to force'),
2590 )
2598 )
2591
2599
2592 ui.status(msg)
2600 ui.status(msg)
2593 if dryrun:
2601 if dryrun:
2594 return 0
2602 return 0
2595
2603
2596 parents = self.dirstate.parents()
2604 parents = self.dirstate.parents()
2597 self.destroying()
2605 self.destroying()
2598 vfsmap = {b'plain': self.vfs, b'': self.svfs}
2606 vfsmap = {b'plain': self.vfs, b'': self.svfs}
2599 transaction.rollback(
2607 transaction.rollback(
2600 self.svfs, vfsmap, b'undo', ui.warn, checkambigfiles=_cachedfiles
2608 self.svfs, vfsmap, b'undo', ui.warn, checkambigfiles=_cachedfiles
2601 )
2609 )
2602 bookmarksvfs = bookmarks.bookmarksvfs(self)
2610 bookmarksvfs = bookmarks.bookmarksvfs(self)
2603 if bookmarksvfs.exists(b'undo.bookmarks'):
2611 if bookmarksvfs.exists(b'undo.bookmarks'):
2604 bookmarksvfs.rename(
2612 bookmarksvfs.rename(
2605 b'undo.bookmarks', b'bookmarks', checkambig=True
2613 b'undo.bookmarks', b'bookmarks', checkambig=True
2606 )
2614 )
2607 if self.svfs.exists(b'undo.phaseroots'):
2615 if self.svfs.exists(b'undo.phaseroots'):
2608 self.svfs.rename(b'undo.phaseroots', b'phaseroots', checkambig=True)
2616 self.svfs.rename(b'undo.phaseroots', b'phaseroots', checkambig=True)
2609 self.invalidate()
2617 self.invalidate()
2610
2618
2611 has_node = self.changelog.index.has_node
2619 has_node = self.changelog.index.has_node
2612 parentgone = any(not has_node(p) for p in parents)
2620 parentgone = any(not has_node(p) for p in parents)
2613 if parentgone:
2621 if parentgone:
2614 # prevent dirstateguard from overwriting already restored one
2622 # prevent dirstateguard from overwriting already restored one
2615 dsguard.close()
2623 dsguard.close()
2616
2624
2617 narrowspec.restorebackup(self, b'undo.narrowspec')
2625 narrowspec.restorebackup(self, b'undo.narrowspec')
2618 narrowspec.restorewcbackup(self, b'undo.narrowspec.dirstate')
2626 narrowspec.restorewcbackup(self, b'undo.narrowspec.dirstate')
2619 self.dirstate.restorebackup(None, b'undo.dirstate')
2627 self.dirstate.restorebackup(None, b'undo.dirstate')
2620 try:
2628 try:
2621 branch = self.vfs.read(b'undo.branch')
2629 branch = self.vfs.read(b'undo.branch')
2622 self.dirstate.setbranch(encoding.tolocal(branch))
2630 self.dirstate.setbranch(encoding.tolocal(branch))
2623 except IOError:
2631 except IOError:
2624 ui.warn(
2632 ui.warn(
2625 _(
2633 _(
2626 b'named branch could not be reset: '
2634 b'named branch could not be reset: '
2627 b'current branch is still \'%s\'\n'
2635 b'current branch is still \'%s\'\n'
2628 )
2636 )
2629 % self.dirstate.branch()
2637 % self.dirstate.branch()
2630 )
2638 )
2631
2639
2632 parents = tuple([p.rev() for p in self[None].parents()])
2640 parents = tuple([p.rev() for p in self[None].parents()])
2633 if len(parents) > 1:
2641 if len(parents) > 1:
2634 ui.status(
2642 ui.status(
2635 _(
2643 _(
2636 b'working directory now based on '
2644 b'working directory now based on '
2637 b'revisions %d and %d\n'
2645 b'revisions %d and %d\n'
2638 )
2646 )
2639 % parents
2647 % parents
2640 )
2648 )
2641 else:
2649 else:
2642 ui.status(
2650 ui.status(
2643 _(b'working directory now based on revision %d\n') % parents
2651 _(b'working directory now based on revision %d\n') % parents
2644 )
2652 )
2645 mergestatemod.mergestate.clean(self)
2653 mergestatemod.mergestate.clean(self)
2646
2654
2647 # TODO: if we know which new heads may result from this rollback, pass
2655 # TODO: if we know which new heads may result from this rollback, pass
2648 # them to destroy(), which will prevent the branchhead cache from being
2656 # them to destroy(), which will prevent the branchhead cache from being
2649 # invalidated.
2657 # invalidated.
2650 self.destroyed()
2658 self.destroyed()
2651 return 0
2659 return 0
2652
2660
2653 def _buildcacheupdater(self, newtransaction):
2661 def _buildcacheupdater(self, newtransaction):
2654 """called during transaction to build the callback updating cache
2662 """called during transaction to build the callback updating cache
2655
2663
2656 Lives on the repository to help extension who might want to augment
2664 Lives on the repository to help extension who might want to augment
2657 this logic. For this purpose, the created transaction is passed to the
2665 this logic. For this purpose, the created transaction is passed to the
2658 method.
2666 method.
2659 """
2667 """
2660 # we must avoid cyclic reference between repo and transaction.
2668 # we must avoid cyclic reference between repo and transaction.
2661 reporef = weakref.ref(self)
2669 reporef = weakref.ref(self)
2662
2670
2663 def updater(tr):
2671 def updater(tr):
2664 repo = reporef()
2672 repo = reporef()
2665 repo.updatecaches(tr)
2673 repo.updatecaches(tr)
2666
2674
2667 return updater
2675 return updater
2668
2676
2669 @unfilteredmethod
2677 @unfilteredmethod
2670 def updatecaches(self, tr=None, full=False):
2678 def updatecaches(self, tr=None, full=False):
2671 """warm appropriate caches
2679 """warm appropriate caches
2672
2680
2673 If this function is called after a transaction closed. The transaction
2681 If this function is called after a transaction closed. The transaction
2674 will be available in the 'tr' argument. This can be used to selectively
2682 will be available in the 'tr' argument. This can be used to selectively
2675 update caches relevant to the changes in that transaction.
2683 update caches relevant to the changes in that transaction.
2676
2684
2677 If 'full' is set, make sure all caches the function knows about have
2685 If 'full' is set, make sure all caches the function knows about have
2678 up-to-date data. Even the ones usually loaded more lazily.
2686 up-to-date data. Even the ones usually loaded more lazily.
2679 """
2687 """
2680 if tr is not None and tr.hookargs.get(b'source') == b'strip':
2688 if tr is not None and tr.hookargs.get(b'source') == b'strip':
2681 # During strip, many caches are invalid but
2689 # During strip, many caches are invalid but
2682 # later call to `destroyed` will refresh them.
2690 # later call to `destroyed` will refresh them.
2683 return
2691 return
2684
2692
2685 if tr is None or tr.changes[b'origrepolen'] < len(self):
2693 if tr is None or tr.changes[b'origrepolen'] < len(self):
2686 # accessing the 'served' branchmap should refresh all the others,
2694 # accessing the 'served' branchmap should refresh all the others,
2687 self.ui.debug(b'updating the branch cache\n')
2695 self.ui.debug(b'updating the branch cache\n')
2688 self.filtered(b'served').branchmap()
2696 self.filtered(b'served').branchmap()
2689 self.filtered(b'served.hidden').branchmap()
2697 self.filtered(b'served.hidden').branchmap()
2690
2698
2691 if full:
2699 if full:
2692 unfi = self.unfiltered()
2700 unfi = self.unfiltered()
2693
2701
2694 self.changelog.update_caches(transaction=tr)
2702 self.changelog.update_caches(transaction=tr)
2695 self.manifestlog.update_caches(transaction=tr)
2703 self.manifestlog.update_caches(transaction=tr)
2696
2704
2697 rbc = unfi.revbranchcache()
2705 rbc = unfi.revbranchcache()
2698 for r in unfi.changelog:
2706 for r in unfi.changelog:
2699 rbc.branchinfo(r)
2707 rbc.branchinfo(r)
2700 rbc.write()
2708 rbc.write()
2701
2709
2702 # ensure the working copy parents are in the manifestfulltextcache
2710 # ensure the working copy parents are in the manifestfulltextcache
2703 for ctx in self[b'.'].parents():
2711 for ctx in self[b'.'].parents():
2704 ctx.manifest() # accessing the manifest is enough
2712 ctx.manifest() # accessing the manifest is enough
2705
2713
2706 # accessing fnode cache warms the cache
2714 # accessing fnode cache warms the cache
2707 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2715 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2708 # accessing tags warm the cache
2716 # accessing tags warm the cache
2709 self.tags()
2717 self.tags()
2710 self.filtered(b'served').tags()
2718 self.filtered(b'served').tags()
2711
2719
2712 # The `full` arg is documented as updating even the lazily-loaded
2720 # The `full` arg is documented as updating even the lazily-loaded
2713 # caches immediately, so we're forcing a write to cause these caches
2721 # caches immediately, so we're forcing a write to cause these caches
2714 # to be warmed up even if they haven't explicitly been requested
2722 # to be warmed up even if they haven't explicitly been requested
2715 # yet (if they've never been used by hg, they won't ever have been
2723 # yet (if they've never been used by hg, they won't ever have been
2716 # written, even if they're a subset of another kind of cache that
2724 # written, even if they're a subset of another kind of cache that
2717 # *has* been used).
2725 # *has* been used).
2718 for filt in repoview.filtertable.keys():
2726 for filt in repoview.filtertable.keys():
2719 filtered = self.filtered(filt)
2727 filtered = self.filtered(filt)
2720 filtered.branchmap().write(filtered)
2728 filtered.branchmap().write(filtered)
2721
2729
2722 def invalidatecaches(self):
2730 def invalidatecaches(self):
2723
2731
2724 if '_tagscache' in vars(self):
2732 if '_tagscache' in vars(self):
2725 # can't use delattr on proxy
2733 # can't use delattr on proxy
2726 del self.__dict__['_tagscache']
2734 del self.__dict__['_tagscache']
2727
2735
2728 self._branchcaches.clear()
2736 self._branchcaches.clear()
2729 self.invalidatevolatilesets()
2737 self.invalidatevolatilesets()
2730 self._sparsesignaturecache.clear()
2738 self._sparsesignaturecache.clear()
2731
2739
2732 def invalidatevolatilesets(self):
2740 def invalidatevolatilesets(self):
2733 self.filteredrevcache.clear()
2741 self.filteredrevcache.clear()
2734 obsolete.clearobscaches(self)
2742 obsolete.clearobscaches(self)
2735 self._quick_access_changeid_invalidate()
2743 self._quick_access_changeid_invalidate()
2736
2744
2737 def invalidatedirstate(self):
2745 def invalidatedirstate(self):
2738 """Invalidates the dirstate, causing the next call to dirstate
2746 """Invalidates the dirstate, causing the next call to dirstate
2739 to check if it was modified since the last time it was read,
2747 to check if it was modified since the last time it was read,
2740 rereading it if it has.
2748 rereading it if it has.
2741
2749
2742 This is different to dirstate.invalidate() that it doesn't always
2750 This is different to dirstate.invalidate() that it doesn't always
2743 rereads the dirstate. Use dirstate.invalidate() if you want to
2751 rereads the dirstate. Use dirstate.invalidate() if you want to
2744 explicitly read the dirstate again (i.e. restoring it to a previous
2752 explicitly read the dirstate again (i.e. restoring it to a previous
2745 known good state)."""
2753 known good state)."""
2746 if hasunfilteredcache(self, 'dirstate'):
2754 if hasunfilteredcache(self, 'dirstate'):
2747 for k in self.dirstate._filecache:
2755 for k in self.dirstate._filecache:
2748 try:
2756 try:
2749 delattr(self.dirstate, k)
2757 delattr(self.dirstate, k)
2750 except AttributeError:
2758 except AttributeError:
2751 pass
2759 pass
2752 delattr(self.unfiltered(), 'dirstate')
2760 delattr(self.unfiltered(), 'dirstate')
2753
2761
2754 def invalidate(self, clearfilecache=False):
2762 def invalidate(self, clearfilecache=False):
2755 """Invalidates both store and non-store parts other than dirstate
2763 """Invalidates both store and non-store parts other than dirstate
2756
2764
2757 If a transaction is running, invalidation of store is omitted,
2765 If a transaction is running, invalidation of store is omitted,
2758 because discarding in-memory changes might cause inconsistency
2766 because discarding in-memory changes might cause inconsistency
2759 (e.g. incomplete fncache causes unintentional failure, but
2767 (e.g. incomplete fncache causes unintentional failure, but
2760 redundant one doesn't).
2768 redundant one doesn't).
2761 """
2769 """
2762 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2770 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2763 for k in list(self._filecache.keys()):
2771 for k in list(self._filecache.keys()):
2764 # dirstate is invalidated separately in invalidatedirstate()
2772 # dirstate is invalidated separately in invalidatedirstate()
2765 if k == b'dirstate':
2773 if k == b'dirstate':
2766 continue
2774 continue
2767 if (
2775 if (
2768 k == b'changelog'
2776 k == b'changelog'
2769 and self.currenttransaction()
2777 and self.currenttransaction()
2770 and self.changelog._delayed
2778 and self.changelog._delayed
2771 ):
2779 ):
2772 # The changelog object may store unwritten revisions. We don't
2780 # The changelog object may store unwritten revisions. We don't
2773 # want to lose them.
2781 # want to lose them.
2774 # TODO: Solve the problem instead of working around it.
2782 # TODO: Solve the problem instead of working around it.
2775 continue
2783 continue
2776
2784
2777 if clearfilecache:
2785 if clearfilecache:
2778 del self._filecache[k]
2786 del self._filecache[k]
2779 try:
2787 try:
2780 delattr(unfiltered, k)
2788 delattr(unfiltered, k)
2781 except AttributeError:
2789 except AttributeError:
2782 pass
2790 pass
2783 self.invalidatecaches()
2791 self.invalidatecaches()
2784 if not self.currenttransaction():
2792 if not self.currenttransaction():
2785 # TODO: Changing contents of store outside transaction
2793 # TODO: Changing contents of store outside transaction
2786 # causes inconsistency. We should make in-memory store
2794 # causes inconsistency. We should make in-memory store
2787 # changes detectable, and abort if changed.
2795 # changes detectable, and abort if changed.
2788 self.store.invalidatecaches()
2796 self.store.invalidatecaches()
2789
2797
2790 def invalidateall(self):
2798 def invalidateall(self):
2791 """Fully invalidates both store and non-store parts, causing the
2799 """Fully invalidates both store and non-store parts, causing the
2792 subsequent operation to reread any outside changes."""
2800 subsequent operation to reread any outside changes."""
2793 # extension should hook this to invalidate its caches
2801 # extension should hook this to invalidate its caches
2794 self.invalidate()
2802 self.invalidate()
2795 self.invalidatedirstate()
2803 self.invalidatedirstate()
2796
2804
2797 @unfilteredmethod
2805 @unfilteredmethod
2798 def _refreshfilecachestats(self, tr):
2806 def _refreshfilecachestats(self, tr):
2799 """Reload stats of cached files so that they are flagged as valid"""
2807 """Reload stats of cached files so that they are flagged as valid"""
2800 for k, ce in self._filecache.items():
2808 for k, ce in self._filecache.items():
2801 k = pycompat.sysstr(k)
2809 k = pycompat.sysstr(k)
2802 if k == 'dirstate' or k not in self.__dict__:
2810 if k == 'dirstate' or k not in self.__dict__:
2803 continue
2811 continue
2804 ce.refresh()
2812 ce.refresh()
2805
2813
2806 def _lock(
2814 def _lock(
2807 self,
2815 self,
2808 vfs,
2816 vfs,
2809 lockname,
2817 lockname,
2810 wait,
2818 wait,
2811 releasefn,
2819 releasefn,
2812 acquirefn,
2820 acquirefn,
2813 desc,
2821 desc,
2814 ):
2822 ):
2815 timeout = 0
2823 timeout = 0
2816 warntimeout = 0
2824 warntimeout = 0
2817 if wait:
2825 if wait:
2818 timeout = self.ui.configint(b"ui", b"timeout")
2826 timeout = self.ui.configint(b"ui", b"timeout")
2819 warntimeout = self.ui.configint(b"ui", b"timeout.warn")
2827 warntimeout = self.ui.configint(b"ui", b"timeout.warn")
2820 # internal config: ui.signal-safe-lock
2828 # internal config: ui.signal-safe-lock
2821 signalsafe = self.ui.configbool(b'ui', b'signal-safe-lock')
2829 signalsafe = self.ui.configbool(b'ui', b'signal-safe-lock')
2822
2830
2823 l = lockmod.trylock(
2831 l = lockmod.trylock(
2824 self.ui,
2832 self.ui,
2825 vfs,
2833 vfs,
2826 lockname,
2834 lockname,
2827 timeout,
2835 timeout,
2828 warntimeout,
2836 warntimeout,
2829 releasefn=releasefn,
2837 releasefn=releasefn,
2830 acquirefn=acquirefn,
2838 acquirefn=acquirefn,
2831 desc=desc,
2839 desc=desc,
2832 signalsafe=signalsafe,
2840 signalsafe=signalsafe,
2833 )
2841 )
2834 return l
2842 return l
2835
2843
2836 def _afterlock(self, callback):
2844 def _afterlock(self, callback):
2837 """add a callback to be run when the repository is fully unlocked
2845 """add a callback to be run when the repository is fully unlocked
2838
2846
2839 The callback will be executed when the outermost lock is released
2847 The callback will be executed when the outermost lock is released
2840 (with wlock being higher level than 'lock')."""
2848 (with wlock being higher level than 'lock')."""
2841 for ref in (self._wlockref, self._lockref):
2849 for ref in (self._wlockref, self._lockref):
2842 l = ref and ref()
2850 l = ref and ref()
2843 if l and l.held:
2851 if l and l.held:
2844 l.postrelease.append(callback)
2852 l.postrelease.append(callback)
2845 break
2853 break
2846 else: # no lock have been found.
2854 else: # no lock have been found.
2847 callback(True)
2855 callback(True)
2848
2856
2849 def lock(self, wait=True):
2857 def lock(self, wait=True):
2850 """Lock the repository store (.hg/store) and return a weak reference
2858 """Lock the repository store (.hg/store) and return a weak reference
2851 to the lock. Use this before modifying the store (e.g. committing or
2859 to the lock. Use this before modifying the store (e.g. committing or
2852 stripping). If you are opening a transaction, get a lock as well.)
2860 stripping). If you are opening a transaction, get a lock as well.)
2853
2861
2854 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2862 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2855 'wlock' first to avoid a dead-lock hazard."""
2863 'wlock' first to avoid a dead-lock hazard."""
2856 l = self._currentlock(self._lockref)
2864 l = self._currentlock(self._lockref)
2857 if l is not None:
2865 if l is not None:
2858 l.lock()
2866 l.lock()
2859 return l
2867 return l
2860
2868
2861 l = self._lock(
2869 l = self._lock(
2862 vfs=self.svfs,
2870 vfs=self.svfs,
2863 lockname=b"lock",
2871 lockname=b"lock",
2864 wait=wait,
2872 wait=wait,
2865 releasefn=None,
2873 releasefn=None,
2866 acquirefn=self.invalidate,
2874 acquirefn=self.invalidate,
2867 desc=_(b'repository %s') % self.origroot,
2875 desc=_(b'repository %s') % self.origroot,
2868 )
2876 )
2869 self._lockref = weakref.ref(l)
2877 self._lockref = weakref.ref(l)
2870 return l
2878 return l
2871
2879
2872 def wlock(self, wait=True):
2880 def wlock(self, wait=True):
2873 """Lock the non-store parts of the repository (everything under
2881 """Lock the non-store parts of the repository (everything under
2874 .hg except .hg/store) and return a weak reference to the lock.
2882 .hg except .hg/store) and return a weak reference to the lock.
2875
2883
2876 Use this before modifying files in .hg.
2884 Use this before modifying files in .hg.
2877
2885
2878 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2886 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2879 'wlock' first to avoid a dead-lock hazard."""
2887 'wlock' first to avoid a dead-lock hazard."""
2880 l = self._wlockref and self._wlockref()
2888 l = self._wlockref and self._wlockref()
2881 if l is not None and l.held:
2889 if l is not None and l.held:
2882 l.lock()
2890 l.lock()
2883 return l
2891 return l
2884
2892
2885 # We do not need to check for non-waiting lock acquisition. Such
2893 # We do not need to check for non-waiting lock acquisition. Such
2886 # acquisition would not cause dead-lock as they would just fail.
2894 # acquisition would not cause dead-lock as they would just fail.
2887 if wait and (
2895 if wait and (
2888 self.ui.configbool(b'devel', b'all-warnings')
2896 self.ui.configbool(b'devel', b'all-warnings')
2889 or self.ui.configbool(b'devel', b'check-locks')
2897 or self.ui.configbool(b'devel', b'check-locks')
2890 ):
2898 ):
2891 if self._currentlock(self._lockref) is not None:
2899 if self._currentlock(self._lockref) is not None:
2892 self.ui.develwarn(b'"wlock" acquired after "lock"')
2900 self.ui.develwarn(b'"wlock" acquired after "lock"')
2893
2901
2894 def unlock():
2902 def unlock():
2895 if self.dirstate.pendingparentchange():
2903 if self.dirstate.pendingparentchange():
2896 self.dirstate.invalidate()
2904 self.dirstate.invalidate()
2897 else:
2905 else:
2898 self.dirstate.write(None)
2906 self.dirstate.write(None)
2899
2907
2900 self._filecache[b'dirstate'].refresh()
2908 self._filecache[b'dirstate'].refresh()
2901
2909
2902 l = self._lock(
2910 l = self._lock(
2903 self.vfs,
2911 self.vfs,
2904 b"wlock",
2912 b"wlock",
2905 wait,
2913 wait,
2906 unlock,
2914 unlock,
2907 self.invalidatedirstate,
2915 self.invalidatedirstate,
2908 _(b'working directory of %s') % self.origroot,
2916 _(b'working directory of %s') % self.origroot,
2909 )
2917 )
2910 self._wlockref = weakref.ref(l)
2918 self._wlockref = weakref.ref(l)
2911 return l
2919 return l
2912
2920
2913 def _currentlock(self, lockref):
2921 def _currentlock(self, lockref):
2914 """Returns the lock if it's held, or None if it's not."""
2922 """Returns the lock if it's held, or None if it's not."""
2915 if lockref is None:
2923 if lockref is None:
2916 return None
2924 return None
2917 l = lockref()
2925 l = lockref()
2918 if l is None or not l.held:
2926 if l is None or not l.held:
2919 return None
2927 return None
2920 return l
2928 return l
2921
2929
2922 def currentwlock(self):
2930 def currentwlock(self):
2923 """Returns the wlock if it's held, or None if it's not."""
2931 """Returns the wlock if it's held, or None if it's not."""
2924 return self._currentlock(self._wlockref)
2932 return self._currentlock(self._wlockref)
2925
2933
2926 def checkcommitpatterns(self, wctx, match, status, fail):
2934 def checkcommitpatterns(self, wctx, match, status, fail):
2927 """check for commit arguments that aren't committable"""
2935 """check for commit arguments that aren't committable"""
2928 if match.isexact() or match.prefix():
2936 if match.isexact() or match.prefix():
2929 matched = set(status.modified + status.added + status.removed)
2937 matched = set(status.modified + status.added + status.removed)
2930
2938
2931 for f in match.files():
2939 for f in match.files():
2932 f = self.dirstate.normalize(f)
2940 f = self.dirstate.normalize(f)
2933 if f == b'.' or f in matched or f in wctx.substate:
2941 if f == b'.' or f in matched or f in wctx.substate:
2934 continue
2942 continue
2935 if f in status.deleted:
2943 if f in status.deleted:
2936 fail(f, _(b'file not found!'))
2944 fail(f, _(b'file not found!'))
2937 # Is it a directory that exists or used to exist?
2945 # Is it a directory that exists or used to exist?
2938 if self.wvfs.isdir(f) or wctx.p1().hasdir(f):
2946 if self.wvfs.isdir(f) or wctx.p1().hasdir(f):
2939 d = f + b'/'
2947 d = f + b'/'
2940 for mf in matched:
2948 for mf in matched:
2941 if mf.startswith(d):
2949 if mf.startswith(d):
2942 break
2950 break
2943 else:
2951 else:
2944 fail(f, _(b"no match under directory!"))
2952 fail(f, _(b"no match under directory!"))
2945 elif f not in self.dirstate:
2953 elif f not in self.dirstate:
2946 fail(f, _(b"file not tracked!"))
2954 fail(f, _(b"file not tracked!"))
2947
2955
2948 @unfilteredmethod
2956 @unfilteredmethod
2949 def commit(
2957 def commit(
2950 self,
2958 self,
2951 text=b"",
2959 text=b"",
2952 user=None,
2960 user=None,
2953 date=None,
2961 date=None,
2954 match=None,
2962 match=None,
2955 force=False,
2963 force=False,
2956 editor=None,
2964 editor=None,
2957 extra=None,
2965 extra=None,
2958 ):
2966 ):
2959 """Add a new revision to current repository.
2967 """Add a new revision to current repository.
2960
2968
2961 Revision information is gathered from the working directory,
2969 Revision information is gathered from the working directory,
2962 match can be used to filter the committed files. If editor is
2970 match can be used to filter the committed files. If editor is
2963 supplied, it is called to get a commit message.
2971 supplied, it is called to get a commit message.
2964 """
2972 """
2965 if extra is None:
2973 if extra is None:
2966 extra = {}
2974 extra = {}
2967
2975
2968 def fail(f, msg):
2976 def fail(f, msg):
2969 raise error.InputError(b'%s: %s' % (f, msg))
2977 raise error.InputError(b'%s: %s' % (f, msg))
2970
2978
2971 if not match:
2979 if not match:
2972 match = matchmod.always()
2980 match = matchmod.always()
2973
2981
2974 if not force:
2982 if not force:
2975 match.bad = fail
2983 match.bad = fail
2976
2984
2977 # lock() for recent changelog (see issue4368)
2985 # lock() for recent changelog (see issue4368)
2978 with self.wlock(), self.lock():
2986 with self.wlock(), self.lock():
2979 wctx = self[None]
2987 wctx = self[None]
2980 merge = len(wctx.parents()) > 1
2988 merge = len(wctx.parents()) > 1
2981
2989
2982 if not force and merge and not match.always():
2990 if not force and merge and not match.always():
2983 raise error.Abort(
2991 raise error.Abort(
2984 _(
2992 _(
2985 b'cannot partially commit a merge '
2993 b'cannot partially commit a merge '
2986 b'(do not specify files or patterns)'
2994 b'(do not specify files or patterns)'
2987 )
2995 )
2988 )
2996 )
2989
2997
2990 status = self.status(match=match, clean=force)
2998 status = self.status(match=match, clean=force)
2991 if force:
2999 if force:
2992 status.modified.extend(
3000 status.modified.extend(
2993 status.clean
3001 status.clean
2994 ) # mq may commit clean files
3002 ) # mq may commit clean files
2995
3003
2996 # check subrepos
3004 # check subrepos
2997 subs, commitsubs, newstate = subrepoutil.precommit(
3005 subs, commitsubs, newstate = subrepoutil.precommit(
2998 self.ui, wctx, status, match, force=force
3006 self.ui, wctx, status, match, force=force
2999 )
3007 )
3000
3008
3001 # make sure all explicit patterns are matched
3009 # make sure all explicit patterns are matched
3002 if not force:
3010 if not force:
3003 self.checkcommitpatterns(wctx, match, status, fail)
3011 self.checkcommitpatterns(wctx, match, status, fail)
3004
3012
3005 cctx = context.workingcommitctx(
3013 cctx = context.workingcommitctx(
3006 self, status, text, user, date, extra
3014 self, status, text, user, date, extra
3007 )
3015 )
3008
3016
3009 ms = mergestatemod.mergestate.read(self)
3017 ms = mergestatemod.mergestate.read(self)
3010 mergeutil.checkunresolved(ms)
3018 mergeutil.checkunresolved(ms)
3011
3019
3012 # internal config: ui.allowemptycommit
3020 # internal config: ui.allowemptycommit
3013 if cctx.isempty() and not self.ui.configbool(
3021 if cctx.isempty() and not self.ui.configbool(
3014 b'ui', b'allowemptycommit'
3022 b'ui', b'allowemptycommit'
3015 ):
3023 ):
3016 self.ui.debug(b'nothing to commit, clearing merge state\n')
3024 self.ui.debug(b'nothing to commit, clearing merge state\n')
3017 ms.reset()
3025 ms.reset()
3018 return None
3026 return None
3019
3027
3020 if merge and cctx.deleted():
3028 if merge and cctx.deleted():
3021 raise error.Abort(_(b"cannot commit merge with missing files"))
3029 raise error.Abort(_(b"cannot commit merge with missing files"))
3022
3030
3023 if editor:
3031 if editor:
3024 cctx._text = editor(self, cctx, subs)
3032 cctx._text = editor(self, cctx, subs)
3025 edited = text != cctx._text
3033 edited = text != cctx._text
3026
3034
3027 # Save commit message in case this transaction gets rolled back
3035 # Save commit message in case this transaction gets rolled back
3028 # (e.g. by a pretxncommit hook). Leave the content alone on
3036 # (e.g. by a pretxncommit hook). Leave the content alone on
3029 # the assumption that the user will use the same editor again.
3037 # the assumption that the user will use the same editor again.
3030 msgfn = self.savecommitmessage(cctx._text)
3038 msgfn = self.savecommitmessage(cctx._text)
3031
3039
3032 # commit subs and write new state
3040 # commit subs and write new state
3033 if subs:
3041 if subs:
3034 uipathfn = scmutil.getuipathfn(self)
3042 uipathfn = scmutil.getuipathfn(self)
3035 for s in sorted(commitsubs):
3043 for s in sorted(commitsubs):
3036 sub = wctx.sub(s)
3044 sub = wctx.sub(s)
3037 self.ui.status(
3045 self.ui.status(
3038 _(b'committing subrepository %s\n')
3046 _(b'committing subrepository %s\n')
3039 % uipathfn(subrepoutil.subrelpath(sub))
3047 % uipathfn(subrepoutil.subrelpath(sub))
3040 )
3048 )
3041 sr = sub.commit(cctx._text, user, date)
3049 sr = sub.commit(cctx._text, user, date)
3042 newstate[s] = (newstate[s][0], sr)
3050 newstate[s] = (newstate[s][0], sr)
3043 subrepoutil.writestate(self, newstate)
3051 subrepoutil.writestate(self, newstate)
3044
3052
3045 p1, p2 = self.dirstate.parents()
3053 p1, p2 = self.dirstate.parents()
3046 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or b'')
3054 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or b'')
3047 try:
3055 try:
3048 self.hook(
3056 self.hook(
3049 b"precommit", throw=True, parent1=hookp1, parent2=hookp2
3057 b"precommit", throw=True, parent1=hookp1, parent2=hookp2
3050 )
3058 )
3051 with self.transaction(b'commit'):
3059 with self.transaction(b'commit'):
3052 ret = self.commitctx(cctx, True)
3060 ret = self.commitctx(cctx, True)
3053 # update bookmarks, dirstate and mergestate
3061 # update bookmarks, dirstate and mergestate
3054 bookmarks.update(self, [p1, p2], ret)
3062 bookmarks.update(self, [p1, p2], ret)
3055 cctx.markcommitted(ret)
3063 cctx.markcommitted(ret)
3056 ms.reset()
3064 ms.reset()
3057 except: # re-raises
3065 except: # re-raises
3058 if edited:
3066 if edited:
3059 self.ui.write(
3067 self.ui.write(
3060 _(b'note: commit message saved in %s\n') % msgfn
3068 _(b'note: commit message saved in %s\n') % msgfn
3061 )
3069 )
3062 self.ui.write(
3070 self.ui.write(
3063 _(
3071 _(
3064 b"note: use 'hg commit --logfile "
3072 b"note: use 'hg commit --logfile "
3065 b".hg/last-message.txt --edit' to reuse it\n"
3073 b".hg/last-message.txt --edit' to reuse it\n"
3066 )
3074 )
3067 )
3075 )
3068 raise
3076 raise
3069
3077
3070 def commithook(unused_success):
3078 def commithook(unused_success):
3071 # hack for command that use a temporary commit (eg: histedit)
3079 # hack for command that use a temporary commit (eg: histedit)
3072 # temporary commit got stripped before hook release
3080 # temporary commit got stripped before hook release
3073 if self.changelog.hasnode(ret):
3081 if self.changelog.hasnode(ret):
3074 self.hook(
3082 self.hook(
3075 b"commit", node=hex(ret), parent1=hookp1, parent2=hookp2
3083 b"commit", node=hex(ret), parent1=hookp1, parent2=hookp2
3076 )
3084 )
3077
3085
3078 self._afterlock(commithook)
3086 self._afterlock(commithook)
3079 return ret
3087 return ret
3080
3088
3081 @unfilteredmethod
3089 @unfilteredmethod
3082 def commitctx(self, ctx, error=False, origctx=None):
3090 def commitctx(self, ctx, error=False, origctx=None):
3083 return commit.commitctx(self, ctx, error=error, origctx=origctx)
3091 return commit.commitctx(self, ctx, error=error, origctx=origctx)
3084
3092
3085 @unfilteredmethod
3093 @unfilteredmethod
3086 def destroying(self):
3094 def destroying(self):
3087 """Inform the repository that nodes are about to be destroyed.
3095 """Inform the repository that nodes are about to be destroyed.
3088 Intended for use by strip and rollback, so there's a common
3096 Intended for use by strip and rollback, so there's a common
3089 place for anything that has to be done before destroying history.
3097 place for anything that has to be done before destroying history.
3090
3098
3091 This is mostly useful for saving state that is in memory and waiting
3099 This is mostly useful for saving state that is in memory and waiting
3092 to be flushed when the current lock is released. Because a call to
3100 to be flushed when the current lock is released. Because a call to
3093 destroyed is imminent, the repo will be invalidated causing those
3101 destroyed is imminent, the repo will be invalidated causing those
3094 changes to stay in memory (waiting for the next unlock), or vanish
3102 changes to stay in memory (waiting for the next unlock), or vanish
3095 completely.
3103 completely.
3096 """
3104 """
3097 # When using the same lock to commit and strip, the phasecache is left
3105 # When using the same lock to commit and strip, the phasecache is left
3098 # dirty after committing. Then when we strip, the repo is invalidated,
3106 # dirty after committing. Then when we strip, the repo is invalidated,
3099 # causing those changes to disappear.
3107 # causing those changes to disappear.
3100 if '_phasecache' in vars(self):
3108 if '_phasecache' in vars(self):
3101 self._phasecache.write()
3109 self._phasecache.write()
3102
3110
3103 @unfilteredmethod
3111 @unfilteredmethod
3104 def destroyed(self):
3112 def destroyed(self):
3105 """Inform the repository that nodes have been destroyed.
3113 """Inform the repository that nodes have been destroyed.
3106 Intended for use by strip and rollback, so there's a common
3114 Intended for use by strip and rollback, so there's a common
3107 place for anything that has to be done after destroying history.
3115 place for anything that has to be done after destroying history.
3108 """
3116 """
3109 # When one tries to:
3117 # When one tries to:
3110 # 1) destroy nodes thus calling this method (e.g. strip)
3118 # 1) destroy nodes thus calling this method (e.g. strip)
3111 # 2) use phasecache somewhere (e.g. commit)
3119 # 2) use phasecache somewhere (e.g. commit)
3112 #
3120 #
3113 # then 2) will fail because the phasecache contains nodes that were
3121 # then 2) will fail because the phasecache contains nodes that were
3114 # removed. We can either remove phasecache from the filecache,
3122 # removed. We can either remove phasecache from the filecache,
3115 # causing it to reload next time it is accessed, or simply filter
3123 # causing it to reload next time it is accessed, or simply filter
3116 # the removed nodes now and write the updated cache.
3124 # the removed nodes now and write the updated cache.
3117 self._phasecache.filterunknown(self)
3125 self._phasecache.filterunknown(self)
3118 self._phasecache.write()
3126 self._phasecache.write()
3119
3127
3120 # refresh all repository caches
3128 # refresh all repository caches
3121 self.updatecaches()
3129 self.updatecaches()
3122
3130
3123 # Ensure the persistent tag cache is updated. Doing it now
3131 # Ensure the persistent tag cache is updated. Doing it now
3124 # means that the tag cache only has to worry about destroyed
3132 # means that the tag cache only has to worry about destroyed
3125 # heads immediately after a strip/rollback. That in turn
3133 # heads immediately after a strip/rollback. That in turn
3126 # guarantees that "cachetip == currenttip" (comparing both rev
3134 # guarantees that "cachetip == currenttip" (comparing both rev
3127 # and node) always means no nodes have been added or destroyed.
3135 # and node) always means no nodes have been added or destroyed.
3128
3136
3129 # XXX this is suboptimal when qrefresh'ing: we strip the current
3137 # XXX this is suboptimal when qrefresh'ing: we strip the current
3130 # head, refresh the tag cache, then immediately add a new head.
3138 # head, refresh the tag cache, then immediately add a new head.
3131 # But I think doing it this way is necessary for the "instant
3139 # But I think doing it this way is necessary for the "instant
3132 # tag cache retrieval" case to work.
3140 # tag cache retrieval" case to work.
3133 self.invalidate()
3141 self.invalidate()
3134
3142
3135 def status(
3143 def status(
3136 self,
3144 self,
3137 node1=b'.',
3145 node1=b'.',
3138 node2=None,
3146 node2=None,
3139 match=None,
3147 match=None,
3140 ignored=False,
3148 ignored=False,
3141 clean=False,
3149 clean=False,
3142 unknown=False,
3150 unknown=False,
3143 listsubrepos=False,
3151 listsubrepos=False,
3144 ):
3152 ):
3145 '''a convenience method that calls node1.status(node2)'''
3153 '''a convenience method that calls node1.status(node2)'''
3146 return self[node1].status(
3154 return self[node1].status(
3147 node2, match, ignored, clean, unknown, listsubrepos
3155 node2, match, ignored, clean, unknown, listsubrepos
3148 )
3156 )
3149
3157
3150 def addpostdsstatus(self, ps):
3158 def addpostdsstatus(self, ps):
3151 """Add a callback to run within the wlock, at the point at which status
3159 """Add a callback to run within the wlock, at the point at which status
3152 fixups happen.
3160 fixups happen.
3153
3161
3154 On status completion, callback(wctx, status) will be called with the
3162 On status completion, callback(wctx, status) will be called with the
3155 wlock held, unless the dirstate has changed from underneath or the wlock
3163 wlock held, unless the dirstate has changed from underneath or the wlock
3156 couldn't be grabbed.
3164 couldn't be grabbed.
3157
3165
3158 Callbacks should not capture and use a cached copy of the dirstate --
3166 Callbacks should not capture and use a cached copy of the dirstate --
3159 it might change in the meanwhile. Instead, they should access the
3167 it might change in the meanwhile. Instead, they should access the
3160 dirstate via wctx.repo().dirstate.
3168 dirstate via wctx.repo().dirstate.
3161
3169
3162 This list is emptied out after each status run -- extensions should
3170 This list is emptied out after each status run -- extensions should
3163 make sure it adds to this list each time dirstate.status is called.
3171 make sure it adds to this list each time dirstate.status is called.
3164 Extensions should also make sure they don't call this for statuses
3172 Extensions should also make sure they don't call this for statuses
3165 that don't involve the dirstate.
3173 that don't involve the dirstate.
3166 """
3174 """
3167
3175
3168 # The list is located here for uniqueness reasons -- it is actually
3176 # The list is located here for uniqueness reasons -- it is actually
3169 # managed by the workingctx, but that isn't unique per-repo.
3177 # managed by the workingctx, but that isn't unique per-repo.
3170 self._postdsstatus.append(ps)
3178 self._postdsstatus.append(ps)
3171
3179
3172 def postdsstatus(self):
3180 def postdsstatus(self):
3173 """Used by workingctx to get the list of post-dirstate-status hooks."""
3181 """Used by workingctx to get the list of post-dirstate-status hooks."""
3174 return self._postdsstatus
3182 return self._postdsstatus
3175
3183
3176 def clearpostdsstatus(self):
3184 def clearpostdsstatus(self):
3177 """Used by workingctx to clear post-dirstate-status hooks."""
3185 """Used by workingctx to clear post-dirstate-status hooks."""
3178 del self._postdsstatus[:]
3186 del self._postdsstatus[:]
3179
3187
3180 def heads(self, start=None):
3188 def heads(self, start=None):
3181 if start is None:
3189 if start is None:
3182 cl = self.changelog
3190 cl = self.changelog
3183 headrevs = reversed(cl.headrevs())
3191 headrevs = reversed(cl.headrevs())
3184 return [cl.node(rev) for rev in headrevs]
3192 return [cl.node(rev) for rev in headrevs]
3185
3193
3186 heads = self.changelog.heads(start)
3194 heads = self.changelog.heads(start)
3187 # sort the output in rev descending order
3195 # sort the output in rev descending order
3188 return sorted(heads, key=self.changelog.rev, reverse=True)
3196 return sorted(heads, key=self.changelog.rev, reverse=True)
3189
3197
3190 def branchheads(self, branch=None, start=None, closed=False):
3198 def branchheads(self, branch=None, start=None, closed=False):
3191 """return a (possibly filtered) list of heads for the given branch
3199 """return a (possibly filtered) list of heads for the given branch
3192
3200
3193 Heads are returned in topological order, from newest to oldest.
3201 Heads are returned in topological order, from newest to oldest.
3194 If branch is None, use the dirstate branch.
3202 If branch is None, use the dirstate branch.
3195 If start is not None, return only heads reachable from start.
3203 If start is not None, return only heads reachable from start.
3196 If closed is True, return heads that are marked as closed as well.
3204 If closed is True, return heads that are marked as closed as well.
3197 """
3205 """
3198 if branch is None:
3206 if branch is None:
3199 branch = self[None].branch()
3207 branch = self[None].branch()
3200 branches = self.branchmap()
3208 branches = self.branchmap()
3201 if not branches.hasbranch(branch):
3209 if not branches.hasbranch(branch):
3202 return []
3210 return []
3203 # the cache returns heads ordered lowest to highest
3211 # the cache returns heads ordered lowest to highest
3204 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
3212 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
3205 if start is not None:
3213 if start is not None:
3206 # filter out the heads that cannot be reached from startrev
3214 # filter out the heads that cannot be reached from startrev
3207 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
3215 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
3208 bheads = [h for h in bheads if h in fbheads]
3216 bheads = [h for h in bheads if h in fbheads]
3209 return bheads
3217 return bheads
3210
3218
3211 def branches(self, nodes):
3219 def branches(self, nodes):
3212 if not nodes:
3220 if not nodes:
3213 nodes = [self.changelog.tip()]
3221 nodes = [self.changelog.tip()]
3214 b = []
3222 b = []
3215 for n in nodes:
3223 for n in nodes:
3216 t = n
3224 t = n
3217 while True:
3225 while True:
3218 p = self.changelog.parents(n)
3226 p = self.changelog.parents(n)
3219 if p[1] != nullid or p[0] == nullid:
3227 if p[1] != nullid or p[0] == nullid:
3220 b.append((t, n, p[0], p[1]))
3228 b.append((t, n, p[0], p[1]))
3221 break
3229 break
3222 n = p[0]
3230 n = p[0]
3223 return b
3231 return b
3224
3232
3225 def between(self, pairs):
3233 def between(self, pairs):
3226 r = []
3234 r = []
3227
3235
3228 for top, bottom in pairs:
3236 for top, bottom in pairs:
3229 n, l, i = top, [], 0
3237 n, l, i = top, [], 0
3230 f = 1
3238 f = 1
3231
3239
3232 while n != bottom and n != nullid:
3240 while n != bottom and n != nullid:
3233 p = self.changelog.parents(n)[0]
3241 p = self.changelog.parents(n)[0]
3234 if i == f:
3242 if i == f:
3235 l.append(n)
3243 l.append(n)
3236 f = f * 2
3244 f = f * 2
3237 n = p
3245 n = p
3238 i += 1
3246 i += 1
3239
3247
3240 r.append(l)
3248 r.append(l)
3241
3249
3242 return r
3250 return r
3243
3251
3244 def checkpush(self, pushop):
3252 def checkpush(self, pushop):
3245 """Extensions can override this function if additional checks have
3253 """Extensions can override this function if additional checks have
3246 to be performed before pushing, or call it if they override push
3254 to be performed before pushing, or call it if they override push
3247 command.
3255 command.
3248 """
3256 """
3249
3257
3250 @unfilteredpropertycache
3258 @unfilteredpropertycache
3251 def prepushoutgoinghooks(self):
3259 def prepushoutgoinghooks(self):
3252 """Return util.hooks consists of a pushop with repo, remote, outgoing
3260 """Return util.hooks consists of a pushop with repo, remote, outgoing
3253 methods, which are called before pushing changesets.
3261 methods, which are called before pushing changesets.
3254 """
3262 """
3255 return util.hooks()
3263 return util.hooks()
3256
3264
3257 def pushkey(self, namespace, key, old, new):
3265 def pushkey(self, namespace, key, old, new):
3258 try:
3266 try:
3259 tr = self.currenttransaction()
3267 tr = self.currenttransaction()
3260 hookargs = {}
3268 hookargs = {}
3261 if tr is not None:
3269 if tr is not None:
3262 hookargs.update(tr.hookargs)
3270 hookargs.update(tr.hookargs)
3263 hookargs = pycompat.strkwargs(hookargs)
3271 hookargs = pycompat.strkwargs(hookargs)
3264 hookargs['namespace'] = namespace
3272 hookargs['namespace'] = namespace
3265 hookargs['key'] = key
3273 hookargs['key'] = key
3266 hookargs['old'] = old
3274 hookargs['old'] = old
3267 hookargs['new'] = new
3275 hookargs['new'] = new
3268 self.hook(b'prepushkey', throw=True, **hookargs)
3276 self.hook(b'prepushkey', throw=True, **hookargs)
3269 except error.HookAbort as exc:
3277 except error.HookAbort as exc:
3270 self.ui.write_err(_(b"pushkey-abort: %s\n") % exc)
3278 self.ui.write_err(_(b"pushkey-abort: %s\n") % exc)
3271 if exc.hint:
3279 if exc.hint:
3272 self.ui.write_err(_(b"(%s)\n") % exc.hint)
3280 self.ui.write_err(_(b"(%s)\n") % exc.hint)
3273 return False
3281 return False
3274 self.ui.debug(b'pushing key for "%s:%s"\n' % (namespace, key))
3282 self.ui.debug(b'pushing key for "%s:%s"\n' % (namespace, key))
3275 ret = pushkey.push(self, namespace, key, old, new)
3283 ret = pushkey.push(self, namespace, key, old, new)
3276
3284
3277 def runhook(unused_success):
3285 def runhook(unused_success):
3278 self.hook(
3286 self.hook(
3279 b'pushkey',
3287 b'pushkey',
3280 namespace=namespace,
3288 namespace=namespace,
3281 key=key,
3289 key=key,
3282 old=old,
3290 old=old,
3283 new=new,
3291 new=new,
3284 ret=ret,
3292 ret=ret,
3285 )
3293 )
3286
3294
3287 self._afterlock(runhook)
3295 self._afterlock(runhook)
3288 return ret
3296 return ret
3289
3297
3290 def listkeys(self, namespace):
3298 def listkeys(self, namespace):
3291 self.hook(b'prelistkeys', throw=True, namespace=namespace)
3299 self.hook(b'prelistkeys', throw=True, namespace=namespace)
3292 self.ui.debug(b'listing keys for "%s"\n' % namespace)
3300 self.ui.debug(b'listing keys for "%s"\n' % namespace)
3293 values = pushkey.list(self, namespace)
3301 values = pushkey.list(self, namespace)
3294 self.hook(b'listkeys', namespace=namespace, values=values)
3302 self.hook(b'listkeys', namespace=namespace, values=values)
3295 return values
3303 return values
3296
3304
3297 def debugwireargs(self, one, two, three=None, four=None, five=None):
3305 def debugwireargs(self, one, two, three=None, four=None, five=None):
3298 '''used to test argument passing over the wire'''
3306 '''used to test argument passing over the wire'''
3299 return b"%s %s %s %s %s" % (
3307 return b"%s %s %s %s %s" % (
3300 one,
3308 one,
3301 two,
3309 two,
3302 pycompat.bytestr(three),
3310 pycompat.bytestr(three),
3303 pycompat.bytestr(four),
3311 pycompat.bytestr(four),
3304 pycompat.bytestr(five),
3312 pycompat.bytestr(five),
3305 )
3313 )
3306
3314
3307 def savecommitmessage(self, text):
3315 def savecommitmessage(self, text):
3308 fp = self.vfs(b'last-message.txt', b'wb')
3316 fp = self.vfs(b'last-message.txt', b'wb')
3309 try:
3317 try:
3310 fp.write(text)
3318 fp.write(text)
3311 finally:
3319 finally:
3312 fp.close()
3320 fp.close()
3313 return self.pathto(fp.name[len(self.root) + 1 :])
3321 return self.pathto(fp.name[len(self.root) + 1 :])
3314
3322
3315
3323
3316 # used to avoid circular references so destructors work
3324 # used to avoid circular references so destructors work
3317 def aftertrans(files):
3325 def aftertrans(files):
3318 renamefiles = [tuple(t) for t in files]
3326 renamefiles = [tuple(t) for t in files]
3319
3327
3320 def a():
3328 def a():
3321 for vfs, src, dest in renamefiles:
3329 for vfs, src, dest in renamefiles:
3322 # if src and dest refer to a same file, vfs.rename is a no-op,
3330 # if src and dest refer to a same file, vfs.rename is a no-op,
3323 # leaving both src and dest on disk. delete dest to make sure
3331 # leaving both src and dest on disk. delete dest to make sure
3324 # the rename couldn't be such a no-op.
3332 # the rename couldn't be such a no-op.
3325 vfs.tryunlink(dest)
3333 vfs.tryunlink(dest)
3326 try:
3334 try:
3327 vfs.rename(src, dest)
3335 vfs.rename(src, dest)
3328 except OSError: # journal file does not yet exist
3336 except OSError: # journal file does not yet exist
3329 pass
3337 pass
3330
3338
3331 return a
3339 return a
3332
3340
3333
3341
3334 def undoname(fn):
3342 def undoname(fn):
3335 base, name = os.path.split(fn)
3343 base, name = os.path.split(fn)
3336 assert name.startswith(b'journal')
3344 assert name.startswith(b'journal')
3337 return os.path.join(base, name.replace(b'journal', b'undo', 1))
3345 return os.path.join(base, name.replace(b'journal', b'undo', 1))
3338
3346
3339
3347
3340 def instance(ui, path, create, intents=None, createopts=None):
3348 def instance(ui, path, create, intents=None, createopts=None):
3341 localpath = util.urllocalpath(path)
3349 localpath = util.urllocalpath(path)
3342 if create:
3350 if create:
3343 createrepository(ui, localpath, createopts=createopts)
3351 createrepository(ui, localpath, createopts=createopts)
3344
3352
3345 return makelocalrepository(ui, localpath, intents=intents)
3353 return makelocalrepository(ui, localpath, intents=intents)
3346
3354
3347
3355
3348 def islocal(path):
3356 def islocal(path):
3349 return True
3357 return True
3350
3358
3351
3359
3352 def defaultcreateopts(ui, createopts=None):
3360 def defaultcreateopts(ui, createopts=None):
3353 """Populate the default creation options for a repository.
3361 """Populate the default creation options for a repository.
3354
3362
3355 A dictionary of explicitly requested creation options can be passed
3363 A dictionary of explicitly requested creation options can be passed
3356 in. Missing keys will be populated.
3364 in. Missing keys will be populated.
3357 """
3365 """
3358 createopts = dict(createopts or {})
3366 createopts = dict(createopts or {})
3359
3367
3360 if b'backend' not in createopts:
3368 if b'backend' not in createopts:
3361 # experimental config: storage.new-repo-backend
3369 # experimental config: storage.new-repo-backend
3362 createopts[b'backend'] = ui.config(b'storage', b'new-repo-backend')
3370 createopts[b'backend'] = ui.config(b'storage', b'new-repo-backend')
3363
3371
3364 return createopts
3372 return createopts
3365
3373
3366
3374
3367 def newreporequirements(ui, createopts):
3375 def newreporequirements(ui, createopts):
3368 """Determine the set of requirements for a new local repository.
3376 """Determine the set of requirements for a new local repository.
3369
3377
3370 Extensions can wrap this function to specify custom requirements for
3378 Extensions can wrap this function to specify custom requirements for
3371 new repositories.
3379 new repositories.
3372 """
3380 """
3373 # If the repo is being created from a shared repository, we copy
3381 # If the repo is being created from a shared repository, we copy
3374 # its requirements.
3382 # its requirements.
3375 if b'sharedrepo' in createopts:
3383 if b'sharedrepo' in createopts:
3376 requirements = set(createopts[b'sharedrepo'].requirements)
3384 requirements = set(createopts[b'sharedrepo'].requirements)
3377 if createopts.get(b'sharedrelative'):
3385 if createopts.get(b'sharedrelative'):
3378 requirements.add(requirementsmod.RELATIVE_SHARED_REQUIREMENT)
3386 requirements.add(requirementsmod.RELATIVE_SHARED_REQUIREMENT)
3379 else:
3387 else:
3380 requirements.add(requirementsmod.SHARED_REQUIREMENT)
3388 requirements.add(requirementsmod.SHARED_REQUIREMENT)
3381
3389
3382 return requirements
3390 return requirements
3383
3391
3384 if b'backend' not in createopts:
3392 if b'backend' not in createopts:
3385 raise error.ProgrammingError(
3393 raise error.ProgrammingError(
3386 b'backend key not present in createopts; '
3394 b'backend key not present in createopts; '
3387 b'was defaultcreateopts() called?'
3395 b'was defaultcreateopts() called?'
3388 )
3396 )
3389
3397
3390 if createopts[b'backend'] != b'revlogv1':
3398 if createopts[b'backend'] != b'revlogv1':
3391 raise error.Abort(
3399 raise error.Abort(
3392 _(
3400 _(
3393 b'unable to determine repository requirements for '
3401 b'unable to determine repository requirements for '
3394 b'storage backend: %s'
3402 b'storage backend: %s'
3395 )
3403 )
3396 % createopts[b'backend']
3404 % createopts[b'backend']
3397 )
3405 )
3398
3406
3399 requirements = {b'revlogv1'}
3407 requirements = {b'revlogv1'}
3400 if ui.configbool(b'format', b'usestore'):
3408 if ui.configbool(b'format', b'usestore'):
3401 requirements.add(b'store')
3409 requirements.add(b'store')
3402 if ui.configbool(b'format', b'usefncache'):
3410 if ui.configbool(b'format', b'usefncache'):
3403 requirements.add(b'fncache')
3411 requirements.add(b'fncache')
3404 if ui.configbool(b'format', b'dotencode'):
3412 if ui.configbool(b'format', b'dotencode'):
3405 requirements.add(b'dotencode')
3413 requirements.add(b'dotencode')
3406
3414
3407 compengines = ui.configlist(b'format', b'revlog-compression')
3415 compengines = ui.configlist(b'format', b'revlog-compression')
3408 for compengine in compengines:
3416 for compengine in compengines:
3409 if compengine in util.compengines:
3417 if compengine in util.compengines:
3410 break
3418 break
3411 else:
3419 else:
3412 raise error.Abort(
3420 raise error.Abort(
3413 _(
3421 _(
3414 b'compression engines %s defined by '
3422 b'compression engines %s defined by '
3415 b'format.revlog-compression not available'
3423 b'format.revlog-compression not available'
3416 )
3424 )
3417 % b', '.join(b'"%s"' % e for e in compengines),
3425 % b', '.join(b'"%s"' % e for e in compengines),
3418 hint=_(
3426 hint=_(
3419 b'run "hg debuginstall" to list available '
3427 b'run "hg debuginstall" to list available '
3420 b'compression engines'
3428 b'compression engines'
3421 ),
3429 ),
3422 )
3430 )
3423
3431
3424 # zlib is the historical default and doesn't need an explicit requirement.
3432 # zlib is the historical default and doesn't need an explicit requirement.
3425 if compengine == b'zstd':
3433 if compengine == b'zstd':
3426 requirements.add(b'revlog-compression-zstd')
3434 requirements.add(b'revlog-compression-zstd')
3427 elif compengine != b'zlib':
3435 elif compengine != b'zlib':
3428 requirements.add(b'exp-compression-%s' % compengine)
3436 requirements.add(b'exp-compression-%s' % compengine)
3429
3437
3430 if scmutil.gdinitconfig(ui):
3438 if scmutil.gdinitconfig(ui):
3431 requirements.add(b'generaldelta')
3439 requirements.add(b'generaldelta')
3432 if ui.configbool(b'format', b'sparse-revlog'):
3440 if ui.configbool(b'format', b'sparse-revlog'):
3433 requirements.add(requirementsmod.SPARSEREVLOG_REQUIREMENT)
3441 requirements.add(requirementsmod.SPARSEREVLOG_REQUIREMENT)
3434
3442
3435 # experimental config: format.exp-use-side-data
3443 # experimental config: format.exp-use-side-data
3436 if ui.configbool(b'format', b'exp-use-side-data'):
3444 if ui.configbool(b'format', b'exp-use-side-data'):
3437 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3445 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3438 # experimental config: format.exp-use-copies-side-data-changeset
3446 # experimental config: format.exp-use-copies-side-data-changeset
3439 if ui.configbool(b'format', b'exp-use-copies-side-data-changeset'):
3447 if ui.configbool(b'format', b'exp-use-copies-side-data-changeset'):
3440 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3448 requirements.add(requirementsmod.SIDEDATA_REQUIREMENT)
3441 requirements.add(requirementsmod.COPIESSDC_REQUIREMENT)
3449 requirements.add(requirementsmod.COPIESSDC_REQUIREMENT)
3442 if ui.configbool(b'experimental', b'treemanifest'):
3450 if ui.configbool(b'experimental', b'treemanifest'):
3443 requirements.add(requirementsmod.TREEMANIFEST_REQUIREMENT)
3451 requirements.add(requirementsmod.TREEMANIFEST_REQUIREMENT)
3444
3452
3445 revlogv2 = ui.config(b'experimental', b'revlogv2')
3453 revlogv2 = ui.config(b'experimental', b'revlogv2')
3446 if revlogv2 == b'enable-unstable-format-and-corrupt-my-data':
3454 if revlogv2 == b'enable-unstable-format-and-corrupt-my-data':
3447 requirements.remove(b'revlogv1')
3455 requirements.remove(b'revlogv1')
3448 # generaldelta is implied by revlogv2.
3456 # generaldelta is implied by revlogv2.
3449 requirements.discard(b'generaldelta')
3457 requirements.discard(b'generaldelta')
3450 requirements.add(requirementsmod.REVLOGV2_REQUIREMENT)
3458 requirements.add(requirementsmod.REVLOGV2_REQUIREMENT)
3451 # experimental config: format.internal-phase
3459 # experimental config: format.internal-phase
3452 if ui.configbool(b'format', b'internal-phase'):
3460 if ui.configbool(b'format', b'internal-phase'):
3453 requirements.add(requirementsmod.INTERNAL_PHASE_REQUIREMENT)
3461 requirements.add(requirementsmod.INTERNAL_PHASE_REQUIREMENT)
3454
3462
3455 if createopts.get(b'narrowfiles'):
3463 if createopts.get(b'narrowfiles'):
3456 requirements.add(requirementsmod.NARROW_REQUIREMENT)
3464 requirements.add(requirementsmod.NARROW_REQUIREMENT)
3457
3465
3458 if createopts.get(b'lfs'):
3466 if createopts.get(b'lfs'):
3459 requirements.add(b'lfs')
3467 requirements.add(b'lfs')
3460
3468
3461 if ui.configbool(b'format', b'bookmarks-in-store'):
3469 if ui.configbool(b'format', b'bookmarks-in-store'):
3462 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3470 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3463
3471
3464 if ui.configbool(b'format', b'use-persistent-nodemap'):
3472 if ui.configbool(b'format', b'use-persistent-nodemap'):
3465 requirements.add(requirementsmod.NODEMAP_REQUIREMENT)
3473 requirements.add(requirementsmod.NODEMAP_REQUIREMENT)
3466
3474
3467 # if share-safe is enabled, let's create the new repository with the new
3475 # if share-safe is enabled, let's create the new repository with the new
3468 # requirement
3476 # requirement
3469 if ui.configbool(b'format', b'exp-share-safe'):
3477 if ui.configbool(b'format', b'exp-share-safe'):
3470 requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
3478 requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
3471
3479
3472 return requirements
3480 return requirements
3473
3481
3474
3482
3475 def checkrequirementscompat(ui, requirements):
3483 def checkrequirementscompat(ui, requirements):
3476 """Checks compatibility of repository requirements enabled and disabled.
3484 """Checks compatibility of repository requirements enabled and disabled.
3477
3485
3478 Returns a set of requirements which needs to be dropped because dependend
3486 Returns a set of requirements which needs to be dropped because dependend
3479 requirements are not enabled. Also warns users about it"""
3487 requirements are not enabled. Also warns users about it"""
3480
3488
3481 dropped = set()
3489 dropped = set()
3482
3490
3483 if b'store' not in requirements:
3491 if b'store' not in requirements:
3484 if bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT in requirements:
3492 if bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT in requirements:
3485 ui.warn(
3493 ui.warn(
3486 _(
3494 _(
3487 b'ignoring enabled \'format.bookmarks-in-store\' config '
3495 b'ignoring enabled \'format.bookmarks-in-store\' config '
3488 b'beacuse it is incompatible with disabled '
3496 b'beacuse it is incompatible with disabled '
3489 b'\'format.usestore\' config\n'
3497 b'\'format.usestore\' config\n'
3490 )
3498 )
3491 )
3499 )
3492 dropped.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3500 dropped.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3493
3501
3494 if (
3502 if (
3495 requirementsmod.SHARED_REQUIREMENT in requirements
3503 requirementsmod.SHARED_REQUIREMENT in requirements
3496 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
3504 or requirementsmod.RELATIVE_SHARED_REQUIREMENT in requirements
3497 ):
3505 ):
3498 raise error.Abort(
3506 raise error.Abort(
3499 _(
3507 _(
3500 b"cannot create shared repository as source was created"
3508 b"cannot create shared repository as source was created"
3501 b" with 'format.usestore' config disabled"
3509 b" with 'format.usestore' config disabled"
3502 )
3510 )
3503 )
3511 )
3504
3512
3505 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
3513 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
3506 ui.warn(
3514 ui.warn(
3507 _(
3515 _(
3508 b"ignoring enabled 'format.exp-share-safe' config because "
3516 b"ignoring enabled 'format.exp-share-safe' config because "
3509 b"it is incompatible with disabled 'format.usestore'"
3517 b"it is incompatible with disabled 'format.usestore'"
3510 b" config\n"
3518 b" config\n"
3511 )
3519 )
3512 )
3520 )
3513 dropped.add(requirementsmod.SHARESAFE_REQUIREMENT)
3521 dropped.add(requirementsmod.SHARESAFE_REQUIREMENT)
3514
3522
3515 return dropped
3523 return dropped
3516
3524
3517
3525
3518 def filterknowncreateopts(ui, createopts):
3526 def filterknowncreateopts(ui, createopts):
3519 """Filters a dict of repo creation options against options that are known.
3527 """Filters a dict of repo creation options against options that are known.
3520
3528
3521 Receives a dict of repo creation options and returns a dict of those
3529 Receives a dict of repo creation options and returns a dict of those
3522 options that we don't know how to handle.
3530 options that we don't know how to handle.
3523
3531
3524 This function is called as part of repository creation. If the
3532 This function is called as part of repository creation. If the
3525 returned dict contains any items, repository creation will not
3533 returned dict contains any items, repository creation will not
3526 be allowed, as it means there was a request to create a repository
3534 be allowed, as it means there was a request to create a repository
3527 with options not recognized by loaded code.
3535 with options not recognized by loaded code.
3528
3536
3529 Extensions can wrap this function to filter out creation options
3537 Extensions can wrap this function to filter out creation options
3530 they know how to handle.
3538 they know how to handle.
3531 """
3539 """
3532 known = {
3540 known = {
3533 b'backend',
3541 b'backend',
3534 b'lfs',
3542 b'lfs',
3535 b'narrowfiles',
3543 b'narrowfiles',
3536 b'sharedrepo',
3544 b'sharedrepo',
3537 b'sharedrelative',
3545 b'sharedrelative',
3538 b'shareditems',
3546 b'shareditems',
3539 b'shallowfilestore',
3547 b'shallowfilestore',
3540 }
3548 }
3541
3549
3542 return {k: v for k, v in createopts.items() if k not in known}
3550 return {k: v for k, v in createopts.items() if k not in known}
3543
3551
3544
3552
3545 def createrepository(ui, path, createopts=None):
3553 def createrepository(ui, path, createopts=None):
3546 """Create a new repository in a vfs.
3554 """Create a new repository in a vfs.
3547
3555
3548 ``path`` path to the new repo's working directory.
3556 ``path`` path to the new repo's working directory.
3549 ``createopts`` options for the new repository.
3557 ``createopts`` options for the new repository.
3550
3558
3551 The following keys for ``createopts`` are recognized:
3559 The following keys for ``createopts`` are recognized:
3552
3560
3553 backend
3561 backend
3554 The storage backend to use.
3562 The storage backend to use.
3555 lfs
3563 lfs
3556 Repository will be created with ``lfs`` requirement. The lfs extension
3564 Repository will be created with ``lfs`` requirement. The lfs extension
3557 will automatically be loaded when the repository is accessed.
3565 will automatically be loaded when the repository is accessed.
3558 narrowfiles
3566 narrowfiles
3559 Set up repository to support narrow file storage.
3567 Set up repository to support narrow file storage.
3560 sharedrepo
3568 sharedrepo
3561 Repository object from which storage should be shared.
3569 Repository object from which storage should be shared.
3562 sharedrelative
3570 sharedrelative
3563 Boolean indicating if the path to the shared repo should be
3571 Boolean indicating if the path to the shared repo should be
3564 stored as relative. By default, the pointer to the "parent" repo
3572 stored as relative. By default, the pointer to the "parent" repo
3565 is stored as an absolute path.
3573 is stored as an absolute path.
3566 shareditems
3574 shareditems
3567 Set of items to share to the new repository (in addition to storage).
3575 Set of items to share to the new repository (in addition to storage).
3568 shallowfilestore
3576 shallowfilestore
3569 Indicates that storage for files should be shallow (not all ancestor
3577 Indicates that storage for files should be shallow (not all ancestor
3570 revisions are known).
3578 revisions are known).
3571 """
3579 """
3572 createopts = defaultcreateopts(ui, createopts=createopts)
3580 createopts = defaultcreateopts(ui, createopts=createopts)
3573
3581
3574 unknownopts = filterknowncreateopts(ui, createopts)
3582 unknownopts = filterknowncreateopts(ui, createopts)
3575
3583
3576 if not isinstance(unknownopts, dict):
3584 if not isinstance(unknownopts, dict):
3577 raise error.ProgrammingError(
3585 raise error.ProgrammingError(
3578 b'filterknowncreateopts() did not return a dict'
3586 b'filterknowncreateopts() did not return a dict'
3579 )
3587 )
3580
3588
3581 if unknownopts:
3589 if unknownopts:
3582 raise error.Abort(
3590 raise error.Abort(
3583 _(
3591 _(
3584 b'unable to create repository because of unknown '
3592 b'unable to create repository because of unknown '
3585 b'creation option: %s'
3593 b'creation option: %s'
3586 )
3594 )
3587 % b', '.join(sorted(unknownopts)),
3595 % b', '.join(sorted(unknownopts)),
3588 hint=_(b'is a required extension not loaded?'),
3596 hint=_(b'is a required extension not loaded?'),
3589 )
3597 )
3590
3598
3591 requirements = newreporequirements(ui, createopts=createopts)
3599 requirements = newreporequirements(ui, createopts=createopts)
3592 requirements -= checkrequirementscompat(ui, requirements)
3600 requirements -= checkrequirementscompat(ui, requirements)
3593
3601
3594 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3602 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3595
3603
3596 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3604 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3597 if hgvfs.exists():
3605 if hgvfs.exists():
3598 raise error.RepoError(_(b'repository %s already exists') % path)
3606 raise error.RepoError(_(b'repository %s already exists') % path)
3599
3607
3600 if b'sharedrepo' in createopts:
3608 if b'sharedrepo' in createopts:
3601 sharedpath = createopts[b'sharedrepo'].sharedpath
3609 sharedpath = createopts[b'sharedrepo'].sharedpath
3602
3610
3603 if createopts.get(b'sharedrelative'):
3611 if createopts.get(b'sharedrelative'):
3604 try:
3612 try:
3605 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3613 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3606 except (IOError, ValueError) as e:
3614 except (IOError, ValueError) as e:
3607 # ValueError is raised on Windows if the drive letters differ
3615 # ValueError is raised on Windows if the drive letters differ
3608 # on each path.
3616 # on each path.
3609 raise error.Abort(
3617 raise error.Abort(
3610 _(b'cannot calculate relative path'),
3618 _(b'cannot calculate relative path'),
3611 hint=stringutil.forcebytestr(e),
3619 hint=stringutil.forcebytestr(e),
3612 )
3620 )
3613
3621
3614 if not wdirvfs.exists():
3622 if not wdirvfs.exists():
3615 wdirvfs.makedirs()
3623 wdirvfs.makedirs()
3616
3624
3617 hgvfs.makedir(notindexed=True)
3625 hgvfs.makedir(notindexed=True)
3618 if b'sharedrepo' not in createopts:
3626 if b'sharedrepo' not in createopts:
3619 hgvfs.mkdir(b'cache')
3627 hgvfs.mkdir(b'cache')
3620 hgvfs.mkdir(b'wcache')
3628 hgvfs.mkdir(b'wcache')
3621
3629
3622 if b'store' in requirements and b'sharedrepo' not in createopts:
3630 if b'store' in requirements and b'sharedrepo' not in createopts:
3623 hgvfs.mkdir(b'store')
3631 hgvfs.mkdir(b'store')
3624
3632
3625 # We create an invalid changelog outside the store so very old
3633 # We create an invalid changelog outside the store so very old
3626 # Mercurial versions (which didn't know about the requirements
3634 # Mercurial versions (which didn't know about the requirements
3627 # file) encounter an error on reading the changelog. This
3635 # file) encounter an error on reading the changelog. This
3628 # effectively locks out old clients and prevents them from
3636 # effectively locks out old clients and prevents them from
3629 # mucking with a repo in an unknown format.
3637 # mucking with a repo in an unknown format.
3630 #
3638 #
3631 # The revlog header has version 2, which won't be recognized by
3639 # The revlog header has version 2, which won't be recognized by
3632 # such old clients.
3640 # such old clients.
3633 hgvfs.append(
3641 hgvfs.append(
3634 b'00changelog.i',
3642 b'00changelog.i',
3635 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3643 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3636 b'layout',
3644 b'layout',
3637 )
3645 )
3638
3646
3639 # Filter the requirements into working copy and store ones
3647 # Filter the requirements into working copy and store ones
3640 wcreq, storereq = scmutil.filterrequirements(requirements)
3648 wcreq, storereq = scmutil.filterrequirements(requirements)
3641 # write working copy ones
3649 # write working copy ones
3642 scmutil.writerequires(hgvfs, wcreq)
3650 scmutil.writerequires(hgvfs, wcreq)
3643 # If there are store requirements and the current repository
3651 # If there are store requirements and the current repository
3644 # is not a shared one, write stored requirements
3652 # is not a shared one, write stored requirements
3645 # For new shared repository, we don't need to write the store
3653 # For new shared repository, we don't need to write the store
3646 # requirements as they are already present in store requires
3654 # requirements as they are already present in store requires
3647 if storereq and b'sharedrepo' not in createopts:
3655 if storereq and b'sharedrepo' not in createopts:
3648 storevfs = vfsmod.vfs(hgvfs.join(b'store'), cacheaudited=True)
3656 storevfs = vfsmod.vfs(hgvfs.join(b'store'), cacheaudited=True)
3649 scmutil.writerequires(storevfs, storereq)
3657 scmutil.writerequires(storevfs, storereq)
3650
3658
3651 # Write out file telling readers where to find the shared store.
3659 # Write out file telling readers where to find the shared store.
3652 if b'sharedrepo' in createopts:
3660 if b'sharedrepo' in createopts:
3653 hgvfs.write(b'sharedpath', sharedpath)
3661 hgvfs.write(b'sharedpath', sharedpath)
3654
3662
3655 if createopts.get(b'shareditems'):
3663 if createopts.get(b'shareditems'):
3656 shared = b'\n'.join(sorted(createopts[b'shareditems'])) + b'\n'
3664 shared = b'\n'.join(sorted(createopts[b'shareditems'])) + b'\n'
3657 hgvfs.write(b'shared', shared)
3665 hgvfs.write(b'shared', shared)
3658
3666
3659
3667
3660 def poisonrepository(repo):
3668 def poisonrepository(repo):
3661 """Poison a repository instance so it can no longer be used."""
3669 """Poison a repository instance so it can no longer be used."""
3662 # Perform any cleanup on the instance.
3670 # Perform any cleanup on the instance.
3663 repo.close()
3671 repo.close()
3664
3672
3665 # Our strategy is to replace the type of the object with one that
3673 # Our strategy is to replace the type of the object with one that
3666 # has all attribute lookups result in error.
3674 # has all attribute lookups result in error.
3667 #
3675 #
3668 # But we have to allow the close() method because some constructors
3676 # But we have to allow the close() method because some constructors
3669 # of repos call close() on repo references.
3677 # of repos call close() on repo references.
3670 class poisonedrepository(object):
3678 class poisonedrepository(object):
3671 def __getattribute__(self, item):
3679 def __getattribute__(self, item):
3672 if item == 'close':
3680 if item == 'close':
3673 return object.__getattribute__(self, item)
3681 return object.__getattribute__(self, item)
3674
3682
3675 raise error.ProgrammingError(
3683 raise error.ProgrammingError(
3676 b'repo instances should not be used after unshare'
3684 b'repo instances should not be used after unshare'
3677 )
3685 )
3678
3686
3679 def close(self):
3687 def close(self):
3680 pass
3688 pass
3681
3689
3682 # We may have a repoview, which intercepts __setattr__. So be sure
3690 # We may have a repoview, which intercepts __setattr__. So be sure
3683 # we operate at the lowest level possible.
3691 # we operate at the lowest level possible.
3684 object.__setattr__(repo, '__class__', poisonedrepository)
3692 object.__setattr__(repo, '__class__', poisonedrepository)
@@ -1,340 +1,351 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
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 from .i18n import _
10 from .i18n import _
11 from . import (
11 from . import (
12 error,
12 error,
13 hg,
13 hg,
14 localrepo,
14 localrepo,
15 lock as lockmod,
15 lock as lockmod,
16 pycompat,
16 pycompat,
17 requirements as requirementsmod,
17 requirements as requirementsmod,
18 scmutil,
18 scmutil,
19 )
19 )
20
20
21 from .upgrade_utils import (
21 from .upgrade_utils import (
22 actions as upgrade_actions,
22 actions as upgrade_actions,
23 engine as upgrade_engine,
23 engine as upgrade_engine,
24 )
24 )
25
25
26 from .utils import (
26 from .utils import (
27 stringutil,
27 stringutil,
28 )
28 )
29
29
30 allformatvariant = upgrade_actions.allformatvariant
30 allformatvariant = upgrade_actions.allformatvariant
31
31
32
32
33 def upgraderepo(
33 def upgraderepo(
34 ui,
34 ui,
35 repo,
35 repo,
36 run=False,
36 run=False,
37 optimize=None,
37 optimize=None,
38 backup=True,
38 backup=True,
39 manifest=None,
39 manifest=None,
40 changelog=None,
40 changelog=None,
41 filelogs=None,
41 filelogs=None,
42 ):
42 ):
43 """Upgrade a repository in place."""
43 """Upgrade a repository in place."""
44 if optimize is None:
44 if optimize is None:
45 optimize = {}
45 optimize = {}
46 repo = repo.unfiltered()
46 repo = repo.unfiltered()
47
47
48 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
48 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
49 specentries = (
49 specentries = (
50 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
50 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
51 (upgrade_engine.UPGRADE_MANIFEST, manifest),
51 (upgrade_engine.UPGRADE_MANIFEST, manifest),
52 (upgrade_engine.UPGRADE_FILELOGS, filelogs),
52 (upgrade_engine.UPGRADE_FILELOGS, filelogs),
53 )
53 )
54 specified = [(y, x) for (y, x) in specentries if x is not None]
54 specified = [(y, x) for (y, x) in specentries if x is not None]
55 if specified:
55 if specified:
56 # we have some limitation on revlogs to be recloned
56 # we have some limitation on revlogs to be recloned
57 if any(x for y, x in specified):
57 if any(x for y, x in specified):
58 revlogs = set()
58 revlogs = set()
59 for upgrade, enabled in specified:
59 for upgrade, enabled in specified:
60 if enabled:
60 if enabled:
61 revlogs.add(upgrade)
61 revlogs.add(upgrade)
62 else:
62 else:
63 # none are enabled
63 # none are enabled
64 for upgrade, __ in specified:
64 for upgrade, __ in specified:
65 revlogs.discard(upgrade)
65 revlogs.discard(upgrade)
66
66
67 # Ensure the repository can be upgraded.
67 # Ensure the repository can be upgraded.
68 upgrade_actions.check_source_requirements(repo)
68 upgrade_actions.check_source_requirements(repo)
69
69
70 default_options = localrepo.defaultcreateopts(repo.ui)
70 default_options = localrepo.defaultcreateopts(repo.ui)
71 newreqs = localrepo.newreporequirements(repo.ui, default_options)
71 newreqs = localrepo.newreporequirements(repo.ui, default_options)
72 newreqs.update(upgrade_actions.preservedrequirements(repo))
72 newreqs.update(upgrade_actions.preservedrequirements(repo))
73
73
74 upgrade_actions.check_requirements_changes(repo, newreqs)
74 upgrade_actions.check_requirements_changes(repo, newreqs)
75
75
76 # Find and validate all improvements that can be made.
76 # Find and validate all improvements that can be made.
77 alloptimizations = upgrade_actions.findoptimizations(repo)
77 alloptimizations = upgrade_actions.findoptimizations(repo)
78
78
79 # Apply and Validate arguments.
79 # Apply and Validate arguments.
80 optimizations = []
80 optimizations = []
81 for o in alloptimizations:
81 for o in alloptimizations:
82 if o.name in optimize:
82 if o.name in optimize:
83 optimizations.append(o)
83 optimizations.append(o)
84 optimize.discard(o.name)
84 optimize.discard(o.name)
85
85
86 if optimize: # anything left is unknown
86 if optimize: # anything left is unknown
87 raise error.Abort(
87 raise error.Abort(
88 _(b'unknown optimization action requested: %s')
88 _(b'unknown optimization action requested: %s')
89 % b', '.join(sorted(optimize)),
89 % b', '.join(sorted(optimize)),
90 hint=_(b'run without arguments to see valid optimizations'),
90 hint=_(b'run without arguments to see valid optimizations'),
91 )
91 )
92
92
93 format_upgrades = upgrade_actions.find_format_upgrades(repo)
93 format_upgrades = upgrade_actions.find_format_upgrades(repo)
94 up_actions = upgrade_actions.determine_upgrade_actions(
94 up_actions = upgrade_actions.determine_upgrade_actions(
95 repo, format_upgrades, optimizations, repo.requirements, newreqs
95 repo, format_upgrades, optimizations, repo.requirements, newreqs
96 )
96 )
97 removed_actions = upgrade_actions.find_format_downgrades(repo)
97 removed_actions = upgrade_actions.find_format_downgrades(repo)
98
98
99 removedreqs = repo.requirements - newreqs
99 removedreqs = repo.requirements - newreqs
100 addedreqs = newreqs - repo.requirements
100 addedreqs = newreqs - repo.requirements
101
101
102 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
102 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
103 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
103 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
104 removedreqs | addedreqs
104 removedreqs | addedreqs
105 )
105 )
106 if incompatible:
106 if incompatible:
107 msg = _(
107 msg = _(
108 b'ignoring revlogs selection flags, format requirements '
108 b'ignoring revlogs selection flags, format requirements '
109 b'change: %s\n'
109 b'change: %s\n'
110 )
110 )
111 ui.warn(msg % b', '.join(sorted(incompatible)))
111 ui.warn(msg % b', '.join(sorted(incompatible)))
112 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
112 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
113
113
114 upgrade_op = upgrade_actions.UpgradeOperation(
114 upgrade_op = upgrade_actions.UpgradeOperation(
115 ui,
115 ui,
116 newreqs,
116 newreqs,
117 repo.requirements,
117 repo.requirements,
118 up_actions,
118 up_actions,
119 removed_actions,
119 removed_actions,
120 revlogs,
120 revlogs,
121 )
121 )
122
122
123 if not run:
123 if not run:
124 fromconfig = []
124 fromconfig = []
125 onlydefault = []
125 onlydefault = []
126
126
127 for d in format_upgrades:
127 for d in format_upgrades:
128 if d.fromconfig(repo):
128 if d.fromconfig(repo):
129 fromconfig.append(d)
129 fromconfig.append(d)
130 elif d.default:
130 elif d.default:
131 onlydefault.append(d)
131 onlydefault.append(d)
132
132
133 if fromconfig or onlydefault:
133 if fromconfig or onlydefault:
134
134
135 if fromconfig:
135 if fromconfig:
136 ui.status(
136 ui.status(
137 _(
137 _(
138 b'repository lacks features recommended by '
138 b'repository lacks features recommended by '
139 b'current config options:\n\n'
139 b'current config options:\n\n'
140 )
140 )
141 )
141 )
142 for i in fromconfig:
142 for i in fromconfig:
143 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
143 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
144
144
145 if onlydefault:
145 if onlydefault:
146 ui.status(
146 ui.status(
147 _(
147 _(
148 b'repository lacks features used by the default '
148 b'repository lacks features used by the default '
149 b'config options:\n\n'
149 b'config options:\n\n'
150 )
150 )
151 )
151 )
152 for i in onlydefault:
152 for i in onlydefault:
153 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
153 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
154
154
155 ui.status(b'\n')
155 ui.status(b'\n')
156 else:
156 else:
157 ui.status(_(b'(no format upgrades found in existing repository)\n'))
157 ui.status(_(b'(no format upgrades found in existing repository)\n'))
158
158
159 ui.status(
159 ui.status(
160 _(
160 _(
161 b'performing an upgrade with "--run" will make the following '
161 b'performing an upgrade with "--run" will make the following '
162 b'changes:\n\n'
162 b'changes:\n\n'
163 )
163 )
164 )
164 )
165
165
166 upgrade_op.print_requirements()
166 upgrade_op.print_requirements()
167 upgrade_op.print_optimisations()
167 upgrade_op.print_optimisations()
168 upgrade_op.print_upgrade_actions()
168 upgrade_op.print_upgrade_actions()
169 upgrade_op.print_affected_revlogs()
169 upgrade_op.print_affected_revlogs()
170
170
171 if upgrade_op.unused_optimizations:
171 if upgrade_op.unused_optimizations:
172 ui.status(
172 ui.status(
173 _(
173 _(
174 b'additional optimizations are available by specifying '
174 b'additional optimizations are available by specifying '
175 b'"--optimize <name>":\n\n'
175 b'"--optimize <name>":\n\n'
176 )
176 )
177 )
177 )
178 upgrade_op.print_unused_optimizations()
178 upgrade_op.print_unused_optimizations()
179 return
179 return
180
180
181 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
181 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
182 ui.status(_(b'nothing to do\n'))
182 ui.status(_(b'nothing to do\n'))
183 return
183 return
184 # Else we're in the run=true case.
184 # Else we're in the run=true case.
185 ui.write(_(b'upgrade will perform the following actions:\n\n'))
185 ui.write(_(b'upgrade will perform the following actions:\n\n'))
186 upgrade_op.print_requirements()
186 upgrade_op.print_requirements()
187 upgrade_op.print_optimisations()
187 upgrade_op.print_optimisations()
188 upgrade_op.print_upgrade_actions()
188 upgrade_op.print_upgrade_actions()
189 upgrade_op.print_affected_revlogs()
189 upgrade_op.print_affected_revlogs()
190
190
191 ui.status(_(b'beginning upgrade...\n'))
191 ui.status(_(b'beginning upgrade...\n'))
192 with repo.wlock(), repo.lock():
192 with repo.wlock(), repo.lock():
193 ui.status(_(b'repository locked and read-only\n'))
193 ui.status(_(b'repository locked and read-only\n'))
194 # Our strategy for upgrading the repository is to create a new,
194 # Our strategy for upgrading the repository is to create a new,
195 # temporary repository, write data to it, then do a swap of the
195 # temporary repository, write data to it, then do a swap of the
196 # data. There are less heavyweight ways to do this, but it is easier
196 # data. There are less heavyweight ways to do this, but it is easier
197 # to create a new repo object than to instantiate all the components
197 # to create a new repo object than to instantiate all the components
198 # (like the store) separately.
198 # (like the store) separately.
199 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
199 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
200 backuppath = None
200 backuppath = None
201 try:
201 try:
202 ui.status(
202 ui.status(
203 _(
203 _(
204 b'creating temporary repository to stage upgraded '
204 b'creating temporary repository to stage upgraded '
205 b'data: %s\n'
205 b'data: %s\n'
206 )
206 )
207 % tmppath
207 % tmppath
208 )
208 )
209
209
210 # clone ui without using ui.copy because repo.ui is protected
210 # clone ui without using ui.copy because repo.ui is protected
211 repoui = repo.ui.__class__(repo.ui)
211 repoui = repo.ui.__class__(repo.ui)
212 dstrepo = hg.repository(repoui, path=tmppath, create=True)
212 dstrepo = hg.repository(repoui, path=tmppath, create=True)
213
213
214 with dstrepo.wlock(), dstrepo.lock():
214 with dstrepo.wlock(), dstrepo.lock():
215 backuppath = upgrade_engine.upgrade(
215 backuppath = upgrade_engine.upgrade(
216 ui, repo, dstrepo, upgrade_op
216 ui, repo, dstrepo, upgrade_op
217 )
217 )
218 if not backup:
218 if not backup:
219 ui.status(
219 ui.status(
220 _(b'removing old repository content %s\n') % backuppath
220 _(b'removing old repository content %s\n') % backuppath
221 )
221 )
222 repo.vfs.rmtree(backuppath, forcibly=True)
222 repo.vfs.rmtree(backuppath, forcibly=True)
223 backuppath = None
223 backuppath = None
224
224
225 finally:
225 finally:
226 ui.status(_(b'removing temporary repository %s\n') % tmppath)
226 ui.status(_(b'removing temporary repository %s\n') % tmppath)
227 repo.vfs.rmtree(tmppath, forcibly=True)
227 repo.vfs.rmtree(tmppath, forcibly=True)
228
228
229 if backuppath and not ui.quiet:
229 if backuppath and not ui.quiet:
230 ui.warn(
230 ui.warn(
231 _(b'copy of old repository backed up at %s\n') % backuppath
231 _(b'copy of old repository backed up at %s\n') % backuppath
232 )
232 )
233 ui.warn(
233 ui.warn(
234 _(
234 _(
235 b'the old repository will not be deleted; remove '
235 b'the old repository will not be deleted; remove '
236 b'it to free up disk space once the upgraded '
236 b'it to free up disk space once the upgraded '
237 b'repository is verified\n'
237 b'repository is verified\n'
238 )
238 )
239 )
239 )
240
240
241 upgrade_op.print_post_op_messages()
241 upgrade_op.print_post_op_messages()
242
242
243
243
244 def upgrade_share_to_safe(
244 def upgrade_share_to_safe(
245 ui, hgvfs, storevfs, current_requirements, mismatch_config
245 ui,
246 hgvfs,
247 storevfs,
248 current_requirements,
249 mismatch_config,
250 mismatch_warn,
246 ):
251 ):
247 """Upgrades a share to use share-safe mechanism"""
252 """Upgrades a share to use share-safe mechanism"""
248 wlock = None
253 wlock = None
249 store_requirements = localrepo._readrequires(storevfs, False)
254 store_requirements = localrepo._readrequires(storevfs, False)
250 original_crequirements = current_requirements.copy()
255 original_crequirements = current_requirements.copy()
251 # after upgrade, store requires will be shared, so lets find
256 # after upgrade, store requires will be shared, so lets find
252 # the requirements which are not present in store and
257 # the requirements which are not present in store and
253 # write them to share's .hg/requires
258 # write them to share's .hg/requires
254 diffrequires = current_requirements - store_requirements
259 diffrequires = current_requirements - store_requirements
255 # add share-safe requirement as it will mark the share as share-safe
260 # add share-safe requirement as it will mark the share as share-safe
256 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
261 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
257 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
262 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
258 # in `allow` case, we don't try to upgrade, we just respect the source
263 # in `allow` case, we don't try to upgrade, we just respect the source
259 # state, update requirements and continue
264 # state, update requirements and continue
260 if mismatch_config == b'allow':
265 if mismatch_config == b'allow':
261 return
266 return
262 try:
267 try:
263 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
268 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
264 # some process might change the requirement in between, re-read
269 # some process might change the requirement in between, re-read
265 # and update current_requirements
270 # and update current_requirements
266 locked_requirements = localrepo._readrequires(hgvfs, True)
271 locked_requirements = localrepo._readrequires(hgvfs, True)
267 if locked_requirements != original_crequirements:
272 if locked_requirements != original_crequirements:
268 removed = current_requirements - locked_requirements
273 removed = current_requirements - locked_requirements
269 # update current_requirements in place because it's passed
274 # update current_requirements in place because it's passed
270 # as reference
275 # as reference
271 current_requirements -= removed
276 current_requirements -= removed
272 current_requirements |= locked_requirements
277 current_requirements |= locked_requirements
273 diffrequires = current_requirements - store_requirements
278 diffrequires = current_requirements - store_requirements
274 # add share-safe requirement as it will mark the share as share-safe
279 # add share-safe requirement as it will mark the share as share-safe
275 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
280 diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT)
276 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
281 current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT)
277 scmutil.writerequires(hgvfs, diffrequires)
282 scmutil.writerequires(hgvfs, diffrequires)
278 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
283 ui.warn(_(b'repository upgraded to use share-safe mode\n'))
279 except error.LockError as e:
284 except error.LockError as e:
280 if mismatch_config == b'upgrade-abort':
285 if mismatch_config == b'upgrade-abort':
281 raise error.Abort(
286 raise error.Abort(
282 _(b'failed to upgrade share, got error: %s')
287 _(b'failed to upgrade share, got error: %s')
283 % stringutil.forcebytestr(e.strerror)
288 % stringutil.forcebytestr(e.strerror)
284 )
289 )
285 elif ui.configbool(b'experimental', b'sharesafe-warn-outdated-shares'):
290 elif mismatch_warn:
286 ui.warn(
291 ui.warn(
287 _(b'failed to upgrade share, got error: %s\n')
292 _(b'failed to upgrade share, got error: %s\n')
288 % stringutil.forcebytestr(e.strerror)
293 % stringutil.forcebytestr(e.strerror)
289 )
294 )
290 finally:
295 finally:
291 if wlock:
296 if wlock:
292 wlock.release()
297 wlock.release()
293
298
294
299
295 def downgrade_share_to_non_safe(
300 def downgrade_share_to_non_safe(
296 ui,
301 ui,
297 hgvfs,
302 hgvfs,
298 sharedvfs,
303 sharedvfs,
299 current_requirements,
304 current_requirements,
300 mismatch_config,
305 mismatch_config,
306 mismatch_warn,
301 ):
307 ):
302 """Downgrades a share which use share-safe to not use it"""
308 """Downgrades a share which use share-safe to not use it"""
303 wlock = None
309 wlock = None
304 source_requirements = localrepo._readrequires(sharedvfs, True)
310 source_requirements = localrepo._readrequires(sharedvfs, True)
305 original_crequirements = current_requirements.copy()
311 original_crequirements = current_requirements.copy()
306 # we cannot be 100% sure on which requirements were present in store when
312 # we cannot be 100% sure on which requirements were present in store when
307 # the source supported share-safe. However, we do know that working
313 # the source supported share-safe. However, we do know that working
308 # directory requirements were not there. Hence we remove them
314 # directory requirements were not there. Hence we remove them
309 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
315 source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
310 current_requirements |= source_requirements
316 current_requirements |= source_requirements
311 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
317 current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT)
312 if mismatch_config == b'allow':
318 if mismatch_config == b'allow':
313 return
319 return
314
320
315 try:
321 try:
316 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
322 wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0)
317 # some process might change the requirement in between, re-read
323 # some process might change the requirement in between, re-read
318 # and update current_requirements
324 # and update current_requirements
319 locked_requirements = localrepo._readrequires(hgvfs, True)
325 locked_requirements = localrepo._readrequires(hgvfs, True)
320 if locked_requirements != original_crequirements:
326 if locked_requirements != original_crequirements:
321 removed = current_requirements - locked_requirements
327 removed = current_requirements - locked_requirements
322 # update current_requirements in place because it's passed
328 # update current_requirements in place because it's passed
323 # as reference
329 # as reference
324 current_requirements -= removed
330 current_requirements -= removed
325 current_requirements |= locked_requirements
331 current_requirements |= locked_requirements
326 current_requirements |= source_requirements
332 current_requirements |= source_requirements
327 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
333 current_requirements -= set(requirementsmod.SHARESAFE_REQUIREMENT)
328 scmutil.writerequires(hgvfs, current_requirements)
334 scmutil.writerequires(hgvfs, current_requirements)
329 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
335 ui.warn(_(b'repository downgraded to not use share-safe mode\n'))
330 except error.LockError as e:
336 except error.LockError as e:
331 # If upgrade-abort is set, abort when upgrade fails, else let the
337 # If upgrade-abort is set, abort when upgrade fails, else let the
332 # process continue as `upgrade-allow` is set
338 # process continue as `upgrade-allow` is set
333 if mismatch_config == b'downgrade-abort':
339 if mismatch_config == b'downgrade-abort':
334 raise error.Abort(
340 raise error.Abort(
335 _(b'failed to downgrade share, got error: %s')
341 _(b'failed to downgrade share, got error: %s')
336 % stringutil.forcebytestr(e.strerror)
342 % stringutil.forcebytestr(e.strerror)
337 )
343 )
344 elif mismatch_warn:
345 ui.warn(
346 _(b'failed to downgrade share, got error: %s\n')
347 % stringutil.forcebytestr(e.strerror)
348 )
338 finally:
349 finally:
339 if wlock:
350 if wlock:
340 wlock.release()
351 wlock.release()
@@ -1,574 +1,574 b''
1 setup
1 setup
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > share =
5 > share =
6 > [format]
6 > [format]
7 > exp-share-safe = True
7 > exp-share-safe = True
8 > [storage]
8 > [storage]
9 > revlog.persistent-nodemap.slow-path=allow
9 > revlog.persistent-nodemap.slow-path=allow
10 > EOF
10 > EOF
11
11
12 prepare source repo
12 prepare source repo
13
13
14 $ hg init source
14 $ hg init source
15 $ cd source
15 $ cd source
16 $ cat .hg/requires
16 $ cat .hg/requires
17 exp-sharesafe
17 exp-sharesafe
18 $ cat .hg/store/requires
18 $ cat .hg/store/requires
19 dotencode
19 dotencode
20 fncache
20 fncache
21 generaldelta
21 generaldelta
22 revlogv1
22 revlogv1
23 sparserevlog
23 sparserevlog
24 store
24 store
25 $ hg debugrequirements
25 $ hg debugrequirements
26 dotencode
26 dotencode
27 exp-sharesafe
27 exp-sharesafe
28 fncache
28 fncache
29 generaldelta
29 generaldelta
30 revlogv1
30 revlogv1
31 sparserevlog
31 sparserevlog
32 store
32 store
33
33
34 $ echo a > a
34 $ echo a > a
35 $ hg ci -Aqm "added a"
35 $ hg ci -Aqm "added a"
36 $ echo b > b
36 $ echo b > b
37 $ hg ci -Aqm "added b"
37 $ hg ci -Aqm "added b"
38
38
39 $ HGEDITOR=cat hg config --shared
39 $ HGEDITOR=cat hg config --shared
40 abort: repository is not shared; can't use --shared
40 abort: repository is not shared; can't use --shared
41 [10]
41 [10]
42 $ cd ..
42 $ cd ..
43
43
44 Create a shared repo and check the requirements are shared and read correctly
44 Create a shared repo and check the requirements are shared and read correctly
45 $ hg share source shared1
45 $ hg share source shared1
46 updating working directory
46 updating working directory
47 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 $ cd shared1
48 $ cd shared1
49 $ cat .hg/requires
49 $ cat .hg/requires
50 exp-sharesafe
50 exp-sharesafe
51 shared
51 shared
52
52
53 $ hg debugrequirements -R ../source
53 $ hg debugrequirements -R ../source
54 dotencode
54 dotencode
55 exp-sharesafe
55 exp-sharesafe
56 fncache
56 fncache
57 generaldelta
57 generaldelta
58 revlogv1
58 revlogv1
59 sparserevlog
59 sparserevlog
60 store
60 store
61
61
62 $ hg debugrequirements
62 $ hg debugrequirements
63 dotencode
63 dotencode
64 exp-sharesafe
64 exp-sharesafe
65 fncache
65 fncache
66 generaldelta
66 generaldelta
67 revlogv1
67 revlogv1
68 shared
68 shared
69 sparserevlog
69 sparserevlog
70 store
70 store
71
71
72 $ echo c > c
72 $ echo c > c
73 $ hg ci -Aqm "added c"
73 $ hg ci -Aqm "added c"
74
74
75 Check that config of the source repository is also loaded
75 Check that config of the source repository is also loaded
76
76
77 $ hg showconfig ui.curses
77 $ hg showconfig ui.curses
78 [1]
78 [1]
79
79
80 $ echo "[ui]" >> ../source/.hg/hgrc
80 $ echo "[ui]" >> ../source/.hg/hgrc
81 $ echo "curses=true" >> ../source/.hg/hgrc
81 $ echo "curses=true" >> ../source/.hg/hgrc
82
82
83 $ hg showconfig ui.curses
83 $ hg showconfig ui.curses
84 true
84 true
85
85
86 Test that extensions of source repository are also loaded
86 Test that extensions of source repository are also loaded
87
87
88 $ hg debugextensions
88 $ hg debugextensions
89 share
89 share
90 $ hg extdiff -p echo
90 $ hg extdiff -p echo
91 hg: unknown command 'extdiff'
91 hg: unknown command 'extdiff'
92 'extdiff' is provided by the following extension:
92 'extdiff' is provided by the following extension:
93
93
94 extdiff command to allow external programs to compare revisions
94 extdiff command to allow external programs to compare revisions
95
95
96 (use 'hg help extensions' for information on enabling extensions)
96 (use 'hg help extensions' for information on enabling extensions)
97 [10]
97 [10]
98
98
99 $ echo "[extensions]" >> ../source/.hg/hgrc
99 $ echo "[extensions]" >> ../source/.hg/hgrc
100 $ echo "extdiff=" >> ../source/.hg/hgrc
100 $ echo "extdiff=" >> ../source/.hg/hgrc
101
101
102 $ hg debugextensions -R ../source
102 $ hg debugextensions -R ../source
103 extdiff
103 extdiff
104 share
104 share
105 $ hg extdiff -R ../source -p echo
105 $ hg extdiff -R ../source -p echo
106
106
107 BROKEN: the command below will not work if config of shared source is not loaded
107 BROKEN: the command below will not work if config of shared source is not loaded
108 on dispatch but debugextensions says that extension
108 on dispatch but debugextensions says that extension
109 is loaded
109 is loaded
110 $ hg debugextensions
110 $ hg debugextensions
111 extdiff
111 extdiff
112 share
112 share
113
113
114 $ hg extdiff -p echo
114 $ hg extdiff -p echo
115
115
116 However, local .hg/hgrc should override the config set by share source
116 However, local .hg/hgrc should override the config set by share source
117
117
118 $ echo "[ui]" >> .hg/hgrc
118 $ echo "[ui]" >> .hg/hgrc
119 $ echo "curses=false" >> .hg/hgrc
119 $ echo "curses=false" >> .hg/hgrc
120
120
121 $ hg showconfig ui.curses
121 $ hg showconfig ui.curses
122 false
122 false
123
123
124 $ HGEDITOR=cat hg config --shared
124 $ HGEDITOR=cat hg config --shared
125 [ui]
125 [ui]
126 curses=true
126 curses=true
127 [extensions]
127 [extensions]
128 extdiff=
128 extdiff=
129
129
130 $ HGEDITOR=cat hg config --local
130 $ HGEDITOR=cat hg config --local
131 [ui]
131 [ui]
132 curses=false
132 curses=false
133
133
134 Testing that hooks set in source repository also runs in shared repo
134 Testing that hooks set in source repository also runs in shared repo
135
135
136 $ cd ../source
136 $ cd ../source
137 $ cat <<EOF >> .hg/hgrc
137 $ cat <<EOF >> .hg/hgrc
138 > [extensions]
138 > [extensions]
139 > hooklib=
139 > hooklib=
140 > [hooks]
140 > [hooks]
141 > pretxnchangegroup.reject_merge_commits = \
141 > pretxnchangegroup.reject_merge_commits = \
142 > python:hgext.hooklib.reject_merge_commits.hook
142 > python:hgext.hooklib.reject_merge_commits.hook
143 > EOF
143 > EOF
144
144
145 $ cd ..
145 $ cd ..
146 $ hg clone source cloned
146 $ hg clone source cloned
147 updating to branch default
147 updating to branch default
148 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 $ cd cloned
149 $ cd cloned
150 $ hg up 0
150 $ hg up 0
151 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
151 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
152 $ echo bar > bar
152 $ echo bar > bar
153 $ hg ci -Aqm "added bar"
153 $ hg ci -Aqm "added bar"
154 $ hg merge
154 $ hg merge
155 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 (branch merge, don't forget to commit)
156 (branch merge, don't forget to commit)
157 $ hg ci -m "merge commit"
157 $ hg ci -m "merge commit"
158
158
159 $ hg push ../source
159 $ hg push ../source
160 pushing to ../source
160 pushing to ../source
161 searching for changes
161 searching for changes
162 adding changesets
162 adding changesets
163 adding manifests
163 adding manifests
164 adding file changes
164 adding file changes
165 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
165 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
166 transaction abort!
166 transaction abort!
167 rollback completed
167 rollback completed
168 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
168 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
169 [255]
169 [255]
170
170
171 $ hg push ../shared1
171 $ hg push ../shared1
172 pushing to ../shared1
172 pushing to ../shared1
173 searching for changes
173 searching for changes
174 adding changesets
174 adding changesets
175 adding manifests
175 adding manifests
176 adding file changes
176 adding file changes
177 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
177 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
178 transaction abort!
178 transaction abort!
179 rollback completed
179 rollback completed
180 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
180 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
181 [255]
181 [255]
182
182
183 Test that if share source config is untrusted, we dont read it
183 Test that if share source config is untrusted, we dont read it
184
184
185 $ cd ../shared1
185 $ cd ../shared1
186
186
187 $ cat << EOF > $TESTTMP/untrusted.py
187 $ cat << EOF > $TESTTMP/untrusted.py
188 > from mercurial import scmutil, util
188 > from mercurial import scmutil, util
189 > def uisetup(ui):
189 > def uisetup(ui):
190 > class untrustedui(ui.__class__):
190 > class untrustedui(ui.__class__):
191 > def _trusted(self, fp, f):
191 > def _trusted(self, fp, f):
192 > if util.normpath(fp.name).endswith(b'source/.hg/hgrc'):
192 > if util.normpath(fp.name).endswith(b'source/.hg/hgrc'):
193 > return False
193 > return False
194 > return super(untrustedui, self)._trusted(fp, f)
194 > return super(untrustedui, self)._trusted(fp, f)
195 > ui.__class__ = untrustedui
195 > ui.__class__ = untrustedui
196 > EOF
196 > EOF
197
197
198 $ hg showconfig hooks
198 $ hg showconfig hooks
199 hooks.pretxnchangegroup.reject_merge_commits=python:hgext.hooklib.reject_merge_commits.hook
199 hooks.pretxnchangegroup.reject_merge_commits=python:hgext.hooklib.reject_merge_commits.hook
200
200
201 $ hg showconfig hooks --config extensions.untrusted=$TESTTMP/untrusted.py
201 $ hg showconfig hooks --config extensions.untrusted=$TESTTMP/untrusted.py
202 [1]
202 [1]
203
203
204 Update the source repository format and check that shared repo works
204 Update the source repository format and check that shared repo works
205
205
206 $ cd ../source
206 $ cd ../source
207
207
208 Disable zstd related tests because its not present on pure version
208 Disable zstd related tests because its not present on pure version
209 #if zstd
209 #if zstd
210 $ echo "[format]" >> .hg/hgrc
210 $ echo "[format]" >> .hg/hgrc
211 $ echo "revlog-compression=zstd" >> .hg/hgrc
211 $ echo "revlog-compression=zstd" >> .hg/hgrc
212
212
213 $ hg debugupgraderepo --run -q
213 $ hg debugupgraderepo --run -q
214 upgrade will perform the following actions:
214 upgrade will perform the following actions:
215
215
216 requirements
216 requirements
217 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlogv1, sparserevlog, store
217 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlogv1, sparserevlog, store
218 added: revlog-compression-zstd
218 added: revlog-compression-zstd
219
219
220 processed revlogs:
220 processed revlogs:
221 - all-filelogs
221 - all-filelogs
222 - changelog
222 - changelog
223 - manifest
223 - manifest
224
224
225 $ hg log -r .
225 $ hg log -r .
226 changeset: 1:5f6d8a4bf34a
226 changeset: 1:5f6d8a4bf34a
227 user: test
227 user: test
228 date: Thu Jan 01 00:00:00 1970 +0000
228 date: Thu Jan 01 00:00:00 1970 +0000
229 summary: added b
229 summary: added b
230
230
231 #endif
231 #endif
232 $ echo "[format]" >> .hg/hgrc
232 $ echo "[format]" >> .hg/hgrc
233 $ echo "use-persistent-nodemap=True" >> .hg/hgrc
233 $ echo "use-persistent-nodemap=True" >> .hg/hgrc
234
234
235 $ hg debugupgraderepo --run -q -R ../shared1
235 $ hg debugupgraderepo --run -q -R ../shared1
236 abort: cannot upgrade repository; unsupported source requirement: shared
236 abort: cannot upgrade repository; unsupported source requirement: shared
237 [255]
237 [255]
238
238
239 $ hg debugupgraderepo --run -q
239 $ hg debugupgraderepo --run -q
240 upgrade will perform the following actions:
240 upgrade will perform the following actions:
241
241
242 requirements
242 requirements
243 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
243 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlogv1, sparserevlog, store (no-zstd !)
244 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
244 preserved: dotencode, exp-sharesafe, fncache, generaldelta, revlog-compression-zstd, revlogv1, sparserevlog, store (zstd !)
245 added: persistent-nodemap
245 added: persistent-nodemap
246
246
247 processed revlogs:
247 processed revlogs:
248 - all-filelogs
248 - all-filelogs
249 - changelog
249 - changelog
250 - manifest
250 - manifest
251
251
252 $ hg log -r .
252 $ hg log -r .
253 changeset: 1:5f6d8a4bf34a
253 changeset: 1:5f6d8a4bf34a
254 user: test
254 user: test
255 date: Thu Jan 01 00:00:00 1970 +0000
255 date: Thu Jan 01 00:00:00 1970 +0000
256 summary: added b
256 summary: added b
257
257
258
258
259 Shared one should work
259 Shared one should work
260 $ cd ../shared1
260 $ cd ../shared1
261 $ hg log -r .
261 $ hg log -r .
262 changeset: 2:155349b645be
262 changeset: 2:155349b645be
263 tag: tip
263 tag: tip
264 user: test
264 user: test
265 date: Thu Jan 01 00:00:00 1970 +0000
265 date: Thu Jan 01 00:00:00 1970 +0000
266 summary: added c
266 summary: added c
267
267
268
268
269 Testing that nonsharedrc is loaded for source and not shared
269 Testing that nonsharedrc is loaded for source and not shared
270
270
271 $ cd ../source
271 $ cd ../source
272 $ touch .hg/hgrc-not-shared
272 $ touch .hg/hgrc-not-shared
273 $ echo "[ui]" >> .hg/hgrc-not-shared
273 $ echo "[ui]" >> .hg/hgrc-not-shared
274 $ echo "traceback=true" >> .hg/hgrc-not-shared
274 $ echo "traceback=true" >> .hg/hgrc-not-shared
275
275
276 $ hg showconfig ui.traceback
276 $ hg showconfig ui.traceback
277 true
277 true
278
278
279 $ HGEDITOR=cat hg config --non-shared
279 $ HGEDITOR=cat hg config --non-shared
280 [ui]
280 [ui]
281 traceback=true
281 traceback=true
282
282
283 $ cd ../shared1
283 $ cd ../shared1
284 $ hg showconfig ui.traceback
284 $ hg showconfig ui.traceback
285 [1]
285 [1]
286
286
287 Unsharing works
287 Unsharing works
288
288
289 $ hg unshare
289 $ hg unshare
290
290
291 Test that source config is added to the shared one after unshare, and the config
291 Test that source config is added to the shared one after unshare, and the config
292 of current repo is still respected over the config which came from source config
292 of current repo is still respected over the config which came from source config
293 $ cd ../cloned
293 $ cd ../cloned
294 $ hg push ../shared1
294 $ hg push ../shared1
295 pushing to ../shared1
295 pushing to ../shared1
296 searching for changes
296 searching for changes
297 adding changesets
297 adding changesets
298 adding manifests
298 adding manifests
299 adding file changes
299 adding file changes
300 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
300 error: pretxnchangegroup.reject_merge_commits hook failed: bcde3522682d rejected as merge on the same branch. Please consider rebase.
301 transaction abort!
301 transaction abort!
302 rollback completed
302 rollback completed
303 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
303 abort: bcde3522682d rejected as merge on the same branch. Please consider rebase.
304 [255]
304 [255]
305 $ hg showconfig ui.curses -R ../shared1
305 $ hg showconfig ui.curses -R ../shared1
306 false
306 false
307
307
308 $ cd ../
308 $ cd ../
309
309
310 Test that upgrading using debugupgraderepo works
310 Test that upgrading using debugupgraderepo works
311 =================================================
311 =================================================
312
312
313 $ hg init non-share-safe --config format.exp-share-safe=false
313 $ hg init non-share-safe --config format.exp-share-safe=false
314 $ cd non-share-safe
314 $ cd non-share-safe
315 $ hg debugrequirements
315 $ hg debugrequirements
316 dotencode
316 dotencode
317 fncache
317 fncache
318 generaldelta
318 generaldelta
319 revlogv1
319 revlogv1
320 sparserevlog
320 sparserevlog
321 store
321 store
322 $ echo foo > foo
322 $ echo foo > foo
323 $ hg ci -Aqm 'added foo'
323 $ hg ci -Aqm 'added foo'
324 $ echo bar > bar
324 $ echo bar > bar
325 $ hg ci -Aqm 'added bar'
325 $ hg ci -Aqm 'added bar'
326
326
327 Create a share before upgrading
327 Create a share before upgrading
328
328
329 $ cd ..
329 $ cd ..
330 $ hg share non-share-safe nss-share
330 $ hg share non-share-safe nss-share
331 updating working directory
331 updating working directory
332 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 $ hg debugrequirements -R nss-share
333 $ hg debugrequirements -R nss-share
334 dotencode
334 dotencode
335 fncache
335 fncache
336 generaldelta
336 generaldelta
337 revlogv1
337 revlogv1
338 shared
338 shared
339 sparserevlog
339 sparserevlog
340 store
340 store
341 $ cd non-share-safe
341 $ cd non-share-safe
342
342
343 Upgrade
343 Upgrade
344
344
345 $ hg debugupgraderepo -q
345 $ hg debugupgraderepo -q
346 requirements
346 requirements
347 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
347 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
348 added: exp-sharesafe
348 added: exp-sharesafe
349
349
350 processed revlogs:
350 processed revlogs:
351 - all-filelogs
351 - all-filelogs
352 - changelog
352 - changelog
353 - manifest
353 - manifest
354
354
355 $ hg debugupgraderepo --run -q
355 $ hg debugupgraderepo --run -q
356 upgrade will perform the following actions:
356 upgrade will perform the following actions:
357
357
358 requirements
358 requirements
359 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
359 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
360 added: exp-sharesafe
360 added: exp-sharesafe
361
361
362 processed revlogs:
362 processed revlogs:
363 - all-filelogs
363 - all-filelogs
364 - changelog
364 - changelog
365 - manifest
365 - manifest
366
366
367 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
367 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
368
368
369 $ hg debugrequirements
369 $ hg debugrequirements
370 dotencode
370 dotencode
371 exp-sharesafe
371 exp-sharesafe
372 fncache
372 fncache
373 generaldelta
373 generaldelta
374 revlogv1
374 revlogv1
375 sparserevlog
375 sparserevlog
376 store
376 store
377
377
378 $ cat .hg/requires
378 $ cat .hg/requires
379 exp-sharesafe
379 exp-sharesafe
380
380
381 $ cat .hg/store/requires
381 $ cat .hg/store/requires
382 dotencode
382 dotencode
383 fncache
383 fncache
384 generaldelta
384 generaldelta
385 revlogv1
385 revlogv1
386 sparserevlog
386 sparserevlog
387 store
387 store
388
388
389 $ hg log -GT "{node}: {desc}\n"
389 $ hg log -GT "{node}: {desc}\n"
390 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
390 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
391 |
391 |
392 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
392 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
393
393
394
394
395 Make sure existing shares dont work with default config
395 Make sure existing shares dont work with default config
396
396
397 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
397 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
398 abort: version mismatch: source uses share-safe functionality while the current share does not
398 abort: version mismatch: source uses share-safe functionality while the current share does not
399 [255]
399 [255]
400
400
401
401
402 Create a safe share from upgrade one
402 Create a safe share from upgrade one
403
403
404 $ cd ..
404 $ cd ..
405 $ hg share non-share-safe ss-share
405 $ hg share non-share-safe ss-share
406 updating working directory
406 updating working directory
407 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 $ cd ss-share
408 $ cd ss-share
409 $ hg log -GT "{node}: {desc}\n"
409 $ hg log -GT "{node}: {desc}\n"
410 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
410 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
411 |
411 |
412 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
412 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
413
413
414 $ cd ../non-share-safe
414 $ cd ../non-share-safe
415
415
416 Test that downgrading works too
416 Test that downgrading works too
417
417
418 $ cat >> $HGRCPATH <<EOF
418 $ cat >> $HGRCPATH <<EOF
419 > [extensions]
419 > [extensions]
420 > share =
420 > share =
421 > [format]
421 > [format]
422 > exp-share-safe = False
422 > exp-share-safe = False
423 > EOF
423 > EOF
424
424
425 $ hg debugupgraderepo -q
425 $ hg debugupgraderepo -q
426 requirements
426 requirements
427 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
427 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
428 removed: exp-sharesafe
428 removed: exp-sharesafe
429
429
430 processed revlogs:
430 processed revlogs:
431 - all-filelogs
431 - all-filelogs
432 - changelog
432 - changelog
433 - manifest
433 - manifest
434
434
435 $ hg debugupgraderepo -q --run
435 $ hg debugupgraderepo -q --run
436 upgrade will perform the following actions:
436 upgrade will perform the following actions:
437
437
438 requirements
438 requirements
439 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
439 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
440 removed: exp-sharesafe
440 removed: exp-sharesafe
441
441
442 processed revlogs:
442 processed revlogs:
443 - all-filelogs
443 - all-filelogs
444 - changelog
444 - changelog
445 - manifest
445 - manifest
446
446
447 repository downgraded to not use share safe mode, existing shares will not work and needs to be reshared.
447 repository downgraded to not use share safe mode, existing shares will not work and needs to be reshared.
448
448
449 $ hg debugrequirements
449 $ hg debugrequirements
450 dotencode
450 dotencode
451 fncache
451 fncache
452 generaldelta
452 generaldelta
453 revlogv1
453 revlogv1
454 sparserevlog
454 sparserevlog
455 store
455 store
456
456
457 $ cat .hg/requires
457 $ cat .hg/requires
458 dotencode
458 dotencode
459 fncache
459 fncache
460 generaldelta
460 generaldelta
461 revlogv1
461 revlogv1
462 sparserevlog
462 sparserevlog
463 store
463 store
464
464
465 $ test -f .hg/store/requires
465 $ test -f .hg/store/requires
466 [1]
466 [1]
467
467
468 $ hg log -GT "{node}: {desc}\n"
468 $ hg log -GT "{node}: {desc}\n"
469 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
469 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
470 |
470 |
471 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
471 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
472
472
473
473
474 Make sure existing shares still works
474 Make sure existing shares still works
475
475
476 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
476 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
477 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
477 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
478 |
478 |
479 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
479 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
480
480
481
481
482 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
482 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
483 abort: share source does not support exp-sharesafe requirement
483 abort: share source does not support exp-sharesafe requirement
484 [255]
484 [255]
485
485
486 Testing automatic downgrade of shares when config is set
486 Testing automatic downgrade of shares when config is set
487
487
488 $ touch ../ss-share/.hg/wlock
488 $ touch ../ss-share/.hg/wlock
489 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
489 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
490 abort: failed to downgrade share, got error: Lock held
490 abort: failed to downgrade share, got error: Lock held
491 [255]
491 [255]
492 $ rm ../ss-share/.hg/wlock
492 $ rm ../ss-share/.hg/wlock
493
493
494 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
494 $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.safe-mismatch.source-not-safe=downgrade-abort
495 repository downgraded to not use share-safe mode
495 repository downgraded to not use share-safe mode
496 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
496 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
497 |
497 |
498 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
498 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
499
499
500
500
501 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
501 $ hg log -GT "{node}: {desc}\n" -R ../ss-share
502 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
502 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
503 |
503 |
504 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
504 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
505
505
506
506
507
507
508 Testing automatic upgrade of shares when config is set
508 Testing automatic upgrade of shares when config is set
509
509
510 $ hg debugupgraderepo -q --run --config format.exp-share-safe=True
510 $ hg debugupgraderepo -q --run --config format.exp-share-safe=True
511 upgrade will perform the following actions:
511 upgrade will perform the following actions:
512
512
513 requirements
513 requirements
514 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
514 preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store
515 added: exp-sharesafe
515 added: exp-sharesafe
516
516
517 processed revlogs:
517 processed revlogs:
518 - all-filelogs
518 - all-filelogs
519 - changelog
519 - changelog
520 - manifest
520 - manifest
521
521
522 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
522 repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode.
523 $ hg debugrequirements
523 $ hg debugrequirements
524 dotencode
524 dotencode
525 exp-sharesafe
525 exp-sharesafe
526 fncache
526 fncache
527 generaldelta
527 generaldelta
528 revlogv1
528 revlogv1
529 sparserevlog
529 sparserevlog
530 store
530 store
531 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
531 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
532 abort: version mismatch: source uses share-safe functionality while the current share does not
532 abort: version mismatch: source uses share-safe functionality while the current share does not
533 [255]
533 [255]
534
534
535 Check that if lock is taken, upgrade fails but read operation are successful
535 Check that if lock is taken, upgrade fails but read operation are successful
536 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgra
536 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgra
537 abort: share-safe mismatch with source.
537 abort: share-safe mismatch with source.
538 Unrecognized value 'upgra' of `share.safe-mismatch.source-safe` set.
538 Unrecognized value 'upgra' of `share.safe-mismatch.source-safe` set.
539 (run `hg help config.share.safe-mismatch.source-safe`)
539 (run `hg help config.share.safe-mismatch.source-safe`)
540 [255]
540 [255]
541 $ touch ../nss-share/.hg/wlock
541 $ touch ../nss-share/.hg/wlock
542 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow
542 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow
543 failed to upgrade share, got error: Lock held
543 failed to upgrade share, got error: Lock held
544 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
544 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
545 |
545 |
546 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
546 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
547
547
548
548
549 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow --config experimental.sharesafe-warn-outdated-shares=false
549 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow --config share.safe-mismatch.source-safe.warn=False
550 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
550 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
551 |
551 |
552 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
552 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
553
553
554
554
555 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
555 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
556 abort: failed to upgrade share, got error: Lock held
556 abort: failed to upgrade share, got error: Lock held
557 [255]
557 [255]
558
558
559 $ rm ../nss-share/.hg/wlock
559 $ rm ../nss-share/.hg/wlock
560 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
560 $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort
561 repository upgraded to use share-safe mode
561 repository upgraded to use share-safe mode
562 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
562 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
563 |
563 |
564 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
564 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
565
565
566
566
567 Test that unshare works
567 Test that unshare works
568
568
569 $ hg unshare -R ../nss-share
569 $ hg unshare -R ../nss-share
570 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
570 $ hg log -GT "{node}: {desc}\n" -R ../nss-share
571 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
571 @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar
572 |
572 |
573 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
573 o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo
574
574
General Comments 0
You need to be logged in to leave comments. Login now