##// END OF EJS Templates
hgweb: add support to explicitly access hidden changesets...
marmoute -
r51308:4077d622 default
parent child Browse files
Show More
@@ -1,2970 +1,2975 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
8
9 import functools
9 import functools
10 import re
10 import re
11
11
12 from . import (
12 from . import (
13 encoding,
13 encoding,
14 error,
14 error,
15 )
15 )
16
16
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = b"extension '%s' overwrite config item '%s.%s'"
25 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config=b'warn-config')
27 ui.develwarn(msg, config=b'warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31
31
32 class configitem:
32 class configitem:
33 """represent a known config item
33 """represent a known config item
34
34
35 :section: the official config section where to find this item,
35 :section: the official config section where to find this item,
36 :name: the official name within the section,
36 :name: the official name within the section,
37 :default: default value for this item,
37 :default: default value for this item,
38 :alias: optional list of tuples as alternatives,
38 :alias: optional list of tuples as alternatives,
39 :generic: this is a generic definition, match name using regular expression.
39 :generic: this is a generic definition, match name using regular expression.
40 """
40 """
41
41
42 def __init__(
42 def __init__(
43 self,
43 self,
44 section,
44 section,
45 name,
45 name,
46 default=None,
46 default=None,
47 alias=(),
47 alias=(),
48 generic=False,
48 generic=False,
49 priority=0,
49 priority=0,
50 experimental=False,
50 experimental=False,
51 ):
51 ):
52 self.section = section
52 self.section = section
53 self.name = name
53 self.name = name
54 self.default = default
54 self.default = default
55 self.alias = list(alias)
55 self.alias = list(alias)
56 self.generic = generic
56 self.generic = generic
57 self.priority = priority
57 self.priority = priority
58 self.experimental = experimental
58 self.experimental = experimental
59 self._re = None
59 self._re = None
60 if generic:
60 if generic:
61 self._re = re.compile(self.name)
61 self._re = re.compile(self.name)
62
62
63
63
64 class itemregister(dict):
64 class itemregister(dict):
65 """A specialized dictionary that can handle wild-card selection"""
65 """A specialized dictionary that can handle wild-card selection"""
66
66
67 def __init__(self):
67 def __init__(self):
68 super(itemregister, self).__init__()
68 super(itemregister, self).__init__()
69 self._generics = set()
69 self._generics = set()
70
70
71 def update(self, other):
71 def update(self, other):
72 super(itemregister, self).update(other)
72 super(itemregister, self).update(other)
73 self._generics.update(other._generics)
73 self._generics.update(other._generics)
74
74
75 def __setitem__(self, key, item):
75 def __setitem__(self, key, item):
76 super(itemregister, self).__setitem__(key, item)
76 super(itemregister, self).__setitem__(key, item)
77 if item.generic:
77 if item.generic:
78 self._generics.add(item)
78 self._generics.add(item)
79
79
80 def get(self, key):
80 def get(self, key):
81 baseitem = super(itemregister, self).get(key)
81 baseitem = super(itemregister, self).get(key)
82 if baseitem is not None and not baseitem.generic:
82 if baseitem is not None and not baseitem.generic:
83 return baseitem
83 return baseitem
84
84
85 # search for a matching generic item
85 # search for a matching generic item
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 for item in generics:
87 for item in generics:
88 # we use 'match' instead of 'search' to make the matching simpler
88 # we use 'match' instead of 'search' to make the matching simpler
89 # for people unfamiliar with regular expression. Having the match
89 # for people unfamiliar with regular expression. Having the match
90 # rooted to the start of the string will produce less surprising
90 # rooted to the start of the string will produce less surprising
91 # result for user writing simple regex for sub-attribute.
91 # result for user writing simple regex for sub-attribute.
92 #
92 #
93 # For example using "color\..*" match produces an unsurprising
93 # For example using "color\..*" match produces an unsurprising
94 # result, while using search could suddenly match apparently
94 # result, while using search could suddenly match apparently
95 # unrelated configuration that happens to contains "color."
95 # unrelated configuration that happens to contains "color."
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # some match to avoid the need to prefix most pattern with "^".
97 # some match to avoid the need to prefix most pattern with "^".
98 # The "^" seems more error prone.
98 # The "^" seems more error prone.
99 if item._re.match(key):
99 if item._re.match(key):
100 return item
100 return item
101
101
102 return None
102 return None
103
103
104
104
105 coreitems = {}
105 coreitems = {}
106
106
107
107
108 def _register(configtable, *args, **kwargs):
108 def _register(configtable, *args, **kwargs):
109 item = configitem(*args, **kwargs)
109 item = configitem(*args, **kwargs)
110 section = configtable.setdefault(item.section, itemregister())
110 section = configtable.setdefault(item.section, itemregister())
111 if item.name in section:
111 if item.name in section:
112 msg = b"duplicated config item registration for '%s.%s'"
112 msg = b"duplicated config item registration for '%s.%s'"
113 raise error.ProgrammingError(msg % (item.section, item.name))
113 raise error.ProgrammingError(msg % (item.section, item.name))
114 section[item.name] = item
114 section[item.name] = item
115
115
116
116
117 # special value for case where the default is derived from other values
117 # special value for case where the default is derived from other values
118 dynamicdefault = object()
118 dynamicdefault = object()
119
119
120 # Registering actual config items
120 # Registering actual config items
121
121
122
122
123 def getitemregister(configtable):
123 def getitemregister(configtable):
124 f = functools.partial(_register, configtable)
124 f = functools.partial(_register, configtable)
125 # export pseudo enum as configitem.*
125 # export pseudo enum as configitem.*
126 f.dynamicdefault = dynamicdefault
126 f.dynamicdefault = dynamicdefault
127 return f
127 return f
128
128
129
129
130 coreconfigitem = getitemregister(coreitems)
130 coreconfigitem = getitemregister(coreitems)
131
131
132
132
133 def _registerdiffopts(section, configprefix=b''):
133 def _registerdiffopts(section, configprefix=b''):
134 coreconfigitem(
134 coreconfigitem(
135 section,
135 section,
136 configprefix + b'nodates',
136 configprefix + b'nodates',
137 default=False,
137 default=False,
138 )
138 )
139 coreconfigitem(
139 coreconfigitem(
140 section,
140 section,
141 configprefix + b'showfunc',
141 configprefix + b'showfunc',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(
144 coreconfigitem(
145 section,
145 section,
146 configprefix + b'unified',
146 configprefix + b'unified',
147 default=None,
147 default=None,
148 )
148 )
149 coreconfigitem(
149 coreconfigitem(
150 section,
150 section,
151 configprefix + b'git',
151 configprefix + b'git',
152 default=False,
152 default=False,
153 )
153 )
154 coreconfigitem(
154 coreconfigitem(
155 section,
155 section,
156 configprefix + b'ignorews',
156 configprefix + b'ignorews',
157 default=False,
157 default=False,
158 )
158 )
159 coreconfigitem(
159 coreconfigitem(
160 section,
160 section,
161 configprefix + b'ignorewsamount',
161 configprefix + b'ignorewsamount',
162 default=False,
162 default=False,
163 )
163 )
164 coreconfigitem(
164 coreconfigitem(
165 section,
165 section,
166 configprefix + b'ignoreblanklines',
166 configprefix + b'ignoreblanklines',
167 default=False,
167 default=False,
168 )
168 )
169 coreconfigitem(
169 coreconfigitem(
170 section,
170 section,
171 configprefix + b'ignorewseol',
171 configprefix + b'ignorewseol',
172 default=False,
172 default=False,
173 )
173 )
174 coreconfigitem(
174 coreconfigitem(
175 section,
175 section,
176 configprefix + b'nobinary',
176 configprefix + b'nobinary',
177 default=False,
177 default=False,
178 )
178 )
179 coreconfigitem(
179 coreconfigitem(
180 section,
180 section,
181 configprefix + b'noprefix',
181 configprefix + b'noprefix',
182 default=False,
182 default=False,
183 )
183 )
184 coreconfigitem(
184 coreconfigitem(
185 section,
185 section,
186 configprefix + b'word-diff',
186 configprefix + b'word-diff',
187 default=False,
187 default=False,
188 )
188 )
189
189
190
190
191 coreconfigitem(
191 coreconfigitem(
192 b'alias',
192 b'alias',
193 b'.*',
193 b'.*',
194 default=dynamicdefault,
194 default=dynamicdefault,
195 generic=True,
195 generic=True,
196 )
196 )
197 coreconfigitem(
197 coreconfigitem(
198 b'auth',
198 b'auth',
199 b'cookiefile',
199 b'cookiefile',
200 default=None,
200 default=None,
201 )
201 )
202 _registerdiffopts(section=b'annotate')
202 _registerdiffopts(section=b'annotate')
203 # bookmarks.pushing: internal hack for discovery
203 # bookmarks.pushing: internal hack for discovery
204 coreconfigitem(
204 coreconfigitem(
205 b'bookmarks',
205 b'bookmarks',
206 b'pushing',
206 b'pushing',
207 default=list,
207 default=list,
208 )
208 )
209 # bundle.mainreporoot: internal hack for bundlerepo
209 # bundle.mainreporoot: internal hack for bundlerepo
210 coreconfigitem(
210 coreconfigitem(
211 b'bundle',
211 b'bundle',
212 b'mainreporoot',
212 b'mainreporoot',
213 default=b'',
213 default=b'',
214 )
214 )
215 coreconfigitem(
215 coreconfigitem(
216 b'censor',
216 b'censor',
217 b'policy',
217 b'policy',
218 default=b'abort',
218 default=b'abort',
219 experimental=True,
219 experimental=True,
220 )
220 )
221 coreconfigitem(
221 coreconfigitem(
222 b'chgserver',
222 b'chgserver',
223 b'idletimeout',
223 b'idletimeout',
224 default=3600,
224 default=3600,
225 )
225 )
226 coreconfigitem(
226 coreconfigitem(
227 b'chgserver',
227 b'chgserver',
228 b'skiphash',
228 b'skiphash',
229 default=False,
229 default=False,
230 )
230 )
231 coreconfigitem(
231 coreconfigitem(
232 b'cmdserver',
232 b'cmdserver',
233 b'log',
233 b'log',
234 default=None,
234 default=None,
235 )
235 )
236 coreconfigitem(
236 coreconfigitem(
237 b'cmdserver',
237 b'cmdserver',
238 b'max-log-files',
238 b'max-log-files',
239 default=7,
239 default=7,
240 )
240 )
241 coreconfigitem(
241 coreconfigitem(
242 b'cmdserver',
242 b'cmdserver',
243 b'max-log-size',
243 b'max-log-size',
244 default=b'1 MB',
244 default=b'1 MB',
245 )
245 )
246 coreconfigitem(
246 coreconfigitem(
247 b'cmdserver',
247 b'cmdserver',
248 b'max-repo-cache',
248 b'max-repo-cache',
249 default=0,
249 default=0,
250 experimental=True,
250 experimental=True,
251 )
251 )
252 coreconfigitem(
252 coreconfigitem(
253 b'cmdserver',
253 b'cmdserver',
254 b'message-encodings',
254 b'message-encodings',
255 default=list,
255 default=list,
256 )
256 )
257 coreconfigitem(
257 coreconfigitem(
258 b'cmdserver',
258 b'cmdserver',
259 b'track-log',
259 b'track-log',
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 )
261 )
262 coreconfigitem(
262 coreconfigitem(
263 b'cmdserver',
263 b'cmdserver',
264 b'shutdown-on-interrupt',
264 b'shutdown-on-interrupt',
265 default=True,
265 default=True,
266 )
266 )
267 coreconfigitem(
267 coreconfigitem(
268 b'color',
268 b'color',
269 b'.*',
269 b'.*',
270 default=None,
270 default=None,
271 generic=True,
271 generic=True,
272 )
272 )
273 coreconfigitem(
273 coreconfigitem(
274 b'color',
274 b'color',
275 b'mode',
275 b'mode',
276 default=b'auto',
276 default=b'auto',
277 )
277 )
278 coreconfigitem(
278 coreconfigitem(
279 b'color',
279 b'color',
280 b'pagermode',
280 b'pagermode',
281 default=dynamicdefault,
281 default=dynamicdefault,
282 )
282 )
283 coreconfigitem(
283 coreconfigitem(
284 b'command-templates',
284 b'command-templates',
285 b'graphnode',
285 b'graphnode',
286 default=None,
286 default=None,
287 alias=[(b'ui', b'graphnodetemplate')],
287 alias=[(b'ui', b'graphnodetemplate')],
288 )
288 )
289 coreconfigitem(
289 coreconfigitem(
290 b'command-templates',
290 b'command-templates',
291 b'log',
291 b'log',
292 default=None,
292 default=None,
293 alias=[(b'ui', b'logtemplate')],
293 alias=[(b'ui', b'logtemplate')],
294 )
294 )
295 coreconfigitem(
295 coreconfigitem(
296 b'command-templates',
296 b'command-templates',
297 b'mergemarker',
297 b'mergemarker',
298 default=(
298 default=(
299 b'{node|short} '
299 b'{node|short} '
300 b'{ifeq(tags, "tip", "", '
300 b'{ifeq(tags, "tip", "", '
301 b'ifeq(tags, "", "", "{tags} "))}'
301 b'ifeq(tags, "", "", "{tags} "))}'
302 b'{if(bookmarks, "{bookmarks} ")}'
302 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'- {author|user}: {desc|firstline}'
304 b'- {author|user}: {desc|firstline}'
305 ),
305 ),
306 alias=[(b'ui', b'mergemarkertemplate')],
306 alias=[(b'ui', b'mergemarkertemplate')],
307 )
307 )
308 coreconfigitem(
308 coreconfigitem(
309 b'command-templates',
309 b'command-templates',
310 b'pre-merge-tool-output',
310 b'pre-merge-tool-output',
311 default=None,
311 default=None,
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 )
313 )
314 coreconfigitem(
314 coreconfigitem(
315 b'command-templates',
315 b'command-templates',
316 b'oneline-summary',
316 b'oneline-summary',
317 default=None,
317 default=None,
318 )
318 )
319 coreconfigitem(
319 coreconfigitem(
320 b'command-templates',
320 b'command-templates',
321 b'oneline-summary.*',
321 b'oneline-summary.*',
322 default=dynamicdefault,
322 default=dynamicdefault,
323 generic=True,
323 generic=True,
324 )
324 )
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 coreconfigitem(
326 coreconfigitem(
327 b'commands',
327 b'commands',
328 b'commit.post-status',
328 b'commit.post-status',
329 default=False,
329 default=False,
330 )
330 )
331 coreconfigitem(
331 coreconfigitem(
332 b'commands',
332 b'commands',
333 b'grep.all-files',
333 b'grep.all-files',
334 default=False,
334 default=False,
335 experimental=True,
335 experimental=True,
336 )
336 )
337 coreconfigitem(
337 coreconfigitem(
338 b'commands',
338 b'commands',
339 b'merge.require-rev',
339 b'merge.require-rev',
340 default=False,
340 default=False,
341 )
341 )
342 coreconfigitem(
342 coreconfigitem(
343 b'commands',
343 b'commands',
344 b'push.require-revs',
344 b'push.require-revs',
345 default=False,
345 default=False,
346 )
346 )
347 coreconfigitem(
347 coreconfigitem(
348 b'commands',
348 b'commands',
349 b'resolve.confirm',
349 b'resolve.confirm',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem(
352 coreconfigitem(
353 b'commands',
353 b'commands',
354 b'resolve.explicit-re-merge',
354 b'resolve.explicit-re-merge',
355 default=False,
355 default=False,
356 )
356 )
357 coreconfigitem(
357 coreconfigitem(
358 b'commands',
358 b'commands',
359 b'resolve.mark-check',
359 b'resolve.mark-check',
360 default=b'none',
360 default=b'none',
361 )
361 )
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 coreconfigitem(
363 coreconfigitem(
364 b'commands',
364 b'commands',
365 b'show.aliasprefix',
365 b'show.aliasprefix',
366 default=list,
366 default=list,
367 )
367 )
368 coreconfigitem(
368 coreconfigitem(
369 b'commands',
369 b'commands',
370 b'status.relative',
370 b'status.relative',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem(
373 coreconfigitem(
374 b'commands',
374 b'commands',
375 b'status.skipstates',
375 b'status.skipstates',
376 default=[],
376 default=[],
377 experimental=True,
377 experimental=True,
378 )
378 )
379 coreconfigitem(
379 coreconfigitem(
380 b'commands',
380 b'commands',
381 b'status.terse',
381 b'status.terse',
382 default=b'',
382 default=b'',
383 )
383 )
384 coreconfigitem(
384 coreconfigitem(
385 b'commands',
385 b'commands',
386 b'status.verbose',
386 b'status.verbose',
387 default=False,
387 default=False,
388 )
388 )
389 coreconfigitem(
389 coreconfigitem(
390 b'commands',
390 b'commands',
391 b'update.check',
391 b'update.check',
392 default=None,
392 default=None,
393 )
393 )
394 coreconfigitem(
394 coreconfigitem(
395 b'commands',
395 b'commands',
396 b'update.requiredest',
396 b'update.requiredest',
397 default=False,
397 default=False,
398 )
398 )
399 coreconfigitem(
399 coreconfigitem(
400 b'committemplate',
400 b'committemplate',
401 b'.*',
401 b'.*',
402 default=None,
402 default=None,
403 generic=True,
403 generic=True,
404 )
404 )
405 coreconfigitem(
405 coreconfigitem(
406 b'convert',
406 b'convert',
407 b'bzr.saverev',
407 b'bzr.saverev',
408 default=True,
408 default=True,
409 )
409 )
410 coreconfigitem(
410 coreconfigitem(
411 b'convert',
411 b'convert',
412 b'cvsps.cache',
412 b'cvsps.cache',
413 default=True,
413 default=True,
414 )
414 )
415 coreconfigitem(
415 coreconfigitem(
416 b'convert',
416 b'convert',
417 b'cvsps.fuzz',
417 b'cvsps.fuzz',
418 default=60,
418 default=60,
419 )
419 )
420 coreconfigitem(
420 coreconfigitem(
421 b'convert',
421 b'convert',
422 b'cvsps.logencoding',
422 b'cvsps.logencoding',
423 default=None,
423 default=None,
424 )
424 )
425 coreconfigitem(
425 coreconfigitem(
426 b'convert',
426 b'convert',
427 b'cvsps.mergefrom',
427 b'cvsps.mergefrom',
428 default=None,
428 default=None,
429 )
429 )
430 coreconfigitem(
430 coreconfigitem(
431 b'convert',
431 b'convert',
432 b'cvsps.mergeto',
432 b'cvsps.mergeto',
433 default=None,
433 default=None,
434 )
434 )
435 coreconfigitem(
435 coreconfigitem(
436 b'convert',
436 b'convert',
437 b'git.committeractions',
437 b'git.committeractions',
438 default=lambda: [b'messagedifferent'],
438 default=lambda: [b'messagedifferent'],
439 )
439 )
440 coreconfigitem(
440 coreconfigitem(
441 b'convert',
441 b'convert',
442 b'git.extrakeys',
442 b'git.extrakeys',
443 default=list,
443 default=list,
444 )
444 )
445 coreconfigitem(
445 coreconfigitem(
446 b'convert',
446 b'convert',
447 b'git.findcopiesharder',
447 b'git.findcopiesharder',
448 default=False,
448 default=False,
449 )
449 )
450 coreconfigitem(
450 coreconfigitem(
451 b'convert',
451 b'convert',
452 b'git.remoteprefix',
452 b'git.remoteprefix',
453 default=b'remote',
453 default=b'remote',
454 )
454 )
455 coreconfigitem(
455 coreconfigitem(
456 b'convert',
456 b'convert',
457 b'git.renamelimit',
457 b'git.renamelimit',
458 default=400,
458 default=400,
459 )
459 )
460 coreconfigitem(
460 coreconfigitem(
461 b'convert',
461 b'convert',
462 b'git.saverev',
462 b'git.saverev',
463 default=True,
463 default=True,
464 )
464 )
465 coreconfigitem(
465 coreconfigitem(
466 b'convert',
466 b'convert',
467 b'git.similarity',
467 b'git.similarity',
468 default=50,
468 default=50,
469 )
469 )
470 coreconfigitem(
470 coreconfigitem(
471 b'convert',
471 b'convert',
472 b'git.skipsubmodules',
472 b'git.skipsubmodules',
473 default=False,
473 default=False,
474 )
474 )
475 coreconfigitem(
475 coreconfigitem(
476 b'convert',
476 b'convert',
477 b'hg.clonebranches',
477 b'hg.clonebranches',
478 default=False,
478 default=False,
479 )
479 )
480 coreconfigitem(
480 coreconfigitem(
481 b'convert',
481 b'convert',
482 b'hg.ignoreerrors',
482 b'hg.ignoreerrors',
483 default=False,
483 default=False,
484 )
484 )
485 coreconfigitem(
485 coreconfigitem(
486 b'convert',
486 b'convert',
487 b'hg.preserve-hash',
487 b'hg.preserve-hash',
488 default=False,
488 default=False,
489 )
489 )
490 coreconfigitem(
490 coreconfigitem(
491 b'convert',
491 b'convert',
492 b'hg.revs',
492 b'hg.revs',
493 default=None,
493 default=None,
494 )
494 )
495 coreconfigitem(
495 coreconfigitem(
496 b'convert',
496 b'convert',
497 b'hg.saverev',
497 b'hg.saverev',
498 default=False,
498 default=False,
499 )
499 )
500 coreconfigitem(
500 coreconfigitem(
501 b'convert',
501 b'convert',
502 b'hg.sourcename',
502 b'hg.sourcename',
503 default=None,
503 default=None,
504 )
504 )
505 coreconfigitem(
505 coreconfigitem(
506 b'convert',
506 b'convert',
507 b'hg.startrev',
507 b'hg.startrev',
508 default=None,
508 default=None,
509 )
509 )
510 coreconfigitem(
510 coreconfigitem(
511 b'convert',
511 b'convert',
512 b'hg.tagsbranch',
512 b'hg.tagsbranch',
513 default=b'default',
513 default=b'default',
514 )
514 )
515 coreconfigitem(
515 coreconfigitem(
516 b'convert',
516 b'convert',
517 b'hg.usebranchnames',
517 b'hg.usebranchnames',
518 default=True,
518 default=True,
519 )
519 )
520 coreconfigitem(
520 coreconfigitem(
521 b'convert',
521 b'convert',
522 b'ignoreancestorcheck',
522 b'ignoreancestorcheck',
523 default=False,
523 default=False,
524 experimental=True,
524 experimental=True,
525 )
525 )
526 coreconfigitem(
526 coreconfigitem(
527 b'convert',
527 b'convert',
528 b'localtimezone',
528 b'localtimezone',
529 default=False,
529 default=False,
530 )
530 )
531 coreconfigitem(
531 coreconfigitem(
532 b'convert',
532 b'convert',
533 b'p4.encoding',
533 b'p4.encoding',
534 default=dynamicdefault,
534 default=dynamicdefault,
535 )
535 )
536 coreconfigitem(
536 coreconfigitem(
537 b'convert',
537 b'convert',
538 b'p4.startrev',
538 b'p4.startrev',
539 default=0,
539 default=0,
540 )
540 )
541 coreconfigitem(
541 coreconfigitem(
542 b'convert',
542 b'convert',
543 b'skiptags',
543 b'skiptags',
544 default=False,
544 default=False,
545 )
545 )
546 coreconfigitem(
546 coreconfigitem(
547 b'convert',
547 b'convert',
548 b'svn.debugsvnlog',
548 b'svn.debugsvnlog',
549 default=True,
549 default=True,
550 )
550 )
551 coreconfigitem(
551 coreconfigitem(
552 b'convert',
552 b'convert',
553 b'svn.trunk',
553 b'svn.trunk',
554 default=None,
554 default=None,
555 )
555 )
556 coreconfigitem(
556 coreconfigitem(
557 b'convert',
557 b'convert',
558 b'svn.tags',
558 b'svn.tags',
559 default=None,
559 default=None,
560 )
560 )
561 coreconfigitem(
561 coreconfigitem(
562 b'convert',
562 b'convert',
563 b'svn.branches',
563 b'svn.branches',
564 default=None,
564 default=None,
565 )
565 )
566 coreconfigitem(
566 coreconfigitem(
567 b'convert',
567 b'convert',
568 b'svn.startrev',
568 b'svn.startrev',
569 default=0,
569 default=0,
570 )
570 )
571 coreconfigitem(
571 coreconfigitem(
572 b'convert',
572 b'convert',
573 b'svn.dangerous-set-commit-dates',
573 b'svn.dangerous-set-commit-dates',
574 default=False,
574 default=False,
575 )
575 )
576 coreconfigitem(
576 coreconfigitem(
577 b'debug',
577 b'debug',
578 b'dirstate.delaywrite',
578 b'dirstate.delaywrite',
579 default=0,
579 default=0,
580 )
580 )
581 coreconfigitem(
581 coreconfigitem(
582 b'debug',
582 b'debug',
583 b'revlog.verifyposition.changelog',
583 b'revlog.verifyposition.changelog',
584 default=b'',
584 default=b'',
585 )
585 )
586 coreconfigitem(
586 coreconfigitem(
587 b'debug',
587 b'debug',
588 b'revlog.debug-delta',
588 b'revlog.debug-delta',
589 default=False,
589 default=False,
590 )
590 )
591 # display extra information about the bundling process
591 # display extra information about the bundling process
592 coreconfigitem(
592 coreconfigitem(
593 b'debug',
593 b'debug',
594 b'bundling-stats',
594 b'bundling-stats',
595 default=False,
595 default=False,
596 )
596 )
597 # display extra information about the unbundling process
597 # display extra information about the unbundling process
598 coreconfigitem(
598 coreconfigitem(
599 b'debug',
599 b'debug',
600 b'unbundling-stats',
600 b'unbundling-stats',
601 default=False,
601 default=False,
602 )
602 )
603 coreconfigitem(
603 coreconfigitem(
604 b'defaults',
604 b'defaults',
605 b'.*',
605 b'.*',
606 default=None,
606 default=None,
607 generic=True,
607 generic=True,
608 )
608 )
609 coreconfigitem(
609 coreconfigitem(
610 b'devel',
610 b'devel',
611 b'all-warnings',
611 b'all-warnings',
612 default=False,
612 default=False,
613 )
613 )
614 coreconfigitem(
614 coreconfigitem(
615 b'devel',
615 b'devel',
616 b'bundle2.debug',
616 b'bundle2.debug',
617 default=False,
617 default=False,
618 )
618 )
619 coreconfigitem(
619 coreconfigitem(
620 b'devel',
620 b'devel',
621 b'bundle.delta',
621 b'bundle.delta',
622 default=b'',
622 default=b'',
623 )
623 )
624 coreconfigitem(
624 coreconfigitem(
625 b'devel',
625 b'devel',
626 b'cache-vfs',
626 b'cache-vfs',
627 default=None,
627 default=None,
628 )
628 )
629 coreconfigitem(
629 coreconfigitem(
630 b'devel',
630 b'devel',
631 b'check-locks',
631 b'check-locks',
632 default=False,
632 default=False,
633 )
633 )
634 coreconfigitem(
634 coreconfigitem(
635 b'devel',
635 b'devel',
636 b'check-relroot',
636 b'check-relroot',
637 default=False,
637 default=False,
638 )
638 )
639 # Track copy information for all file, not just "added" one (very slow)
639 # Track copy information for all file, not just "added" one (very slow)
640 coreconfigitem(
640 coreconfigitem(
641 b'devel',
641 b'devel',
642 b'copy-tracing.trace-all-files',
642 b'copy-tracing.trace-all-files',
643 default=False,
643 default=False,
644 )
644 )
645 coreconfigitem(
645 coreconfigitem(
646 b'devel',
646 b'devel',
647 b'default-date',
647 b'default-date',
648 default=None,
648 default=None,
649 )
649 )
650 coreconfigitem(
650 coreconfigitem(
651 b'devel',
651 b'devel',
652 b'deprec-warn',
652 b'deprec-warn',
653 default=False,
653 default=False,
654 )
654 )
655 # possible values:
655 # possible values:
656 # - auto (the default)
656 # - auto (the default)
657 # - force-append
657 # - force-append
658 # - force-new
658 # - force-new
659 coreconfigitem(
659 coreconfigitem(
660 b'devel',
660 b'devel',
661 b'dirstate.v2.data_update_mode',
661 b'dirstate.v2.data_update_mode',
662 default="auto",
662 default="auto",
663 )
663 )
664 coreconfigitem(
664 coreconfigitem(
665 b'devel',
665 b'devel',
666 b'disableloaddefaultcerts',
666 b'disableloaddefaultcerts',
667 default=False,
667 default=False,
668 )
668 )
669 coreconfigitem(
669 coreconfigitem(
670 b'devel',
670 b'devel',
671 b'warn-empty-changegroup',
671 b'warn-empty-changegroup',
672 default=False,
672 default=False,
673 )
673 )
674 coreconfigitem(
674 coreconfigitem(
675 b'devel',
675 b'devel',
676 b'legacy.exchange',
676 b'legacy.exchange',
677 default=list,
677 default=list,
678 )
678 )
679 # When True, revlogs use a special reference version of the nodemap, that is not
679 # When True, revlogs use a special reference version of the nodemap, that is not
680 # performant but is "known" to behave properly.
680 # performant but is "known" to behave properly.
681 coreconfigitem(
681 coreconfigitem(
682 b'devel',
682 b'devel',
683 b'persistent-nodemap',
683 b'persistent-nodemap',
684 default=False,
684 default=False,
685 )
685 )
686 coreconfigitem(
686 coreconfigitem(
687 b'devel',
687 b'devel',
688 b'servercafile',
688 b'servercafile',
689 default=b'',
689 default=b'',
690 )
690 )
691 # This config option is intended for use in tests only. It is a giant
691 # This config option is intended for use in tests only. It is a giant
692 # footgun to kill security. Don't define it.
692 # footgun to kill security. Don't define it.
693 coreconfigitem(
693 coreconfigitem(
694 b'devel',
694 b'devel',
695 b'server-insecure-exact-protocol',
695 b'server-insecure-exact-protocol',
696 default=b'',
696 default=b'',
697 )
697 )
698 coreconfigitem(
698 coreconfigitem(
699 b'devel',
699 b'devel',
700 b'serverrequirecert',
700 b'serverrequirecert',
701 default=False,
701 default=False,
702 )
702 )
703 # Makes the status algorithm wait for the existence of this file
703 # Makes the status algorithm wait for the existence of this file
704 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
704 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
705 # seconds) before taking the lock and writing the dirstate.
705 # seconds) before taking the lock and writing the dirstate.
706 # Status signals that it's ready to wait by creating a file
706 # Status signals that it's ready to wait by creating a file
707 # with the same name + `.waiting`.
707 # with the same name + `.waiting`.
708 # Useful when testing race conditions.
708 # Useful when testing race conditions.
709 coreconfigitem(
709 coreconfigitem(
710 b'devel',
710 b'devel',
711 b'sync.status.pre-dirstate-write-file',
711 b'sync.status.pre-dirstate-write-file',
712 default=None,
712 default=None,
713 )
713 )
714 coreconfigitem(
714 coreconfigitem(
715 b'devel',
715 b'devel',
716 b'sync.status.pre-dirstate-write-file-timeout',
716 b'sync.status.pre-dirstate-write-file-timeout',
717 default=2,
717 default=2,
718 )
718 )
719 coreconfigitem(
719 coreconfigitem(
720 b'devel',
720 b'devel',
721 b'sync.dirstate.post-docket-read-file',
721 b'sync.dirstate.post-docket-read-file',
722 default=None,
722 default=None,
723 )
723 )
724 coreconfigitem(
724 coreconfigitem(
725 b'devel',
725 b'devel',
726 b'sync.dirstate.post-docket-read-file-timeout',
726 b'sync.dirstate.post-docket-read-file-timeout',
727 default=2,
727 default=2,
728 )
728 )
729 coreconfigitem(
729 coreconfigitem(
730 b'devel',
730 b'devel',
731 b'sync.dirstate.pre-read-file',
731 b'sync.dirstate.pre-read-file',
732 default=None,
732 default=None,
733 )
733 )
734 coreconfigitem(
734 coreconfigitem(
735 b'devel',
735 b'devel',
736 b'sync.dirstate.pre-read-file-timeout',
736 b'sync.dirstate.pre-read-file-timeout',
737 default=2,
737 default=2,
738 )
738 )
739 coreconfigitem(
739 coreconfigitem(
740 b'devel',
740 b'devel',
741 b'strip-obsmarkers',
741 b'strip-obsmarkers',
742 default=True,
742 default=True,
743 )
743 )
744 coreconfigitem(
744 coreconfigitem(
745 b'devel',
745 b'devel',
746 b'warn-config',
746 b'warn-config',
747 default=None,
747 default=None,
748 )
748 )
749 coreconfigitem(
749 coreconfigitem(
750 b'devel',
750 b'devel',
751 b'warn-config-default',
751 b'warn-config-default',
752 default=None,
752 default=None,
753 )
753 )
754 coreconfigitem(
754 coreconfigitem(
755 b'devel',
755 b'devel',
756 b'user.obsmarker',
756 b'user.obsmarker',
757 default=None,
757 default=None,
758 )
758 )
759 coreconfigitem(
759 coreconfigitem(
760 b'devel',
760 b'devel',
761 b'warn-config-unknown',
761 b'warn-config-unknown',
762 default=None,
762 default=None,
763 )
763 )
764 coreconfigitem(
764 coreconfigitem(
765 b'devel',
765 b'devel',
766 b'debug.copies',
766 b'debug.copies',
767 default=False,
767 default=False,
768 )
768 )
769 coreconfigitem(
769 coreconfigitem(
770 b'devel',
770 b'devel',
771 b'copy-tracing.multi-thread',
771 b'copy-tracing.multi-thread',
772 default=True,
772 default=True,
773 )
773 )
774 coreconfigitem(
774 coreconfigitem(
775 b'devel',
775 b'devel',
776 b'debug.extensions',
776 b'debug.extensions',
777 default=False,
777 default=False,
778 )
778 )
779 coreconfigitem(
779 coreconfigitem(
780 b'devel',
780 b'devel',
781 b'debug.repo-filters',
781 b'debug.repo-filters',
782 default=False,
782 default=False,
783 )
783 )
784 coreconfigitem(
784 coreconfigitem(
785 b'devel',
785 b'devel',
786 b'debug.peer-request',
786 b'debug.peer-request',
787 default=False,
787 default=False,
788 )
788 )
789 # If discovery.exchange-heads is False, the discovery will not start with
789 # If discovery.exchange-heads is False, the discovery will not start with
790 # remote head fetching and local head querying.
790 # remote head fetching and local head querying.
791 coreconfigitem(
791 coreconfigitem(
792 b'devel',
792 b'devel',
793 b'discovery.exchange-heads',
793 b'discovery.exchange-heads',
794 default=True,
794 default=True,
795 )
795 )
796 # If devel.debug.abort-update is True, then any merge with the working copy,
796 # If devel.debug.abort-update is True, then any merge with the working copy,
797 # e.g. [hg update], will be aborted after figuring out what needs to be done,
797 # e.g. [hg update], will be aborted after figuring out what needs to be done,
798 # but before spawning the parallel worker
798 # but before spawning the parallel worker
799 coreconfigitem(
799 coreconfigitem(
800 b'devel',
800 b'devel',
801 b'debug.abort-update',
801 b'debug.abort-update',
802 default=False,
802 default=False,
803 )
803 )
804 # If discovery.grow-sample is False, the sample size used in set discovery will
804 # If discovery.grow-sample is False, the sample size used in set discovery will
805 # not be increased through the process
805 # not be increased through the process
806 coreconfigitem(
806 coreconfigitem(
807 b'devel',
807 b'devel',
808 b'discovery.grow-sample',
808 b'discovery.grow-sample',
809 default=True,
809 default=True,
810 )
810 )
811 # When discovery.grow-sample.dynamic is True, the default, the sample size is
811 # When discovery.grow-sample.dynamic is True, the default, the sample size is
812 # adapted to the shape of the undecided set (it is set to the max of:
812 # adapted to the shape of the undecided set (it is set to the max of:
813 # <target-size>, len(roots(undecided)), len(heads(undecided)
813 # <target-size>, len(roots(undecided)), len(heads(undecided)
814 coreconfigitem(
814 coreconfigitem(
815 b'devel',
815 b'devel',
816 b'discovery.grow-sample.dynamic',
816 b'discovery.grow-sample.dynamic',
817 default=True,
817 default=True,
818 )
818 )
819 # discovery.grow-sample.rate control the rate at which the sample grow
819 # discovery.grow-sample.rate control the rate at which the sample grow
820 coreconfigitem(
820 coreconfigitem(
821 b'devel',
821 b'devel',
822 b'discovery.grow-sample.rate',
822 b'discovery.grow-sample.rate',
823 default=1.05,
823 default=1.05,
824 )
824 )
825 # If discovery.randomize is False, random sampling during discovery are
825 # If discovery.randomize is False, random sampling during discovery are
826 # deterministic. It is meant for integration tests.
826 # deterministic. It is meant for integration tests.
827 coreconfigitem(
827 coreconfigitem(
828 b'devel',
828 b'devel',
829 b'discovery.randomize',
829 b'discovery.randomize',
830 default=True,
830 default=True,
831 )
831 )
832 # Control the initial size of the discovery sample
832 # Control the initial size of the discovery sample
833 coreconfigitem(
833 coreconfigitem(
834 b'devel',
834 b'devel',
835 b'discovery.sample-size',
835 b'discovery.sample-size',
836 default=200,
836 default=200,
837 )
837 )
838 # Control the initial size of the discovery for initial change
838 # Control the initial size of the discovery for initial change
839 coreconfigitem(
839 coreconfigitem(
840 b'devel',
840 b'devel',
841 b'discovery.sample-size.initial',
841 b'discovery.sample-size.initial',
842 default=100,
842 default=100,
843 )
843 )
844 _registerdiffopts(section=b'diff')
844 _registerdiffopts(section=b'diff')
845 coreconfigitem(
845 coreconfigitem(
846 b'diff',
846 b'diff',
847 b'merge',
847 b'merge',
848 default=False,
848 default=False,
849 experimental=True,
849 experimental=True,
850 )
850 )
851 coreconfigitem(
851 coreconfigitem(
852 b'email',
852 b'email',
853 b'bcc',
853 b'bcc',
854 default=None,
854 default=None,
855 )
855 )
856 coreconfigitem(
856 coreconfigitem(
857 b'email',
857 b'email',
858 b'cc',
858 b'cc',
859 default=None,
859 default=None,
860 )
860 )
861 coreconfigitem(
861 coreconfigitem(
862 b'email',
862 b'email',
863 b'charsets',
863 b'charsets',
864 default=list,
864 default=list,
865 )
865 )
866 coreconfigitem(
866 coreconfigitem(
867 b'email',
867 b'email',
868 b'from',
868 b'from',
869 default=None,
869 default=None,
870 )
870 )
871 coreconfigitem(
871 coreconfigitem(
872 b'email',
872 b'email',
873 b'method',
873 b'method',
874 default=b'smtp',
874 default=b'smtp',
875 )
875 )
876 coreconfigitem(
876 coreconfigitem(
877 b'email',
877 b'email',
878 b'reply-to',
878 b'reply-to',
879 default=None,
879 default=None,
880 )
880 )
881 coreconfigitem(
881 coreconfigitem(
882 b'email',
882 b'email',
883 b'to',
883 b'to',
884 default=None,
884 default=None,
885 )
885 )
886 coreconfigitem(
886 coreconfigitem(
887 b'experimental',
887 b'experimental',
888 b'archivemetatemplate',
888 b'archivemetatemplate',
889 default=dynamicdefault,
889 default=dynamicdefault,
890 )
890 )
891 coreconfigitem(
891 coreconfigitem(
892 b'experimental',
892 b'experimental',
893 b'auto-publish',
893 b'auto-publish',
894 default=b'publish',
894 default=b'publish',
895 )
895 )
896 coreconfigitem(
896 coreconfigitem(
897 b'experimental',
897 b'experimental',
898 b'bundle-phases',
898 b'bundle-phases',
899 default=False,
899 default=False,
900 )
900 )
901 coreconfigitem(
901 coreconfigitem(
902 b'experimental',
902 b'experimental',
903 b'bundle2-advertise',
903 b'bundle2-advertise',
904 default=True,
904 default=True,
905 )
905 )
906 coreconfigitem(
906 coreconfigitem(
907 b'experimental',
907 b'experimental',
908 b'bundle2-output-capture',
908 b'bundle2-output-capture',
909 default=False,
909 default=False,
910 )
910 )
911 coreconfigitem(
911 coreconfigitem(
912 b'experimental',
912 b'experimental',
913 b'bundle2.pushback',
913 b'bundle2.pushback',
914 default=False,
914 default=False,
915 )
915 )
916 coreconfigitem(
916 coreconfigitem(
917 b'experimental',
917 b'experimental',
918 b'bundle2lazylocking',
918 b'bundle2lazylocking',
919 default=False,
919 default=False,
920 )
920 )
921 coreconfigitem(
921 coreconfigitem(
922 b'experimental',
922 b'experimental',
923 b'bundlecomplevel',
923 b'bundlecomplevel',
924 default=None,
924 default=None,
925 )
925 )
926 coreconfigitem(
926 coreconfigitem(
927 b'experimental',
927 b'experimental',
928 b'bundlecomplevel.bzip2',
928 b'bundlecomplevel.bzip2',
929 default=None,
929 default=None,
930 )
930 )
931 coreconfigitem(
931 coreconfigitem(
932 b'experimental',
932 b'experimental',
933 b'bundlecomplevel.gzip',
933 b'bundlecomplevel.gzip',
934 default=None,
934 default=None,
935 )
935 )
936 coreconfigitem(
936 coreconfigitem(
937 b'experimental',
937 b'experimental',
938 b'bundlecomplevel.none',
938 b'bundlecomplevel.none',
939 default=None,
939 default=None,
940 )
940 )
941 coreconfigitem(
941 coreconfigitem(
942 b'experimental',
942 b'experimental',
943 b'bundlecomplevel.zstd',
943 b'bundlecomplevel.zstd',
944 default=None,
944 default=None,
945 )
945 )
946 coreconfigitem(
946 coreconfigitem(
947 b'experimental',
947 b'experimental',
948 b'bundlecompthreads',
948 b'bundlecompthreads',
949 default=None,
949 default=None,
950 )
950 )
951 coreconfigitem(
951 coreconfigitem(
952 b'experimental',
952 b'experimental',
953 b'bundlecompthreads.bzip2',
953 b'bundlecompthreads.bzip2',
954 default=None,
954 default=None,
955 )
955 )
956 coreconfigitem(
956 coreconfigitem(
957 b'experimental',
957 b'experimental',
958 b'bundlecompthreads.gzip',
958 b'bundlecompthreads.gzip',
959 default=None,
959 default=None,
960 )
960 )
961 coreconfigitem(
961 coreconfigitem(
962 b'experimental',
962 b'experimental',
963 b'bundlecompthreads.none',
963 b'bundlecompthreads.none',
964 default=None,
964 default=None,
965 )
965 )
966 coreconfigitem(
966 coreconfigitem(
967 b'experimental',
967 b'experimental',
968 b'bundlecompthreads.zstd',
968 b'bundlecompthreads.zstd',
969 default=None,
969 default=None,
970 )
970 )
971 coreconfigitem(
971 coreconfigitem(
972 b'experimental',
972 b'experimental',
973 b'changegroup3',
973 b'changegroup3',
974 default=True,
974 default=True,
975 )
975 )
976 coreconfigitem(
976 coreconfigitem(
977 b'experimental',
977 b'experimental',
978 b'changegroup4',
978 b'changegroup4',
979 default=False,
979 default=False,
980 )
980 )
981
981
982 # might remove rank configuration once the computation has no impact
982 # might remove rank configuration once the computation has no impact
983 coreconfigitem(
983 coreconfigitem(
984 b'experimental',
984 b'experimental',
985 b'changelog-v2.compute-rank',
985 b'changelog-v2.compute-rank',
986 default=True,
986 default=True,
987 )
987 )
988 coreconfigitem(
988 coreconfigitem(
989 b'experimental',
989 b'experimental',
990 b'cleanup-as-archived',
990 b'cleanup-as-archived',
991 default=False,
991 default=False,
992 )
992 )
993 coreconfigitem(
993 coreconfigitem(
994 b'experimental',
994 b'experimental',
995 b'clientcompressionengines',
995 b'clientcompressionengines',
996 default=list,
996 default=list,
997 )
997 )
998 coreconfigitem(
998 coreconfigitem(
999 b'experimental',
999 b'experimental',
1000 b'copytrace',
1000 b'copytrace',
1001 default=b'on',
1001 default=b'on',
1002 )
1002 )
1003 coreconfigitem(
1003 coreconfigitem(
1004 b'experimental',
1004 b'experimental',
1005 b'copytrace.movecandidateslimit',
1005 b'copytrace.movecandidateslimit',
1006 default=100,
1006 default=100,
1007 )
1007 )
1008 coreconfigitem(
1008 coreconfigitem(
1009 b'experimental',
1009 b'experimental',
1010 b'copytrace.sourcecommitlimit',
1010 b'copytrace.sourcecommitlimit',
1011 default=100,
1011 default=100,
1012 )
1012 )
1013 coreconfigitem(
1013 coreconfigitem(
1014 b'experimental',
1014 b'experimental',
1015 b'copies.read-from',
1015 b'copies.read-from',
1016 default=b"filelog-only",
1016 default=b"filelog-only",
1017 )
1017 )
1018 coreconfigitem(
1018 coreconfigitem(
1019 b'experimental',
1019 b'experimental',
1020 b'copies.write-to',
1020 b'copies.write-to',
1021 default=b'filelog-only',
1021 default=b'filelog-only',
1022 )
1022 )
1023 coreconfigitem(
1023 coreconfigitem(
1024 b'experimental',
1024 b'experimental',
1025 b'crecordtest',
1025 b'crecordtest',
1026 default=None,
1026 default=None,
1027 )
1027 )
1028 coreconfigitem(
1028 coreconfigitem(
1029 b'experimental',
1029 b'experimental',
1030 b'directaccess',
1030 b'directaccess',
1031 default=False,
1031 default=False,
1032 )
1032 )
1033 coreconfigitem(
1033 coreconfigitem(
1034 b'experimental',
1034 b'experimental',
1035 b'directaccess.revnums',
1035 b'directaccess.revnums',
1036 default=False,
1036 default=False,
1037 )
1037 )
1038 coreconfigitem(
1038 coreconfigitem(
1039 b'experimental',
1039 b'experimental',
1040 b'editortmpinhg',
1040 b'editortmpinhg',
1041 default=False,
1041 default=False,
1042 )
1042 )
1043 coreconfigitem(
1043 coreconfigitem(
1044 b'experimental',
1044 b'experimental',
1045 b'evolution',
1045 b'evolution',
1046 default=list,
1046 default=list,
1047 )
1047 )
1048 coreconfigitem(
1048 coreconfigitem(
1049 b'experimental',
1049 b'experimental',
1050 b'evolution.allowdivergence',
1050 b'evolution.allowdivergence',
1051 default=False,
1051 default=False,
1052 alias=[(b'experimental', b'allowdivergence')],
1052 alias=[(b'experimental', b'allowdivergence')],
1053 )
1053 )
1054 coreconfigitem(
1054 coreconfigitem(
1055 b'experimental',
1055 b'experimental',
1056 b'evolution.allowunstable',
1056 b'evolution.allowunstable',
1057 default=None,
1057 default=None,
1058 )
1058 )
1059 coreconfigitem(
1059 coreconfigitem(
1060 b'experimental',
1060 b'experimental',
1061 b'evolution.createmarkers',
1061 b'evolution.createmarkers',
1062 default=None,
1062 default=None,
1063 )
1063 )
1064 coreconfigitem(
1064 coreconfigitem(
1065 b'experimental',
1065 b'experimental',
1066 b'evolution.effect-flags',
1066 b'evolution.effect-flags',
1067 default=True,
1067 default=True,
1068 alias=[(b'experimental', b'effect-flags')],
1068 alias=[(b'experimental', b'effect-flags')],
1069 )
1069 )
1070 coreconfigitem(
1070 coreconfigitem(
1071 b'experimental',
1071 b'experimental',
1072 b'evolution.exchange',
1072 b'evolution.exchange',
1073 default=None,
1073 default=None,
1074 )
1074 )
1075 coreconfigitem(
1075 coreconfigitem(
1076 b'experimental',
1076 b'experimental',
1077 b'evolution.bundle-obsmarker',
1077 b'evolution.bundle-obsmarker',
1078 default=False,
1078 default=False,
1079 )
1079 )
1080 coreconfigitem(
1080 coreconfigitem(
1081 b'experimental',
1081 b'experimental',
1082 b'evolution.bundle-obsmarker:mandatory',
1082 b'evolution.bundle-obsmarker:mandatory',
1083 default=True,
1083 default=True,
1084 )
1084 )
1085 coreconfigitem(
1085 coreconfigitem(
1086 b'experimental',
1086 b'experimental',
1087 b'log.topo',
1087 b'log.topo',
1088 default=False,
1088 default=False,
1089 )
1089 )
1090 coreconfigitem(
1090 coreconfigitem(
1091 b'experimental',
1091 b'experimental',
1092 b'evolution.report-instabilities',
1092 b'evolution.report-instabilities',
1093 default=True,
1093 default=True,
1094 )
1094 )
1095 coreconfigitem(
1095 coreconfigitem(
1096 b'experimental',
1096 b'experimental',
1097 b'evolution.track-operation',
1097 b'evolution.track-operation',
1098 default=True,
1098 default=True,
1099 )
1099 )
1100 # repo-level config to exclude a revset visibility
1100 # repo-level config to exclude a revset visibility
1101 #
1101 #
1102 # The target use case is to use `share` to expose different subset of the same
1102 # The target use case is to use `share` to expose different subset of the same
1103 # repository, especially server side. See also `server.view`.
1103 # repository, especially server side. See also `server.view`.
1104 coreconfigitem(
1104 coreconfigitem(
1105 b'experimental',
1105 b'experimental',
1106 b'extra-filter-revs',
1106 b'extra-filter-revs',
1107 default=None,
1107 default=None,
1108 )
1108 )
1109 coreconfigitem(
1109 coreconfigitem(
1110 b'experimental',
1110 b'experimental',
1111 b'maxdeltachainspan',
1111 b'maxdeltachainspan',
1112 default=-1,
1112 default=-1,
1113 )
1113 )
1114 # tracks files which were undeleted (merge might delete them but we explicitly
1114 # tracks files which were undeleted (merge might delete them but we explicitly
1115 # kept/undeleted them) and creates new filenodes for them
1115 # kept/undeleted them) and creates new filenodes for them
1116 coreconfigitem(
1116 coreconfigitem(
1117 b'experimental',
1117 b'experimental',
1118 b'merge-track-salvaged',
1118 b'merge-track-salvaged',
1119 default=False,
1119 default=False,
1120 )
1120 )
1121 coreconfigitem(
1121 coreconfigitem(
1122 b'experimental',
1122 b'experimental',
1123 b'mmapindexthreshold',
1123 b'mmapindexthreshold',
1124 default=None,
1124 default=None,
1125 )
1125 )
1126 coreconfigitem(
1126 coreconfigitem(
1127 b'experimental',
1127 b'experimental',
1128 b'narrow',
1128 b'narrow',
1129 default=False,
1129 default=False,
1130 )
1130 )
1131 coreconfigitem(
1131 coreconfigitem(
1132 b'experimental',
1132 b'experimental',
1133 b'nonnormalparanoidcheck',
1133 b'nonnormalparanoidcheck',
1134 default=False,
1134 default=False,
1135 )
1135 )
1136 coreconfigitem(
1136 coreconfigitem(
1137 b'experimental',
1137 b'experimental',
1138 b'exportableenviron',
1138 b'exportableenviron',
1139 default=list,
1139 default=list,
1140 )
1140 )
1141 coreconfigitem(
1141 coreconfigitem(
1142 b'experimental',
1142 b'experimental',
1143 b'extendedheader.index',
1143 b'extendedheader.index',
1144 default=None,
1144 default=None,
1145 )
1145 )
1146 coreconfigitem(
1146 coreconfigitem(
1147 b'experimental',
1147 b'experimental',
1148 b'extendedheader.similarity',
1148 b'extendedheader.similarity',
1149 default=False,
1149 default=False,
1150 )
1150 )
1151 coreconfigitem(
1151 coreconfigitem(
1152 b'experimental',
1152 b'experimental',
1153 b'graphshorten',
1153 b'graphshorten',
1154 default=False,
1154 default=False,
1155 )
1155 )
1156 coreconfigitem(
1156 coreconfigitem(
1157 b'experimental',
1157 b'experimental',
1158 b'graphstyle.parent',
1158 b'graphstyle.parent',
1159 default=dynamicdefault,
1159 default=dynamicdefault,
1160 )
1160 )
1161 coreconfigitem(
1161 coreconfigitem(
1162 b'experimental',
1162 b'experimental',
1163 b'graphstyle.missing',
1163 b'graphstyle.missing',
1164 default=dynamicdefault,
1164 default=dynamicdefault,
1165 )
1165 )
1166 coreconfigitem(
1166 coreconfigitem(
1167 b'experimental',
1167 b'experimental',
1168 b'graphstyle.grandparent',
1168 b'graphstyle.grandparent',
1169 default=dynamicdefault,
1169 default=dynamicdefault,
1170 )
1170 )
1171 coreconfigitem(
1171 coreconfigitem(
1172 b'experimental',
1172 b'experimental',
1173 b'hook-track-tags',
1173 b'hook-track-tags',
1174 default=False,
1174 default=False,
1175 )
1175 )
1176 coreconfigitem(
1176 coreconfigitem(
1177 b'experimental',
1177 b'experimental',
1178 b'httppostargs',
1178 b'httppostargs',
1179 default=False,
1179 default=False,
1180 )
1180 )
1181 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1181 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1182 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1182 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1183
1183
1184 coreconfigitem(
1184 coreconfigitem(
1185 b'experimental',
1185 b'experimental',
1186 b'obsmarkers-exchange-debug',
1186 b'obsmarkers-exchange-debug',
1187 default=False,
1187 default=False,
1188 )
1188 )
1189 coreconfigitem(
1189 coreconfigitem(
1190 b'experimental',
1190 b'experimental',
1191 b'remotenames',
1191 b'remotenames',
1192 default=False,
1192 default=False,
1193 )
1193 )
1194 coreconfigitem(
1194 coreconfigitem(
1195 b'experimental',
1195 b'experimental',
1196 b'removeemptydirs',
1196 b'removeemptydirs',
1197 default=True,
1197 default=True,
1198 )
1198 )
1199 coreconfigitem(
1199 coreconfigitem(
1200 b'experimental',
1200 b'experimental',
1201 b'revert.interactive.select-to-keep',
1201 b'revert.interactive.select-to-keep',
1202 default=False,
1202 default=False,
1203 )
1203 )
1204 coreconfigitem(
1204 coreconfigitem(
1205 b'experimental',
1205 b'experimental',
1206 b'revisions.prefixhexnode',
1206 b'revisions.prefixhexnode',
1207 default=False,
1207 default=False,
1208 )
1208 )
1209 # "out of experimental" todo list.
1209 # "out of experimental" todo list.
1210 #
1210 #
1211 # * include management of a persistent nodemap in the main docket
1211 # * include management of a persistent nodemap in the main docket
1212 # * enforce a "no-truncate" policy for mmap safety
1212 # * enforce a "no-truncate" policy for mmap safety
1213 # - for censoring operation
1213 # - for censoring operation
1214 # - for stripping operation
1214 # - for stripping operation
1215 # - for rollback operation
1215 # - for rollback operation
1216 # * proper streaming (race free) of the docket file
1216 # * proper streaming (race free) of the docket file
1217 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1217 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1218 # * Exchange-wise, we will also need to do something more efficient than
1218 # * Exchange-wise, we will also need to do something more efficient than
1219 # keeping references to the affected revlogs, especially memory-wise when
1219 # keeping references to the affected revlogs, especially memory-wise when
1220 # rewriting sidedata.
1220 # rewriting sidedata.
1221 # * introduce a proper solution to reduce the number of filelog related files.
1221 # * introduce a proper solution to reduce the number of filelog related files.
1222 # * use caching for reading sidedata (similar to what we do for data).
1222 # * use caching for reading sidedata (similar to what we do for data).
1223 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1223 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1224 # * Improvement to consider
1224 # * Improvement to consider
1225 # - avoid compression header in chunk using the default compression?
1225 # - avoid compression header in chunk using the default compression?
1226 # - forbid "inline" compression mode entirely?
1226 # - forbid "inline" compression mode entirely?
1227 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1227 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1228 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1228 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1229 # - keep track of chain base or size (probably not that useful anymore)
1229 # - keep track of chain base or size (probably not that useful anymore)
1230 coreconfigitem(
1230 coreconfigitem(
1231 b'experimental',
1231 b'experimental',
1232 b'revlogv2',
1232 b'revlogv2',
1233 default=None,
1233 default=None,
1234 )
1234 )
1235 coreconfigitem(
1235 coreconfigitem(
1236 b'experimental',
1236 b'experimental',
1237 b'revisions.disambiguatewithin',
1237 b'revisions.disambiguatewithin',
1238 default=None,
1238 default=None,
1239 )
1239 )
1240 coreconfigitem(
1240 coreconfigitem(
1241 b'experimental',
1241 b'experimental',
1242 b'rust.index',
1242 b'rust.index',
1243 default=False,
1243 default=False,
1244 )
1244 )
1245 coreconfigitem(
1245 coreconfigitem(
1246 b'experimental',
1246 b'experimental',
1247 b'server.allow-hidden-access',
1248 default=list,
1249 )
1250 coreconfigitem(
1251 b'experimental',
1247 b'server.filesdata.recommended-batch-size',
1252 b'server.filesdata.recommended-batch-size',
1248 default=50000,
1253 default=50000,
1249 )
1254 )
1250 coreconfigitem(
1255 coreconfigitem(
1251 b'experimental',
1256 b'experimental',
1252 b'server.manifestdata.recommended-batch-size',
1257 b'server.manifestdata.recommended-batch-size',
1253 default=100000,
1258 default=100000,
1254 )
1259 )
1255 coreconfigitem(
1260 coreconfigitem(
1256 b'experimental',
1261 b'experimental',
1257 b'server.stream-narrow-clones',
1262 b'server.stream-narrow-clones',
1258 default=False,
1263 default=False,
1259 )
1264 )
1260 coreconfigitem(
1265 coreconfigitem(
1261 b'experimental',
1266 b'experimental',
1262 b'single-head-per-branch',
1267 b'single-head-per-branch',
1263 default=False,
1268 default=False,
1264 )
1269 )
1265 coreconfigitem(
1270 coreconfigitem(
1266 b'experimental',
1271 b'experimental',
1267 b'single-head-per-branch:account-closed-heads',
1272 b'single-head-per-branch:account-closed-heads',
1268 default=False,
1273 default=False,
1269 )
1274 )
1270 coreconfigitem(
1275 coreconfigitem(
1271 b'experimental',
1276 b'experimental',
1272 b'single-head-per-branch:public-changes-only',
1277 b'single-head-per-branch:public-changes-only',
1273 default=False,
1278 default=False,
1274 )
1279 )
1275 coreconfigitem(
1280 coreconfigitem(
1276 b'experimental',
1281 b'experimental',
1277 b'sparse-read',
1282 b'sparse-read',
1278 default=False,
1283 default=False,
1279 )
1284 )
1280 coreconfigitem(
1285 coreconfigitem(
1281 b'experimental',
1286 b'experimental',
1282 b'sparse-read.density-threshold',
1287 b'sparse-read.density-threshold',
1283 default=0.50,
1288 default=0.50,
1284 )
1289 )
1285 coreconfigitem(
1290 coreconfigitem(
1286 b'experimental',
1291 b'experimental',
1287 b'sparse-read.min-gap-size',
1292 b'sparse-read.min-gap-size',
1288 default=b'65K',
1293 default=b'65K',
1289 )
1294 )
1290 coreconfigitem(
1295 coreconfigitem(
1291 b'experimental',
1296 b'experimental',
1292 b'treemanifest',
1297 b'treemanifest',
1293 default=False,
1298 default=False,
1294 )
1299 )
1295 coreconfigitem(
1300 coreconfigitem(
1296 b'experimental',
1301 b'experimental',
1297 b'update.atomic-file',
1302 b'update.atomic-file',
1298 default=False,
1303 default=False,
1299 )
1304 )
1300 coreconfigitem(
1305 coreconfigitem(
1301 b'experimental',
1306 b'experimental',
1302 b'web.full-garbage-collection-rate',
1307 b'web.full-garbage-collection-rate',
1303 default=1, # still forcing a full collection on each request
1308 default=1, # still forcing a full collection on each request
1304 )
1309 )
1305 coreconfigitem(
1310 coreconfigitem(
1306 b'experimental',
1311 b'experimental',
1307 b'worker.wdir-get-thread-safe',
1312 b'worker.wdir-get-thread-safe',
1308 default=False,
1313 default=False,
1309 )
1314 )
1310 coreconfigitem(
1315 coreconfigitem(
1311 b'experimental',
1316 b'experimental',
1312 b'worker.repository-upgrade',
1317 b'worker.repository-upgrade',
1313 default=False,
1318 default=False,
1314 )
1319 )
1315 coreconfigitem(
1320 coreconfigitem(
1316 b'experimental',
1321 b'experimental',
1317 b'xdiff',
1322 b'xdiff',
1318 default=False,
1323 default=False,
1319 )
1324 )
1320 coreconfigitem(
1325 coreconfigitem(
1321 b'extensions',
1326 b'extensions',
1322 b'[^:]*',
1327 b'[^:]*',
1323 default=None,
1328 default=None,
1324 generic=True,
1329 generic=True,
1325 )
1330 )
1326 coreconfigitem(
1331 coreconfigitem(
1327 b'extensions',
1332 b'extensions',
1328 b'[^:]*:required',
1333 b'[^:]*:required',
1329 default=False,
1334 default=False,
1330 generic=True,
1335 generic=True,
1331 )
1336 )
1332 coreconfigitem(
1337 coreconfigitem(
1333 b'extdata',
1338 b'extdata',
1334 b'.*',
1339 b'.*',
1335 default=None,
1340 default=None,
1336 generic=True,
1341 generic=True,
1337 )
1342 )
1338 coreconfigitem(
1343 coreconfigitem(
1339 b'format',
1344 b'format',
1340 b'bookmarks-in-store',
1345 b'bookmarks-in-store',
1341 default=False,
1346 default=False,
1342 )
1347 )
1343 coreconfigitem(
1348 coreconfigitem(
1344 b'format',
1349 b'format',
1345 b'chunkcachesize',
1350 b'chunkcachesize',
1346 default=None,
1351 default=None,
1347 experimental=True,
1352 experimental=True,
1348 )
1353 )
1349 coreconfigitem(
1354 coreconfigitem(
1350 # Enable this dirstate format *when creating a new repository*.
1355 # Enable this dirstate format *when creating a new repository*.
1351 # Which format to use for existing repos is controlled by .hg/requires
1356 # Which format to use for existing repos is controlled by .hg/requires
1352 b'format',
1357 b'format',
1353 b'use-dirstate-v2',
1358 b'use-dirstate-v2',
1354 default=False,
1359 default=False,
1355 experimental=True,
1360 experimental=True,
1356 alias=[(b'format', b'exp-rc-dirstate-v2')],
1361 alias=[(b'format', b'exp-rc-dirstate-v2')],
1357 )
1362 )
1358 coreconfigitem(
1363 coreconfigitem(
1359 b'format',
1364 b'format',
1360 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1365 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1361 default=False,
1366 default=False,
1362 experimental=True,
1367 experimental=True,
1363 )
1368 )
1364 coreconfigitem(
1369 coreconfigitem(
1365 b'format',
1370 b'format',
1366 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1371 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1367 default=False,
1372 default=False,
1368 experimental=True,
1373 experimental=True,
1369 )
1374 )
1370 coreconfigitem(
1375 coreconfigitem(
1371 b'format',
1376 b'format',
1372 b'use-dirstate-tracked-hint',
1377 b'use-dirstate-tracked-hint',
1373 default=False,
1378 default=False,
1374 experimental=True,
1379 experimental=True,
1375 )
1380 )
1376 coreconfigitem(
1381 coreconfigitem(
1377 b'format',
1382 b'format',
1378 b'use-dirstate-tracked-hint.version',
1383 b'use-dirstate-tracked-hint.version',
1379 default=1,
1384 default=1,
1380 experimental=True,
1385 experimental=True,
1381 )
1386 )
1382 coreconfigitem(
1387 coreconfigitem(
1383 b'format',
1388 b'format',
1384 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1389 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1385 default=False,
1390 default=False,
1386 experimental=True,
1391 experimental=True,
1387 )
1392 )
1388 coreconfigitem(
1393 coreconfigitem(
1389 b'format',
1394 b'format',
1390 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1395 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1391 default=False,
1396 default=False,
1392 experimental=True,
1397 experimental=True,
1393 )
1398 )
1394 coreconfigitem(
1399 coreconfigitem(
1395 b'format',
1400 b'format',
1396 b'dotencode',
1401 b'dotencode',
1397 default=True,
1402 default=True,
1398 )
1403 )
1399 coreconfigitem(
1404 coreconfigitem(
1400 b'format',
1405 b'format',
1401 b'generaldelta',
1406 b'generaldelta',
1402 default=False,
1407 default=False,
1403 experimental=True,
1408 experimental=True,
1404 )
1409 )
1405 coreconfigitem(
1410 coreconfigitem(
1406 b'format',
1411 b'format',
1407 b'manifestcachesize',
1412 b'manifestcachesize',
1408 default=None,
1413 default=None,
1409 experimental=True,
1414 experimental=True,
1410 )
1415 )
1411 coreconfigitem(
1416 coreconfigitem(
1412 b'format',
1417 b'format',
1413 b'maxchainlen',
1418 b'maxchainlen',
1414 default=dynamicdefault,
1419 default=dynamicdefault,
1415 experimental=True,
1420 experimental=True,
1416 )
1421 )
1417 coreconfigitem(
1422 coreconfigitem(
1418 b'format',
1423 b'format',
1419 b'obsstore-version',
1424 b'obsstore-version',
1420 default=None,
1425 default=None,
1421 )
1426 )
1422 coreconfigitem(
1427 coreconfigitem(
1423 b'format',
1428 b'format',
1424 b'sparse-revlog',
1429 b'sparse-revlog',
1425 default=True,
1430 default=True,
1426 )
1431 )
1427 coreconfigitem(
1432 coreconfigitem(
1428 b'format',
1433 b'format',
1429 b'revlog-compression',
1434 b'revlog-compression',
1430 default=lambda: [b'zstd', b'zlib'],
1435 default=lambda: [b'zstd', b'zlib'],
1431 alias=[(b'experimental', b'format.compression')],
1436 alias=[(b'experimental', b'format.compression')],
1432 )
1437 )
1433 # Experimental TODOs:
1438 # Experimental TODOs:
1434 #
1439 #
1435 # * Same as for revlogv2 (but for the reduction of the number of files)
1440 # * Same as for revlogv2 (but for the reduction of the number of files)
1436 # * Actually computing the rank of changesets
1441 # * Actually computing the rank of changesets
1437 # * Improvement to investigate
1442 # * Improvement to investigate
1438 # - storing .hgtags fnode
1443 # - storing .hgtags fnode
1439 # - storing branch related identifier
1444 # - storing branch related identifier
1440
1445
1441 coreconfigitem(
1446 coreconfigitem(
1442 b'format',
1447 b'format',
1443 b'exp-use-changelog-v2',
1448 b'exp-use-changelog-v2',
1444 default=None,
1449 default=None,
1445 experimental=True,
1450 experimental=True,
1446 )
1451 )
1447 coreconfigitem(
1452 coreconfigitem(
1448 b'format',
1453 b'format',
1449 b'usefncache',
1454 b'usefncache',
1450 default=True,
1455 default=True,
1451 )
1456 )
1452 coreconfigitem(
1457 coreconfigitem(
1453 b'format',
1458 b'format',
1454 b'usegeneraldelta',
1459 b'usegeneraldelta',
1455 default=True,
1460 default=True,
1456 )
1461 )
1457 coreconfigitem(
1462 coreconfigitem(
1458 b'format',
1463 b'format',
1459 b'usestore',
1464 b'usestore',
1460 default=True,
1465 default=True,
1461 )
1466 )
1462
1467
1463
1468
1464 def _persistent_nodemap_default():
1469 def _persistent_nodemap_default():
1465 """compute `use-persistent-nodemap` default value
1470 """compute `use-persistent-nodemap` default value
1466
1471
1467 The feature is disabled unless a fast implementation is available.
1472 The feature is disabled unless a fast implementation is available.
1468 """
1473 """
1469 from . import policy
1474 from . import policy
1470
1475
1471 return policy.importrust('revlog') is not None
1476 return policy.importrust('revlog') is not None
1472
1477
1473
1478
1474 coreconfigitem(
1479 coreconfigitem(
1475 b'format',
1480 b'format',
1476 b'use-persistent-nodemap',
1481 b'use-persistent-nodemap',
1477 default=_persistent_nodemap_default,
1482 default=_persistent_nodemap_default,
1478 )
1483 )
1479 coreconfigitem(
1484 coreconfigitem(
1480 b'format',
1485 b'format',
1481 b'exp-use-copies-side-data-changeset',
1486 b'exp-use-copies-side-data-changeset',
1482 default=False,
1487 default=False,
1483 experimental=True,
1488 experimental=True,
1484 )
1489 )
1485 coreconfigitem(
1490 coreconfigitem(
1486 b'format',
1491 b'format',
1487 b'use-share-safe',
1492 b'use-share-safe',
1488 default=True,
1493 default=True,
1489 )
1494 )
1490 coreconfigitem(
1495 coreconfigitem(
1491 b'format',
1496 b'format',
1492 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1497 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1493 default=False,
1498 default=False,
1494 experimental=True,
1499 experimental=True,
1495 )
1500 )
1496 coreconfigitem(
1501 coreconfigitem(
1497 b'format',
1502 b'format',
1498 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1503 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1499 default=False,
1504 default=False,
1500 experimental=True,
1505 experimental=True,
1501 )
1506 )
1502
1507
1503 # Moving this on by default means we are confident about the scaling of phases.
1508 # Moving this on by default means we are confident about the scaling of phases.
1504 # This is not garanteed to be the case at the time this message is written.
1509 # This is not garanteed to be the case at the time this message is written.
1505 coreconfigitem(
1510 coreconfigitem(
1506 b'format',
1511 b'format',
1507 b'use-internal-phase',
1512 b'use-internal-phase',
1508 default=False,
1513 default=False,
1509 experimental=True,
1514 experimental=True,
1510 )
1515 )
1511 # The interaction between the archived phase and obsolescence markers needs to
1516 # The interaction between the archived phase and obsolescence markers needs to
1512 # be sorted out before wider usage of this are to be considered.
1517 # be sorted out before wider usage of this are to be considered.
1513 #
1518 #
1514 # At the time this message is written, behavior when archiving obsolete
1519 # At the time this message is written, behavior when archiving obsolete
1515 # changeset differ significantly from stripping. As part of stripping, we also
1520 # changeset differ significantly from stripping. As part of stripping, we also
1516 # remove the obsolescence marker associated to the stripped changesets,
1521 # remove the obsolescence marker associated to the stripped changesets,
1517 # revealing the precedecessors changesets when applicable. When archiving, we
1522 # revealing the precedecessors changesets when applicable. When archiving, we
1518 # don't touch the obsolescence markers, keeping everything hidden. This can
1523 # don't touch the obsolescence markers, keeping everything hidden. This can
1519 # result in quite confusing situation for people combining exchanging draft
1524 # result in quite confusing situation for people combining exchanging draft
1520 # with the archived phases. As some markers needed by others may be skipped
1525 # with the archived phases. As some markers needed by others may be skipped
1521 # during exchange.
1526 # during exchange.
1522 coreconfigitem(
1527 coreconfigitem(
1523 b'format',
1528 b'format',
1524 b'exp-archived-phase',
1529 b'exp-archived-phase',
1525 default=False,
1530 default=False,
1526 experimental=True,
1531 experimental=True,
1527 )
1532 )
1528 coreconfigitem(
1533 coreconfigitem(
1529 b'shelve',
1534 b'shelve',
1530 b'store',
1535 b'store',
1531 default=b'internal',
1536 default=b'internal',
1532 experimental=True,
1537 experimental=True,
1533 )
1538 )
1534 coreconfigitem(
1539 coreconfigitem(
1535 b'fsmonitor',
1540 b'fsmonitor',
1536 b'warn_when_unused',
1541 b'warn_when_unused',
1537 default=True,
1542 default=True,
1538 )
1543 )
1539 coreconfigitem(
1544 coreconfigitem(
1540 b'fsmonitor',
1545 b'fsmonitor',
1541 b'warn_update_file_count',
1546 b'warn_update_file_count',
1542 default=50000,
1547 default=50000,
1543 )
1548 )
1544 coreconfigitem(
1549 coreconfigitem(
1545 b'fsmonitor',
1550 b'fsmonitor',
1546 b'warn_update_file_count_rust',
1551 b'warn_update_file_count_rust',
1547 default=400000,
1552 default=400000,
1548 )
1553 )
1549 coreconfigitem(
1554 coreconfigitem(
1550 b'help',
1555 b'help',
1551 br'hidden-command\..*',
1556 br'hidden-command\..*',
1552 default=False,
1557 default=False,
1553 generic=True,
1558 generic=True,
1554 )
1559 )
1555 coreconfigitem(
1560 coreconfigitem(
1556 b'help',
1561 b'help',
1557 br'hidden-topic\..*',
1562 br'hidden-topic\..*',
1558 default=False,
1563 default=False,
1559 generic=True,
1564 generic=True,
1560 )
1565 )
1561 coreconfigitem(
1566 coreconfigitem(
1562 b'hooks',
1567 b'hooks',
1563 b'[^:]*',
1568 b'[^:]*',
1564 default=dynamicdefault,
1569 default=dynamicdefault,
1565 generic=True,
1570 generic=True,
1566 )
1571 )
1567 coreconfigitem(
1572 coreconfigitem(
1568 b'hooks',
1573 b'hooks',
1569 b'.*:run-with-plain',
1574 b'.*:run-with-plain',
1570 default=True,
1575 default=True,
1571 generic=True,
1576 generic=True,
1572 )
1577 )
1573 coreconfigitem(
1578 coreconfigitem(
1574 b'hgweb-paths',
1579 b'hgweb-paths',
1575 b'.*',
1580 b'.*',
1576 default=list,
1581 default=list,
1577 generic=True,
1582 generic=True,
1578 )
1583 )
1579 coreconfigitem(
1584 coreconfigitem(
1580 b'hostfingerprints',
1585 b'hostfingerprints',
1581 b'.*',
1586 b'.*',
1582 default=list,
1587 default=list,
1583 generic=True,
1588 generic=True,
1584 )
1589 )
1585 coreconfigitem(
1590 coreconfigitem(
1586 b'hostsecurity',
1591 b'hostsecurity',
1587 b'ciphers',
1592 b'ciphers',
1588 default=None,
1593 default=None,
1589 )
1594 )
1590 coreconfigitem(
1595 coreconfigitem(
1591 b'hostsecurity',
1596 b'hostsecurity',
1592 b'minimumprotocol',
1597 b'minimumprotocol',
1593 default=dynamicdefault,
1598 default=dynamicdefault,
1594 )
1599 )
1595 coreconfigitem(
1600 coreconfigitem(
1596 b'hostsecurity',
1601 b'hostsecurity',
1597 b'.*:minimumprotocol$',
1602 b'.*:minimumprotocol$',
1598 default=dynamicdefault,
1603 default=dynamicdefault,
1599 generic=True,
1604 generic=True,
1600 )
1605 )
1601 coreconfigitem(
1606 coreconfigitem(
1602 b'hostsecurity',
1607 b'hostsecurity',
1603 b'.*:ciphers$',
1608 b'.*:ciphers$',
1604 default=dynamicdefault,
1609 default=dynamicdefault,
1605 generic=True,
1610 generic=True,
1606 )
1611 )
1607 coreconfigitem(
1612 coreconfigitem(
1608 b'hostsecurity',
1613 b'hostsecurity',
1609 b'.*:fingerprints$',
1614 b'.*:fingerprints$',
1610 default=list,
1615 default=list,
1611 generic=True,
1616 generic=True,
1612 )
1617 )
1613 coreconfigitem(
1618 coreconfigitem(
1614 b'hostsecurity',
1619 b'hostsecurity',
1615 b'.*:verifycertsfile$',
1620 b'.*:verifycertsfile$',
1616 default=None,
1621 default=None,
1617 generic=True,
1622 generic=True,
1618 )
1623 )
1619
1624
1620 coreconfigitem(
1625 coreconfigitem(
1621 b'http_proxy',
1626 b'http_proxy',
1622 b'always',
1627 b'always',
1623 default=False,
1628 default=False,
1624 )
1629 )
1625 coreconfigitem(
1630 coreconfigitem(
1626 b'http_proxy',
1631 b'http_proxy',
1627 b'host',
1632 b'host',
1628 default=None,
1633 default=None,
1629 )
1634 )
1630 coreconfigitem(
1635 coreconfigitem(
1631 b'http_proxy',
1636 b'http_proxy',
1632 b'no',
1637 b'no',
1633 default=list,
1638 default=list,
1634 )
1639 )
1635 coreconfigitem(
1640 coreconfigitem(
1636 b'http_proxy',
1641 b'http_proxy',
1637 b'passwd',
1642 b'passwd',
1638 default=None,
1643 default=None,
1639 )
1644 )
1640 coreconfigitem(
1645 coreconfigitem(
1641 b'http_proxy',
1646 b'http_proxy',
1642 b'user',
1647 b'user',
1643 default=None,
1648 default=None,
1644 )
1649 )
1645
1650
1646 coreconfigitem(
1651 coreconfigitem(
1647 b'http',
1652 b'http',
1648 b'timeout',
1653 b'timeout',
1649 default=None,
1654 default=None,
1650 )
1655 )
1651
1656
1652 coreconfigitem(
1657 coreconfigitem(
1653 b'logtoprocess',
1658 b'logtoprocess',
1654 b'commandexception',
1659 b'commandexception',
1655 default=None,
1660 default=None,
1656 )
1661 )
1657 coreconfigitem(
1662 coreconfigitem(
1658 b'logtoprocess',
1663 b'logtoprocess',
1659 b'commandfinish',
1664 b'commandfinish',
1660 default=None,
1665 default=None,
1661 )
1666 )
1662 coreconfigitem(
1667 coreconfigitem(
1663 b'logtoprocess',
1668 b'logtoprocess',
1664 b'command',
1669 b'command',
1665 default=None,
1670 default=None,
1666 )
1671 )
1667 coreconfigitem(
1672 coreconfigitem(
1668 b'logtoprocess',
1673 b'logtoprocess',
1669 b'develwarn',
1674 b'develwarn',
1670 default=None,
1675 default=None,
1671 )
1676 )
1672 coreconfigitem(
1677 coreconfigitem(
1673 b'logtoprocess',
1678 b'logtoprocess',
1674 b'uiblocked',
1679 b'uiblocked',
1675 default=None,
1680 default=None,
1676 )
1681 )
1677 coreconfigitem(
1682 coreconfigitem(
1678 b'merge',
1683 b'merge',
1679 b'checkunknown',
1684 b'checkunknown',
1680 default=b'abort',
1685 default=b'abort',
1681 )
1686 )
1682 coreconfigitem(
1687 coreconfigitem(
1683 b'merge',
1688 b'merge',
1684 b'checkignored',
1689 b'checkignored',
1685 default=b'abort',
1690 default=b'abort',
1686 )
1691 )
1687 coreconfigitem(
1692 coreconfigitem(
1688 b'experimental',
1693 b'experimental',
1689 b'merge.checkpathconflicts',
1694 b'merge.checkpathconflicts',
1690 default=False,
1695 default=False,
1691 )
1696 )
1692 coreconfigitem(
1697 coreconfigitem(
1693 b'merge',
1698 b'merge',
1694 b'followcopies',
1699 b'followcopies',
1695 default=True,
1700 default=True,
1696 )
1701 )
1697 coreconfigitem(
1702 coreconfigitem(
1698 b'merge',
1703 b'merge',
1699 b'on-failure',
1704 b'on-failure',
1700 default=b'continue',
1705 default=b'continue',
1701 )
1706 )
1702 coreconfigitem(
1707 coreconfigitem(
1703 b'merge',
1708 b'merge',
1704 b'preferancestor',
1709 b'preferancestor',
1705 default=lambda: [b'*'],
1710 default=lambda: [b'*'],
1706 experimental=True,
1711 experimental=True,
1707 )
1712 )
1708 coreconfigitem(
1713 coreconfigitem(
1709 b'merge',
1714 b'merge',
1710 b'strict-capability-check',
1715 b'strict-capability-check',
1711 default=False,
1716 default=False,
1712 )
1717 )
1713 coreconfigitem(
1718 coreconfigitem(
1714 b'merge',
1719 b'merge',
1715 b'disable-partial-tools',
1720 b'disable-partial-tools',
1716 default=False,
1721 default=False,
1717 experimental=True,
1722 experimental=True,
1718 )
1723 )
1719 coreconfigitem(
1724 coreconfigitem(
1720 b'partial-merge-tools',
1725 b'partial-merge-tools',
1721 b'.*',
1726 b'.*',
1722 default=None,
1727 default=None,
1723 generic=True,
1728 generic=True,
1724 experimental=True,
1729 experimental=True,
1725 )
1730 )
1726 coreconfigitem(
1731 coreconfigitem(
1727 b'partial-merge-tools',
1732 b'partial-merge-tools',
1728 br'.*\.patterns',
1733 br'.*\.patterns',
1729 default=dynamicdefault,
1734 default=dynamicdefault,
1730 generic=True,
1735 generic=True,
1731 priority=-1,
1736 priority=-1,
1732 experimental=True,
1737 experimental=True,
1733 )
1738 )
1734 coreconfigitem(
1739 coreconfigitem(
1735 b'partial-merge-tools',
1740 b'partial-merge-tools',
1736 br'.*\.executable$',
1741 br'.*\.executable$',
1737 default=dynamicdefault,
1742 default=dynamicdefault,
1738 generic=True,
1743 generic=True,
1739 priority=-1,
1744 priority=-1,
1740 experimental=True,
1745 experimental=True,
1741 )
1746 )
1742 coreconfigitem(
1747 coreconfigitem(
1743 b'partial-merge-tools',
1748 b'partial-merge-tools',
1744 br'.*\.order',
1749 br'.*\.order',
1745 default=0,
1750 default=0,
1746 generic=True,
1751 generic=True,
1747 priority=-1,
1752 priority=-1,
1748 experimental=True,
1753 experimental=True,
1749 )
1754 )
1750 coreconfigitem(
1755 coreconfigitem(
1751 b'partial-merge-tools',
1756 b'partial-merge-tools',
1752 br'.*\.args',
1757 br'.*\.args',
1753 default=b"$local $base $other",
1758 default=b"$local $base $other",
1754 generic=True,
1759 generic=True,
1755 priority=-1,
1760 priority=-1,
1756 experimental=True,
1761 experimental=True,
1757 )
1762 )
1758 coreconfigitem(
1763 coreconfigitem(
1759 b'partial-merge-tools',
1764 b'partial-merge-tools',
1760 br'.*\.disable',
1765 br'.*\.disable',
1761 default=False,
1766 default=False,
1762 generic=True,
1767 generic=True,
1763 priority=-1,
1768 priority=-1,
1764 experimental=True,
1769 experimental=True,
1765 )
1770 )
1766 coreconfigitem(
1771 coreconfigitem(
1767 b'merge-tools',
1772 b'merge-tools',
1768 b'.*',
1773 b'.*',
1769 default=None,
1774 default=None,
1770 generic=True,
1775 generic=True,
1771 )
1776 )
1772 coreconfigitem(
1777 coreconfigitem(
1773 b'merge-tools',
1778 b'merge-tools',
1774 br'.*\.args$',
1779 br'.*\.args$',
1775 default=b"$local $base $other",
1780 default=b"$local $base $other",
1776 generic=True,
1781 generic=True,
1777 priority=-1,
1782 priority=-1,
1778 )
1783 )
1779 coreconfigitem(
1784 coreconfigitem(
1780 b'merge-tools',
1785 b'merge-tools',
1781 br'.*\.binary$',
1786 br'.*\.binary$',
1782 default=False,
1787 default=False,
1783 generic=True,
1788 generic=True,
1784 priority=-1,
1789 priority=-1,
1785 )
1790 )
1786 coreconfigitem(
1791 coreconfigitem(
1787 b'merge-tools',
1792 b'merge-tools',
1788 br'.*\.check$',
1793 br'.*\.check$',
1789 default=list,
1794 default=list,
1790 generic=True,
1795 generic=True,
1791 priority=-1,
1796 priority=-1,
1792 )
1797 )
1793 coreconfigitem(
1798 coreconfigitem(
1794 b'merge-tools',
1799 b'merge-tools',
1795 br'.*\.checkchanged$',
1800 br'.*\.checkchanged$',
1796 default=False,
1801 default=False,
1797 generic=True,
1802 generic=True,
1798 priority=-1,
1803 priority=-1,
1799 )
1804 )
1800 coreconfigitem(
1805 coreconfigitem(
1801 b'merge-tools',
1806 b'merge-tools',
1802 br'.*\.executable$',
1807 br'.*\.executable$',
1803 default=dynamicdefault,
1808 default=dynamicdefault,
1804 generic=True,
1809 generic=True,
1805 priority=-1,
1810 priority=-1,
1806 )
1811 )
1807 coreconfigitem(
1812 coreconfigitem(
1808 b'merge-tools',
1813 b'merge-tools',
1809 br'.*\.fixeol$',
1814 br'.*\.fixeol$',
1810 default=False,
1815 default=False,
1811 generic=True,
1816 generic=True,
1812 priority=-1,
1817 priority=-1,
1813 )
1818 )
1814 coreconfigitem(
1819 coreconfigitem(
1815 b'merge-tools',
1820 b'merge-tools',
1816 br'.*\.gui$',
1821 br'.*\.gui$',
1817 default=False,
1822 default=False,
1818 generic=True,
1823 generic=True,
1819 priority=-1,
1824 priority=-1,
1820 )
1825 )
1821 coreconfigitem(
1826 coreconfigitem(
1822 b'merge-tools',
1827 b'merge-tools',
1823 br'.*\.mergemarkers$',
1828 br'.*\.mergemarkers$',
1824 default=b'basic',
1829 default=b'basic',
1825 generic=True,
1830 generic=True,
1826 priority=-1,
1831 priority=-1,
1827 )
1832 )
1828 coreconfigitem(
1833 coreconfigitem(
1829 b'merge-tools',
1834 b'merge-tools',
1830 br'.*\.mergemarkertemplate$',
1835 br'.*\.mergemarkertemplate$',
1831 default=dynamicdefault, # take from command-templates.mergemarker
1836 default=dynamicdefault, # take from command-templates.mergemarker
1832 generic=True,
1837 generic=True,
1833 priority=-1,
1838 priority=-1,
1834 )
1839 )
1835 coreconfigitem(
1840 coreconfigitem(
1836 b'merge-tools',
1841 b'merge-tools',
1837 br'.*\.priority$',
1842 br'.*\.priority$',
1838 default=0,
1843 default=0,
1839 generic=True,
1844 generic=True,
1840 priority=-1,
1845 priority=-1,
1841 )
1846 )
1842 coreconfigitem(
1847 coreconfigitem(
1843 b'merge-tools',
1848 b'merge-tools',
1844 br'.*\.premerge$',
1849 br'.*\.premerge$',
1845 default=dynamicdefault,
1850 default=dynamicdefault,
1846 generic=True,
1851 generic=True,
1847 priority=-1,
1852 priority=-1,
1848 )
1853 )
1849 coreconfigitem(
1854 coreconfigitem(
1850 b'merge-tools',
1855 b'merge-tools',
1851 br'.*\.regappend$',
1856 br'.*\.regappend$',
1852 default=b"",
1857 default=b"",
1853 generic=True,
1858 generic=True,
1854 priority=-1,
1859 priority=-1,
1855 )
1860 )
1856 coreconfigitem(
1861 coreconfigitem(
1857 b'merge-tools',
1862 b'merge-tools',
1858 br'.*\.symlink$',
1863 br'.*\.symlink$',
1859 default=False,
1864 default=False,
1860 generic=True,
1865 generic=True,
1861 priority=-1,
1866 priority=-1,
1862 )
1867 )
1863 coreconfigitem(
1868 coreconfigitem(
1864 b'pager',
1869 b'pager',
1865 b'attend-.*',
1870 b'attend-.*',
1866 default=dynamicdefault,
1871 default=dynamicdefault,
1867 generic=True,
1872 generic=True,
1868 )
1873 )
1869 coreconfigitem(
1874 coreconfigitem(
1870 b'pager',
1875 b'pager',
1871 b'ignore',
1876 b'ignore',
1872 default=list,
1877 default=list,
1873 )
1878 )
1874 coreconfigitem(
1879 coreconfigitem(
1875 b'pager',
1880 b'pager',
1876 b'pager',
1881 b'pager',
1877 default=dynamicdefault,
1882 default=dynamicdefault,
1878 )
1883 )
1879 coreconfigitem(
1884 coreconfigitem(
1880 b'patch',
1885 b'patch',
1881 b'eol',
1886 b'eol',
1882 default=b'strict',
1887 default=b'strict',
1883 )
1888 )
1884 coreconfigitem(
1889 coreconfigitem(
1885 b'patch',
1890 b'patch',
1886 b'fuzz',
1891 b'fuzz',
1887 default=2,
1892 default=2,
1888 )
1893 )
1889 coreconfigitem(
1894 coreconfigitem(
1890 b'paths',
1895 b'paths',
1891 b'default',
1896 b'default',
1892 default=None,
1897 default=None,
1893 )
1898 )
1894 coreconfigitem(
1899 coreconfigitem(
1895 b'paths',
1900 b'paths',
1896 b'default-push',
1901 b'default-push',
1897 default=None,
1902 default=None,
1898 )
1903 )
1899 coreconfigitem(
1904 coreconfigitem(
1900 b'paths',
1905 b'paths',
1901 b'[^:]*',
1906 b'[^:]*',
1902 default=None,
1907 default=None,
1903 generic=True,
1908 generic=True,
1904 )
1909 )
1905 coreconfigitem(
1910 coreconfigitem(
1906 b'paths',
1911 b'paths',
1907 b'.*:bookmarks.mode',
1912 b'.*:bookmarks.mode',
1908 default='default',
1913 default='default',
1909 generic=True,
1914 generic=True,
1910 )
1915 )
1911 coreconfigitem(
1916 coreconfigitem(
1912 b'paths',
1917 b'paths',
1913 b'.*:multi-urls',
1918 b'.*:multi-urls',
1914 default=False,
1919 default=False,
1915 generic=True,
1920 generic=True,
1916 )
1921 )
1917 coreconfigitem(
1922 coreconfigitem(
1918 b'paths',
1923 b'paths',
1919 b'.*:pushrev',
1924 b'.*:pushrev',
1920 default=None,
1925 default=None,
1921 generic=True,
1926 generic=True,
1922 )
1927 )
1923 coreconfigitem(
1928 coreconfigitem(
1924 b'paths',
1929 b'paths',
1925 b'.*:pushurl',
1930 b'.*:pushurl',
1926 default=None,
1931 default=None,
1927 generic=True,
1932 generic=True,
1928 )
1933 )
1929 coreconfigitem(
1934 coreconfigitem(
1930 b'paths',
1935 b'paths',
1931 b'.*:pulled-delta-reuse-policy',
1936 b'.*:pulled-delta-reuse-policy',
1932 default=None,
1937 default=None,
1933 generic=True,
1938 generic=True,
1934 )
1939 )
1935 coreconfigitem(
1940 coreconfigitem(
1936 b'phases',
1941 b'phases',
1937 b'checksubrepos',
1942 b'checksubrepos',
1938 default=b'follow',
1943 default=b'follow',
1939 )
1944 )
1940 coreconfigitem(
1945 coreconfigitem(
1941 b'phases',
1946 b'phases',
1942 b'new-commit',
1947 b'new-commit',
1943 default=b'draft',
1948 default=b'draft',
1944 )
1949 )
1945 coreconfigitem(
1950 coreconfigitem(
1946 b'phases',
1951 b'phases',
1947 b'publish',
1952 b'publish',
1948 default=True,
1953 default=True,
1949 )
1954 )
1950 coreconfigitem(
1955 coreconfigitem(
1951 b'profiling',
1956 b'profiling',
1952 b'enabled',
1957 b'enabled',
1953 default=False,
1958 default=False,
1954 )
1959 )
1955 coreconfigitem(
1960 coreconfigitem(
1956 b'profiling',
1961 b'profiling',
1957 b'format',
1962 b'format',
1958 default=b'text',
1963 default=b'text',
1959 )
1964 )
1960 coreconfigitem(
1965 coreconfigitem(
1961 b'profiling',
1966 b'profiling',
1962 b'freq',
1967 b'freq',
1963 default=1000,
1968 default=1000,
1964 )
1969 )
1965 coreconfigitem(
1970 coreconfigitem(
1966 b'profiling',
1971 b'profiling',
1967 b'limit',
1972 b'limit',
1968 default=30,
1973 default=30,
1969 )
1974 )
1970 coreconfigitem(
1975 coreconfigitem(
1971 b'profiling',
1976 b'profiling',
1972 b'nested',
1977 b'nested',
1973 default=0,
1978 default=0,
1974 )
1979 )
1975 coreconfigitem(
1980 coreconfigitem(
1976 b'profiling',
1981 b'profiling',
1977 b'output',
1982 b'output',
1978 default=None,
1983 default=None,
1979 )
1984 )
1980 coreconfigitem(
1985 coreconfigitem(
1981 b'profiling',
1986 b'profiling',
1982 b'showmax',
1987 b'showmax',
1983 default=0.999,
1988 default=0.999,
1984 )
1989 )
1985 coreconfigitem(
1990 coreconfigitem(
1986 b'profiling',
1991 b'profiling',
1987 b'showmin',
1992 b'showmin',
1988 default=dynamicdefault,
1993 default=dynamicdefault,
1989 )
1994 )
1990 coreconfigitem(
1995 coreconfigitem(
1991 b'profiling',
1996 b'profiling',
1992 b'showtime',
1997 b'showtime',
1993 default=True,
1998 default=True,
1994 )
1999 )
1995 coreconfigitem(
2000 coreconfigitem(
1996 b'profiling',
2001 b'profiling',
1997 b'sort',
2002 b'sort',
1998 default=b'inlinetime',
2003 default=b'inlinetime',
1999 )
2004 )
2000 coreconfigitem(
2005 coreconfigitem(
2001 b'profiling',
2006 b'profiling',
2002 b'statformat',
2007 b'statformat',
2003 default=b'hotpath',
2008 default=b'hotpath',
2004 )
2009 )
2005 coreconfigitem(
2010 coreconfigitem(
2006 b'profiling',
2011 b'profiling',
2007 b'time-track',
2012 b'time-track',
2008 default=dynamicdefault,
2013 default=dynamicdefault,
2009 )
2014 )
2010 coreconfigitem(
2015 coreconfigitem(
2011 b'profiling',
2016 b'profiling',
2012 b'type',
2017 b'type',
2013 default=b'stat',
2018 default=b'stat',
2014 )
2019 )
2015 coreconfigitem(
2020 coreconfigitem(
2016 b'progress',
2021 b'progress',
2017 b'assume-tty',
2022 b'assume-tty',
2018 default=False,
2023 default=False,
2019 )
2024 )
2020 coreconfigitem(
2025 coreconfigitem(
2021 b'progress',
2026 b'progress',
2022 b'changedelay',
2027 b'changedelay',
2023 default=1,
2028 default=1,
2024 )
2029 )
2025 coreconfigitem(
2030 coreconfigitem(
2026 b'progress',
2031 b'progress',
2027 b'clear-complete',
2032 b'clear-complete',
2028 default=True,
2033 default=True,
2029 )
2034 )
2030 coreconfigitem(
2035 coreconfigitem(
2031 b'progress',
2036 b'progress',
2032 b'debug',
2037 b'debug',
2033 default=False,
2038 default=False,
2034 )
2039 )
2035 coreconfigitem(
2040 coreconfigitem(
2036 b'progress',
2041 b'progress',
2037 b'delay',
2042 b'delay',
2038 default=3,
2043 default=3,
2039 )
2044 )
2040 coreconfigitem(
2045 coreconfigitem(
2041 b'progress',
2046 b'progress',
2042 b'disable',
2047 b'disable',
2043 default=False,
2048 default=False,
2044 )
2049 )
2045 coreconfigitem(
2050 coreconfigitem(
2046 b'progress',
2051 b'progress',
2047 b'estimateinterval',
2052 b'estimateinterval',
2048 default=60.0,
2053 default=60.0,
2049 )
2054 )
2050 coreconfigitem(
2055 coreconfigitem(
2051 b'progress',
2056 b'progress',
2052 b'format',
2057 b'format',
2053 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2058 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2054 )
2059 )
2055 coreconfigitem(
2060 coreconfigitem(
2056 b'progress',
2061 b'progress',
2057 b'refresh',
2062 b'refresh',
2058 default=0.1,
2063 default=0.1,
2059 )
2064 )
2060 coreconfigitem(
2065 coreconfigitem(
2061 b'progress',
2066 b'progress',
2062 b'width',
2067 b'width',
2063 default=dynamicdefault,
2068 default=dynamicdefault,
2064 )
2069 )
2065 coreconfigitem(
2070 coreconfigitem(
2066 b'pull',
2071 b'pull',
2067 b'confirm',
2072 b'confirm',
2068 default=False,
2073 default=False,
2069 )
2074 )
2070 coreconfigitem(
2075 coreconfigitem(
2071 b'push',
2076 b'push',
2072 b'pushvars.server',
2077 b'pushvars.server',
2073 default=False,
2078 default=False,
2074 )
2079 )
2075 coreconfigitem(
2080 coreconfigitem(
2076 b'rewrite',
2081 b'rewrite',
2077 b'backup-bundle',
2082 b'backup-bundle',
2078 default=True,
2083 default=True,
2079 alias=[(b'ui', b'history-editing-backup')],
2084 alias=[(b'ui', b'history-editing-backup')],
2080 )
2085 )
2081 coreconfigitem(
2086 coreconfigitem(
2082 b'rewrite',
2087 b'rewrite',
2083 b'update-timestamp',
2088 b'update-timestamp',
2084 default=False,
2089 default=False,
2085 )
2090 )
2086 coreconfigitem(
2091 coreconfigitem(
2087 b'rewrite',
2092 b'rewrite',
2088 b'empty-successor',
2093 b'empty-successor',
2089 default=b'skip',
2094 default=b'skip',
2090 experimental=True,
2095 experimental=True,
2091 )
2096 )
2092 # experimental as long as format.use-dirstate-v2 is.
2097 # experimental as long as format.use-dirstate-v2 is.
2093 coreconfigitem(
2098 coreconfigitem(
2094 b'storage',
2099 b'storage',
2095 b'dirstate-v2.slow-path',
2100 b'dirstate-v2.slow-path',
2096 default=b"abort",
2101 default=b"abort",
2097 experimental=True,
2102 experimental=True,
2098 )
2103 )
2099 coreconfigitem(
2104 coreconfigitem(
2100 b'storage',
2105 b'storage',
2101 b'new-repo-backend',
2106 b'new-repo-backend',
2102 default=b'revlogv1',
2107 default=b'revlogv1',
2103 experimental=True,
2108 experimental=True,
2104 )
2109 )
2105 coreconfigitem(
2110 coreconfigitem(
2106 b'storage',
2111 b'storage',
2107 b'revlog.optimize-delta-parent-choice',
2112 b'revlog.optimize-delta-parent-choice',
2108 default=True,
2113 default=True,
2109 alias=[(b'format', b'aggressivemergedeltas')],
2114 alias=[(b'format', b'aggressivemergedeltas')],
2110 )
2115 )
2111 coreconfigitem(
2116 coreconfigitem(
2112 b'storage',
2117 b'storage',
2113 b'revlog.delta-parent-search.candidate-group-chunk-size',
2118 b'revlog.delta-parent-search.candidate-group-chunk-size',
2114 default=20,
2119 default=20,
2115 )
2120 )
2116 coreconfigitem(
2121 coreconfigitem(
2117 b'storage',
2122 b'storage',
2118 b'revlog.issue6528.fix-incoming',
2123 b'revlog.issue6528.fix-incoming',
2119 default=True,
2124 default=True,
2120 )
2125 )
2121 # experimental as long as rust is experimental (or a C version is implemented)
2126 # experimental as long as rust is experimental (or a C version is implemented)
2122 coreconfigitem(
2127 coreconfigitem(
2123 b'storage',
2128 b'storage',
2124 b'revlog.persistent-nodemap.mmap',
2129 b'revlog.persistent-nodemap.mmap',
2125 default=True,
2130 default=True,
2126 )
2131 )
2127 # experimental as long as format.use-persistent-nodemap is.
2132 # experimental as long as format.use-persistent-nodemap is.
2128 coreconfigitem(
2133 coreconfigitem(
2129 b'storage',
2134 b'storage',
2130 b'revlog.persistent-nodemap.slow-path',
2135 b'revlog.persistent-nodemap.slow-path',
2131 default=b"abort",
2136 default=b"abort",
2132 )
2137 )
2133
2138
2134 coreconfigitem(
2139 coreconfigitem(
2135 b'storage',
2140 b'storage',
2136 b'revlog.reuse-external-delta',
2141 b'revlog.reuse-external-delta',
2137 default=True,
2142 default=True,
2138 )
2143 )
2139 # This option is True unless `format.generaldelta` is set.
2144 # This option is True unless `format.generaldelta` is set.
2140 coreconfigitem(
2145 coreconfigitem(
2141 b'storage',
2146 b'storage',
2142 b'revlog.reuse-external-delta-parent',
2147 b'revlog.reuse-external-delta-parent',
2143 default=None,
2148 default=None,
2144 )
2149 )
2145 coreconfigitem(
2150 coreconfigitem(
2146 b'storage',
2151 b'storage',
2147 b'revlog.zlib.level',
2152 b'revlog.zlib.level',
2148 default=None,
2153 default=None,
2149 )
2154 )
2150 coreconfigitem(
2155 coreconfigitem(
2151 b'storage',
2156 b'storage',
2152 b'revlog.zstd.level',
2157 b'revlog.zstd.level',
2153 default=None,
2158 default=None,
2154 )
2159 )
2155 coreconfigitem(
2160 coreconfigitem(
2156 b'server',
2161 b'server',
2157 b'bookmarks-pushkey-compat',
2162 b'bookmarks-pushkey-compat',
2158 default=True,
2163 default=True,
2159 )
2164 )
2160 coreconfigitem(
2165 coreconfigitem(
2161 b'server',
2166 b'server',
2162 b'bundle1',
2167 b'bundle1',
2163 default=True,
2168 default=True,
2164 )
2169 )
2165 coreconfigitem(
2170 coreconfigitem(
2166 b'server',
2171 b'server',
2167 b'bundle1gd',
2172 b'bundle1gd',
2168 default=None,
2173 default=None,
2169 )
2174 )
2170 coreconfigitem(
2175 coreconfigitem(
2171 b'server',
2176 b'server',
2172 b'bundle1.pull',
2177 b'bundle1.pull',
2173 default=None,
2178 default=None,
2174 )
2179 )
2175 coreconfigitem(
2180 coreconfigitem(
2176 b'server',
2181 b'server',
2177 b'bundle1gd.pull',
2182 b'bundle1gd.pull',
2178 default=None,
2183 default=None,
2179 )
2184 )
2180 coreconfigitem(
2185 coreconfigitem(
2181 b'server',
2186 b'server',
2182 b'bundle1.push',
2187 b'bundle1.push',
2183 default=None,
2188 default=None,
2184 )
2189 )
2185 coreconfigitem(
2190 coreconfigitem(
2186 b'server',
2191 b'server',
2187 b'bundle1gd.push',
2192 b'bundle1gd.push',
2188 default=None,
2193 default=None,
2189 )
2194 )
2190 coreconfigitem(
2195 coreconfigitem(
2191 b'server',
2196 b'server',
2192 b'bundle2.stream',
2197 b'bundle2.stream',
2193 default=True,
2198 default=True,
2194 alias=[(b'experimental', b'bundle2.stream')],
2199 alias=[(b'experimental', b'bundle2.stream')],
2195 )
2200 )
2196 coreconfigitem(
2201 coreconfigitem(
2197 b'server',
2202 b'server',
2198 b'compressionengines',
2203 b'compressionengines',
2199 default=list,
2204 default=list,
2200 )
2205 )
2201 coreconfigitem(
2206 coreconfigitem(
2202 b'server',
2207 b'server',
2203 b'concurrent-push-mode',
2208 b'concurrent-push-mode',
2204 default=b'check-related',
2209 default=b'check-related',
2205 )
2210 )
2206 coreconfigitem(
2211 coreconfigitem(
2207 b'server',
2212 b'server',
2208 b'disablefullbundle',
2213 b'disablefullbundle',
2209 default=False,
2214 default=False,
2210 )
2215 )
2211 coreconfigitem(
2216 coreconfigitem(
2212 b'server',
2217 b'server',
2213 b'maxhttpheaderlen',
2218 b'maxhttpheaderlen',
2214 default=1024,
2219 default=1024,
2215 )
2220 )
2216 coreconfigitem(
2221 coreconfigitem(
2217 b'server',
2222 b'server',
2218 b'pullbundle',
2223 b'pullbundle',
2219 default=True,
2224 default=True,
2220 )
2225 )
2221 coreconfigitem(
2226 coreconfigitem(
2222 b'server',
2227 b'server',
2223 b'preferuncompressed',
2228 b'preferuncompressed',
2224 default=False,
2229 default=False,
2225 )
2230 )
2226 coreconfigitem(
2231 coreconfigitem(
2227 b'server',
2232 b'server',
2228 b'streamunbundle',
2233 b'streamunbundle',
2229 default=False,
2234 default=False,
2230 )
2235 )
2231 coreconfigitem(
2236 coreconfigitem(
2232 b'server',
2237 b'server',
2233 b'uncompressed',
2238 b'uncompressed',
2234 default=True,
2239 default=True,
2235 )
2240 )
2236 coreconfigitem(
2241 coreconfigitem(
2237 b'server',
2242 b'server',
2238 b'uncompressedallowsecret',
2243 b'uncompressedallowsecret',
2239 default=False,
2244 default=False,
2240 )
2245 )
2241 coreconfigitem(
2246 coreconfigitem(
2242 b'server',
2247 b'server',
2243 b'view',
2248 b'view',
2244 default=b'served',
2249 default=b'served',
2245 )
2250 )
2246 coreconfigitem(
2251 coreconfigitem(
2247 b'server',
2252 b'server',
2248 b'validate',
2253 b'validate',
2249 default=False,
2254 default=False,
2250 )
2255 )
2251 coreconfigitem(
2256 coreconfigitem(
2252 b'server',
2257 b'server',
2253 b'zliblevel',
2258 b'zliblevel',
2254 default=-1,
2259 default=-1,
2255 )
2260 )
2256 coreconfigitem(
2261 coreconfigitem(
2257 b'server',
2262 b'server',
2258 b'zstdlevel',
2263 b'zstdlevel',
2259 default=3,
2264 default=3,
2260 )
2265 )
2261 coreconfigitem(
2266 coreconfigitem(
2262 b'share',
2267 b'share',
2263 b'pool',
2268 b'pool',
2264 default=None,
2269 default=None,
2265 )
2270 )
2266 coreconfigitem(
2271 coreconfigitem(
2267 b'share',
2272 b'share',
2268 b'poolnaming',
2273 b'poolnaming',
2269 default=b'identity',
2274 default=b'identity',
2270 )
2275 )
2271 coreconfigitem(
2276 coreconfigitem(
2272 b'share',
2277 b'share',
2273 b'safe-mismatch.source-not-safe',
2278 b'safe-mismatch.source-not-safe',
2274 default=b'abort',
2279 default=b'abort',
2275 )
2280 )
2276 coreconfigitem(
2281 coreconfigitem(
2277 b'share',
2282 b'share',
2278 b'safe-mismatch.source-safe',
2283 b'safe-mismatch.source-safe',
2279 default=b'abort',
2284 default=b'abort',
2280 )
2285 )
2281 coreconfigitem(
2286 coreconfigitem(
2282 b'share',
2287 b'share',
2283 b'safe-mismatch.source-not-safe.warn',
2288 b'safe-mismatch.source-not-safe.warn',
2284 default=True,
2289 default=True,
2285 )
2290 )
2286 coreconfigitem(
2291 coreconfigitem(
2287 b'share',
2292 b'share',
2288 b'safe-mismatch.source-safe.warn',
2293 b'safe-mismatch.source-safe.warn',
2289 default=True,
2294 default=True,
2290 )
2295 )
2291 coreconfigitem(
2296 coreconfigitem(
2292 b'share',
2297 b'share',
2293 b'safe-mismatch.source-not-safe:verbose-upgrade',
2298 b'safe-mismatch.source-not-safe:verbose-upgrade',
2294 default=True,
2299 default=True,
2295 )
2300 )
2296 coreconfigitem(
2301 coreconfigitem(
2297 b'share',
2302 b'share',
2298 b'safe-mismatch.source-safe:verbose-upgrade',
2303 b'safe-mismatch.source-safe:verbose-upgrade',
2299 default=True,
2304 default=True,
2300 )
2305 )
2301 coreconfigitem(
2306 coreconfigitem(
2302 b'shelve',
2307 b'shelve',
2303 b'maxbackups',
2308 b'maxbackups',
2304 default=10,
2309 default=10,
2305 )
2310 )
2306 coreconfigitem(
2311 coreconfigitem(
2307 b'smtp',
2312 b'smtp',
2308 b'host',
2313 b'host',
2309 default=None,
2314 default=None,
2310 )
2315 )
2311 coreconfigitem(
2316 coreconfigitem(
2312 b'smtp',
2317 b'smtp',
2313 b'local_hostname',
2318 b'local_hostname',
2314 default=None,
2319 default=None,
2315 )
2320 )
2316 coreconfigitem(
2321 coreconfigitem(
2317 b'smtp',
2322 b'smtp',
2318 b'password',
2323 b'password',
2319 default=None,
2324 default=None,
2320 )
2325 )
2321 coreconfigitem(
2326 coreconfigitem(
2322 b'smtp',
2327 b'smtp',
2323 b'port',
2328 b'port',
2324 default=dynamicdefault,
2329 default=dynamicdefault,
2325 )
2330 )
2326 coreconfigitem(
2331 coreconfigitem(
2327 b'smtp',
2332 b'smtp',
2328 b'tls',
2333 b'tls',
2329 default=b'none',
2334 default=b'none',
2330 )
2335 )
2331 coreconfigitem(
2336 coreconfigitem(
2332 b'smtp',
2337 b'smtp',
2333 b'username',
2338 b'username',
2334 default=None,
2339 default=None,
2335 )
2340 )
2336 coreconfigitem(
2341 coreconfigitem(
2337 b'sparse',
2342 b'sparse',
2338 b'missingwarning',
2343 b'missingwarning',
2339 default=True,
2344 default=True,
2340 experimental=True,
2345 experimental=True,
2341 )
2346 )
2342 coreconfigitem(
2347 coreconfigitem(
2343 b'subrepos',
2348 b'subrepos',
2344 b'allowed',
2349 b'allowed',
2345 default=dynamicdefault, # to make backporting simpler
2350 default=dynamicdefault, # to make backporting simpler
2346 )
2351 )
2347 coreconfigitem(
2352 coreconfigitem(
2348 b'subrepos',
2353 b'subrepos',
2349 b'hg:allowed',
2354 b'hg:allowed',
2350 default=dynamicdefault,
2355 default=dynamicdefault,
2351 )
2356 )
2352 coreconfigitem(
2357 coreconfigitem(
2353 b'subrepos',
2358 b'subrepos',
2354 b'git:allowed',
2359 b'git:allowed',
2355 default=dynamicdefault,
2360 default=dynamicdefault,
2356 )
2361 )
2357 coreconfigitem(
2362 coreconfigitem(
2358 b'subrepos',
2363 b'subrepos',
2359 b'svn:allowed',
2364 b'svn:allowed',
2360 default=dynamicdefault,
2365 default=dynamicdefault,
2361 )
2366 )
2362 coreconfigitem(
2367 coreconfigitem(
2363 b'templates',
2368 b'templates',
2364 b'.*',
2369 b'.*',
2365 default=None,
2370 default=None,
2366 generic=True,
2371 generic=True,
2367 )
2372 )
2368 coreconfigitem(
2373 coreconfigitem(
2369 b'templateconfig',
2374 b'templateconfig',
2370 b'.*',
2375 b'.*',
2371 default=dynamicdefault,
2376 default=dynamicdefault,
2372 generic=True,
2377 generic=True,
2373 )
2378 )
2374 coreconfigitem(
2379 coreconfigitem(
2375 b'trusted',
2380 b'trusted',
2376 b'groups',
2381 b'groups',
2377 default=list,
2382 default=list,
2378 )
2383 )
2379 coreconfigitem(
2384 coreconfigitem(
2380 b'trusted',
2385 b'trusted',
2381 b'users',
2386 b'users',
2382 default=list,
2387 default=list,
2383 )
2388 )
2384 coreconfigitem(
2389 coreconfigitem(
2385 b'ui',
2390 b'ui',
2386 b'_usedassubrepo',
2391 b'_usedassubrepo',
2387 default=False,
2392 default=False,
2388 )
2393 )
2389 coreconfigitem(
2394 coreconfigitem(
2390 b'ui',
2395 b'ui',
2391 b'allowemptycommit',
2396 b'allowemptycommit',
2392 default=False,
2397 default=False,
2393 )
2398 )
2394 coreconfigitem(
2399 coreconfigitem(
2395 b'ui',
2400 b'ui',
2396 b'archivemeta',
2401 b'archivemeta',
2397 default=True,
2402 default=True,
2398 )
2403 )
2399 coreconfigitem(
2404 coreconfigitem(
2400 b'ui',
2405 b'ui',
2401 b'askusername',
2406 b'askusername',
2402 default=False,
2407 default=False,
2403 )
2408 )
2404 coreconfigitem(
2409 coreconfigitem(
2405 b'ui',
2410 b'ui',
2406 b'available-memory',
2411 b'available-memory',
2407 default=None,
2412 default=None,
2408 )
2413 )
2409
2414
2410 coreconfigitem(
2415 coreconfigitem(
2411 b'ui',
2416 b'ui',
2412 b'clonebundlefallback',
2417 b'clonebundlefallback',
2413 default=False,
2418 default=False,
2414 )
2419 )
2415 coreconfigitem(
2420 coreconfigitem(
2416 b'ui',
2421 b'ui',
2417 b'clonebundleprefers',
2422 b'clonebundleprefers',
2418 default=list,
2423 default=list,
2419 )
2424 )
2420 coreconfigitem(
2425 coreconfigitem(
2421 b'ui',
2426 b'ui',
2422 b'clonebundles',
2427 b'clonebundles',
2423 default=True,
2428 default=True,
2424 )
2429 )
2425 coreconfigitem(
2430 coreconfigitem(
2426 b'ui',
2431 b'ui',
2427 b'color',
2432 b'color',
2428 default=b'auto',
2433 default=b'auto',
2429 )
2434 )
2430 coreconfigitem(
2435 coreconfigitem(
2431 b'ui',
2436 b'ui',
2432 b'commitsubrepos',
2437 b'commitsubrepos',
2433 default=False,
2438 default=False,
2434 )
2439 )
2435 coreconfigitem(
2440 coreconfigitem(
2436 b'ui',
2441 b'ui',
2437 b'debug',
2442 b'debug',
2438 default=False,
2443 default=False,
2439 )
2444 )
2440 coreconfigitem(
2445 coreconfigitem(
2441 b'ui',
2446 b'ui',
2442 b'debugger',
2447 b'debugger',
2443 default=None,
2448 default=None,
2444 )
2449 )
2445 coreconfigitem(
2450 coreconfigitem(
2446 b'ui',
2451 b'ui',
2447 b'editor',
2452 b'editor',
2448 default=dynamicdefault,
2453 default=dynamicdefault,
2449 )
2454 )
2450 coreconfigitem(
2455 coreconfigitem(
2451 b'ui',
2456 b'ui',
2452 b'detailed-exit-code',
2457 b'detailed-exit-code',
2453 default=False,
2458 default=False,
2454 experimental=True,
2459 experimental=True,
2455 )
2460 )
2456 coreconfigitem(
2461 coreconfigitem(
2457 b'ui',
2462 b'ui',
2458 b'fallbackencoding',
2463 b'fallbackencoding',
2459 default=None,
2464 default=None,
2460 )
2465 )
2461 coreconfigitem(
2466 coreconfigitem(
2462 b'ui',
2467 b'ui',
2463 b'forcecwd',
2468 b'forcecwd',
2464 default=None,
2469 default=None,
2465 )
2470 )
2466 coreconfigitem(
2471 coreconfigitem(
2467 b'ui',
2472 b'ui',
2468 b'forcemerge',
2473 b'forcemerge',
2469 default=None,
2474 default=None,
2470 )
2475 )
2471 coreconfigitem(
2476 coreconfigitem(
2472 b'ui',
2477 b'ui',
2473 b'formatdebug',
2478 b'formatdebug',
2474 default=False,
2479 default=False,
2475 )
2480 )
2476 coreconfigitem(
2481 coreconfigitem(
2477 b'ui',
2482 b'ui',
2478 b'formatjson',
2483 b'formatjson',
2479 default=False,
2484 default=False,
2480 )
2485 )
2481 coreconfigitem(
2486 coreconfigitem(
2482 b'ui',
2487 b'ui',
2483 b'formatted',
2488 b'formatted',
2484 default=None,
2489 default=None,
2485 )
2490 )
2486 coreconfigitem(
2491 coreconfigitem(
2487 b'ui',
2492 b'ui',
2488 b'interactive',
2493 b'interactive',
2489 default=None,
2494 default=None,
2490 )
2495 )
2491 coreconfigitem(
2496 coreconfigitem(
2492 b'ui',
2497 b'ui',
2493 b'interface',
2498 b'interface',
2494 default=None,
2499 default=None,
2495 )
2500 )
2496 coreconfigitem(
2501 coreconfigitem(
2497 b'ui',
2502 b'ui',
2498 b'interface.chunkselector',
2503 b'interface.chunkselector',
2499 default=None,
2504 default=None,
2500 )
2505 )
2501 coreconfigitem(
2506 coreconfigitem(
2502 b'ui',
2507 b'ui',
2503 b'large-file-limit',
2508 b'large-file-limit',
2504 default=10 * (2 ** 20),
2509 default=10 * (2 ** 20),
2505 )
2510 )
2506 coreconfigitem(
2511 coreconfigitem(
2507 b'ui',
2512 b'ui',
2508 b'logblockedtimes',
2513 b'logblockedtimes',
2509 default=False,
2514 default=False,
2510 )
2515 )
2511 coreconfigitem(
2516 coreconfigitem(
2512 b'ui',
2517 b'ui',
2513 b'merge',
2518 b'merge',
2514 default=None,
2519 default=None,
2515 )
2520 )
2516 coreconfigitem(
2521 coreconfigitem(
2517 b'ui',
2522 b'ui',
2518 b'mergemarkers',
2523 b'mergemarkers',
2519 default=b'basic',
2524 default=b'basic',
2520 )
2525 )
2521 coreconfigitem(
2526 coreconfigitem(
2522 b'ui',
2527 b'ui',
2523 b'message-output',
2528 b'message-output',
2524 default=b'stdio',
2529 default=b'stdio',
2525 )
2530 )
2526 coreconfigitem(
2531 coreconfigitem(
2527 b'ui',
2532 b'ui',
2528 b'nontty',
2533 b'nontty',
2529 default=False,
2534 default=False,
2530 )
2535 )
2531 coreconfigitem(
2536 coreconfigitem(
2532 b'ui',
2537 b'ui',
2533 b'origbackuppath',
2538 b'origbackuppath',
2534 default=None,
2539 default=None,
2535 )
2540 )
2536 coreconfigitem(
2541 coreconfigitem(
2537 b'ui',
2542 b'ui',
2538 b'paginate',
2543 b'paginate',
2539 default=True,
2544 default=True,
2540 )
2545 )
2541 coreconfigitem(
2546 coreconfigitem(
2542 b'ui',
2547 b'ui',
2543 b'patch',
2548 b'patch',
2544 default=None,
2549 default=None,
2545 )
2550 )
2546 coreconfigitem(
2551 coreconfigitem(
2547 b'ui',
2552 b'ui',
2548 b'portablefilenames',
2553 b'portablefilenames',
2549 default=b'warn',
2554 default=b'warn',
2550 )
2555 )
2551 coreconfigitem(
2556 coreconfigitem(
2552 b'ui',
2557 b'ui',
2553 b'promptecho',
2558 b'promptecho',
2554 default=False,
2559 default=False,
2555 )
2560 )
2556 coreconfigitem(
2561 coreconfigitem(
2557 b'ui',
2562 b'ui',
2558 b'quiet',
2563 b'quiet',
2559 default=False,
2564 default=False,
2560 )
2565 )
2561 coreconfigitem(
2566 coreconfigitem(
2562 b'ui',
2567 b'ui',
2563 b'quietbookmarkmove',
2568 b'quietbookmarkmove',
2564 default=False,
2569 default=False,
2565 )
2570 )
2566 coreconfigitem(
2571 coreconfigitem(
2567 b'ui',
2572 b'ui',
2568 b'relative-paths',
2573 b'relative-paths',
2569 default=b'legacy',
2574 default=b'legacy',
2570 )
2575 )
2571 coreconfigitem(
2576 coreconfigitem(
2572 b'ui',
2577 b'ui',
2573 b'remotecmd',
2578 b'remotecmd',
2574 default=b'hg',
2579 default=b'hg',
2575 )
2580 )
2576 coreconfigitem(
2581 coreconfigitem(
2577 b'ui',
2582 b'ui',
2578 b'report_untrusted',
2583 b'report_untrusted',
2579 default=True,
2584 default=True,
2580 )
2585 )
2581 coreconfigitem(
2586 coreconfigitem(
2582 b'ui',
2587 b'ui',
2583 b'rollback',
2588 b'rollback',
2584 default=True,
2589 default=True,
2585 )
2590 )
2586 coreconfigitem(
2591 coreconfigitem(
2587 b'ui',
2592 b'ui',
2588 b'signal-safe-lock',
2593 b'signal-safe-lock',
2589 default=True,
2594 default=True,
2590 )
2595 )
2591 coreconfigitem(
2596 coreconfigitem(
2592 b'ui',
2597 b'ui',
2593 b'slash',
2598 b'slash',
2594 default=False,
2599 default=False,
2595 )
2600 )
2596 coreconfigitem(
2601 coreconfigitem(
2597 b'ui',
2602 b'ui',
2598 b'ssh',
2603 b'ssh',
2599 default=b'ssh',
2604 default=b'ssh',
2600 )
2605 )
2601 coreconfigitem(
2606 coreconfigitem(
2602 b'ui',
2607 b'ui',
2603 b'ssherrorhint',
2608 b'ssherrorhint',
2604 default=None,
2609 default=None,
2605 )
2610 )
2606 coreconfigitem(
2611 coreconfigitem(
2607 b'ui',
2612 b'ui',
2608 b'statuscopies',
2613 b'statuscopies',
2609 default=False,
2614 default=False,
2610 )
2615 )
2611 coreconfigitem(
2616 coreconfigitem(
2612 b'ui',
2617 b'ui',
2613 b'strict',
2618 b'strict',
2614 default=False,
2619 default=False,
2615 )
2620 )
2616 coreconfigitem(
2621 coreconfigitem(
2617 b'ui',
2622 b'ui',
2618 b'style',
2623 b'style',
2619 default=b'',
2624 default=b'',
2620 )
2625 )
2621 coreconfigitem(
2626 coreconfigitem(
2622 b'ui',
2627 b'ui',
2623 b'supportcontact',
2628 b'supportcontact',
2624 default=None,
2629 default=None,
2625 )
2630 )
2626 coreconfigitem(
2631 coreconfigitem(
2627 b'ui',
2632 b'ui',
2628 b'textwidth',
2633 b'textwidth',
2629 default=78,
2634 default=78,
2630 )
2635 )
2631 coreconfigitem(
2636 coreconfigitem(
2632 b'ui',
2637 b'ui',
2633 b'timeout',
2638 b'timeout',
2634 default=b'600',
2639 default=b'600',
2635 )
2640 )
2636 coreconfigitem(
2641 coreconfigitem(
2637 b'ui',
2642 b'ui',
2638 b'timeout.warn',
2643 b'timeout.warn',
2639 default=0,
2644 default=0,
2640 )
2645 )
2641 coreconfigitem(
2646 coreconfigitem(
2642 b'ui',
2647 b'ui',
2643 b'timestamp-output',
2648 b'timestamp-output',
2644 default=False,
2649 default=False,
2645 )
2650 )
2646 coreconfigitem(
2651 coreconfigitem(
2647 b'ui',
2652 b'ui',
2648 b'traceback',
2653 b'traceback',
2649 default=False,
2654 default=False,
2650 )
2655 )
2651 coreconfigitem(
2656 coreconfigitem(
2652 b'ui',
2657 b'ui',
2653 b'tweakdefaults',
2658 b'tweakdefaults',
2654 default=False,
2659 default=False,
2655 )
2660 )
2656 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2661 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2657 coreconfigitem(
2662 coreconfigitem(
2658 b'ui',
2663 b'ui',
2659 b'verbose',
2664 b'verbose',
2660 default=False,
2665 default=False,
2661 )
2666 )
2662 coreconfigitem(
2667 coreconfigitem(
2663 b'verify',
2668 b'verify',
2664 b'skipflags',
2669 b'skipflags',
2665 default=0,
2670 default=0,
2666 )
2671 )
2667 coreconfigitem(
2672 coreconfigitem(
2668 b'web',
2673 b'web',
2669 b'allowbz2',
2674 b'allowbz2',
2670 default=False,
2675 default=False,
2671 )
2676 )
2672 coreconfigitem(
2677 coreconfigitem(
2673 b'web',
2678 b'web',
2674 b'allowgz',
2679 b'allowgz',
2675 default=False,
2680 default=False,
2676 )
2681 )
2677 coreconfigitem(
2682 coreconfigitem(
2678 b'web',
2683 b'web',
2679 b'allow-pull',
2684 b'allow-pull',
2680 alias=[(b'web', b'allowpull')],
2685 alias=[(b'web', b'allowpull')],
2681 default=True,
2686 default=True,
2682 )
2687 )
2683 coreconfigitem(
2688 coreconfigitem(
2684 b'web',
2689 b'web',
2685 b'allow-push',
2690 b'allow-push',
2686 alias=[(b'web', b'allow_push')],
2691 alias=[(b'web', b'allow_push')],
2687 default=list,
2692 default=list,
2688 )
2693 )
2689 coreconfigitem(
2694 coreconfigitem(
2690 b'web',
2695 b'web',
2691 b'allowzip',
2696 b'allowzip',
2692 default=False,
2697 default=False,
2693 )
2698 )
2694 coreconfigitem(
2699 coreconfigitem(
2695 b'web',
2700 b'web',
2696 b'archivesubrepos',
2701 b'archivesubrepos',
2697 default=False,
2702 default=False,
2698 )
2703 )
2699 coreconfigitem(
2704 coreconfigitem(
2700 b'web',
2705 b'web',
2701 b'cache',
2706 b'cache',
2702 default=True,
2707 default=True,
2703 )
2708 )
2704 coreconfigitem(
2709 coreconfigitem(
2705 b'web',
2710 b'web',
2706 b'comparisoncontext',
2711 b'comparisoncontext',
2707 default=5,
2712 default=5,
2708 )
2713 )
2709 coreconfigitem(
2714 coreconfigitem(
2710 b'web',
2715 b'web',
2711 b'contact',
2716 b'contact',
2712 default=None,
2717 default=None,
2713 )
2718 )
2714 coreconfigitem(
2719 coreconfigitem(
2715 b'web',
2720 b'web',
2716 b'deny_push',
2721 b'deny_push',
2717 default=list,
2722 default=list,
2718 )
2723 )
2719 coreconfigitem(
2724 coreconfigitem(
2720 b'web',
2725 b'web',
2721 b'guessmime',
2726 b'guessmime',
2722 default=False,
2727 default=False,
2723 )
2728 )
2724 coreconfigitem(
2729 coreconfigitem(
2725 b'web',
2730 b'web',
2726 b'hidden',
2731 b'hidden',
2727 default=False,
2732 default=False,
2728 )
2733 )
2729 coreconfigitem(
2734 coreconfigitem(
2730 b'web',
2735 b'web',
2731 b'labels',
2736 b'labels',
2732 default=list,
2737 default=list,
2733 )
2738 )
2734 coreconfigitem(
2739 coreconfigitem(
2735 b'web',
2740 b'web',
2736 b'logoimg',
2741 b'logoimg',
2737 default=b'hglogo.png',
2742 default=b'hglogo.png',
2738 )
2743 )
2739 coreconfigitem(
2744 coreconfigitem(
2740 b'web',
2745 b'web',
2741 b'logourl',
2746 b'logourl',
2742 default=b'https://mercurial-scm.org/',
2747 default=b'https://mercurial-scm.org/',
2743 )
2748 )
2744 coreconfigitem(
2749 coreconfigitem(
2745 b'web',
2750 b'web',
2746 b'accesslog',
2751 b'accesslog',
2747 default=b'-',
2752 default=b'-',
2748 )
2753 )
2749 coreconfigitem(
2754 coreconfigitem(
2750 b'web',
2755 b'web',
2751 b'address',
2756 b'address',
2752 default=b'',
2757 default=b'',
2753 )
2758 )
2754 coreconfigitem(
2759 coreconfigitem(
2755 b'web',
2760 b'web',
2756 b'allow-archive',
2761 b'allow-archive',
2757 alias=[(b'web', b'allow_archive')],
2762 alias=[(b'web', b'allow_archive')],
2758 default=list,
2763 default=list,
2759 )
2764 )
2760 coreconfigitem(
2765 coreconfigitem(
2761 b'web',
2766 b'web',
2762 b'allow_read',
2767 b'allow_read',
2763 default=list,
2768 default=list,
2764 )
2769 )
2765 coreconfigitem(
2770 coreconfigitem(
2766 b'web',
2771 b'web',
2767 b'baseurl',
2772 b'baseurl',
2768 default=None,
2773 default=None,
2769 )
2774 )
2770 coreconfigitem(
2775 coreconfigitem(
2771 b'web',
2776 b'web',
2772 b'cacerts',
2777 b'cacerts',
2773 default=None,
2778 default=None,
2774 )
2779 )
2775 coreconfigitem(
2780 coreconfigitem(
2776 b'web',
2781 b'web',
2777 b'certificate',
2782 b'certificate',
2778 default=None,
2783 default=None,
2779 )
2784 )
2780 coreconfigitem(
2785 coreconfigitem(
2781 b'web',
2786 b'web',
2782 b'collapse',
2787 b'collapse',
2783 default=False,
2788 default=False,
2784 )
2789 )
2785 coreconfigitem(
2790 coreconfigitem(
2786 b'web',
2791 b'web',
2787 b'csp',
2792 b'csp',
2788 default=None,
2793 default=None,
2789 )
2794 )
2790 coreconfigitem(
2795 coreconfigitem(
2791 b'web',
2796 b'web',
2792 b'deny_read',
2797 b'deny_read',
2793 default=list,
2798 default=list,
2794 )
2799 )
2795 coreconfigitem(
2800 coreconfigitem(
2796 b'web',
2801 b'web',
2797 b'descend',
2802 b'descend',
2798 default=True,
2803 default=True,
2799 )
2804 )
2800 coreconfigitem(
2805 coreconfigitem(
2801 b'web',
2806 b'web',
2802 b'description',
2807 b'description',
2803 default=b"",
2808 default=b"",
2804 )
2809 )
2805 coreconfigitem(
2810 coreconfigitem(
2806 b'web',
2811 b'web',
2807 b'encoding',
2812 b'encoding',
2808 default=lambda: encoding.encoding,
2813 default=lambda: encoding.encoding,
2809 )
2814 )
2810 coreconfigitem(
2815 coreconfigitem(
2811 b'web',
2816 b'web',
2812 b'errorlog',
2817 b'errorlog',
2813 default=b'-',
2818 default=b'-',
2814 )
2819 )
2815 coreconfigitem(
2820 coreconfigitem(
2816 b'web',
2821 b'web',
2817 b'ipv6',
2822 b'ipv6',
2818 default=False,
2823 default=False,
2819 )
2824 )
2820 coreconfigitem(
2825 coreconfigitem(
2821 b'web',
2826 b'web',
2822 b'maxchanges',
2827 b'maxchanges',
2823 default=10,
2828 default=10,
2824 )
2829 )
2825 coreconfigitem(
2830 coreconfigitem(
2826 b'web',
2831 b'web',
2827 b'maxfiles',
2832 b'maxfiles',
2828 default=10,
2833 default=10,
2829 )
2834 )
2830 coreconfigitem(
2835 coreconfigitem(
2831 b'web',
2836 b'web',
2832 b'maxshortchanges',
2837 b'maxshortchanges',
2833 default=60,
2838 default=60,
2834 )
2839 )
2835 coreconfigitem(
2840 coreconfigitem(
2836 b'web',
2841 b'web',
2837 b'motd',
2842 b'motd',
2838 default=b'',
2843 default=b'',
2839 )
2844 )
2840 coreconfigitem(
2845 coreconfigitem(
2841 b'web',
2846 b'web',
2842 b'name',
2847 b'name',
2843 default=dynamicdefault,
2848 default=dynamicdefault,
2844 )
2849 )
2845 coreconfigitem(
2850 coreconfigitem(
2846 b'web',
2851 b'web',
2847 b'port',
2852 b'port',
2848 default=8000,
2853 default=8000,
2849 )
2854 )
2850 coreconfigitem(
2855 coreconfigitem(
2851 b'web',
2856 b'web',
2852 b'prefix',
2857 b'prefix',
2853 default=b'',
2858 default=b'',
2854 )
2859 )
2855 coreconfigitem(
2860 coreconfigitem(
2856 b'web',
2861 b'web',
2857 b'push_ssl',
2862 b'push_ssl',
2858 default=True,
2863 default=True,
2859 )
2864 )
2860 coreconfigitem(
2865 coreconfigitem(
2861 b'web',
2866 b'web',
2862 b'refreshinterval',
2867 b'refreshinterval',
2863 default=20,
2868 default=20,
2864 )
2869 )
2865 coreconfigitem(
2870 coreconfigitem(
2866 b'web',
2871 b'web',
2867 b'server-header',
2872 b'server-header',
2868 default=None,
2873 default=None,
2869 )
2874 )
2870 coreconfigitem(
2875 coreconfigitem(
2871 b'web',
2876 b'web',
2872 b'static',
2877 b'static',
2873 default=None,
2878 default=None,
2874 )
2879 )
2875 coreconfigitem(
2880 coreconfigitem(
2876 b'web',
2881 b'web',
2877 b'staticurl',
2882 b'staticurl',
2878 default=None,
2883 default=None,
2879 )
2884 )
2880 coreconfigitem(
2885 coreconfigitem(
2881 b'web',
2886 b'web',
2882 b'stripes',
2887 b'stripes',
2883 default=1,
2888 default=1,
2884 )
2889 )
2885 coreconfigitem(
2890 coreconfigitem(
2886 b'web',
2891 b'web',
2887 b'style',
2892 b'style',
2888 default=b'paper',
2893 default=b'paper',
2889 )
2894 )
2890 coreconfigitem(
2895 coreconfigitem(
2891 b'web',
2896 b'web',
2892 b'templates',
2897 b'templates',
2893 default=None,
2898 default=None,
2894 )
2899 )
2895 coreconfigitem(
2900 coreconfigitem(
2896 b'web',
2901 b'web',
2897 b'view',
2902 b'view',
2898 default=b'served',
2903 default=b'served',
2899 experimental=True,
2904 experimental=True,
2900 )
2905 )
2901 coreconfigitem(
2906 coreconfigitem(
2902 b'worker',
2907 b'worker',
2903 b'backgroundclose',
2908 b'backgroundclose',
2904 default=dynamicdefault,
2909 default=dynamicdefault,
2905 )
2910 )
2906 # Windows defaults to a limit of 512 open files. A buffer of 128
2911 # Windows defaults to a limit of 512 open files. A buffer of 128
2907 # should give us enough headway.
2912 # should give us enough headway.
2908 coreconfigitem(
2913 coreconfigitem(
2909 b'worker',
2914 b'worker',
2910 b'backgroundclosemaxqueue',
2915 b'backgroundclosemaxqueue',
2911 default=384,
2916 default=384,
2912 )
2917 )
2913 coreconfigitem(
2918 coreconfigitem(
2914 b'worker',
2919 b'worker',
2915 b'backgroundcloseminfilecount',
2920 b'backgroundcloseminfilecount',
2916 default=2048,
2921 default=2048,
2917 )
2922 )
2918 coreconfigitem(
2923 coreconfigitem(
2919 b'worker',
2924 b'worker',
2920 b'backgroundclosethreadcount',
2925 b'backgroundclosethreadcount',
2921 default=4,
2926 default=4,
2922 )
2927 )
2923 coreconfigitem(
2928 coreconfigitem(
2924 b'worker',
2929 b'worker',
2925 b'enabled',
2930 b'enabled',
2926 default=True,
2931 default=True,
2927 )
2932 )
2928 coreconfigitem(
2933 coreconfigitem(
2929 b'worker',
2934 b'worker',
2930 b'numcpus',
2935 b'numcpus',
2931 default=None,
2936 default=None,
2932 )
2937 )
2933
2938
2934 # Rebase related configuration moved to core because other extension are doing
2939 # Rebase related configuration moved to core because other extension are doing
2935 # strange things. For example, shelve import the extensions to reuse some bit
2940 # strange things. For example, shelve import the extensions to reuse some bit
2936 # without formally loading it.
2941 # without formally loading it.
2937 coreconfigitem(
2942 coreconfigitem(
2938 b'commands',
2943 b'commands',
2939 b'rebase.requiredest',
2944 b'rebase.requiredest',
2940 default=False,
2945 default=False,
2941 )
2946 )
2942 coreconfigitem(
2947 coreconfigitem(
2943 b'experimental',
2948 b'experimental',
2944 b'rebaseskipobsolete',
2949 b'rebaseskipobsolete',
2945 default=True,
2950 default=True,
2946 )
2951 )
2947 coreconfigitem(
2952 coreconfigitem(
2948 b'rebase',
2953 b'rebase',
2949 b'singletransaction',
2954 b'singletransaction',
2950 default=False,
2955 default=False,
2951 )
2956 )
2952 coreconfigitem(
2957 coreconfigitem(
2953 b'rebase',
2958 b'rebase',
2954 b'experimental.inmemory',
2959 b'experimental.inmemory',
2955 default=False,
2960 default=False,
2956 )
2961 )
2957
2962
2958 # This setting controls creation of a rebase_source extra field
2963 # This setting controls creation of a rebase_source extra field
2959 # during rebase. When False, no such field is created. This is
2964 # during rebase. When False, no such field is created. This is
2960 # useful eg for incrementally converting changesets and then
2965 # useful eg for incrementally converting changesets and then
2961 # rebasing them onto an existing repo.
2966 # rebasing them onto an existing repo.
2962 # WARNING: this is an advanced setting reserved for people who know
2967 # WARNING: this is an advanced setting reserved for people who know
2963 # exactly what they are doing. Misuse of this setting can easily
2968 # exactly what they are doing. Misuse of this setting can easily
2964 # result in obsmarker cycles and a vivid headache.
2969 # result in obsmarker cycles and a vivid headache.
2965 coreconfigitem(
2970 coreconfigitem(
2966 b'rebase',
2971 b'rebase',
2967 b'store-source',
2972 b'store-source',
2968 default=True,
2973 default=True,
2969 experimental=True,
2974 experimental=True,
2970 )
2975 )
@@ -1,287 +1,314 b''
1 # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
1 # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
4 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9
9
10 import base64
10 import base64
11 import errno
11 import errno
12 import mimetypes
12 import mimetypes
13 import os
13 import os
14 import stat
14 import stat
15
15
16 from ..i18n import _
16 from ..pycompat import (
17 from ..pycompat import (
17 getattr,
18 getattr,
18 open,
19 open,
19 )
20 )
20 from .. import (
21 from .. import (
21 encoding,
22 encoding,
22 pycompat,
23 pycompat,
23 templater,
24 templater,
24 util,
25 util,
25 )
26 )
26
27
27 httpserver = util.httpserver
28 httpserver = util.httpserver
28
29
29 HTTP_OK = 200
30 HTTP_OK = 200
30 HTTP_CREATED = 201
31 HTTP_CREATED = 201
31 HTTP_NOT_MODIFIED = 304
32 HTTP_NOT_MODIFIED = 304
32 HTTP_BAD_REQUEST = 400
33 HTTP_BAD_REQUEST = 400
33 HTTP_UNAUTHORIZED = 401
34 HTTP_UNAUTHORIZED = 401
34 HTTP_FORBIDDEN = 403
35 HTTP_FORBIDDEN = 403
35 HTTP_NOT_FOUND = 404
36 HTTP_NOT_FOUND = 404
36 HTTP_METHOD_NOT_ALLOWED = 405
37 HTTP_METHOD_NOT_ALLOWED = 405
37 HTTP_NOT_ACCEPTABLE = 406
38 HTTP_NOT_ACCEPTABLE = 406
38 HTTP_UNSUPPORTED_MEDIA_TYPE = 415
39 HTTP_UNSUPPORTED_MEDIA_TYPE = 415
39 HTTP_SERVER_ERROR = 500
40 HTTP_SERVER_ERROR = 500
40
41
41
42
42 def ismember(ui, username, userlist):
43 def ismember(ui, username, userlist):
43 """Check if username is a member of userlist.
44 """Check if username is a member of userlist.
44
45
45 If userlist has a single '*' member, all users are considered members.
46 If userlist has a single '*' member, all users are considered members.
46 Can be overridden by extensions to provide more complex authorization
47 Can be overridden by extensions to provide more complex authorization
47 schemes.
48 schemes.
48 """
49 """
49 return userlist == [b'*'] or username in userlist
50 return userlist == [b'*'] or username in userlist
50
51
51
52
53 def hashiddenaccess(repo, req):
54 if bool(req.qsparams.get(b'access-hidden')):
55 # Disable this by default for now. Main risk is to get critical
56 # information exposed through this. This is expecially risky if
57 # someone decided to make a changeset secret for good reason, but
58 # its predecessors are still draft.
59 #
60 # The feature is currently experimental, so we can still decide to
61 # change the default.
62 ui = repo.ui
63 allow = ui.configlist(b'experimental', b'server.allow-hidden-access')
64 user = req.remoteuser
65 if allow and ismember(ui, user, allow):
66 return True
67 else:
68 msg = (
69 _(
70 b'ignoring request to access hidden changeset by '
71 b'unauthorized user: %r\n'
72 )
73 % user
74 )
75 ui.warn(msg)
76 return False
77
78
52 def checkauthz(hgweb, req, op):
79 def checkauthz(hgweb, req, op):
53 """Check permission for operation based on request data (including
80 """Check permission for operation based on request data (including
54 authentication info). Return if op allowed, else raise an ErrorResponse
81 authentication info). Return if op allowed, else raise an ErrorResponse
55 exception."""
82 exception."""
56
83
57 user = req.remoteuser
84 user = req.remoteuser
58
85
59 deny_read = hgweb.configlist(b'web', b'deny_read')
86 deny_read = hgweb.configlist(b'web', b'deny_read')
60 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)):
87 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)):
61 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
88 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
62
89
63 allow_read = hgweb.configlist(b'web', b'allow_read')
90 allow_read = hgweb.configlist(b'web', b'allow_read')
64 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)):
91 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)):
65 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
92 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
66
93
67 if op == b'pull' and not hgweb.allowpull:
94 if op == b'pull' and not hgweb.allowpull:
68 raise ErrorResponse(HTTP_UNAUTHORIZED, b'pull not authorized')
95 raise ErrorResponse(HTTP_UNAUTHORIZED, b'pull not authorized')
69 elif op == b'pull' or op is None: # op is None for interface requests
96 elif op == b'pull' or op is None: # op is None for interface requests
70 return
97 return
71
98
72 # Allow LFS uploading via PUT requests
99 # Allow LFS uploading via PUT requests
73 if op == b'upload':
100 if op == b'upload':
74 if req.method != b'PUT':
101 if req.method != b'PUT':
75 msg = b'upload requires PUT request'
102 msg = b'upload requires PUT request'
76 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
103 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
77 # enforce that you can only push using POST requests
104 # enforce that you can only push using POST requests
78 elif req.method != b'POST':
105 elif req.method != b'POST':
79 msg = b'push requires POST request'
106 msg = b'push requires POST request'
80 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
107 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
81
108
82 # require ssl by default for pushing, auth info cannot be sniffed
109 # require ssl by default for pushing, auth info cannot be sniffed
83 # and replayed
110 # and replayed
84 if hgweb.configbool(b'web', b'push_ssl') and req.urlscheme != b'https':
111 if hgweb.configbool(b'web', b'push_ssl') and req.urlscheme != b'https':
85 raise ErrorResponse(HTTP_FORBIDDEN, b'ssl required')
112 raise ErrorResponse(HTTP_FORBIDDEN, b'ssl required')
86
113
87 deny = hgweb.configlist(b'web', b'deny_push')
114 deny = hgweb.configlist(b'web', b'deny_push')
88 if deny and (not user or ismember(hgweb.repo.ui, user, deny)):
115 if deny and (not user or ismember(hgweb.repo.ui, user, deny)):
89 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
116 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
90
117
91 allow = hgweb.configlist(b'web', b'allow-push')
118 allow = hgweb.configlist(b'web', b'allow-push')
92 if not (allow and ismember(hgweb.repo.ui, user, allow)):
119 if not (allow and ismember(hgweb.repo.ui, user, allow)):
93 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
120 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
94
121
95
122
96 # Hooks for hgweb permission checks; extensions can add hooks here.
123 # Hooks for hgweb permission checks; extensions can add hooks here.
97 # Each hook is invoked like this: hook(hgweb, request, operation),
124 # Each hook is invoked like this: hook(hgweb, request, operation),
98 # where operation is either read, pull, push or upload. Hooks should either
125 # where operation is either read, pull, push or upload. Hooks should either
99 # raise an ErrorResponse exception, or just return.
126 # raise an ErrorResponse exception, or just return.
100 #
127 #
101 # It is possible to do both authentication and authorization through
128 # It is possible to do both authentication and authorization through
102 # this.
129 # this.
103 permhooks = [checkauthz]
130 permhooks = [checkauthz]
104
131
105
132
106 class ErrorResponse(Exception):
133 class ErrorResponse(Exception):
107 def __init__(self, code, message=None, headers=None):
134 def __init__(self, code, message=None, headers=None):
108 if message is None:
135 if message is None:
109 message = _statusmessage(code)
136 message = _statusmessage(code)
110 Exception.__init__(self, pycompat.sysstr(message))
137 Exception.__init__(self, pycompat.sysstr(message))
111 self.code = code
138 self.code = code
112 if headers is None:
139 if headers is None:
113 headers = []
140 headers = []
114 self.headers = headers
141 self.headers = headers
115 self.message = message
142 self.message = message
116
143
117
144
118 class continuereader:
145 class continuereader:
119 """File object wrapper to handle HTTP 100-continue.
146 """File object wrapper to handle HTTP 100-continue.
120
147
121 This is used by servers so they automatically handle Expect: 100-continue
148 This is used by servers so they automatically handle Expect: 100-continue
122 request headers. On first read of the request body, the 100 Continue
149 request headers. On first read of the request body, the 100 Continue
123 response is sent. This should trigger the client into actually sending
150 response is sent. This should trigger the client into actually sending
124 the request body.
151 the request body.
125 """
152 """
126
153
127 def __init__(self, f, write):
154 def __init__(self, f, write):
128 self.f = f
155 self.f = f
129 self._write = write
156 self._write = write
130 self.continued = False
157 self.continued = False
131
158
132 def read(self, amt=-1):
159 def read(self, amt=-1):
133 if not self.continued:
160 if not self.continued:
134 self.continued = True
161 self.continued = True
135 self._write(b'HTTP/1.1 100 Continue\r\n\r\n')
162 self._write(b'HTTP/1.1 100 Continue\r\n\r\n')
136 return self.f.read(amt)
163 return self.f.read(amt)
137
164
138 def __getattr__(self, attr):
165 def __getattr__(self, attr):
139 if attr in (b'close', b'readline', b'readlines', b'__iter__'):
166 if attr in (b'close', b'readline', b'readlines', b'__iter__'):
140 return getattr(self.f, attr)
167 return getattr(self.f, attr)
141 raise AttributeError
168 raise AttributeError
142
169
143
170
144 def _statusmessage(code):
171 def _statusmessage(code):
145 responses = httpserver.basehttprequesthandler.responses
172 responses = httpserver.basehttprequesthandler.responses
146 return pycompat.bytesurl(responses.get(code, ('Error', 'Unknown error'))[0])
173 return pycompat.bytesurl(responses.get(code, ('Error', 'Unknown error'))[0])
147
174
148
175
149 def statusmessage(code, message=None):
176 def statusmessage(code, message=None):
150 return b'%d %s' % (code, message or _statusmessage(code))
177 return b'%d %s' % (code, message or _statusmessage(code))
151
178
152
179
153 def get_stat(spath, fn):
180 def get_stat(spath, fn):
154 """stat fn if it exists, spath otherwise"""
181 """stat fn if it exists, spath otherwise"""
155 cl_path = os.path.join(spath, fn)
182 cl_path = os.path.join(spath, fn)
156 if os.path.exists(cl_path):
183 if os.path.exists(cl_path):
157 return os.stat(cl_path)
184 return os.stat(cl_path)
158 else:
185 else:
159 return os.stat(spath)
186 return os.stat(spath)
160
187
161
188
162 def get_mtime(spath):
189 def get_mtime(spath):
163 return get_stat(spath, b"00changelog.i")[stat.ST_MTIME]
190 return get_stat(spath, b"00changelog.i")[stat.ST_MTIME]
164
191
165
192
166 def ispathsafe(path):
193 def ispathsafe(path):
167 """Determine if a path is safe to use for filesystem access."""
194 """Determine if a path is safe to use for filesystem access."""
168 parts = path.split(b'/')
195 parts = path.split(b'/')
169 for part in parts:
196 for part in parts:
170 if (
197 if (
171 part in (b'', pycompat.oscurdir, pycompat.ospardir)
198 part in (b'', pycompat.oscurdir, pycompat.ospardir)
172 or pycompat.ossep in part
199 or pycompat.ossep in part
173 or pycompat.osaltsep is not None
200 or pycompat.osaltsep is not None
174 and pycompat.osaltsep in part
201 and pycompat.osaltsep in part
175 ):
202 ):
176 return False
203 return False
177
204
178 return True
205 return True
179
206
180
207
181 def staticfile(templatepath, directory, fname, res):
208 def staticfile(templatepath, directory, fname, res):
182 """return a file inside directory with guessed Content-Type header
209 """return a file inside directory with guessed Content-Type header
183
210
184 fname always uses '/' as directory separator and isn't allowed to
211 fname always uses '/' as directory separator and isn't allowed to
185 contain unusual path components.
212 contain unusual path components.
186 Content-Type is guessed using the mimetypes module.
213 Content-Type is guessed using the mimetypes module.
187 Return an empty string if fname is illegal or file not found.
214 Return an empty string if fname is illegal or file not found.
188
215
189 """
216 """
190 if not ispathsafe(fname):
217 if not ispathsafe(fname):
191 return
218 return
192
219
193 if not directory:
220 if not directory:
194 tp = templatepath or templater.templatedir()
221 tp = templatepath or templater.templatedir()
195 if tp is not None:
222 if tp is not None:
196 directory = os.path.join(tp, b'static')
223 directory = os.path.join(tp, b'static')
197
224
198 fpath = os.path.join(*fname.split(b'/'))
225 fpath = os.path.join(*fname.split(b'/'))
199 ct = pycompat.sysbytes(
226 ct = pycompat.sysbytes(
200 mimetypes.guess_type(pycompat.fsdecode(fpath))[0] or r"text/plain"
227 mimetypes.guess_type(pycompat.fsdecode(fpath))[0] or r"text/plain"
201 )
228 )
202 path = os.path.join(directory, fpath)
229 path = os.path.join(directory, fpath)
203 try:
230 try:
204 os.stat(path)
231 os.stat(path)
205 with open(path, b'rb') as fh:
232 with open(path, b'rb') as fh:
206 data = fh.read()
233 data = fh.read()
207 except TypeError:
234 except TypeError:
208 raise ErrorResponse(HTTP_SERVER_ERROR, b'illegal filename')
235 raise ErrorResponse(HTTP_SERVER_ERROR, b'illegal filename')
209 except OSError as err:
236 except OSError as err:
210 if err.errno == errno.ENOENT:
237 if err.errno == errno.ENOENT:
211 raise ErrorResponse(HTTP_NOT_FOUND)
238 raise ErrorResponse(HTTP_NOT_FOUND)
212 else:
239 else:
213 raise ErrorResponse(
240 raise ErrorResponse(
214 HTTP_SERVER_ERROR, encoding.strtolocal(err.strerror)
241 HTTP_SERVER_ERROR, encoding.strtolocal(err.strerror)
215 )
242 )
216
243
217 res.headers[b'Content-Type'] = ct
244 res.headers[b'Content-Type'] = ct
218 res.setbodybytes(data)
245 res.setbodybytes(data)
219 return res
246 return res
220
247
221
248
222 def paritygen(stripecount, offset=0):
249 def paritygen(stripecount, offset=0):
223 """count parity of horizontal stripes for easier reading"""
250 """count parity of horizontal stripes for easier reading"""
224 if stripecount and offset:
251 if stripecount and offset:
225 # account for offset, e.g. due to building the list in reverse
252 # account for offset, e.g. due to building the list in reverse
226 count = (stripecount + offset) % stripecount
253 count = (stripecount + offset) % stripecount
227 parity = (stripecount + offset) // stripecount & 1
254 parity = (stripecount + offset) // stripecount & 1
228 else:
255 else:
229 count = 0
256 count = 0
230 parity = 0
257 parity = 0
231 while True:
258 while True:
232 yield parity
259 yield parity
233 count += 1
260 count += 1
234 if stripecount and count >= stripecount:
261 if stripecount and count >= stripecount:
235 parity = 1 - parity
262 parity = 1 - parity
236 count = 0
263 count = 0
237
264
238
265
239 def get_contact(config):
266 def get_contact(config):
240 """Return repo contact information or empty string.
267 """Return repo contact information or empty string.
241
268
242 web.contact is the primary source, but if that is not set, try
269 web.contact is the primary source, but if that is not set, try
243 ui.username or $EMAIL as a fallback to display something useful.
270 ui.username or $EMAIL as a fallback to display something useful.
244 """
271 """
245 return (
272 return (
246 config(b"web", b"contact")
273 config(b"web", b"contact")
247 or config(b"ui", b"username")
274 or config(b"ui", b"username")
248 or encoding.environ.get(b"EMAIL")
275 or encoding.environ.get(b"EMAIL")
249 or b""
276 or b""
250 )
277 )
251
278
252
279
253 def cspvalues(ui):
280 def cspvalues(ui):
254 """Obtain the Content-Security-Policy header and nonce value.
281 """Obtain the Content-Security-Policy header and nonce value.
255
282
256 Returns a 2-tuple of the CSP header value and the nonce value.
283 Returns a 2-tuple of the CSP header value and the nonce value.
257
284
258 First value is ``None`` if CSP isn't enabled. Second value is ``None``
285 First value is ``None`` if CSP isn't enabled. Second value is ``None``
259 if CSP isn't enabled or if the CSP header doesn't need a nonce.
286 if CSP isn't enabled or if the CSP header doesn't need a nonce.
260 """
287 """
261 # Without demandimport, "import uuid" could have an immediate side-effect
288 # Without demandimport, "import uuid" could have an immediate side-effect
262 # running "ldconfig" on Linux trying to find libuuid.
289 # running "ldconfig" on Linux trying to find libuuid.
263 # With Python <= 2.7.12, that "ldconfig" is run via a shell and the shell
290 # With Python <= 2.7.12, that "ldconfig" is run via a shell and the shell
264 # may pollute the terminal with:
291 # may pollute the terminal with:
265 #
292 #
266 # shell-init: error retrieving current directory: getcwd: cannot access
293 # shell-init: error retrieving current directory: getcwd: cannot access
267 # parent directories: No such file or directory
294 # parent directories: No such file or directory
268 #
295 #
269 # Python >= 2.7.13 has fixed it by running "ldconfig" directly without a
296 # Python >= 2.7.13 has fixed it by running "ldconfig" directly without a
270 # shell (hg changeset a09ae70f3489).
297 # shell (hg changeset a09ae70f3489).
271 #
298 #
272 # Moved "import uuid" from here so it's executed after we know we have
299 # Moved "import uuid" from here so it's executed after we know we have
273 # a sane cwd (i.e. after dispatch.py cwd check).
300 # a sane cwd (i.e. after dispatch.py cwd check).
274 #
301 #
275 # We can move it back once we no longer need Python <= 2.7.12 support.
302 # We can move it back once we no longer need Python <= 2.7.12 support.
276 import uuid
303 import uuid
277
304
278 # Don't allow untrusted CSP setting since it be disable protections
305 # Don't allow untrusted CSP setting since it be disable protections
279 # from a trusted/global source.
306 # from a trusted/global source.
280 csp = ui.config(b'web', b'csp', untrusted=False)
307 csp = ui.config(b'web', b'csp', untrusted=False)
281 nonce = None
308 nonce = None
282
309
283 if csp and b'%nonce%' in csp:
310 if csp and b'%nonce%' in csp:
284 nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip(b'=')
311 nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip(b'=')
285 csp = csp.replace(b'%nonce%', nonce)
312 csp = csp.replace(b'%nonce%', nonce)
286
313
287 return csp, nonce
314 return csp, nonce
@@ -1,516 +1,527 b''
1 # hgweb/hgweb_mod.py - Web interface for a repository.
1 # hgweb/hgweb_mod.py - Web interface for a repository.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9
9
10 import contextlib
10 import contextlib
11 import os
11 import os
12
12
13 from .common import (
13 from .common import (
14 ErrorResponse,
14 ErrorResponse,
15 HTTP_BAD_REQUEST,
15 HTTP_BAD_REQUEST,
16 cspvalues,
16 cspvalues,
17 permhooks,
17 permhooks,
18 statusmessage,
18 statusmessage,
19 )
19 )
20 from ..pycompat import getattr
20 from ..pycompat import getattr
21
21
22 from .. import (
22 from .. import (
23 encoding,
23 encoding,
24 error,
24 error,
25 extensions,
25 extensions,
26 formatter,
26 formatter,
27 hg,
27 hg,
28 hook,
28 hook,
29 profiling,
29 profiling,
30 pycompat,
30 pycompat,
31 registrar,
31 registrar,
32 repoview,
32 repoview,
33 templatefilters,
33 templatefilters,
34 templater,
34 templater,
35 templateutil,
35 templateutil,
36 ui as uimod,
36 ui as uimod,
37 util,
37 util,
38 wireprotoserver,
38 wireprotoserver,
39 )
39 )
40
40
41 from . import (
41 from . import (
42 common,
42 request as requestmod,
43 request as requestmod,
43 webcommands,
44 webcommands,
44 webutil,
45 webutil,
45 wsgicgi,
46 wsgicgi,
46 )
47 )
47
48
48
49
49 def getstyle(req, configfn, templatepath):
50 def getstyle(req, configfn, templatepath):
50 styles = (
51 styles = (
51 req.qsparams.get(b'style', None),
52 req.qsparams.get(b'style', None),
52 configfn(b'web', b'style'),
53 configfn(b'web', b'style'),
53 b'paper',
54 b'paper',
54 )
55 )
55 return styles, _stylemap(styles, templatepath)
56 return styles, _stylemap(styles, templatepath)
56
57
57
58
58 def _stylemap(styles, path=None):
59 def _stylemap(styles, path=None):
59 """Return path to mapfile for a given style.
60 """Return path to mapfile for a given style.
60
61
61 Searches mapfile in the following locations:
62 Searches mapfile in the following locations:
62 1. templatepath/style/map
63 1. templatepath/style/map
63 2. templatepath/map-style
64 2. templatepath/map-style
64 3. templatepath/map
65 3. templatepath/map
65 """
66 """
66
67
67 for style in styles:
68 for style in styles:
68 # only plain name is allowed to honor template paths
69 # only plain name is allowed to honor template paths
69 if (
70 if (
70 not style
71 not style
71 or style in (pycompat.oscurdir, pycompat.ospardir)
72 or style in (pycompat.oscurdir, pycompat.ospardir)
72 or pycompat.ossep in style
73 or pycompat.ossep in style
73 or pycompat.osaltsep
74 or pycompat.osaltsep
74 and pycompat.osaltsep in style
75 and pycompat.osaltsep in style
75 ):
76 ):
76 continue
77 continue
77 locations = (os.path.join(style, b'map'), b'map-' + style, b'map')
78 locations = (os.path.join(style, b'map'), b'map-' + style, b'map')
78
79
79 for location in locations:
80 for location in locations:
80 mapfile, fp = templater.try_open_template(location, path)
81 mapfile, fp = templater.try_open_template(location, path)
81 if mapfile:
82 if mapfile:
82 return style, mapfile, fp
83 return style, mapfile, fp
83
84
84 raise RuntimeError(b"No hgweb templates found in %r" % path)
85 raise RuntimeError(b"No hgweb templates found in %r" % path)
85
86
86
87
87 def makebreadcrumb(url, prefix=b''):
88 def makebreadcrumb(url, prefix=b''):
88 """Return a 'URL breadcrumb' list
89 """Return a 'URL breadcrumb' list
89
90
90 A 'URL breadcrumb' is a list of URL-name pairs,
91 A 'URL breadcrumb' is a list of URL-name pairs,
91 corresponding to each of the path items on a URL.
92 corresponding to each of the path items on a URL.
92 This can be used to create path navigation entries.
93 This can be used to create path navigation entries.
93 """
94 """
94 if url.endswith(b'/'):
95 if url.endswith(b'/'):
95 url = url[:-1]
96 url = url[:-1]
96 if prefix:
97 if prefix:
97 url = b'/' + prefix + url
98 url = b'/' + prefix + url
98 relpath = url
99 relpath = url
99 if relpath.startswith(b'/'):
100 if relpath.startswith(b'/'):
100 relpath = relpath[1:]
101 relpath = relpath[1:]
101
102
102 breadcrumb = []
103 breadcrumb = []
103 urlel = url
104 urlel = url
104 pathitems = [b''] + relpath.split(b'/')
105 pathitems = [b''] + relpath.split(b'/')
105 for pathel in reversed(pathitems):
106 for pathel in reversed(pathitems):
106 if not pathel or not urlel:
107 if not pathel or not urlel:
107 break
108 break
108 breadcrumb.append({b'url': urlel, b'name': pathel})
109 breadcrumb.append({b'url': urlel, b'name': pathel})
109 urlel = os.path.dirname(urlel)
110 urlel = os.path.dirname(urlel)
110 return templateutil.mappinglist(reversed(breadcrumb))
111 return templateutil.mappinglist(reversed(breadcrumb))
111
112
112
113
113 class requestcontext:
114 class requestcontext:
114 """Holds state/context for an individual request.
115 """Holds state/context for an individual request.
115
116
116 Servers can be multi-threaded. Holding state on the WSGI application
117 Servers can be multi-threaded. Holding state on the WSGI application
117 is prone to race conditions. Instances of this class exist to hold
118 is prone to race conditions. Instances of this class exist to hold
118 mutable and race-free state for requests.
119 mutable and race-free state for requests.
119 """
120 """
120
121
121 def __init__(self, app, repo, req, res):
122 def __init__(self, app, repo, req, res):
122 self.repo = repo
123 self.repo = repo
123 self.reponame = app.reponame
124 self.reponame = app.reponame
124 self.req = req
125 self.req = req
125 self.res = res
126 self.res = res
126
127
128 # Only works if the filter actually support being upgraded to show
129 # visible changesets
130 current_filter = repo.filtername
131 if (
132 common.hashiddenaccess(repo, req)
133 and current_filter is not None
134 and current_filter + b'.hidden' in repoview.filtertable
135 ):
136 self.repo = self.repo.filtered(repo.filtername + b'.hidden')
137
127 self.maxchanges = self.configint(b'web', b'maxchanges')
138 self.maxchanges = self.configint(b'web', b'maxchanges')
128 self.stripecount = self.configint(b'web', b'stripes')
139 self.stripecount = self.configint(b'web', b'stripes')
129 self.maxshortchanges = self.configint(b'web', b'maxshortchanges')
140 self.maxshortchanges = self.configint(b'web', b'maxshortchanges')
130 self.maxfiles = self.configint(b'web', b'maxfiles')
141 self.maxfiles = self.configint(b'web', b'maxfiles')
131 self.allowpull = self.configbool(b'web', b'allow-pull')
142 self.allowpull = self.configbool(b'web', b'allow-pull')
132
143
133 # we use untrusted=False to prevent a repo owner from using
144 # we use untrusted=False to prevent a repo owner from using
134 # web.templates in .hg/hgrc to get access to any file readable
145 # web.templates in .hg/hgrc to get access to any file readable
135 # by the user running the CGI script
146 # by the user running the CGI script
136 self.templatepath = self.config(b'web', b'templates', untrusted=False)
147 self.templatepath = self.config(b'web', b'templates', untrusted=False)
137
148
138 # This object is more expensive to build than simple config values.
149 # This object is more expensive to build than simple config values.
139 # It is shared across requests. The app will replace the object
150 # It is shared across requests. The app will replace the object
140 # if it is updated. Since this is a reference and nothing should
151 # if it is updated. Since this is a reference and nothing should
141 # modify the underlying object, it should be constant for the lifetime
152 # modify the underlying object, it should be constant for the lifetime
142 # of the request.
153 # of the request.
143 self.websubtable = app.websubtable
154 self.websubtable = app.websubtable
144
155
145 self.csp, self.nonce = cspvalues(self.repo.ui)
156 self.csp, self.nonce = cspvalues(self.repo.ui)
146
157
147 # Trust the settings from the .hg/hgrc files by default.
158 # Trust the settings from the .hg/hgrc files by default.
148 def config(self, *args, **kwargs):
159 def config(self, *args, **kwargs):
149 kwargs.setdefault('untrusted', True)
160 kwargs.setdefault('untrusted', True)
150 return self.repo.ui.config(*args, **kwargs)
161 return self.repo.ui.config(*args, **kwargs)
151
162
152 def configbool(self, *args, **kwargs):
163 def configbool(self, *args, **kwargs):
153 kwargs.setdefault('untrusted', True)
164 kwargs.setdefault('untrusted', True)
154 return self.repo.ui.configbool(*args, **kwargs)
165 return self.repo.ui.configbool(*args, **kwargs)
155
166
156 def configint(self, *args, **kwargs):
167 def configint(self, *args, **kwargs):
157 kwargs.setdefault('untrusted', True)
168 kwargs.setdefault('untrusted', True)
158 return self.repo.ui.configint(*args, **kwargs)
169 return self.repo.ui.configint(*args, **kwargs)
159
170
160 def configlist(self, *args, **kwargs):
171 def configlist(self, *args, **kwargs):
161 kwargs.setdefault('untrusted', True)
172 kwargs.setdefault('untrusted', True)
162 return self.repo.ui.configlist(*args, **kwargs)
173 return self.repo.ui.configlist(*args, **kwargs)
163
174
164 def archivelist(self, nodeid):
175 def archivelist(self, nodeid):
165 return webutil.archivelist(self.repo.ui, nodeid)
176 return webutil.archivelist(self.repo.ui, nodeid)
166
177
167 def templater(self, req):
178 def templater(self, req):
168 # determine scheme, port and server name
179 # determine scheme, port and server name
169 # this is needed to create absolute urls
180 # this is needed to create absolute urls
170 logourl = self.config(b'web', b'logourl')
181 logourl = self.config(b'web', b'logourl')
171 logoimg = self.config(b'web', b'logoimg')
182 logoimg = self.config(b'web', b'logoimg')
172 staticurl = (
183 staticurl = (
173 self.config(b'web', b'staticurl')
184 self.config(b'web', b'staticurl')
174 or req.apppath.rstrip(b'/') + b'/static/'
185 or req.apppath.rstrip(b'/') + b'/static/'
175 )
186 )
176 if not staticurl.endswith(b'/'):
187 if not staticurl.endswith(b'/'):
177 staticurl += b'/'
188 staticurl += b'/'
178
189
179 # figure out which style to use
190 # figure out which style to use
180
191
181 vars = {}
192 vars = {}
182 styles, (style, mapfile, fp) = getstyle(
193 styles, (style, mapfile, fp) = getstyle(
183 req, self.config, self.templatepath
194 req, self.config, self.templatepath
184 )
195 )
185 if style == styles[0]:
196 if style == styles[0]:
186 vars[b'style'] = style
197 vars[b'style'] = style
187
198
188 sessionvars = webutil.sessionvars(vars, b'?')
199 sessionvars = webutil.sessionvars(vars, b'?')
189
200
190 if not self.reponame:
201 if not self.reponame:
191 self.reponame = (
202 self.reponame = (
192 self.config(b'web', b'name', b'')
203 self.config(b'web', b'name', b'')
193 or req.reponame
204 or req.reponame
194 or req.apppath
205 or req.apppath
195 or self.repo.root
206 or self.repo.root
196 )
207 )
197
208
198 filters = {}
209 filters = {}
199 templatefilter = registrar.templatefilter(filters)
210 templatefilter = registrar.templatefilter(filters)
200
211
201 @templatefilter(b'websub', intype=bytes)
212 @templatefilter(b'websub', intype=bytes)
202 def websubfilter(text):
213 def websubfilter(text):
203 return templatefilters.websub(text, self.websubtable)
214 return templatefilters.websub(text, self.websubtable)
204
215
205 # create the templater
216 # create the templater
206 # TODO: export all keywords: defaults = templatekw.keywords.copy()
217 # TODO: export all keywords: defaults = templatekw.keywords.copy()
207 defaults = {
218 defaults = {
208 b'url': req.apppath + b'/',
219 b'url': req.apppath + b'/',
209 b'logourl': logourl,
220 b'logourl': logourl,
210 b'logoimg': logoimg,
221 b'logoimg': logoimg,
211 b'staticurl': staticurl,
222 b'staticurl': staticurl,
212 b'urlbase': req.advertisedbaseurl,
223 b'urlbase': req.advertisedbaseurl,
213 b'repo': self.reponame,
224 b'repo': self.reponame,
214 b'encoding': encoding.encoding,
225 b'encoding': encoding.encoding,
215 b'sessionvars': sessionvars,
226 b'sessionvars': sessionvars,
216 b'pathdef': makebreadcrumb(req.apppath),
227 b'pathdef': makebreadcrumb(req.apppath),
217 b'style': style,
228 b'style': style,
218 b'nonce': self.nonce,
229 b'nonce': self.nonce,
219 }
230 }
220 templatekeyword = registrar.templatekeyword(defaults)
231 templatekeyword = registrar.templatekeyword(defaults)
221
232
222 @templatekeyword(b'motd', requires=())
233 @templatekeyword(b'motd', requires=())
223 def motd(context, mapping):
234 def motd(context, mapping):
224 yield self.config(b'web', b'motd')
235 yield self.config(b'web', b'motd')
225
236
226 tres = formatter.templateresources(self.repo.ui, self.repo)
237 tres = formatter.templateresources(self.repo.ui, self.repo)
227 return templater.templater.frommapfile(
238 return templater.templater.frommapfile(
228 mapfile, fp=fp, filters=filters, defaults=defaults, resources=tres
239 mapfile, fp=fp, filters=filters, defaults=defaults, resources=tres
229 )
240 )
230
241
231 def sendtemplate(self, name, **kwargs):
242 def sendtemplate(self, name, **kwargs):
232 """Helper function to send a response generated from a template."""
243 """Helper function to send a response generated from a template."""
233 if self.req.method != b'HEAD':
244 if self.req.method != b'HEAD':
234 kwargs = pycompat.byteskwargs(kwargs)
245 kwargs = pycompat.byteskwargs(kwargs)
235 self.res.setbodygen(self.tmpl.generate(name, kwargs))
246 self.res.setbodygen(self.tmpl.generate(name, kwargs))
236 return self.res.sendresponse()
247 return self.res.sendresponse()
237
248
238
249
239 class hgweb:
250 class hgweb:
240 """HTTP server for individual repositories.
251 """HTTP server for individual repositories.
241
252
242 Instances of this class serve HTTP responses for a particular
253 Instances of this class serve HTTP responses for a particular
243 repository.
254 repository.
244
255
245 Instances are typically used as WSGI applications.
256 Instances are typically used as WSGI applications.
246
257
247 Some servers are multi-threaded. On these servers, there may
258 Some servers are multi-threaded. On these servers, there may
248 be multiple active threads inside __call__.
259 be multiple active threads inside __call__.
249 """
260 """
250
261
251 def __init__(self, repo, name=None, baseui=None):
262 def __init__(self, repo, name=None, baseui=None):
252 if isinstance(repo, bytes):
263 if isinstance(repo, bytes):
253 if baseui:
264 if baseui:
254 u = baseui.copy()
265 u = baseui.copy()
255 else:
266 else:
256 u = uimod.ui.load()
267 u = uimod.ui.load()
257 extensions.loadall(u)
268 extensions.loadall(u)
258 extensions.populateui(u)
269 extensions.populateui(u)
259 r = hg.repository(u, repo)
270 r = hg.repository(u, repo)
260 else:
271 else:
261 # we trust caller to give us a private copy
272 # we trust caller to give us a private copy
262 r = repo
273 r = repo
263
274
264 r.ui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
275 r.ui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
265 r.baseui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
276 r.baseui.setconfig(b'ui', b'report_untrusted', b'off', b'hgweb')
266 r.ui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
277 r.ui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
267 r.baseui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
278 r.baseui.setconfig(b'ui', b'nontty', b'true', b'hgweb')
268 # resolve file patterns relative to repo root
279 # resolve file patterns relative to repo root
269 r.ui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
280 r.ui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
270 r.baseui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
281 r.baseui.setconfig(b'ui', b'forcecwd', r.root, b'hgweb')
271 # it's unlikely that we can replace signal handlers in WSGI server,
282 # it's unlikely that we can replace signal handlers in WSGI server,
272 # and mod_wsgi issues a big warning. a plain hgweb process (with no
283 # and mod_wsgi issues a big warning. a plain hgweb process (with no
273 # threading) could replace signal handlers, but we don't bother
284 # threading) could replace signal handlers, but we don't bother
274 # conditionally enabling it.
285 # conditionally enabling it.
275 r.ui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
286 r.ui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
276 r.baseui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
287 r.baseui.setconfig(b'ui', b'signal-safe-lock', b'false', b'hgweb')
277 # displaying bundling progress bar while serving feel wrong and may
288 # displaying bundling progress bar while serving feel wrong and may
278 # break some wsgi implementation.
289 # break some wsgi implementation.
279 r.ui.setconfig(b'progress', b'disable', b'true', b'hgweb')
290 r.ui.setconfig(b'progress', b'disable', b'true', b'hgweb')
280 r.baseui.setconfig(b'progress', b'disable', b'true', b'hgweb')
291 r.baseui.setconfig(b'progress', b'disable', b'true', b'hgweb')
281 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
292 self._repos = [hg.cachedlocalrepo(self._webifyrepo(r))]
282 self._lastrepo = self._repos[0]
293 self._lastrepo = self._repos[0]
283 hook.redirect(True)
294 hook.redirect(True)
284 self.reponame = name
295 self.reponame = name
285
296
286 def _webifyrepo(self, repo):
297 def _webifyrepo(self, repo):
287 repo = getwebview(repo)
298 repo = getwebview(repo)
288 self.websubtable = webutil.getwebsubs(repo)
299 self.websubtable = webutil.getwebsubs(repo)
289 return repo
300 return repo
290
301
291 @contextlib.contextmanager
302 @contextlib.contextmanager
292 def _obtainrepo(self):
303 def _obtainrepo(self):
293 """Obtain a repo unique to the caller.
304 """Obtain a repo unique to the caller.
294
305
295 Internally we maintain a stack of cachedlocalrepo instances
306 Internally we maintain a stack of cachedlocalrepo instances
296 to be handed out. If one is available, we pop it and return it,
307 to be handed out. If one is available, we pop it and return it,
297 ensuring it is up to date in the process. If one is not available,
308 ensuring it is up to date in the process. If one is not available,
298 we clone the most recently used repo instance and return it.
309 we clone the most recently used repo instance and return it.
299
310
300 It is currently possible for the stack to grow without bounds
311 It is currently possible for the stack to grow without bounds
301 if the server allows infinite threads. However, servers should
312 if the server allows infinite threads. However, servers should
302 have a thread limit, thus establishing our limit.
313 have a thread limit, thus establishing our limit.
303 """
314 """
304 if self._repos:
315 if self._repos:
305 cached = self._repos.pop()
316 cached = self._repos.pop()
306 r, created = cached.fetch()
317 r, created = cached.fetch()
307 else:
318 else:
308 cached = self._lastrepo.copy()
319 cached = self._lastrepo.copy()
309 r, created = cached.fetch()
320 r, created = cached.fetch()
310 if created:
321 if created:
311 r = self._webifyrepo(r)
322 r = self._webifyrepo(r)
312
323
313 self._lastrepo = cached
324 self._lastrepo = cached
314 self.mtime = cached.mtime
325 self.mtime = cached.mtime
315 try:
326 try:
316 yield r
327 yield r
317 finally:
328 finally:
318 self._repos.append(cached)
329 self._repos.append(cached)
319
330
320 def run(self):
331 def run(self):
321 """Start a server from CGI environment.
332 """Start a server from CGI environment.
322
333
323 Modern servers should be using WSGI and should avoid this
334 Modern servers should be using WSGI and should avoid this
324 method, if possible.
335 method, if possible.
325 """
336 """
326 if not encoding.environ.get(b'GATEWAY_INTERFACE', b'').startswith(
337 if not encoding.environ.get(b'GATEWAY_INTERFACE', b'').startswith(
327 b"CGI/1."
338 b"CGI/1."
328 ):
339 ):
329 raise RuntimeError(
340 raise RuntimeError(
330 b"This function is only intended to be "
341 b"This function is only intended to be "
331 b"called while running as a CGI script."
342 b"called while running as a CGI script."
332 )
343 )
333 wsgicgi.launch(self)
344 wsgicgi.launch(self)
334
345
335 def __call__(self, env, respond):
346 def __call__(self, env, respond):
336 """Run the WSGI application.
347 """Run the WSGI application.
337
348
338 This may be called by multiple threads.
349 This may be called by multiple threads.
339 """
350 """
340 req = requestmod.parserequestfromenv(env)
351 req = requestmod.parserequestfromenv(env)
341 res = requestmod.wsgiresponse(req, respond)
352 res = requestmod.wsgiresponse(req, respond)
342
353
343 return self.run_wsgi(req, res)
354 return self.run_wsgi(req, res)
344
355
345 def run_wsgi(self, req, res):
356 def run_wsgi(self, req, res):
346 """Internal method to run the WSGI application.
357 """Internal method to run the WSGI application.
347
358
348 This is typically only called by Mercurial. External consumers
359 This is typically only called by Mercurial. External consumers
349 should be using instances of this class as the WSGI application.
360 should be using instances of this class as the WSGI application.
350 """
361 """
351 with self._obtainrepo() as repo:
362 with self._obtainrepo() as repo:
352 profile = repo.ui.configbool(b'profiling', b'enabled')
363 profile = repo.ui.configbool(b'profiling', b'enabled')
353 with profiling.profile(repo.ui, enabled=profile):
364 with profiling.profile(repo.ui, enabled=profile):
354 for r in self._runwsgi(req, res, repo):
365 for r in self._runwsgi(req, res, repo):
355 yield r
366 yield r
356
367
357 def _runwsgi(self, req, res, repo):
368 def _runwsgi(self, req, res, repo):
358 rctx = requestcontext(self, repo, req, res)
369 rctx = requestcontext(self, repo, req, res)
359
370
360 # This state is global across all threads.
371 # This state is global across all threads.
361 encoding.encoding = rctx.config(b'web', b'encoding')
372 encoding.encoding = rctx.config(b'web', b'encoding')
362 rctx.repo.ui.environ = req.rawenv
373 rctx.repo.ui.environ = req.rawenv
363
374
364 if rctx.csp:
375 if rctx.csp:
365 # hgwebdir may have added CSP header. Since we generate our own,
376 # hgwebdir may have added CSP header. Since we generate our own,
366 # replace it.
377 # replace it.
367 res.headers[b'Content-Security-Policy'] = rctx.csp
378 res.headers[b'Content-Security-Policy'] = rctx.csp
368
379
369 handled = wireprotoserver.handlewsgirequest(
380 handled = wireprotoserver.handlewsgirequest(
370 rctx, req, res, self.check_perm
381 rctx, req, res, self.check_perm
371 )
382 )
372 if handled:
383 if handled:
373 return res.sendresponse()
384 return res.sendresponse()
374
385
375 # Old implementations of hgweb supported dispatching the request via
386 # Old implementations of hgweb supported dispatching the request via
376 # the initial query string parameter instead of using PATH_INFO.
387 # the initial query string parameter instead of using PATH_INFO.
377 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
388 # If PATH_INFO is present (signaled by ``req.dispatchpath`` having
378 # a value), we use it. Otherwise fall back to the query string.
389 # a value), we use it. Otherwise fall back to the query string.
379 if req.dispatchpath is not None:
390 if req.dispatchpath is not None:
380 query = req.dispatchpath
391 query = req.dispatchpath
381 else:
392 else:
382 query = req.querystring.partition(b'&')[0].partition(b';')[0]
393 query = req.querystring.partition(b'&')[0].partition(b';')[0]
383
394
384 # translate user-visible url structure to internal structure
395 # translate user-visible url structure to internal structure
385
396
386 args = query.split(b'/', 2)
397 args = query.split(b'/', 2)
387 if b'cmd' not in req.qsparams and args and args[0]:
398 if b'cmd' not in req.qsparams and args and args[0]:
388 cmd = args.pop(0)
399 cmd = args.pop(0)
389 style = cmd.rfind(b'-')
400 style = cmd.rfind(b'-')
390 if style != -1:
401 if style != -1:
391 req.qsparams[b'style'] = cmd[:style]
402 req.qsparams[b'style'] = cmd[:style]
392 cmd = cmd[style + 1 :]
403 cmd = cmd[style + 1 :]
393
404
394 # avoid accepting e.g. style parameter as command
405 # avoid accepting e.g. style parameter as command
395 if util.safehasattr(webcommands, cmd):
406 if util.safehasattr(webcommands, cmd):
396 req.qsparams[b'cmd'] = cmd
407 req.qsparams[b'cmd'] = cmd
397
408
398 if cmd == b'static':
409 if cmd == b'static':
399 req.qsparams[b'file'] = b'/'.join(args)
410 req.qsparams[b'file'] = b'/'.join(args)
400 else:
411 else:
401 if args and args[0]:
412 if args and args[0]:
402 node = args.pop(0).replace(b'%2F', b'/')
413 node = args.pop(0).replace(b'%2F', b'/')
403 req.qsparams[b'node'] = node
414 req.qsparams[b'node'] = node
404 if args:
415 if args:
405 if b'file' in req.qsparams:
416 if b'file' in req.qsparams:
406 del req.qsparams[b'file']
417 del req.qsparams[b'file']
407 for a in args:
418 for a in args:
408 req.qsparams.add(b'file', a)
419 req.qsparams.add(b'file', a)
409
420
410 ua = req.headers.get(b'User-Agent', b'')
421 ua = req.headers.get(b'User-Agent', b'')
411 if cmd == b'rev' and b'mercurial' in ua:
422 if cmd == b'rev' and b'mercurial' in ua:
412 req.qsparams[b'style'] = b'raw'
423 req.qsparams[b'style'] = b'raw'
413
424
414 if cmd == b'archive':
425 if cmd == b'archive':
415 fn = req.qsparams[b'node']
426 fn = req.qsparams[b'node']
416 for type_, spec in webutil.archivespecs.items():
427 for type_, spec in webutil.archivespecs.items():
417 ext = spec[2]
428 ext = spec[2]
418 if fn.endswith(ext):
429 if fn.endswith(ext):
419 req.qsparams[b'node'] = fn[: -len(ext)]
430 req.qsparams[b'node'] = fn[: -len(ext)]
420 req.qsparams[b'type'] = type_
431 req.qsparams[b'type'] = type_
421 else:
432 else:
422 cmd = req.qsparams.get(b'cmd', b'')
433 cmd = req.qsparams.get(b'cmd', b'')
423
434
424 # process the web interface request
435 # process the web interface request
425
436
426 try:
437 try:
427 rctx.tmpl = rctx.templater(req)
438 rctx.tmpl = rctx.templater(req)
428 ctype = rctx.tmpl.render(
439 ctype = rctx.tmpl.render(
429 b'mimetype', {b'encoding': encoding.encoding}
440 b'mimetype', {b'encoding': encoding.encoding}
430 )
441 )
431
442
432 # check read permissions non-static content
443 # check read permissions non-static content
433 if cmd != b'static':
444 if cmd != b'static':
434 self.check_perm(rctx, req, None)
445 self.check_perm(rctx, req, None)
435
446
436 if cmd == b'':
447 if cmd == b'':
437 req.qsparams[b'cmd'] = rctx.tmpl.render(b'default', {})
448 req.qsparams[b'cmd'] = rctx.tmpl.render(b'default', {})
438 cmd = req.qsparams[b'cmd']
449 cmd = req.qsparams[b'cmd']
439
450
440 # Don't enable caching if using a CSP nonce because then it wouldn't
451 # Don't enable caching if using a CSP nonce because then it wouldn't
441 # be a nonce.
452 # be a nonce.
442 if rctx.configbool(b'web', b'cache') and not rctx.nonce:
453 if rctx.configbool(b'web', b'cache') and not rctx.nonce:
443 tag = b'W/"%d"' % self.mtime
454 tag = b'W/"%d"' % self.mtime
444 if req.headers.get(b'If-None-Match') == tag:
455 if req.headers.get(b'If-None-Match') == tag:
445 res.status = b'304 Not Modified'
456 res.status = b'304 Not Modified'
446 # Content-Type may be defined globally. It isn't valid on a
457 # Content-Type may be defined globally. It isn't valid on a
447 # 304, so discard it.
458 # 304, so discard it.
448 try:
459 try:
449 del res.headers[b'Content-Type']
460 del res.headers[b'Content-Type']
450 except KeyError:
461 except KeyError:
451 pass
462 pass
452 # Response body not allowed on 304.
463 # Response body not allowed on 304.
453 res.setbodybytes(b'')
464 res.setbodybytes(b'')
454 return res.sendresponse()
465 return res.sendresponse()
455
466
456 res.headers[b'ETag'] = tag
467 res.headers[b'ETag'] = tag
457
468
458 if cmd not in webcommands.__all__:
469 if cmd not in webcommands.__all__:
459 msg = b'no such method: %s' % cmd
470 msg = b'no such method: %s' % cmd
460 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
471 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
461 else:
472 else:
462 # Set some globals appropriate for web handlers. Commands can
473 # Set some globals appropriate for web handlers. Commands can
463 # override easily enough.
474 # override easily enough.
464 res.status = b'200 Script output follows'
475 res.status = b'200 Script output follows'
465 res.headers[b'Content-Type'] = ctype
476 res.headers[b'Content-Type'] = ctype
466 return getattr(webcommands, cmd)(rctx)
477 return getattr(webcommands, cmd)(rctx)
467
478
468 except (error.LookupError, error.RepoLookupError) as err:
479 except (error.LookupError, error.RepoLookupError) as err:
469 msg = pycompat.bytestr(err)
480 msg = pycompat.bytestr(err)
470 if util.safehasattr(err, b'name') and not isinstance(
481 if util.safehasattr(err, b'name') and not isinstance(
471 err, error.ManifestLookupError
482 err, error.ManifestLookupError
472 ):
483 ):
473 msg = b'revision not found: %s' % err.name
484 msg = b'revision not found: %s' % err.name
474
485
475 res.status = b'404 Not Found'
486 res.status = b'404 Not Found'
476 res.headers[b'Content-Type'] = ctype
487 res.headers[b'Content-Type'] = ctype
477 return rctx.sendtemplate(b'error', error=msg)
488 return rctx.sendtemplate(b'error', error=msg)
478 except (error.RepoError, error.StorageError) as e:
489 except (error.RepoError, error.StorageError) as e:
479 res.status = b'500 Internal Server Error'
490 res.status = b'500 Internal Server Error'
480 res.headers[b'Content-Type'] = ctype
491 res.headers[b'Content-Type'] = ctype
481 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
492 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
482 except error.Abort as e:
493 except error.Abort as e:
483 res.status = b'403 Forbidden'
494 res.status = b'403 Forbidden'
484 res.headers[b'Content-Type'] = ctype
495 res.headers[b'Content-Type'] = ctype
485 return rctx.sendtemplate(b'error', error=e.message)
496 return rctx.sendtemplate(b'error', error=e.message)
486 except ErrorResponse as e:
497 except ErrorResponse as e:
487 for k, v in e.headers:
498 for k, v in e.headers:
488 res.headers[k] = v
499 res.headers[k] = v
489 res.status = statusmessage(e.code, pycompat.bytestr(e))
500 res.status = statusmessage(e.code, pycompat.bytestr(e))
490 res.headers[b'Content-Type'] = ctype
501 res.headers[b'Content-Type'] = ctype
491 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
502 return rctx.sendtemplate(b'error', error=pycompat.bytestr(e))
492
503
493 def check_perm(self, rctx, req, op):
504 def check_perm(self, rctx, req, op):
494 for permhook in permhooks:
505 for permhook in permhooks:
495 permhook(rctx, req, op)
506 permhook(rctx, req, op)
496
507
497
508
498 def getwebview(repo):
509 def getwebview(repo):
499 """The 'web.view' config controls changeset filter to hgweb. Possible
510 """The 'web.view' config controls changeset filter to hgweb. Possible
500 values are ``served``, ``visible`` and ``all``. Default is ``served``.
511 values are ``served``, ``visible`` and ``all``. Default is ``served``.
501 The ``served`` filter only shows changesets that can be pulled from the
512 The ``served`` filter only shows changesets that can be pulled from the
502 hgweb instance. The``visible`` filter includes secret changesets but
513 hgweb instance. The``visible`` filter includes secret changesets but
503 still excludes "hidden" one.
514 still excludes "hidden" one.
504
515
505 See the repoview module for details.
516 See the repoview module for details.
506
517
507 The option has been around undocumented since Mercurial 2.5, but no
518 The option has been around undocumented since Mercurial 2.5, but no
508 user ever asked about it. So we better keep it undocumented for now."""
519 user ever asked about it. So we better keep it undocumented for now."""
509 # experimental config: web.view
520 # experimental config: web.view
510 viewconfig = repo.ui.config(b'web', b'view', untrusted=True)
521 viewconfig = repo.ui.config(b'web', b'view', untrusted=True)
511 if viewconfig == b'all':
522 if viewconfig == b'all':
512 return repo.unfiltered()
523 return repo.unfiltered()
513 elif viewconfig in repoview.filtertable:
524 elif viewconfig in repoview.filtertable:
514 return repo.filtered(viewconfig)
525 return repo.filtered(viewconfig)
515 else:
526 else:
516 return repo.filtered(b'served')
527 return repo.filtered(b'served')
@@ -1,113 +1,157 b''
1 ========================================================
1 ========================================================
2 Test the ability to access a hidden revision on a server
2 Test the ability to access a hidden revision on a server
3 ========================================================
3 ========================================================
4
4
5 #require serve
5 #require serve
6
6
7 $ . $TESTDIR/testlib/obsmarker-common.sh
7 $ . $TESTDIR/testlib/obsmarker-common.sh
8 $ cat >> $HGRCPATH << EOF
8 $ cat >> $HGRCPATH << EOF
9 > [phases]
9 > [phases]
10 > # public changeset are not obsolete
10 > # public changeset are not obsolete
11 > publish=false
11 > publish=false
12 > [experimental]
12 > [experimental]
13 > evolution=all
13 > evolution=all
14 > [ui]
14 > [ui]
15 > logtemplate='{rev}:{node|short} {desc} [{phase}]\n'
15 > logtemplate='{rev}:{node|short} {desc} [{phase}]\n'
16 > EOF
16 > EOF
17
17
18 Setup a simple repository with some hidden revisions
18 Setup a simple repository with some hidden revisions
19 ----------------------------------------------------
19 ----------------------------------------------------
20
20
21 Testing the `served.hidden` view
21 Testing the `served.hidden` view
22
22
23 $ hg init repo-with-hidden
23 $ hg init repo-with-hidden
24 $ cd repo-with-hidden
24 $ cd repo-with-hidden
25
25
26 $ echo 0 > a
26 $ echo 0 > a
27 $ hg ci -qAm "c_Public"
27 $ hg ci -qAm "c_Public"
28 $ hg phase --public
28 $ hg phase --public
29 $ echo 1 > a
29 $ echo 1 > a
30 $ hg ci -m "c_Amend_Old"
30 $ hg ci -m "c_Amend_Old"
31 $ echo 2 > a
31 $ echo 2 > a
32 $ hg ci -m "c_Amend_New" --amend
32 $ hg ci -m "c_Amend_New" --amend
33 $ hg up ".^"
33 $ hg up ".^"
34 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 $ echo 3 > a
35 $ echo 3 > a
36 $ hg ci -m "c_Pruned"
36 $ hg ci -m "c_Pruned"
37 created new head
37 created new head
38 $ hg debugobsolete --record-parents `getid 'desc("c_Pruned")'` -d '0 0'
38 $ hg debugobsolete --record-parents `getid 'desc("c_Pruned")'` -d '0 0'
39 1 new obsolescence markers
39 1 new obsolescence markers
40 obsoleted 1 changesets
40 obsoleted 1 changesets
41 $ hg up ".^"
41 $ hg up ".^"
42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ echo 4 > a
43 $ echo 4 > a
44 $ hg ci -m "c_Secret" --secret
44 $ hg ci -m "c_Secret" --secret
45 created new head
45 created new head
46 $ echo 5 > a
46 $ echo 5 > a
47 $ hg ci -m "c_Secret_Pruned" --secret
47 $ hg ci -m "c_Secret_Pruned" --secret
48 $ hg debugobsolete --record-parents `getid 'desc("c_Secret_Pruned")'` -d '0 0'
48 $ hg debugobsolete --record-parents `getid 'desc("c_Secret_Pruned")'` -d '0 0'
49 1 new obsolescence markers
49 1 new obsolescence markers
50 obsoleted 1 changesets
50 obsoleted 1 changesets
51 $ hg up null
51 $ hg up null
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
53
53
54 $ hg log -G -T '{rev}:{node|short} {desc} [{phase}]\n' --hidden
54 $ hg log -G -T '{rev}:{node|short} {desc} [{phase}]\n' --hidden
55 x 5:8d28cbe335f3 c_Secret_Pruned [secret]
55 x 5:8d28cbe335f3 c_Secret_Pruned [secret]
56 |
56 |
57 o 4:1c6afd79eb66 c_Secret [secret]
57 o 4:1c6afd79eb66 c_Secret [secret]
58 |
58 |
59 | x 3:5d1575e42c25 c_Pruned [draft]
59 | x 3:5d1575e42c25 c_Pruned [draft]
60 |/
60 |/
61 | o 2:c33affeb3f6b c_Amend_New [draft]
61 | o 2:c33affeb3f6b c_Amend_New [draft]
62 |/
62 |/
63 | x 1:be215fbb8c50 c_Amend_Old [draft]
63 | x 1:be215fbb8c50 c_Amend_Old [draft]
64 |/
64 |/
65 o 0:5f354f46e585 c_Public [public]
65 o 0:5f354f46e585 c_Public [public]
66
66
67 $ hg debugobsolete
67 $ hg debugobsolete
68 be215fbb8c5090028b00154c1fe877ad1b376c61 c33affeb3f6b4e9621d1839d6175ddc07708807c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'}
68 be215fbb8c5090028b00154c1fe877ad1b376c61 c33affeb3f6b4e9621d1839d6175ddc07708807c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'}
69 5d1575e42c25b7f2db75cd4e0b881b1c35158fae 0 {5f354f46e5853535841ec7a128423e991ca4d59b} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
69 5d1575e42c25b7f2db75cd4e0b881b1c35158fae 0 {5f354f46e5853535841ec7a128423e991ca4d59b} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
70 8d28cbe335f311bc89332d7bbe8a07889b6914a0 0 {1c6afd79eb6663275bbe30097e162b1c24ced0f0} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
70 8d28cbe335f311bc89332d7bbe8a07889b6914a0 0 {1c6afd79eb6663275bbe30097e162b1c24ced0f0} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
71
71
72 $ cd ..
72 $ cd ..
73
73
74 Test the feature
74 Test the feature
75 ================
75 ================
76
76
77 Check cache pre-warm
77 Check cache pre-warm
78 --------------------
78 --------------------
79
79
80 $ ls -1 repo-with-hidden/.hg/cache
80 $ ls -1 repo-with-hidden/.hg/cache
81 branch2
81 branch2
82 branch2-base
82 branch2-base
83 branch2-served
83 branch2-served
84 branch2-served.hidden
84 branch2-served.hidden
85 branch2-visible
85 branch2-visible
86 rbc-names-v1
86 rbc-names-v1
87 rbc-revs-v1
87 rbc-revs-v1
88 tags2
88 tags2
89 tags2-visible
89 tags2-visible
90
90
91 Check that the `served.hidden` repoview
91 Check that the `served.hidden` repoview
92 ---------------------------------------
92 ---------------------------------------
93
93
94 $ hg -R repo-with-hidden serve -p $HGPORT -d --pid-file hg.pid --config web.view=served.hidden
94 $ hg -R repo-with-hidden serve -p $HGPORT -d --pid-file hg.pid --config web.view=served.hidden
95 $ cat hg.pid >> $DAEMON_PIDS
95 $ cat hg.pid >> $DAEMON_PIDS
96
96
97 changesets in secret and higher phases are not visible through hgweb
97 changesets in secret and higher phases are not visible through hgweb
98
98
99 $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())"
99 $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())"
100 revision: 2
100 revision: 2
101 revision: 0
101 revision: 0
102 $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())" --hidden
102 $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())" --hidden
103 revision: 3
103 revision: 3
104 revision: 2
104 revision: 2
105 revision: 1
105 revision: 1
106 revision: 0
106 revision: 0
107 $ get-with-headers.py localhost:$HGPORT 'log?style=raw' | grep revision:
107 $ get-with-headers.py localhost:$HGPORT 'log?style=raw' | grep revision:
108 revision: 3
108 revision: 3
109 revision: 2
109 revision: 2
110 revision: 1
110 revision: 1
111 revision: 0
111 revision: 0
112
112
113 $ killdaemons.py
113 $ killdaemons.py
114
115 Test accessing hidden changeset through hgweb
116 ---------------------------------------------
117
118 $ hg -R repo-with-hidden serve -p $HGPORT -d --pid-file hg.pid --config "experimental.server.allow-hidden-access=*" -E error.log --accesslog access.log
119 $ cat hg.pid >> $DAEMON_PIDS
120
121 Hidden changeset are hidden by default:
122
123 $ get-with-headers.py localhost:$HGPORT 'log?style=raw' | grep revision:
124 revision: 2
125 revision: 0
126
127 Hidden changeset are visible when requested:
128
129 $ get-with-headers.py localhost:$HGPORT 'log?style=raw&access-hidden=1' | grep revision:
130 revision: 3
131 revision: 2
132 revision: 1
133 revision: 0
134
135 Same check on a server that do not allow hidden access:
136 ```````````````````````````````````````````````````````
137
138 $ hg -R repo-with-hidden serve -p $HGPORT1 -d --pid-file hg2.pid --config "experimental.server.allow-hidden-access=" -E error.log --accesslog access.log
139 $ cat hg2.pid >> $DAEMON_PIDS
140
141 Hidden changeset are hidden by default:
142
143 $ get-with-headers.py localhost:$HGPORT1 'log?style=raw' | grep revision:
144 revision: 2
145 revision: 0
146
147 Hidden changeset are still hidden despite being the hidden access request:
148
149 $ get-with-headers.py localhost:$HGPORT1 'log?style=raw&access-hidden=1' | grep revision:
150 revision: 2
151 revision: 0
152
153 =============
154 Final cleanup
155 =============
156
157 $ killdaemons.py
General Comments 0
You need to be logged in to leave comments. Login now