##// END OF EJS Templates
filemerge: add configs to disable some or all partial merge tools...
Martin von Zweigbergk -
r50060:7af798e4 default
parent child Browse files
Show More
@@ -1,2772 +1,2786 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'defaults',
587 b'defaults',
588 b'.*',
588 b'.*',
589 default=None,
589 default=None,
590 generic=True,
590 generic=True,
591 )
591 )
592 coreconfigitem(
592 coreconfigitem(
593 b'devel',
593 b'devel',
594 b'all-warnings',
594 b'all-warnings',
595 default=False,
595 default=False,
596 )
596 )
597 coreconfigitem(
597 coreconfigitem(
598 b'devel',
598 b'devel',
599 b'bundle2.debug',
599 b'bundle2.debug',
600 default=False,
600 default=False,
601 )
601 )
602 coreconfigitem(
602 coreconfigitem(
603 b'devel',
603 b'devel',
604 b'bundle.delta',
604 b'bundle.delta',
605 default=b'',
605 default=b'',
606 )
606 )
607 coreconfigitem(
607 coreconfigitem(
608 b'devel',
608 b'devel',
609 b'cache-vfs',
609 b'cache-vfs',
610 default=None,
610 default=None,
611 )
611 )
612 coreconfigitem(
612 coreconfigitem(
613 b'devel',
613 b'devel',
614 b'check-locks',
614 b'check-locks',
615 default=False,
615 default=False,
616 )
616 )
617 coreconfigitem(
617 coreconfigitem(
618 b'devel',
618 b'devel',
619 b'check-relroot',
619 b'check-relroot',
620 default=False,
620 default=False,
621 )
621 )
622 # Track copy information for all file, not just "added" one (very slow)
622 # Track copy information for all file, not just "added" one (very slow)
623 coreconfigitem(
623 coreconfigitem(
624 b'devel',
624 b'devel',
625 b'copy-tracing.trace-all-files',
625 b'copy-tracing.trace-all-files',
626 default=False,
626 default=False,
627 )
627 )
628 coreconfigitem(
628 coreconfigitem(
629 b'devel',
629 b'devel',
630 b'default-date',
630 b'default-date',
631 default=None,
631 default=None,
632 )
632 )
633 coreconfigitem(
633 coreconfigitem(
634 b'devel',
634 b'devel',
635 b'deprec-warn',
635 b'deprec-warn',
636 default=False,
636 default=False,
637 )
637 )
638 coreconfigitem(
638 coreconfigitem(
639 b'devel',
639 b'devel',
640 b'disableloaddefaultcerts',
640 b'disableloaddefaultcerts',
641 default=False,
641 default=False,
642 )
642 )
643 coreconfigitem(
643 coreconfigitem(
644 b'devel',
644 b'devel',
645 b'warn-empty-changegroup',
645 b'warn-empty-changegroup',
646 default=False,
646 default=False,
647 )
647 )
648 coreconfigitem(
648 coreconfigitem(
649 b'devel',
649 b'devel',
650 b'legacy.exchange',
650 b'legacy.exchange',
651 default=list,
651 default=list,
652 )
652 )
653 # When True, revlogs use a special reference version of the nodemap, that is not
653 # When True, revlogs use a special reference version of the nodemap, that is not
654 # performant but is "known" to behave properly.
654 # performant but is "known" to behave properly.
655 coreconfigitem(
655 coreconfigitem(
656 b'devel',
656 b'devel',
657 b'persistent-nodemap',
657 b'persistent-nodemap',
658 default=False,
658 default=False,
659 )
659 )
660 coreconfigitem(
660 coreconfigitem(
661 b'devel',
661 b'devel',
662 b'servercafile',
662 b'servercafile',
663 default=b'',
663 default=b'',
664 )
664 )
665 coreconfigitem(
665 coreconfigitem(
666 b'devel',
666 b'devel',
667 b'serverexactprotocol',
667 b'serverexactprotocol',
668 default=b'',
668 default=b'',
669 )
669 )
670 coreconfigitem(
670 coreconfigitem(
671 b'devel',
671 b'devel',
672 b'serverrequirecert',
672 b'serverrequirecert',
673 default=False,
673 default=False,
674 )
674 )
675 coreconfigitem(
675 coreconfigitem(
676 b'devel',
676 b'devel',
677 b'strip-obsmarkers',
677 b'strip-obsmarkers',
678 default=True,
678 default=True,
679 )
679 )
680 coreconfigitem(
680 coreconfigitem(
681 b'devel',
681 b'devel',
682 b'warn-config',
682 b'warn-config',
683 default=None,
683 default=None,
684 )
684 )
685 coreconfigitem(
685 coreconfigitem(
686 b'devel',
686 b'devel',
687 b'warn-config-default',
687 b'warn-config-default',
688 default=None,
688 default=None,
689 )
689 )
690 coreconfigitem(
690 coreconfigitem(
691 b'devel',
691 b'devel',
692 b'user.obsmarker',
692 b'user.obsmarker',
693 default=None,
693 default=None,
694 )
694 )
695 coreconfigitem(
695 coreconfigitem(
696 b'devel',
696 b'devel',
697 b'warn-config-unknown',
697 b'warn-config-unknown',
698 default=None,
698 default=None,
699 )
699 )
700 coreconfigitem(
700 coreconfigitem(
701 b'devel',
701 b'devel',
702 b'debug.copies',
702 b'debug.copies',
703 default=False,
703 default=False,
704 )
704 )
705 coreconfigitem(
705 coreconfigitem(
706 b'devel',
706 b'devel',
707 b'copy-tracing.multi-thread',
707 b'copy-tracing.multi-thread',
708 default=True,
708 default=True,
709 )
709 )
710 coreconfigitem(
710 coreconfigitem(
711 b'devel',
711 b'devel',
712 b'debug.extensions',
712 b'debug.extensions',
713 default=False,
713 default=False,
714 )
714 )
715 coreconfigitem(
715 coreconfigitem(
716 b'devel',
716 b'devel',
717 b'debug.repo-filters',
717 b'debug.repo-filters',
718 default=False,
718 default=False,
719 )
719 )
720 coreconfigitem(
720 coreconfigitem(
721 b'devel',
721 b'devel',
722 b'debug.peer-request',
722 b'debug.peer-request',
723 default=False,
723 default=False,
724 )
724 )
725 # If discovery.exchange-heads is False, the discovery will not start with
725 # If discovery.exchange-heads is False, the discovery will not start with
726 # remote head fetching and local head querying.
726 # remote head fetching and local head querying.
727 coreconfigitem(
727 coreconfigitem(
728 b'devel',
728 b'devel',
729 b'discovery.exchange-heads',
729 b'discovery.exchange-heads',
730 default=True,
730 default=True,
731 )
731 )
732 # If discovery.grow-sample is False, the sample size used in set discovery will
732 # If discovery.grow-sample is False, the sample size used in set discovery will
733 # not be increased through the process
733 # not be increased through the process
734 coreconfigitem(
734 coreconfigitem(
735 b'devel',
735 b'devel',
736 b'discovery.grow-sample',
736 b'discovery.grow-sample',
737 default=True,
737 default=True,
738 )
738 )
739 # When discovery.grow-sample.dynamic is True, the default, the sample size is
739 # When discovery.grow-sample.dynamic is True, the default, the sample size is
740 # adapted to the shape of the undecided set (it is set to the max of:
740 # adapted to the shape of the undecided set (it is set to the max of:
741 # <target-size>, len(roots(undecided)), len(heads(undecided)
741 # <target-size>, len(roots(undecided)), len(heads(undecided)
742 coreconfigitem(
742 coreconfigitem(
743 b'devel',
743 b'devel',
744 b'discovery.grow-sample.dynamic',
744 b'discovery.grow-sample.dynamic',
745 default=True,
745 default=True,
746 )
746 )
747 # discovery.grow-sample.rate control the rate at which the sample grow
747 # discovery.grow-sample.rate control the rate at which the sample grow
748 coreconfigitem(
748 coreconfigitem(
749 b'devel',
749 b'devel',
750 b'discovery.grow-sample.rate',
750 b'discovery.grow-sample.rate',
751 default=1.05,
751 default=1.05,
752 )
752 )
753 # If discovery.randomize is False, random sampling during discovery are
753 # If discovery.randomize is False, random sampling during discovery are
754 # deterministic. It is meant for integration tests.
754 # deterministic. It is meant for integration tests.
755 coreconfigitem(
755 coreconfigitem(
756 b'devel',
756 b'devel',
757 b'discovery.randomize',
757 b'discovery.randomize',
758 default=True,
758 default=True,
759 )
759 )
760 # Control the initial size of the discovery sample
760 # Control the initial size of the discovery sample
761 coreconfigitem(
761 coreconfigitem(
762 b'devel',
762 b'devel',
763 b'discovery.sample-size',
763 b'discovery.sample-size',
764 default=200,
764 default=200,
765 )
765 )
766 # Control the initial size of the discovery for initial change
766 # Control the initial size of the discovery for initial change
767 coreconfigitem(
767 coreconfigitem(
768 b'devel',
768 b'devel',
769 b'discovery.sample-size.initial',
769 b'discovery.sample-size.initial',
770 default=100,
770 default=100,
771 )
771 )
772 _registerdiffopts(section=b'diff')
772 _registerdiffopts(section=b'diff')
773 coreconfigitem(
773 coreconfigitem(
774 b'diff',
774 b'diff',
775 b'merge',
775 b'merge',
776 default=False,
776 default=False,
777 experimental=True,
777 experimental=True,
778 )
778 )
779 coreconfigitem(
779 coreconfigitem(
780 b'email',
780 b'email',
781 b'bcc',
781 b'bcc',
782 default=None,
782 default=None,
783 )
783 )
784 coreconfigitem(
784 coreconfigitem(
785 b'email',
785 b'email',
786 b'cc',
786 b'cc',
787 default=None,
787 default=None,
788 )
788 )
789 coreconfigitem(
789 coreconfigitem(
790 b'email',
790 b'email',
791 b'charsets',
791 b'charsets',
792 default=list,
792 default=list,
793 )
793 )
794 coreconfigitem(
794 coreconfigitem(
795 b'email',
795 b'email',
796 b'from',
796 b'from',
797 default=None,
797 default=None,
798 )
798 )
799 coreconfigitem(
799 coreconfigitem(
800 b'email',
800 b'email',
801 b'method',
801 b'method',
802 default=b'smtp',
802 default=b'smtp',
803 )
803 )
804 coreconfigitem(
804 coreconfigitem(
805 b'email',
805 b'email',
806 b'reply-to',
806 b'reply-to',
807 default=None,
807 default=None,
808 )
808 )
809 coreconfigitem(
809 coreconfigitem(
810 b'email',
810 b'email',
811 b'to',
811 b'to',
812 default=None,
812 default=None,
813 )
813 )
814 coreconfigitem(
814 coreconfigitem(
815 b'experimental',
815 b'experimental',
816 b'archivemetatemplate',
816 b'archivemetatemplate',
817 default=dynamicdefault,
817 default=dynamicdefault,
818 )
818 )
819 coreconfigitem(
819 coreconfigitem(
820 b'experimental',
820 b'experimental',
821 b'auto-publish',
821 b'auto-publish',
822 default=b'publish',
822 default=b'publish',
823 )
823 )
824 coreconfigitem(
824 coreconfigitem(
825 b'experimental',
825 b'experimental',
826 b'bundle-phases',
826 b'bundle-phases',
827 default=False,
827 default=False,
828 )
828 )
829 coreconfigitem(
829 coreconfigitem(
830 b'experimental',
830 b'experimental',
831 b'bundle2-advertise',
831 b'bundle2-advertise',
832 default=True,
832 default=True,
833 )
833 )
834 coreconfigitem(
834 coreconfigitem(
835 b'experimental',
835 b'experimental',
836 b'bundle2-output-capture',
836 b'bundle2-output-capture',
837 default=False,
837 default=False,
838 )
838 )
839 coreconfigitem(
839 coreconfigitem(
840 b'experimental',
840 b'experimental',
841 b'bundle2.pushback',
841 b'bundle2.pushback',
842 default=False,
842 default=False,
843 )
843 )
844 coreconfigitem(
844 coreconfigitem(
845 b'experimental',
845 b'experimental',
846 b'bundle2lazylocking',
846 b'bundle2lazylocking',
847 default=False,
847 default=False,
848 )
848 )
849 coreconfigitem(
849 coreconfigitem(
850 b'experimental',
850 b'experimental',
851 b'bundlecomplevel',
851 b'bundlecomplevel',
852 default=None,
852 default=None,
853 )
853 )
854 coreconfigitem(
854 coreconfigitem(
855 b'experimental',
855 b'experimental',
856 b'bundlecomplevel.bzip2',
856 b'bundlecomplevel.bzip2',
857 default=None,
857 default=None,
858 )
858 )
859 coreconfigitem(
859 coreconfigitem(
860 b'experimental',
860 b'experimental',
861 b'bundlecomplevel.gzip',
861 b'bundlecomplevel.gzip',
862 default=None,
862 default=None,
863 )
863 )
864 coreconfigitem(
864 coreconfigitem(
865 b'experimental',
865 b'experimental',
866 b'bundlecomplevel.none',
866 b'bundlecomplevel.none',
867 default=None,
867 default=None,
868 )
868 )
869 coreconfigitem(
869 coreconfigitem(
870 b'experimental',
870 b'experimental',
871 b'bundlecomplevel.zstd',
871 b'bundlecomplevel.zstd',
872 default=None,
872 default=None,
873 )
873 )
874 coreconfigitem(
874 coreconfigitem(
875 b'experimental',
875 b'experimental',
876 b'bundlecompthreads',
876 b'bundlecompthreads',
877 default=None,
877 default=None,
878 )
878 )
879 coreconfigitem(
879 coreconfigitem(
880 b'experimental',
880 b'experimental',
881 b'bundlecompthreads.bzip2',
881 b'bundlecompthreads.bzip2',
882 default=None,
882 default=None,
883 )
883 )
884 coreconfigitem(
884 coreconfigitem(
885 b'experimental',
885 b'experimental',
886 b'bundlecompthreads.gzip',
886 b'bundlecompthreads.gzip',
887 default=None,
887 default=None,
888 )
888 )
889 coreconfigitem(
889 coreconfigitem(
890 b'experimental',
890 b'experimental',
891 b'bundlecompthreads.none',
891 b'bundlecompthreads.none',
892 default=None,
892 default=None,
893 )
893 )
894 coreconfigitem(
894 coreconfigitem(
895 b'experimental',
895 b'experimental',
896 b'bundlecompthreads.zstd',
896 b'bundlecompthreads.zstd',
897 default=None,
897 default=None,
898 )
898 )
899 coreconfigitem(
899 coreconfigitem(
900 b'experimental',
900 b'experimental',
901 b'changegroup3',
901 b'changegroup3',
902 default=False,
902 default=False,
903 )
903 )
904 coreconfigitem(
904 coreconfigitem(
905 b'experimental',
905 b'experimental',
906 b'changegroup4',
906 b'changegroup4',
907 default=False,
907 default=False,
908 )
908 )
909 coreconfigitem(
909 coreconfigitem(
910 b'experimental',
910 b'experimental',
911 b'cleanup-as-archived',
911 b'cleanup-as-archived',
912 default=False,
912 default=False,
913 )
913 )
914 coreconfigitem(
914 coreconfigitem(
915 b'experimental',
915 b'experimental',
916 b'clientcompressionengines',
916 b'clientcompressionengines',
917 default=list,
917 default=list,
918 )
918 )
919 coreconfigitem(
919 coreconfigitem(
920 b'experimental',
920 b'experimental',
921 b'copytrace',
921 b'copytrace',
922 default=b'on',
922 default=b'on',
923 )
923 )
924 coreconfigitem(
924 coreconfigitem(
925 b'experimental',
925 b'experimental',
926 b'copytrace.movecandidateslimit',
926 b'copytrace.movecandidateslimit',
927 default=100,
927 default=100,
928 )
928 )
929 coreconfigitem(
929 coreconfigitem(
930 b'experimental',
930 b'experimental',
931 b'copytrace.sourcecommitlimit',
931 b'copytrace.sourcecommitlimit',
932 default=100,
932 default=100,
933 )
933 )
934 coreconfigitem(
934 coreconfigitem(
935 b'experimental',
935 b'experimental',
936 b'copies.read-from',
936 b'copies.read-from',
937 default=b"filelog-only",
937 default=b"filelog-only",
938 )
938 )
939 coreconfigitem(
939 coreconfigitem(
940 b'experimental',
940 b'experimental',
941 b'copies.write-to',
941 b'copies.write-to',
942 default=b'filelog-only',
942 default=b'filelog-only',
943 )
943 )
944 coreconfigitem(
944 coreconfigitem(
945 b'experimental',
945 b'experimental',
946 b'crecordtest',
946 b'crecordtest',
947 default=None,
947 default=None,
948 )
948 )
949 coreconfigitem(
949 coreconfigitem(
950 b'experimental',
950 b'experimental',
951 b'directaccess',
951 b'directaccess',
952 default=False,
952 default=False,
953 )
953 )
954 coreconfigitem(
954 coreconfigitem(
955 b'experimental',
955 b'experimental',
956 b'directaccess.revnums',
956 b'directaccess.revnums',
957 default=False,
957 default=False,
958 )
958 )
959 coreconfigitem(
959 coreconfigitem(
960 b'experimental',
960 b'experimental',
961 b'editortmpinhg',
961 b'editortmpinhg',
962 default=False,
962 default=False,
963 )
963 )
964 coreconfigitem(
964 coreconfigitem(
965 b'experimental',
965 b'experimental',
966 b'evolution',
966 b'evolution',
967 default=list,
967 default=list,
968 )
968 )
969 coreconfigitem(
969 coreconfigitem(
970 b'experimental',
970 b'experimental',
971 b'evolution.allowdivergence',
971 b'evolution.allowdivergence',
972 default=False,
972 default=False,
973 alias=[(b'experimental', b'allowdivergence')],
973 alias=[(b'experimental', b'allowdivergence')],
974 )
974 )
975 coreconfigitem(
975 coreconfigitem(
976 b'experimental',
976 b'experimental',
977 b'evolution.allowunstable',
977 b'evolution.allowunstable',
978 default=None,
978 default=None,
979 )
979 )
980 coreconfigitem(
980 coreconfigitem(
981 b'experimental',
981 b'experimental',
982 b'evolution.createmarkers',
982 b'evolution.createmarkers',
983 default=None,
983 default=None,
984 )
984 )
985 coreconfigitem(
985 coreconfigitem(
986 b'experimental',
986 b'experimental',
987 b'evolution.effect-flags',
987 b'evolution.effect-flags',
988 default=True,
988 default=True,
989 alias=[(b'experimental', b'effect-flags')],
989 alias=[(b'experimental', b'effect-flags')],
990 )
990 )
991 coreconfigitem(
991 coreconfigitem(
992 b'experimental',
992 b'experimental',
993 b'evolution.exchange',
993 b'evolution.exchange',
994 default=None,
994 default=None,
995 )
995 )
996 coreconfigitem(
996 coreconfigitem(
997 b'experimental',
997 b'experimental',
998 b'evolution.bundle-obsmarker',
998 b'evolution.bundle-obsmarker',
999 default=False,
999 default=False,
1000 )
1000 )
1001 coreconfigitem(
1001 coreconfigitem(
1002 b'experimental',
1002 b'experimental',
1003 b'evolution.bundle-obsmarker:mandatory',
1003 b'evolution.bundle-obsmarker:mandatory',
1004 default=True,
1004 default=True,
1005 )
1005 )
1006 coreconfigitem(
1006 coreconfigitem(
1007 b'experimental',
1007 b'experimental',
1008 b'log.topo',
1008 b'log.topo',
1009 default=False,
1009 default=False,
1010 )
1010 )
1011 coreconfigitem(
1011 coreconfigitem(
1012 b'experimental',
1012 b'experimental',
1013 b'evolution.report-instabilities',
1013 b'evolution.report-instabilities',
1014 default=True,
1014 default=True,
1015 )
1015 )
1016 coreconfigitem(
1016 coreconfigitem(
1017 b'experimental',
1017 b'experimental',
1018 b'evolution.track-operation',
1018 b'evolution.track-operation',
1019 default=True,
1019 default=True,
1020 )
1020 )
1021 # repo-level config to exclude a revset visibility
1021 # repo-level config to exclude a revset visibility
1022 #
1022 #
1023 # The target use case is to use `share` to expose different subset of the same
1023 # The target use case is to use `share` to expose different subset of the same
1024 # repository, especially server side. See also `server.view`.
1024 # repository, especially server side. See also `server.view`.
1025 coreconfigitem(
1025 coreconfigitem(
1026 b'experimental',
1026 b'experimental',
1027 b'extra-filter-revs',
1027 b'extra-filter-revs',
1028 default=None,
1028 default=None,
1029 )
1029 )
1030 coreconfigitem(
1030 coreconfigitem(
1031 b'experimental',
1031 b'experimental',
1032 b'maxdeltachainspan',
1032 b'maxdeltachainspan',
1033 default=-1,
1033 default=-1,
1034 )
1034 )
1035 # tracks files which were undeleted (merge might delete them but we explicitly
1035 # tracks files which were undeleted (merge might delete them but we explicitly
1036 # kept/undeleted them) and creates new filenodes for them
1036 # kept/undeleted them) and creates new filenodes for them
1037 coreconfigitem(
1037 coreconfigitem(
1038 b'experimental',
1038 b'experimental',
1039 b'merge-track-salvaged',
1039 b'merge-track-salvaged',
1040 default=False,
1040 default=False,
1041 )
1041 )
1042 coreconfigitem(
1042 coreconfigitem(
1043 b'experimental',
1043 b'experimental',
1044 b'mmapindexthreshold',
1044 b'mmapindexthreshold',
1045 default=None,
1045 default=None,
1046 )
1046 )
1047 coreconfigitem(
1047 coreconfigitem(
1048 b'experimental',
1048 b'experimental',
1049 b'narrow',
1049 b'narrow',
1050 default=False,
1050 default=False,
1051 )
1051 )
1052 coreconfigitem(
1052 coreconfigitem(
1053 b'experimental',
1053 b'experimental',
1054 b'nonnormalparanoidcheck',
1054 b'nonnormalparanoidcheck',
1055 default=False,
1055 default=False,
1056 )
1056 )
1057 coreconfigitem(
1057 coreconfigitem(
1058 b'experimental',
1058 b'experimental',
1059 b'exportableenviron',
1059 b'exportableenviron',
1060 default=list,
1060 default=list,
1061 )
1061 )
1062 coreconfigitem(
1062 coreconfigitem(
1063 b'experimental',
1063 b'experimental',
1064 b'extendedheader.index',
1064 b'extendedheader.index',
1065 default=None,
1065 default=None,
1066 )
1066 )
1067 coreconfigitem(
1067 coreconfigitem(
1068 b'experimental',
1068 b'experimental',
1069 b'extendedheader.similarity',
1069 b'extendedheader.similarity',
1070 default=False,
1070 default=False,
1071 )
1071 )
1072 coreconfigitem(
1072 coreconfigitem(
1073 b'experimental',
1073 b'experimental',
1074 b'graphshorten',
1074 b'graphshorten',
1075 default=False,
1075 default=False,
1076 )
1076 )
1077 coreconfigitem(
1077 coreconfigitem(
1078 b'experimental',
1078 b'experimental',
1079 b'graphstyle.parent',
1079 b'graphstyle.parent',
1080 default=dynamicdefault,
1080 default=dynamicdefault,
1081 )
1081 )
1082 coreconfigitem(
1082 coreconfigitem(
1083 b'experimental',
1083 b'experimental',
1084 b'graphstyle.missing',
1084 b'graphstyle.missing',
1085 default=dynamicdefault,
1085 default=dynamicdefault,
1086 )
1086 )
1087 coreconfigitem(
1087 coreconfigitem(
1088 b'experimental',
1088 b'experimental',
1089 b'graphstyle.grandparent',
1089 b'graphstyle.grandparent',
1090 default=dynamicdefault,
1090 default=dynamicdefault,
1091 )
1091 )
1092 coreconfigitem(
1092 coreconfigitem(
1093 b'experimental',
1093 b'experimental',
1094 b'hook-track-tags',
1094 b'hook-track-tags',
1095 default=False,
1095 default=False,
1096 )
1096 )
1097 coreconfigitem(
1097 coreconfigitem(
1098 b'experimental',
1098 b'experimental',
1099 b'httppostargs',
1099 b'httppostargs',
1100 default=False,
1100 default=False,
1101 )
1101 )
1102 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1102 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1103 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1103 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1104
1104
1105 coreconfigitem(
1105 coreconfigitem(
1106 b'experimental',
1106 b'experimental',
1107 b'obsmarkers-exchange-debug',
1107 b'obsmarkers-exchange-debug',
1108 default=False,
1108 default=False,
1109 )
1109 )
1110 coreconfigitem(
1110 coreconfigitem(
1111 b'experimental',
1111 b'experimental',
1112 b'remotenames',
1112 b'remotenames',
1113 default=False,
1113 default=False,
1114 )
1114 )
1115 coreconfigitem(
1115 coreconfigitem(
1116 b'experimental',
1116 b'experimental',
1117 b'removeemptydirs',
1117 b'removeemptydirs',
1118 default=True,
1118 default=True,
1119 )
1119 )
1120 coreconfigitem(
1120 coreconfigitem(
1121 b'experimental',
1121 b'experimental',
1122 b'revert.interactive.select-to-keep',
1122 b'revert.interactive.select-to-keep',
1123 default=False,
1123 default=False,
1124 )
1124 )
1125 coreconfigitem(
1125 coreconfigitem(
1126 b'experimental',
1126 b'experimental',
1127 b'revisions.prefixhexnode',
1127 b'revisions.prefixhexnode',
1128 default=False,
1128 default=False,
1129 )
1129 )
1130 # "out of experimental" todo list.
1130 # "out of experimental" todo list.
1131 #
1131 #
1132 # * include management of a persistent nodemap in the main docket
1132 # * include management of a persistent nodemap in the main docket
1133 # * enforce a "no-truncate" policy for mmap safety
1133 # * enforce a "no-truncate" policy for mmap safety
1134 # - for censoring operation
1134 # - for censoring operation
1135 # - for stripping operation
1135 # - for stripping operation
1136 # - for rollback operation
1136 # - for rollback operation
1137 # * proper streaming (race free) of the docket file
1137 # * proper streaming (race free) of the docket file
1138 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1138 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1139 # * Exchange-wise, we will also need to do something more efficient than
1139 # * Exchange-wise, we will also need to do something more efficient than
1140 # keeping references to the affected revlogs, especially memory-wise when
1140 # keeping references to the affected revlogs, especially memory-wise when
1141 # rewriting sidedata.
1141 # rewriting sidedata.
1142 # * introduce a proper solution to reduce the number of filelog related files.
1142 # * introduce a proper solution to reduce the number of filelog related files.
1143 # * use caching for reading sidedata (similar to what we do for data).
1143 # * use caching for reading sidedata (similar to what we do for data).
1144 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1144 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1145 # * Improvement to consider
1145 # * Improvement to consider
1146 # - avoid compression header in chunk using the default compression?
1146 # - avoid compression header in chunk using the default compression?
1147 # - forbid "inline" compression mode entirely?
1147 # - forbid "inline" compression mode entirely?
1148 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1148 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1149 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1149 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1150 # - keep track of chain base or size (probably not that useful anymore)
1150 # - keep track of chain base or size (probably not that useful anymore)
1151 coreconfigitem(
1151 coreconfigitem(
1152 b'experimental',
1152 b'experimental',
1153 b'revlogv2',
1153 b'revlogv2',
1154 default=None,
1154 default=None,
1155 )
1155 )
1156 coreconfigitem(
1156 coreconfigitem(
1157 b'experimental',
1157 b'experimental',
1158 b'revisions.disambiguatewithin',
1158 b'revisions.disambiguatewithin',
1159 default=None,
1159 default=None,
1160 )
1160 )
1161 coreconfigitem(
1161 coreconfigitem(
1162 b'experimental',
1162 b'experimental',
1163 b'rust.index',
1163 b'rust.index',
1164 default=False,
1164 default=False,
1165 )
1165 )
1166 coreconfigitem(
1166 coreconfigitem(
1167 b'experimental',
1167 b'experimental',
1168 b'server.filesdata.recommended-batch-size',
1168 b'server.filesdata.recommended-batch-size',
1169 default=50000,
1169 default=50000,
1170 )
1170 )
1171 coreconfigitem(
1171 coreconfigitem(
1172 b'experimental',
1172 b'experimental',
1173 b'server.manifestdata.recommended-batch-size',
1173 b'server.manifestdata.recommended-batch-size',
1174 default=100000,
1174 default=100000,
1175 )
1175 )
1176 coreconfigitem(
1176 coreconfigitem(
1177 b'experimental',
1177 b'experimental',
1178 b'server.stream-narrow-clones',
1178 b'server.stream-narrow-clones',
1179 default=False,
1179 default=False,
1180 )
1180 )
1181 coreconfigitem(
1181 coreconfigitem(
1182 b'experimental',
1182 b'experimental',
1183 b'single-head-per-branch',
1183 b'single-head-per-branch',
1184 default=False,
1184 default=False,
1185 )
1185 )
1186 coreconfigitem(
1186 coreconfigitem(
1187 b'experimental',
1187 b'experimental',
1188 b'single-head-per-branch:account-closed-heads',
1188 b'single-head-per-branch:account-closed-heads',
1189 default=False,
1189 default=False,
1190 )
1190 )
1191 coreconfigitem(
1191 coreconfigitem(
1192 b'experimental',
1192 b'experimental',
1193 b'single-head-per-branch:public-changes-only',
1193 b'single-head-per-branch:public-changes-only',
1194 default=False,
1194 default=False,
1195 )
1195 )
1196 coreconfigitem(
1196 coreconfigitem(
1197 b'experimental',
1197 b'experimental',
1198 b'sparse-read',
1198 b'sparse-read',
1199 default=False,
1199 default=False,
1200 )
1200 )
1201 coreconfigitem(
1201 coreconfigitem(
1202 b'experimental',
1202 b'experimental',
1203 b'sparse-read.density-threshold',
1203 b'sparse-read.density-threshold',
1204 default=0.50,
1204 default=0.50,
1205 )
1205 )
1206 coreconfigitem(
1206 coreconfigitem(
1207 b'experimental',
1207 b'experimental',
1208 b'sparse-read.min-gap-size',
1208 b'sparse-read.min-gap-size',
1209 default=b'65K',
1209 default=b'65K',
1210 )
1210 )
1211 coreconfigitem(
1211 coreconfigitem(
1212 b'experimental',
1212 b'experimental',
1213 b'treemanifest',
1213 b'treemanifest',
1214 default=False,
1214 default=False,
1215 )
1215 )
1216 coreconfigitem(
1216 coreconfigitem(
1217 b'experimental',
1217 b'experimental',
1218 b'update.atomic-file',
1218 b'update.atomic-file',
1219 default=False,
1219 default=False,
1220 )
1220 )
1221 coreconfigitem(
1221 coreconfigitem(
1222 b'experimental',
1222 b'experimental',
1223 b'web.full-garbage-collection-rate',
1223 b'web.full-garbage-collection-rate',
1224 default=1, # still forcing a full collection on each request
1224 default=1, # still forcing a full collection on each request
1225 )
1225 )
1226 coreconfigitem(
1226 coreconfigitem(
1227 b'experimental',
1227 b'experimental',
1228 b'worker.wdir-get-thread-safe',
1228 b'worker.wdir-get-thread-safe',
1229 default=False,
1229 default=False,
1230 )
1230 )
1231 coreconfigitem(
1231 coreconfigitem(
1232 b'experimental',
1232 b'experimental',
1233 b'worker.repository-upgrade',
1233 b'worker.repository-upgrade',
1234 default=False,
1234 default=False,
1235 )
1235 )
1236 coreconfigitem(
1236 coreconfigitem(
1237 b'experimental',
1237 b'experimental',
1238 b'xdiff',
1238 b'xdiff',
1239 default=False,
1239 default=False,
1240 )
1240 )
1241 coreconfigitem(
1241 coreconfigitem(
1242 b'extensions',
1242 b'extensions',
1243 b'[^:]*',
1243 b'[^:]*',
1244 default=None,
1244 default=None,
1245 generic=True,
1245 generic=True,
1246 )
1246 )
1247 coreconfigitem(
1247 coreconfigitem(
1248 b'extensions',
1248 b'extensions',
1249 b'[^:]*:required',
1249 b'[^:]*:required',
1250 default=False,
1250 default=False,
1251 generic=True,
1251 generic=True,
1252 )
1252 )
1253 coreconfigitem(
1253 coreconfigitem(
1254 b'extdata',
1254 b'extdata',
1255 b'.*',
1255 b'.*',
1256 default=None,
1256 default=None,
1257 generic=True,
1257 generic=True,
1258 )
1258 )
1259 coreconfigitem(
1259 coreconfigitem(
1260 b'format',
1260 b'format',
1261 b'bookmarks-in-store',
1261 b'bookmarks-in-store',
1262 default=False,
1262 default=False,
1263 )
1263 )
1264 coreconfigitem(
1264 coreconfigitem(
1265 b'format',
1265 b'format',
1266 b'chunkcachesize',
1266 b'chunkcachesize',
1267 default=None,
1267 default=None,
1268 experimental=True,
1268 experimental=True,
1269 )
1269 )
1270 coreconfigitem(
1270 coreconfigitem(
1271 # Enable this dirstate format *when creating a new repository*.
1271 # Enable this dirstate format *when creating a new repository*.
1272 # Which format to use for existing repos is controlled by .hg/requires
1272 # Which format to use for existing repos is controlled by .hg/requires
1273 b'format',
1273 b'format',
1274 b'use-dirstate-v2',
1274 b'use-dirstate-v2',
1275 default=False,
1275 default=False,
1276 experimental=True,
1276 experimental=True,
1277 alias=[(b'format', b'exp-rc-dirstate-v2')],
1277 alias=[(b'format', b'exp-rc-dirstate-v2')],
1278 )
1278 )
1279 coreconfigitem(
1279 coreconfigitem(
1280 b'format',
1280 b'format',
1281 b'use-dirstate-tracked-hint',
1281 b'use-dirstate-tracked-hint',
1282 default=False,
1282 default=False,
1283 experimental=True,
1283 experimental=True,
1284 )
1284 )
1285 coreconfigitem(
1285 coreconfigitem(
1286 b'format',
1286 b'format',
1287 b'use-dirstate-tracked-hint.version',
1287 b'use-dirstate-tracked-hint.version',
1288 default=1,
1288 default=1,
1289 experimental=True,
1289 experimental=True,
1290 )
1290 )
1291 coreconfigitem(
1291 coreconfigitem(
1292 b'format',
1292 b'format',
1293 b'dotencode',
1293 b'dotencode',
1294 default=True,
1294 default=True,
1295 )
1295 )
1296 coreconfigitem(
1296 coreconfigitem(
1297 b'format',
1297 b'format',
1298 b'generaldelta',
1298 b'generaldelta',
1299 default=False,
1299 default=False,
1300 experimental=True,
1300 experimental=True,
1301 )
1301 )
1302 coreconfigitem(
1302 coreconfigitem(
1303 b'format',
1303 b'format',
1304 b'manifestcachesize',
1304 b'manifestcachesize',
1305 default=None,
1305 default=None,
1306 experimental=True,
1306 experimental=True,
1307 )
1307 )
1308 coreconfigitem(
1308 coreconfigitem(
1309 b'format',
1309 b'format',
1310 b'maxchainlen',
1310 b'maxchainlen',
1311 default=dynamicdefault,
1311 default=dynamicdefault,
1312 experimental=True,
1312 experimental=True,
1313 )
1313 )
1314 coreconfigitem(
1314 coreconfigitem(
1315 b'format',
1315 b'format',
1316 b'obsstore-version',
1316 b'obsstore-version',
1317 default=None,
1317 default=None,
1318 )
1318 )
1319 coreconfigitem(
1319 coreconfigitem(
1320 b'format',
1320 b'format',
1321 b'sparse-revlog',
1321 b'sparse-revlog',
1322 default=True,
1322 default=True,
1323 )
1323 )
1324 coreconfigitem(
1324 coreconfigitem(
1325 b'format',
1325 b'format',
1326 b'revlog-compression',
1326 b'revlog-compression',
1327 default=lambda: [b'zstd', b'zlib'],
1327 default=lambda: [b'zstd', b'zlib'],
1328 alias=[(b'experimental', b'format.compression')],
1328 alias=[(b'experimental', b'format.compression')],
1329 )
1329 )
1330 # Experimental TODOs:
1330 # Experimental TODOs:
1331 #
1331 #
1332 # * Same as for revlogv2 (but for the reduction of the number of files)
1332 # * Same as for revlogv2 (but for the reduction of the number of files)
1333 # * Actually computing the rank of changesets
1333 # * Actually computing the rank of changesets
1334 # * Improvement to investigate
1334 # * Improvement to investigate
1335 # - storing .hgtags fnode
1335 # - storing .hgtags fnode
1336 # - storing branch related identifier
1336 # - storing branch related identifier
1337
1337
1338 coreconfigitem(
1338 coreconfigitem(
1339 b'format',
1339 b'format',
1340 b'exp-use-changelog-v2',
1340 b'exp-use-changelog-v2',
1341 default=None,
1341 default=None,
1342 experimental=True,
1342 experimental=True,
1343 )
1343 )
1344 coreconfigitem(
1344 coreconfigitem(
1345 b'format',
1345 b'format',
1346 b'usefncache',
1346 b'usefncache',
1347 default=True,
1347 default=True,
1348 )
1348 )
1349 coreconfigitem(
1349 coreconfigitem(
1350 b'format',
1350 b'format',
1351 b'usegeneraldelta',
1351 b'usegeneraldelta',
1352 default=True,
1352 default=True,
1353 )
1353 )
1354 coreconfigitem(
1354 coreconfigitem(
1355 b'format',
1355 b'format',
1356 b'usestore',
1356 b'usestore',
1357 default=True,
1357 default=True,
1358 )
1358 )
1359
1359
1360
1360
1361 def _persistent_nodemap_default():
1361 def _persistent_nodemap_default():
1362 """compute `use-persistent-nodemap` default value
1362 """compute `use-persistent-nodemap` default value
1363
1363
1364 The feature is disabled unless a fast implementation is available.
1364 The feature is disabled unless a fast implementation is available.
1365 """
1365 """
1366 from . import policy
1366 from . import policy
1367
1367
1368 return policy.importrust('revlog') is not None
1368 return policy.importrust('revlog') is not None
1369
1369
1370
1370
1371 coreconfigitem(
1371 coreconfigitem(
1372 b'format',
1372 b'format',
1373 b'use-persistent-nodemap',
1373 b'use-persistent-nodemap',
1374 default=_persistent_nodemap_default,
1374 default=_persistent_nodemap_default,
1375 )
1375 )
1376 coreconfigitem(
1376 coreconfigitem(
1377 b'format',
1377 b'format',
1378 b'exp-use-copies-side-data-changeset',
1378 b'exp-use-copies-side-data-changeset',
1379 default=False,
1379 default=False,
1380 experimental=True,
1380 experimental=True,
1381 )
1381 )
1382 coreconfigitem(
1382 coreconfigitem(
1383 b'format',
1383 b'format',
1384 b'use-share-safe',
1384 b'use-share-safe',
1385 default=True,
1385 default=True,
1386 )
1386 )
1387 coreconfigitem(
1387 coreconfigitem(
1388 b'format',
1388 b'format',
1389 b'internal-phase',
1389 b'internal-phase',
1390 default=False,
1390 default=False,
1391 experimental=True,
1391 experimental=True,
1392 )
1392 )
1393 coreconfigitem(
1393 coreconfigitem(
1394 b'fsmonitor',
1394 b'fsmonitor',
1395 b'warn_when_unused',
1395 b'warn_when_unused',
1396 default=True,
1396 default=True,
1397 )
1397 )
1398 coreconfigitem(
1398 coreconfigitem(
1399 b'fsmonitor',
1399 b'fsmonitor',
1400 b'warn_update_file_count',
1400 b'warn_update_file_count',
1401 default=50000,
1401 default=50000,
1402 )
1402 )
1403 coreconfigitem(
1403 coreconfigitem(
1404 b'fsmonitor',
1404 b'fsmonitor',
1405 b'warn_update_file_count_rust',
1405 b'warn_update_file_count_rust',
1406 default=400000,
1406 default=400000,
1407 )
1407 )
1408 coreconfigitem(
1408 coreconfigitem(
1409 b'help',
1409 b'help',
1410 br'hidden-command\..*',
1410 br'hidden-command\..*',
1411 default=False,
1411 default=False,
1412 generic=True,
1412 generic=True,
1413 )
1413 )
1414 coreconfigitem(
1414 coreconfigitem(
1415 b'help',
1415 b'help',
1416 br'hidden-topic\..*',
1416 br'hidden-topic\..*',
1417 default=False,
1417 default=False,
1418 generic=True,
1418 generic=True,
1419 )
1419 )
1420 coreconfigitem(
1420 coreconfigitem(
1421 b'hooks',
1421 b'hooks',
1422 b'[^:]*',
1422 b'[^:]*',
1423 default=dynamicdefault,
1423 default=dynamicdefault,
1424 generic=True,
1424 generic=True,
1425 )
1425 )
1426 coreconfigitem(
1426 coreconfigitem(
1427 b'hooks',
1427 b'hooks',
1428 b'.*:run-with-plain',
1428 b'.*:run-with-plain',
1429 default=True,
1429 default=True,
1430 generic=True,
1430 generic=True,
1431 )
1431 )
1432 coreconfigitem(
1432 coreconfigitem(
1433 b'hgweb-paths',
1433 b'hgweb-paths',
1434 b'.*',
1434 b'.*',
1435 default=list,
1435 default=list,
1436 generic=True,
1436 generic=True,
1437 )
1437 )
1438 coreconfigitem(
1438 coreconfigitem(
1439 b'hostfingerprints',
1439 b'hostfingerprints',
1440 b'.*',
1440 b'.*',
1441 default=list,
1441 default=list,
1442 generic=True,
1442 generic=True,
1443 )
1443 )
1444 coreconfigitem(
1444 coreconfigitem(
1445 b'hostsecurity',
1445 b'hostsecurity',
1446 b'ciphers',
1446 b'ciphers',
1447 default=None,
1447 default=None,
1448 )
1448 )
1449 coreconfigitem(
1449 coreconfigitem(
1450 b'hostsecurity',
1450 b'hostsecurity',
1451 b'minimumprotocol',
1451 b'minimumprotocol',
1452 default=dynamicdefault,
1452 default=dynamicdefault,
1453 )
1453 )
1454 coreconfigitem(
1454 coreconfigitem(
1455 b'hostsecurity',
1455 b'hostsecurity',
1456 b'.*:minimumprotocol$',
1456 b'.*:minimumprotocol$',
1457 default=dynamicdefault,
1457 default=dynamicdefault,
1458 generic=True,
1458 generic=True,
1459 )
1459 )
1460 coreconfigitem(
1460 coreconfigitem(
1461 b'hostsecurity',
1461 b'hostsecurity',
1462 b'.*:ciphers$',
1462 b'.*:ciphers$',
1463 default=dynamicdefault,
1463 default=dynamicdefault,
1464 generic=True,
1464 generic=True,
1465 )
1465 )
1466 coreconfigitem(
1466 coreconfigitem(
1467 b'hostsecurity',
1467 b'hostsecurity',
1468 b'.*:fingerprints$',
1468 b'.*:fingerprints$',
1469 default=list,
1469 default=list,
1470 generic=True,
1470 generic=True,
1471 )
1471 )
1472 coreconfigitem(
1472 coreconfigitem(
1473 b'hostsecurity',
1473 b'hostsecurity',
1474 b'.*:verifycertsfile$',
1474 b'.*:verifycertsfile$',
1475 default=None,
1475 default=None,
1476 generic=True,
1476 generic=True,
1477 )
1477 )
1478
1478
1479 coreconfigitem(
1479 coreconfigitem(
1480 b'http_proxy',
1480 b'http_proxy',
1481 b'always',
1481 b'always',
1482 default=False,
1482 default=False,
1483 )
1483 )
1484 coreconfigitem(
1484 coreconfigitem(
1485 b'http_proxy',
1485 b'http_proxy',
1486 b'host',
1486 b'host',
1487 default=None,
1487 default=None,
1488 )
1488 )
1489 coreconfigitem(
1489 coreconfigitem(
1490 b'http_proxy',
1490 b'http_proxy',
1491 b'no',
1491 b'no',
1492 default=list,
1492 default=list,
1493 )
1493 )
1494 coreconfigitem(
1494 coreconfigitem(
1495 b'http_proxy',
1495 b'http_proxy',
1496 b'passwd',
1496 b'passwd',
1497 default=None,
1497 default=None,
1498 )
1498 )
1499 coreconfigitem(
1499 coreconfigitem(
1500 b'http_proxy',
1500 b'http_proxy',
1501 b'user',
1501 b'user',
1502 default=None,
1502 default=None,
1503 )
1503 )
1504
1504
1505 coreconfigitem(
1505 coreconfigitem(
1506 b'http',
1506 b'http',
1507 b'timeout',
1507 b'timeout',
1508 default=None,
1508 default=None,
1509 )
1509 )
1510
1510
1511 coreconfigitem(
1511 coreconfigitem(
1512 b'logtoprocess',
1512 b'logtoprocess',
1513 b'commandexception',
1513 b'commandexception',
1514 default=None,
1514 default=None,
1515 )
1515 )
1516 coreconfigitem(
1516 coreconfigitem(
1517 b'logtoprocess',
1517 b'logtoprocess',
1518 b'commandfinish',
1518 b'commandfinish',
1519 default=None,
1519 default=None,
1520 )
1520 )
1521 coreconfigitem(
1521 coreconfigitem(
1522 b'logtoprocess',
1522 b'logtoprocess',
1523 b'command',
1523 b'command',
1524 default=None,
1524 default=None,
1525 )
1525 )
1526 coreconfigitem(
1526 coreconfigitem(
1527 b'logtoprocess',
1527 b'logtoprocess',
1528 b'develwarn',
1528 b'develwarn',
1529 default=None,
1529 default=None,
1530 )
1530 )
1531 coreconfigitem(
1531 coreconfigitem(
1532 b'logtoprocess',
1532 b'logtoprocess',
1533 b'uiblocked',
1533 b'uiblocked',
1534 default=None,
1534 default=None,
1535 )
1535 )
1536 coreconfigitem(
1536 coreconfigitem(
1537 b'merge',
1537 b'merge',
1538 b'checkunknown',
1538 b'checkunknown',
1539 default=b'abort',
1539 default=b'abort',
1540 )
1540 )
1541 coreconfigitem(
1541 coreconfigitem(
1542 b'merge',
1542 b'merge',
1543 b'checkignored',
1543 b'checkignored',
1544 default=b'abort',
1544 default=b'abort',
1545 )
1545 )
1546 coreconfigitem(
1546 coreconfigitem(
1547 b'experimental',
1547 b'experimental',
1548 b'merge.checkpathconflicts',
1548 b'merge.checkpathconflicts',
1549 default=False,
1549 default=False,
1550 )
1550 )
1551 coreconfigitem(
1551 coreconfigitem(
1552 b'merge',
1552 b'merge',
1553 b'followcopies',
1553 b'followcopies',
1554 default=True,
1554 default=True,
1555 )
1555 )
1556 coreconfigitem(
1556 coreconfigitem(
1557 b'merge',
1557 b'merge',
1558 b'on-failure',
1558 b'on-failure',
1559 default=b'continue',
1559 default=b'continue',
1560 )
1560 )
1561 coreconfigitem(
1561 coreconfigitem(
1562 b'merge',
1562 b'merge',
1563 b'preferancestor',
1563 b'preferancestor',
1564 default=lambda: [b'*'],
1564 default=lambda: [b'*'],
1565 experimental=True,
1565 experimental=True,
1566 )
1566 )
1567 coreconfigitem(
1567 coreconfigitem(
1568 b'merge',
1568 b'merge',
1569 b'strict-capability-check',
1569 b'strict-capability-check',
1570 default=False,
1570 default=False,
1571 )
1571 )
1572 coreconfigitem(
1572 coreconfigitem(
1573 b'merge',
1574 b'disable-partial-tools',
1575 default=False,
1576 experimental=True,
1577 )
1578 coreconfigitem(
1573 b'partial-merge-tools',
1579 b'partial-merge-tools',
1574 b'.*',
1580 b'.*',
1575 default=None,
1581 default=None,
1576 generic=True,
1582 generic=True,
1577 experimental=True,
1583 experimental=True,
1578 )
1584 )
1579 coreconfigitem(
1585 coreconfigitem(
1580 b'partial-merge-tools',
1586 b'partial-merge-tools',
1581 br'.*\.patterns',
1587 br'.*\.patterns',
1582 default=dynamicdefault,
1588 default=dynamicdefault,
1583 generic=True,
1589 generic=True,
1584 priority=-1,
1590 priority=-1,
1585 experimental=True,
1591 experimental=True,
1586 )
1592 )
1587 coreconfigitem(
1593 coreconfigitem(
1588 b'partial-merge-tools',
1594 b'partial-merge-tools',
1589 br'.*\.executable$',
1595 br'.*\.executable$',
1590 default=dynamicdefault,
1596 default=dynamicdefault,
1591 generic=True,
1597 generic=True,
1592 priority=-1,
1598 priority=-1,
1593 experimental=True,
1599 experimental=True,
1594 )
1600 )
1595 coreconfigitem(
1601 coreconfigitem(
1596 b'partial-merge-tools',
1602 b'partial-merge-tools',
1597 br'.*\.order',
1603 br'.*\.order',
1598 default=0,
1604 default=0,
1599 generic=True,
1605 generic=True,
1600 priority=-1,
1606 priority=-1,
1601 experimental=True,
1607 experimental=True,
1602 )
1608 )
1603 coreconfigitem(
1609 coreconfigitem(
1604 b'partial-merge-tools',
1610 b'partial-merge-tools',
1605 br'.*\.args',
1611 br'.*\.args',
1606 default=b"$local $base $other",
1612 default=b"$local $base $other",
1607 generic=True,
1613 generic=True,
1608 priority=-1,
1614 priority=-1,
1609 experimental=True,
1615 experimental=True,
1610 )
1616 )
1611 coreconfigitem(
1617 coreconfigitem(
1618 b'partial-merge-tools',
1619 br'.*\.disable',
1620 default=False,
1621 generic=True,
1622 priority=-1,
1623 experimental=True,
1624 )
1625 coreconfigitem(
1612 b'merge-tools',
1626 b'merge-tools',
1613 b'.*',
1627 b'.*',
1614 default=None,
1628 default=None,
1615 generic=True,
1629 generic=True,
1616 )
1630 )
1617 coreconfigitem(
1631 coreconfigitem(
1618 b'merge-tools',
1632 b'merge-tools',
1619 br'.*\.args$',
1633 br'.*\.args$',
1620 default=b"$local $base $other",
1634 default=b"$local $base $other",
1621 generic=True,
1635 generic=True,
1622 priority=-1,
1636 priority=-1,
1623 )
1637 )
1624 coreconfigitem(
1638 coreconfigitem(
1625 b'merge-tools',
1639 b'merge-tools',
1626 br'.*\.binary$',
1640 br'.*\.binary$',
1627 default=False,
1641 default=False,
1628 generic=True,
1642 generic=True,
1629 priority=-1,
1643 priority=-1,
1630 )
1644 )
1631 coreconfigitem(
1645 coreconfigitem(
1632 b'merge-tools',
1646 b'merge-tools',
1633 br'.*\.check$',
1647 br'.*\.check$',
1634 default=list,
1648 default=list,
1635 generic=True,
1649 generic=True,
1636 priority=-1,
1650 priority=-1,
1637 )
1651 )
1638 coreconfigitem(
1652 coreconfigitem(
1639 b'merge-tools',
1653 b'merge-tools',
1640 br'.*\.checkchanged$',
1654 br'.*\.checkchanged$',
1641 default=False,
1655 default=False,
1642 generic=True,
1656 generic=True,
1643 priority=-1,
1657 priority=-1,
1644 )
1658 )
1645 coreconfigitem(
1659 coreconfigitem(
1646 b'merge-tools',
1660 b'merge-tools',
1647 br'.*\.executable$',
1661 br'.*\.executable$',
1648 default=dynamicdefault,
1662 default=dynamicdefault,
1649 generic=True,
1663 generic=True,
1650 priority=-1,
1664 priority=-1,
1651 )
1665 )
1652 coreconfigitem(
1666 coreconfigitem(
1653 b'merge-tools',
1667 b'merge-tools',
1654 br'.*\.fixeol$',
1668 br'.*\.fixeol$',
1655 default=False,
1669 default=False,
1656 generic=True,
1670 generic=True,
1657 priority=-1,
1671 priority=-1,
1658 )
1672 )
1659 coreconfigitem(
1673 coreconfigitem(
1660 b'merge-tools',
1674 b'merge-tools',
1661 br'.*\.gui$',
1675 br'.*\.gui$',
1662 default=False,
1676 default=False,
1663 generic=True,
1677 generic=True,
1664 priority=-1,
1678 priority=-1,
1665 )
1679 )
1666 coreconfigitem(
1680 coreconfigitem(
1667 b'merge-tools',
1681 b'merge-tools',
1668 br'.*\.mergemarkers$',
1682 br'.*\.mergemarkers$',
1669 default=b'basic',
1683 default=b'basic',
1670 generic=True,
1684 generic=True,
1671 priority=-1,
1685 priority=-1,
1672 )
1686 )
1673 coreconfigitem(
1687 coreconfigitem(
1674 b'merge-tools',
1688 b'merge-tools',
1675 br'.*\.mergemarkertemplate$',
1689 br'.*\.mergemarkertemplate$',
1676 default=dynamicdefault, # take from command-templates.mergemarker
1690 default=dynamicdefault, # take from command-templates.mergemarker
1677 generic=True,
1691 generic=True,
1678 priority=-1,
1692 priority=-1,
1679 )
1693 )
1680 coreconfigitem(
1694 coreconfigitem(
1681 b'merge-tools',
1695 b'merge-tools',
1682 br'.*\.priority$',
1696 br'.*\.priority$',
1683 default=0,
1697 default=0,
1684 generic=True,
1698 generic=True,
1685 priority=-1,
1699 priority=-1,
1686 )
1700 )
1687 coreconfigitem(
1701 coreconfigitem(
1688 b'merge-tools',
1702 b'merge-tools',
1689 br'.*\.premerge$',
1703 br'.*\.premerge$',
1690 default=dynamicdefault,
1704 default=dynamicdefault,
1691 generic=True,
1705 generic=True,
1692 priority=-1,
1706 priority=-1,
1693 )
1707 )
1694 coreconfigitem(
1708 coreconfigitem(
1695 b'merge-tools',
1709 b'merge-tools',
1696 br'.*\.symlink$',
1710 br'.*\.symlink$',
1697 default=False,
1711 default=False,
1698 generic=True,
1712 generic=True,
1699 priority=-1,
1713 priority=-1,
1700 )
1714 )
1701 coreconfigitem(
1715 coreconfigitem(
1702 b'pager',
1716 b'pager',
1703 b'attend-.*',
1717 b'attend-.*',
1704 default=dynamicdefault,
1718 default=dynamicdefault,
1705 generic=True,
1719 generic=True,
1706 )
1720 )
1707 coreconfigitem(
1721 coreconfigitem(
1708 b'pager',
1722 b'pager',
1709 b'ignore',
1723 b'ignore',
1710 default=list,
1724 default=list,
1711 )
1725 )
1712 coreconfigitem(
1726 coreconfigitem(
1713 b'pager',
1727 b'pager',
1714 b'pager',
1728 b'pager',
1715 default=dynamicdefault,
1729 default=dynamicdefault,
1716 )
1730 )
1717 coreconfigitem(
1731 coreconfigitem(
1718 b'patch',
1732 b'patch',
1719 b'eol',
1733 b'eol',
1720 default=b'strict',
1734 default=b'strict',
1721 )
1735 )
1722 coreconfigitem(
1736 coreconfigitem(
1723 b'patch',
1737 b'patch',
1724 b'fuzz',
1738 b'fuzz',
1725 default=2,
1739 default=2,
1726 )
1740 )
1727 coreconfigitem(
1741 coreconfigitem(
1728 b'paths',
1742 b'paths',
1729 b'default',
1743 b'default',
1730 default=None,
1744 default=None,
1731 )
1745 )
1732 coreconfigitem(
1746 coreconfigitem(
1733 b'paths',
1747 b'paths',
1734 b'default-push',
1748 b'default-push',
1735 default=None,
1749 default=None,
1736 )
1750 )
1737 coreconfigitem(
1751 coreconfigitem(
1738 b'paths',
1752 b'paths',
1739 b'.*',
1753 b'.*',
1740 default=None,
1754 default=None,
1741 generic=True,
1755 generic=True,
1742 )
1756 )
1743 coreconfigitem(
1757 coreconfigitem(
1744 b'paths',
1758 b'paths',
1745 b'.*:bookmarks.mode',
1759 b'.*:bookmarks.mode',
1746 default='default',
1760 default='default',
1747 generic=True,
1761 generic=True,
1748 )
1762 )
1749 coreconfigitem(
1763 coreconfigitem(
1750 b'paths',
1764 b'paths',
1751 b'.*:multi-urls',
1765 b'.*:multi-urls',
1752 default=False,
1766 default=False,
1753 generic=True,
1767 generic=True,
1754 )
1768 )
1755 coreconfigitem(
1769 coreconfigitem(
1756 b'paths',
1770 b'paths',
1757 b'.*:pushrev',
1771 b'.*:pushrev',
1758 default=None,
1772 default=None,
1759 generic=True,
1773 generic=True,
1760 )
1774 )
1761 coreconfigitem(
1775 coreconfigitem(
1762 b'paths',
1776 b'paths',
1763 b'.*:pushurl',
1777 b'.*:pushurl',
1764 default=None,
1778 default=None,
1765 generic=True,
1779 generic=True,
1766 )
1780 )
1767 coreconfigitem(
1781 coreconfigitem(
1768 b'phases',
1782 b'phases',
1769 b'checksubrepos',
1783 b'checksubrepos',
1770 default=b'follow',
1784 default=b'follow',
1771 )
1785 )
1772 coreconfigitem(
1786 coreconfigitem(
1773 b'phases',
1787 b'phases',
1774 b'new-commit',
1788 b'new-commit',
1775 default=b'draft',
1789 default=b'draft',
1776 )
1790 )
1777 coreconfigitem(
1791 coreconfigitem(
1778 b'phases',
1792 b'phases',
1779 b'publish',
1793 b'publish',
1780 default=True,
1794 default=True,
1781 )
1795 )
1782 coreconfigitem(
1796 coreconfigitem(
1783 b'profiling',
1797 b'profiling',
1784 b'enabled',
1798 b'enabled',
1785 default=False,
1799 default=False,
1786 )
1800 )
1787 coreconfigitem(
1801 coreconfigitem(
1788 b'profiling',
1802 b'profiling',
1789 b'format',
1803 b'format',
1790 default=b'text',
1804 default=b'text',
1791 )
1805 )
1792 coreconfigitem(
1806 coreconfigitem(
1793 b'profiling',
1807 b'profiling',
1794 b'freq',
1808 b'freq',
1795 default=1000,
1809 default=1000,
1796 )
1810 )
1797 coreconfigitem(
1811 coreconfigitem(
1798 b'profiling',
1812 b'profiling',
1799 b'limit',
1813 b'limit',
1800 default=30,
1814 default=30,
1801 )
1815 )
1802 coreconfigitem(
1816 coreconfigitem(
1803 b'profiling',
1817 b'profiling',
1804 b'nested',
1818 b'nested',
1805 default=0,
1819 default=0,
1806 )
1820 )
1807 coreconfigitem(
1821 coreconfigitem(
1808 b'profiling',
1822 b'profiling',
1809 b'output',
1823 b'output',
1810 default=None,
1824 default=None,
1811 )
1825 )
1812 coreconfigitem(
1826 coreconfigitem(
1813 b'profiling',
1827 b'profiling',
1814 b'showmax',
1828 b'showmax',
1815 default=0.999,
1829 default=0.999,
1816 )
1830 )
1817 coreconfigitem(
1831 coreconfigitem(
1818 b'profiling',
1832 b'profiling',
1819 b'showmin',
1833 b'showmin',
1820 default=dynamicdefault,
1834 default=dynamicdefault,
1821 )
1835 )
1822 coreconfigitem(
1836 coreconfigitem(
1823 b'profiling',
1837 b'profiling',
1824 b'showtime',
1838 b'showtime',
1825 default=True,
1839 default=True,
1826 )
1840 )
1827 coreconfigitem(
1841 coreconfigitem(
1828 b'profiling',
1842 b'profiling',
1829 b'sort',
1843 b'sort',
1830 default=b'inlinetime',
1844 default=b'inlinetime',
1831 )
1845 )
1832 coreconfigitem(
1846 coreconfigitem(
1833 b'profiling',
1847 b'profiling',
1834 b'statformat',
1848 b'statformat',
1835 default=b'hotpath',
1849 default=b'hotpath',
1836 )
1850 )
1837 coreconfigitem(
1851 coreconfigitem(
1838 b'profiling',
1852 b'profiling',
1839 b'time-track',
1853 b'time-track',
1840 default=dynamicdefault,
1854 default=dynamicdefault,
1841 )
1855 )
1842 coreconfigitem(
1856 coreconfigitem(
1843 b'profiling',
1857 b'profiling',
1844 b'type',
1858 b'type',
1845 default=b'stat',
1859 default=b'stat',
1846 )
1860 )
1847 coreconfigitem(
1861 coreconfigitem(
1848 b'progress',
1862 b'progress',
1849 b'assume-tty',
1863 b'assume-tty',
1850 default=False,
1864 default=False,
1851 )
1865 )
1852 coreconfigitem(
1866 coreconfigitem(
1853 b'progress',
1867 b'progress',
1854 b'changedelay',
1868 b'changedelay',
1855 default=1,
1869 default=1,
1856 )
1870 )
1857 coreconfigitem(
1871 coreconfigitem(
1858 b'progress',
1872 b'progress',
1859 b'clear-complete',
1873 b'clear-complete',
1860 default=True,
1874 default=True,
1861 )
1875 )
1862 coreconfigitem(
1876 coreconfigitem(
1863 b'progress',
1877 b'progress',
1864 b'debug',
1878 b'debug',
1865 default=False,
1879 default=False,
1866 )
1880 )
1867 coreconfigitem(
1881 coreconfigitem(
1868 b'progress',
1882 b'progress',
1869 b'delay',
1883 b'delay',
1870 default=3,
1884 default=3,
1871 )
1885 )
1872 coreconfigitem(
1886 coreconfigitem(
1873 b'progress',
1887 b'progress',
1874 b'disable',
1888 b'disable',
1875 default=False,
1889 default=False,
1876 )
1890 )
1877 coreconfigitem(
1891 coreconfigitem(
1878 b'progress',
1892 b'progress',
1879 b'estimateinterval',
1893 b'estimateinterval',
1880 default=60.0,
1894 default=60.0,
1881 )
1895 )
1882 coreconfigitem(
1896 coreconfigitem(
1883 b'progress',
1897 b'progress',
1884 b'format',
1898 b'format',
1885 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1899 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1886 )
1900 )
1887 coreconfigitem(
1901 coreconfigitem(
1888 b'progress',
1902 b'progress',
1889 b'refresh',
1903 b'refresh',
1890 default=0.1,
1904 default=0.1,
1891 )
1905 )
1892 coreconfigitem(
1906 coreconfigitem(
1893 b'progress',
1907 b'progress',
1894 b'width',
1908 b'width',
1895 default=dynamicdefault,
1909 default=dynamicdefault,
1896 )
1910 )
1897 coreconfigitem(
1911 coreconfigitem(
1898 b'pull',
1912 b'pull',
1899 b'confirm',
1913 b'confirm',
1900 default=False,
1914 default=False,
1901 )
1915 )
1902 coreconfigitem(
1916 coreconfigitem(
1903 b'push',
1917 b'push',
1904 b'pushvars.server',
1918 b'pushvars.server',
1905 default=False,
1919 default=False,
1906 )
1920 )
1907 coreconfigitem(
1921 coreconfigitem(
1908 b'rewrite',
1922 b'rewrite',
1909 b'backup-bundle',
1923 b'backup-bundle',
1910 default=True,
1924 default=True,
1911 alias=[(b'ui', b'history-editing-backup')],
1925 alias=[(b'ui', b'history-editing-backup')],
1912 )
1926 )
1913 coreconfigitem(
1927 coreconfigitem(
1914 b'rewrite',
1928 b'rewrite',
1915 b'update-timestamp',
1929 b'update-timestamp',
1916 default=False,
1930 default=False,
1917 )
1931 )
1918 coreconfigitem(
1932 coreconfigitem(
1919 b'rewrite',
1933 b'rewrite',
1920 b'empty-successor',
1934 b'empty-successor',
1921 default=b'skip',
1935 default=b'skip',
1922 experimental=True,
1936 experimental=True,
1923 )
1937 )
1924 # experimental as long as format.use-dirstate-v2 is.
1938 # experimental as long as format.use-dirstate-v2 is.
1925 coreconfigitem(
1939 coreconfigitem(
1926 b'storage',
1940 b'storage',
1927 b'dirstate-v2.slow-path',
1941 b'dirstate-v2.slow-path',
1928 default=b"abort",
1942 default=b"abort",
1929 experimental=True,
1943 experimental=True,
1930 )
1944 )
1931 coreconfigitem(
1945 coreconfigitem(
1932 b'storage',
1946 b'storage',
1933 b'new-repo-backend',
1947 b'new-repo-backend',
1934 default=b'revlogv1',
1948 default=b'revlogv1',
1935 experimental=True,
1949 experimental=True,
1936 )
1950 )
1937 coreconfigitem(
1951 coreconfigitem(
1938 b'storage',
1952 b'storage',
1939 b'revlog.optimize-delta-parent-choice',
1953 b'revlog.optimize-delta-parent-choice',
1940 default=True,
1954 default=True,
1941 alias=[(b'format', b'aggressivemergedeltas')],
1955 alias=[(b'format', b'aggressivemergedeltas')],
1942 )
1956 )
1943 coreconfigitem(
1957 coreconfigitem(
1944 b'storage',
1958 b'storage',
1945 b'revlog.issue6528.fix-incoming',
1959 b'revlog.issue6528.fix-incoming',
1946 default=True,
1960 default=True,
1947 )
1961 )
1948 # experimental as long as rust is experimental (or a C version is implemented)
1962 # experimental as long as rust is experimental (or a C version is implemented)
1949 coreconfigitem(
1963 coreconfigitem(
1950 b'storage',
1964 b'storage',
1951 b'revlog.persistent-nodemap.mmap',
1965 b'revlog.persistent-nodemap.mmap',
1952 default=True,
1966 default=True,
1953 )
1967 )
1954 # experimental as long as format.use-persistent-nodemap is.
1968 # experimental as long as format.use-persistent-nodemap is.
1955 coreconfigitem(
1969 coreconfigitem(
1956 b'storage',
1970 b'storage',
1957 b'revlog.persistent-nodemap.slow-path',
1971 b'revlog.persistent-nodemap.slow-path',
1958 default=b"abort",
1972 default=b"abort",
1959 )
1973 )
1960
1974
1961 coreconfigitem(
1975 coreconfigitem(
1962 b'storage',
1976 b'storage',
1963 b'revlog.reuse-external-delta',
1977 b'revlog.reuse-external-delta',
1964 default=True,
1978 default=True,
1965 )
1979 )
1966 coreconfigitem(
1980 coreconfigitem(
1967 b'storage',
1981 b'storage',
1968 b'revlog.reuse-external-delta-parent',
1982 b'revlog.reuse-external-delta-parent',
1969 default=None,
1983 default=None,
1970 )
1984 )
1971 coreconfigitem(
1985 coreconfigitem(
1972 b'storage',
1986 b'storage',
1973 b'revlog.zlib.level',
1987 b'revlog.zlib.level',
1974 default=None,
1988 default=None,
1975 )
1989 )
1976 coreconfigitem(
1990 coreconfigitem(
1977 b'storage',
1991 b'storage',
1978 b'revlog.zstd.level',
1992 b'revlog.zstd.level',
1979 default=None,
1993 default=None,
1980 )
1994 )
1981 coreconfigitem(
1995 coreconfigitem(
1982 b'server',
1996 b'server',
1983 b'bookmarks-pushkey-compat',
1997 b'bookmarks-pushkey-compat',
1984 default=True,
1998 default=True,
1985 )
1999 )
1986 coreconfigitem(
2000 coreconfigitem(
1987 b'server',
2001 b'server',
1988 b'bundle1',
2002 b'bundle1',
1989 default=True,
2003 default=True,
1990 )
2004 )
1991 coreconfigitem(
2005 coreconfigitem(
1992 b'server',
2006 b'server',
1993 b'bundle1gd',
2007 b'bundle1gd',
1994 default=None,
2008 default=None,
1995 )
2009 )
1996 coreconfigitem(
2010 coreconfigitem(
1997 b'server',
2011 b'server',
1998 b'bundle1.pull',
2012 b'bundle1.pull',
1999 default=None,
2013 default=None,
2000 )
2014 )
2001 coreconfigitem(
2015 coreconfigitem(
2002 b'server',
2016 b'server',
2003 b'bundle1gd.pull',
2017 b'bundle1gd.pull',
2004 default=None,
2018 default=None,
2005 )
2019 )
2006 coreconfigitem(
2020 coreconfigitem(
2007 b'server',
2021 b'server',
2008 b'bundle1.push',
2022 b'bundle1.push',
2009 default=None,
2023 default=None,
2010 )
2024 )
2011 coreconfigitem(
2025 coreconfigitem(
2012 b'server',
2026 b'server',
2013 b'bundle1gd.push',
2027 b'bundle1gd.push',
2014 default=None,
2028 default=None,
2015 )
2029 )
2016 coreconfigitem(
2030 coreconfigitem(
2017 b'server',
2031 b'server',
2018 b'bundle2.stream',
2032 b'bundle2.stream',
2019 default=True,
2033 default=True,
2020 alias=[(b'experimental', b'bundle2.stream')],
2034 alias=[(b'experimental', b'bundle2.stream')],
2021 )
2035 )
2022 coreconfigitem(
2036 coreconfigitem(
2023 b'server',
2037 b'server',
2024 b'compressionengines',
2038 b'compressionengines',
2025 default=list,
2039 default=list,
2026 )
2040 )
2027 coreconfigitem(
2041 coreconfigitem(
2028 b'server',
2042 b'server',
2029 b'concurrent-push-mode',
2043 b'concurrent-push-mode',
2030 default=b'check-related',
2044 default=b'check-related',
2031 )
2045 )
2032 coreconfigitem(
2046 coreconfigitem(
2033 b'server',
2047 b'server',
2034 b'disablefullbundle',
2048 b'disablefullbundle',
2035 default=False,
2049 default=False,
2036 )
2050 )
2037 coreconfigitem(
2051 coreconfigitem(
2038 b'server',
2052 b'server',
2039 b'maxhttpheaderlen',
2053 b'maxhttpheaderlen',
2040 default=1024,
2054 default=1024,
2041 )
2055 )
2042 coreconfigitem(
2056 coreconfigitem(
2043 b'server',
2057 b'server',
2044 b'pullbundle',
2058 b'pullbundle',
2045 default=False,
2059 default=False,
2046 )
2060 )
2047 coreconfigitem(
2061 coreconfigitem(
2048 b'server',
2062 b'server',
2049 b'preferuncompressed',
2063 b'preferuncompressed',
2050 default=False,
2064 default=False,
2051 )
2065 )
2052 coreconfigitem(
2066 coreconfigitem(
2053 b'server',
2067 b'server',
2054 b'streamunbundle',
2068 b'streamunbundle',
2055 default=False,
2069 default=False,
2056 )
2070 )
2057 coreconfigitem(
2071 coreconfigitem(
2058 b'server',
2072 b'server',
2059 b'uncompressed',
2073 b'uncompressed',
2060 default=True,
2074 default=True,
2061 )
2075 )
2062 coreconfigitem(
2076 coreconfigitem(
2063 b'server',
2077 b'server',
2064 b'uncompressedallowsecret',
2078 b'uncompressedallowsecret',
2065 default=False,
2079 default=False,
2066 )
2080 )
2067 coreconfigitem(
2081 coreconfigitem(
2068 b'server',
2082 b'server',
2069 b'view',
2083 b'view',
2070 default=b'served',
2084 default=b'served',
2071 )
2085 )
2072 coreconfigitem(
2086 coreconfigitem(
2073 b'server',
2087 b'server',
2074 b'validate',
2088 b'validate',
2075 default=False,
2089 default=False,
2076 )
2090 )
2077 coreconfigitem(
2091 coreconfigitem(
2078 b'server',
2092 b'server',
2079 b'zliblevel',
2093 b'zliblevel',
2080 default=-1,
2094 default=-1,
2081 )
2095 )
2082 coreconfigitem(
2096 coreconfigitem(
2083 b'server',
2097 b'server',
2084 b'zstdlevel',
2098 b'zstdlevel',
2085 default=3,
2099 default=3,
2086 )
2100 )
2087 coreconfigitem(
2101 coreconfigitem(
2088 b'share',
2102 b'share',
2089 b'pool',
2103 b'pool',
2090 default=None,
2104 default=None,
2091 )
2105 )
2092 coreconfigitem(
2106 coreconfigitem(
2093 b'share',
2107 b'share',
2094 b'poolnaming',
2108 b'poolnaming',
2095 default=b'identity',
2109 default=b'identity',
2096 )
2110 )
2097 coreconfigitem(
2111 coreconfigitem(
2098 b'share',
2112 b'share',
2099 b'safe-mismatch.source-not-safe',
2113 b'safe-mismatch.source-not-safe',
2100 default=b'abort',
2114 default=b'abort',
2101 )
2115 )
2102 coreconfigitem(
2116 coreconfigitem(
2103 b'share',
2117 b'share',
2104 b'safe-mismatch.source-safe',
2118 b'safe-mismatch.source-safe',
2105 default=b'abort',
2119 default=b'abort',
2106 )
2120 )
2107 coreconfigitem(
2121 coreconfigitem(
2108 b'share',
2122 b'share',
2109 b'safe-mismatch.source-not-safe.warn',
2123 b'safe-mismatch.source-not-safe.warn',
2110 default=True,
2124 default=True,
2111 )
2125 )
2112 coreconfigitem(
2126 coreconfigitem(
2113 b'share',
2127 b'share',
2114 b'safe-mismatch.source-safe.warn',
2128 b'safe-mismatch.source-safe.warn',
2115 default=True,
2129 default=True,
2116 )
2130 )
2117 coreconfigitem(
2131 coreconfigitem(
2118 b'shelve',
2132 b'shelve',
2119 b'maxbackups',
2133 b'maxbackups',
2120 default=10,
2134 default=10,
2121 )
2135 )
2122 coreconfigitem(
2136 coreconfigitem(
2123 b'smtp',
2137 b'smtp',
2124 b'host',
2138 b'host',
2125 default=None,
2139 default=None,
2126 )
2140 )
2127 coreconfigitem(
2141 coreconfigitem(
2128 b'smtp',
2142 b'smtp',
2129 b'local_hostname',
2143 b'local_hostname',
2130 default=None,
2144 default=None,
2131 )
2145 )
2132 coreconfigitem(
2146 coreconfigitem(
2133 b'smtp',
2147 b'smtp',
2134 b'password',
2148 b'password',
2135 default=None,
2149 default=None,
2136 )
2150 )
2137 coreconfigitem(
2151 coreconfigitem(
2138 b'smtp',
2152 b'smtp',
2139 b'port',
2153 b'port',
2140 default=dynamicdefault,
2154 default=dynamicdefault,
2141 )
2155 )
2142 coreconfigitem(
2156 coreconfigitem(
2143 b'smtp',
2157 b'smtp',
2144 b'tls',
2158 b'tls',
2145 default=b'none',
2159 default=b'none',
2146 )
2160 )
2147 coreconfigitem(
2161 coreconfigitem(
2148 b'smtp',
2162 b'smtp',
2149 b'username',
2163 b'username',
2150 default=None,
2164 default=None,
2151 )
2165 )
2152 coreconfigitem(
2166 coreconfigitem(
2153 b'sparse',
2167 b'sparse',
2154 b'missingwarning',
2168 b'missingwarning',
2155 default=True,
2169 default=True,
2156 experimental=True,
2170 experimental=True,
2157 )
2171 )
2158 coreconfigitem(
2172 coreconfigitem(
2159 b'subrepos',
2173 b'subrepos',
2160 b'allowed',
2174 b'allowed',
2161 default=dynamicdefault, # to make backporting simpler
2175 default=dynamicdefault, # to make backporting simpler
2162 )
2176 )
2163 coreconfigitem(
2177 coreconfigitem(
2164 b'subrepos',
2178 b'subrepos',
2165 b'hg:allowed',
2179 b'hg:allowed',
2166 default=dynamicdefault,
2180 default=dynamicdefault,
2167 )
2181 )
2168 coreconfigitem(
2182 coreconfigitem(
2169 b'subrepos',
2183 b'subrepos',
2170 b'git:allowed',
2184 b'git:allowed',
2171 default=dynamicdefault,
2185 default=dynamicdefault,
2172 )
2186 )
2173 coreconfigitem(
2187 coreconfigitem(
2174 b'subrepos',
2188 b'subrepos',
2175 b'svn:allowed',
2189 b'svn:allowed',
2176 default=dynamicdefault,
2190 default=dynamicdefault,
2177 )
2191 )
2178 coreconfigitem(
2192 coreconfigitem(
2179 b'templates',
2193 b'templates',
2180 b'.*',
2194 b'.*',
2181 default=None,
2195 default=None,
2182 generic=True,
2196 generic=True,
2183 )
2197 )
2184 coreconfigitem(
2198 coreconfigitem(
2185 b'templateconfig',
2199 b'templateconfig',
2186 b'.*',
2200 b'.*',
2187 default=dynamicdefault,
2201 default=dynamicdefault,
2188 generic=True,
2202 generic=True,
2189 )
2203 )
2190 coreconfigitem(
2204 coreconfigitem(
2191 b'trusted',
2205 b'trusted',
2192 b'groups',
2206 b'groups',
2193 default=list,
2207 default=list,
2194 )
2208 )
2195 coreconfigitem(
2209 coreconfigitem(
2196 b'trusted',
2210 b'trusted',
2197 b'users',
2211 b'users',
2198 default=list,
2212 default=list,
2199 )
2213 )
2200 coreconfigitem(
2214 coreconfigitem(
2201 b'ui',
2215 b'ui',
2202 b'_usedassubrepo',
2216 b'_usedassubrepo',
2203 default=False,
2217 default=False,
2204 )
2218 )
2205 coreconfigitem(
2219 coreconfigitem(
2206 b'ui',
2220 b'ui',
2207 b'allowemptycommit',
2221 b'allowemptycommit',
2208 default=False,
2222 default=False,
2209 )
2223 )
2210 coreconfigitem(
2224 coreconfigitem(
2211 b'ui',
2225 b'ui',
2212 b'archivemeta',
2226 b'archivemeta',
2213 default=True,
2227 default=True,
2214 )
2228 )
2215 coreconfigitem(
2229 coreconfigitem(
2216 b'ui',
2230 b'ui',
2217 b'askusername',
2231 b'askusername',
2218 default=False,
2232 default=False,
2219 )
2233 )
2220 coreconfigitem(
2234 coreconfigitem(
2221 b'ui',
2235 b'ui',
2222 b'available-memory',
2236 b'available-memory',
2223 default=None,
2237 default=None,
2224 )
2238 )
2225
2239
2226 coreconfigitem(
2240 coreconfigitem(
2227 b'ui',
2241 b'ui',
2228 b'clonebundlefallback',
2242 b'clonebundlefallback',
2229 default=False,
2243 default=False,
2230 )
2244 )
2231 coreconfigitem(
2245 coreconfigitem(
2232 b'ui',
2246 b'ui',
2233 b'clonebundleprefers',
2247 b'clonebundleprefers',
2234 default=list,
2248 default=list,
2235 )
2249 )
2236 coreconfigitem(
2250 coreconfigitem(
2237 b'ui',
2251 b'ui',
2238 b'clonebundles',
2252 b'clonebundles',
2239 default=True,
2253 default=True,
2240 )
2254 )
2241 coreconfigitem(
2255 coreconfigitem(
2242 b'ui',
2256 b'ui',
2243 b'color',
2257 b'color',
2244 default=b'auto',
2258 default=b'auto',
2245 )
2259 )
2246 coreconfigitem(
2260 coreconfigitem(
2247 b'ui',
2261 b'ui',
2248 b'commitsubrepos',
2262 b'commitsubrepos',
2249 default=False,
2263 default=False,
2250 )
2264 )
2251 coreconfigitem(
2265 coreconfigitem(
2252 b'ui',
2266 b'ui',
2253 b'debug',
2267 b'debug',
2254 default=False,
2268 default=False,
2255 )
2269 )
2256 coreconfigitem(
2270 coreconfigitem(
2257 b'ui',
2271 b'ui',
2258 b'debugger',
2272 b'debugger',
2259 default=None,
2273 default=None,
2260 )
2274 )
2261 coreconfigitem(
2275 coreconfigitem(
2262 b'ui',
2276 b'ui',
2263 b'editor',
2277 b'editor',
2264 default=dynamicdefault,
2278 default=dynamicdefault,
2265 )
2279 )
2266 coreconfigitem(
2280 coreconfigitem(
2267 b'ui',
2281 b'ui',
2268 b'detailed-exit-code',
2282 b'detailed-exit-code',
2269 default=False,
2283 default=False,
2270 experimental=True,
2284 experimental=True,
2271 )
2285 )
2272 coreconfigitem(
2286 coreconfigitem(
2273 b'ui',
2287 b'ui',
2274 b'fallbackencoding',
2288 b'fallbackencoding',
2275 default=None,
2289 default=None,
2276 )
2290 )
2277 coreconfigitem(
2291 coreconfigitem(
2278 b'ui',
2292 b'ui',
2279 b'forcecwd',
2293 b'forcecwd',
2280 default=None,
2294 default=None,
2281 )
2295 )
2282 coreconfigitem(
2296 coreconfigitem(
2283 b'ui',
2297 b'ui',
2284 b'forcemerge',
2298 b'forcemerge',
2285 default=None,
2299 default=None,
2286 )
2300 )
2287 coreconfigitem(
2301 coreconfigitem(
2288 b'ui',
2302 b'ui',
2289 b'formatdebug',
2303 b'formatdebug',
2290 default=False,
2304 default=False,
2291 )
2305 )
2292 coreconfigitem(
2306 coreconfigitem(
2293 b'ui',
2307 b'ui',
2294 b'formatjson',
2308 b'formatjson',
2295 default=False,
2309 default=False,
2296 )
2310 )
2297 coreconfigitem(
2311 coreconfigitem(
2298 b'ui',
2312 b'ui',
2299 b'formatted',
2313 b'formatted',
2300 default=None,
2314 default=None,
2301 )
2315 )
2302 coreconfigitem(
2316 coreconfigitem(
2303 b'ui',
2317 b'ui',
2304 b'interactive',
2318 b'interactive',
2305 default=None,
2319 default=None,
2306 )
2320 )
2307 coreconfigitem(
2321 coreconfigitem(
2308 b'ui',
2322 b'ui',
2309 b'interface',
2323 b'interface',
2310 default=None,
2324 default=None,
2311 )
2325 )
2312 coreconfigitem(
2326 coreconfigitem(
2313 b'ui',
2327 b'ui',
2314 b'interface.chunkselector',
2328 b'interface.chunkselector',
2315 default=None,
2329 default=None,
2316 )
2330 )
2317 coreconfigitem(
2331 coreconfigitem(
2318 b'ui',
2332 b'ui',
2319 b'large-file-limit',
2333 b'large-file-limit',
2320 default=10 * (2 ** 20),
2334 default=10 * (2 ** 20),
2321 )
2335 )
2322 coreconfigitem(
2336 coreconfigitem(
2323 b'ui',
2337 b'ui',
2324 b'logblockedtimes',
2338 b'logblockedtimes',
2325 default=False,
2339 default=False,
2326 )
2340 )
2327 coreconfigitem(
2341 coreconfigitem(
2328 b'ui',
2342 b'ui',
2329 b'merge',
2343 b'merge',
2330 default=None,
2344 default=None,
2331 )
2345 )
2332 coreconfigitem(
2346 coreconfigitem(
2333 b'ui',
2347 b'ui',
2334 b'mergemarkers',
2348 b'mergemarkers',
2335 default=b'basic',
2349 default=b'basic',
2336 )
2350 )
2337 coreconfigitem(
2351 coreconfigitem(
2338 b'ui',
2352 b'ui',
2339 b'message-output',
2353 b'message-output',
2340 default=b'stdio',
2354 default=b'stdio',
2341 )
2355 )
2342 coreconfigitem(
2356 coreconfigitem(
2343 b'ui',
2357 b'ui',
2344 b'nontty',
2358 b'nontty',
2345 default=False,
2359 default=False,
2346 )
2360 )
2347 coreconfigitem(
2361 coreconfigitem(
2348 b'ui',
2362 b'ui',
2349 b'origbackuppath',
2363 b'origbackuppath',
2350 default=None,
2364 default=None,
2351 )
2365 )
2352 coreconfigitem(
2366 coreconfigitem(
2353 b'ui',
2367 b'ui',
2354 b'paginate',
2368 b'paginate',
2355 default=True,
2369 default=True,
2356 )
2370 )
2357 coreconfigitem(
2371 coreconfigitem(
2358 b'ui',
2372 b'ui',
2359 b'patch',
2373 b'patch',
2360 default=None,
2374 default=None,
2361 )
2375 )
2362 coreconfigitem(
2376 coreconfigitem(
2363 b'ui',
2377 b'ui',
2364 b'portablefilenames',
2378 b'portablefilenames',
2365 default=b'warn',
2379 default=b'warn',
2366 )
2380 )
2367 coreconfigitem(
2381 coreconfigitem(
2368 b'ui',
2382 b'ui',
2369 b'promptecho',
2383 b'promptecho',
2370 default=False,
2384 default=False,
2371 )
2385 )
2372 coreconfigitem(
2386 coreconfigitem(
2373 b'ui',
2387 b'ui',
2374 b'quiet',
2388 b'quiet',
2375 default=False,
2389 default=False,
2376 )
2390 )
2377 coreconfigitem(
2391 coreconfigitem(
2378 b'ui',
2392 b'ui',
2379 b'quietbookmarkmove',
2393 b'quietbookmarkmove',
2380 default=False,
2394 default=False,
2381 )
2395 )
2382 coreconfigitem(
2396 coreconfigitem(
2383 b'ui',
2397 b'ui',
2384 b'relative-paths',
2398 b'relative-paths',
2385 default=b'legacy',
2399 default=b'legacy',
2386 )
2400 )
2387 coreconfigitem(
2401 coreconfigitem(
2388 b'ui',
2402 b'ui',
2389 b'remotecmd',
2403 b'remotecmd',
2390 default=b'hg',
2404 default=b'hg',
2391 )
2405 )
2392 coreconfigitem(
2406 coreconfigitem(
2393 b'ui',
2407 b'ui',
2394 b'report_untrusted',
2408 b'report_untrusted',
2395 default=True,
2409 default=True,
2396 )
2410 )
2397 coreconfigitem(
2411 coreconfigitem(
2398 b'ui',
2412 b'ui',
2399 b'rollback',
2413 b'rollback',
2400 default=True,
2414 default=True,
2401 )
2415 )
2402 coreconfigitem(
2416 coreconfigitem(
2403 b'ui',
2417 b'ui',
2404 b'signal-safe-lock',
2418 b'signal-safe-lock',
2405 default=True,
2419 default=True,
2406 )
2420 )
2407 coreconfigitem(
2421 coreconfigitem(
2408 b'ui',
2422 b'ui',
2409 b'slash',
2423 b'slash',
2410 default=False,
2424 default=False,
2411 )
2425 )
2412 coreconfigitem(
2426 coreconfigitem(
2413 b'ui',
2427 b'ui',
2414 b'ssh',
2428 b'ssh',
2415 default=b'ssh',
2429 default=b'ssh',
2416 )
2430 )
2417 coreconfigitem(
2431 coreconfigitem(
2418 b'ui',
2432 b'ui',
2419 b'ssherrorhint',
2433 b'ssherrorhint',
2420 default=None,
2434 default=None,
2421 )
2435 )
2422 coreconfigitem(
2436 coreconfigitem(
2423 b'ui',
2437 b'ui',
2424 b'statuscopies',
2438 b'statuscopies',
2425 default=False,
2439 default=False,
2426 )
2440 )
2427 coreconfigitem(
2441 coreconfigitem(
2428 b'ui',
2442 b'ui',
2429 b'strict',
2443 b'strict',
2430 default=False,
2444 default=False,
2431 )
2445 )
2432 coreconfigitem(
2446 coreconfigitem(
2433 b'ui',
2447 b'ui',
2434 b'style',
2448 b'style',
2435 default=b'',
2449 default=b'',
2436 )
2450 )
2437 coreconfigitem(
2451 coreconfigitem(
2438 b'ui',
2452 b'ui',
2439 b'supportcontact',
2453 b'supportcontact',
2440 default=None,
2454 default=None,
2441 )
2455 )
2442 coreconfigitem(
2456 coreconfigitem(
2443 b'ui',
2457 b'ui',
2444 b'textwidth',
2458 b'textwidth',
2445 default=78,
2459 default=78,
2446 )
2460 )
2447 coreconfigitem(
2461 coreconfigitem(
2448 b'ui',
2462 b'ui',
2449 b'timeout',
2463 b'timeout',
2450 default=b'600',
2464 default=b'600',
2451 )
2465 )
2452 coreconfigitem(
2466 coreconfigitem(
2453 b'ui',
2467 b'ui',
2454 b'timeout.warn',
2468 b'timeout.warn',
2455 default=0,
2469 default=0,
2456 )
2470 )
2457 coreconfigitem(
2471 coreconfigitem(
2458 b'ui',
2472 b'ui',
2459 b'timestamp-output',
2473 b'timestamp-output',
2460 default=False,
2474 default=False,
2461 )
2475 )
2462 coreconfigitem(
2476 coreconfigitem(
2463 b'ui',
2477 b'ui',
2464 b'traceback',
2478 b'traceback',
2465 default=False,
2479 default=False,
2466 )
2480 )
2467 coreconfigitem(
2481 coreconfigitem(
2468 b'ui',
2482 b'ui',
2469 b'tweakdefaults',
2483 b'tweakdefaults',
2470 default=False,
2484 default=False,
2471 )
2485 )
2472 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2486 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2473 coreconfigitem(
2487 coreconfigitem(
2474 b'ui',
2488 b'ui',
2475 b'verbose',
2489 b'verbose',
2476 default=False,
2490 default=False,
2477 )
2491 )
2478 coreconfigitem(
2492 coreconfigitem(
2479 b'verify',
2493 b'verify',
2480 b'skipflags',
2494 b'skipflags',
2481 default=None,
2495 default=None,
2482 )
2496 )
2483 coreconfigitem(
2497 coreconfigitem(
2484 b'web',
2498 b'web',
2485 b'allowbz2',
2499 b'allowbz2',
2486 default=False,
2500 default=False,
2487 )
2501 )
2488 coreconfigitem(
2502 coreconfigitem(
2489 b'web',
2503 b'web',
2490 b'allowgz',
2504 b'allowgz',
2491 default=False,
2505 default=False,
2492 )
2506 )
2493 coreconfigitem(
2507 coreconfigitem(
2494 b'web',
2508 b'web',
2495 b'allow-pull',
2509 b'allow-pull',
2496 alias=[(b'web', b'allowpull')],
2510 alias=[(b'web', b'allowpull')],
2497 default=True,
2511 default=True,
2498 )
2512 )
2499 coreconfigitem(
2513 coreconfigitem(
2500 b'web',
2514 b'web',
2501 b'allow-push',
2515 b'allow-push',
2502 alias=[(b'web', b'allow_push')],
2516 alias=[(b'web', b'allow_push')],
2503 default=list,
2517 default=list,
2504 )
2518 )
2505 coreconfigitem(
2519 coreconfigitem(
2506 b'web',
2520 b'web',
2507 b'allowzip',
2521 b'allowzip',
2508 default=False,
2522 default=False,
2509 )
2523 )
2510 coreconfigitem(
2524 coreconfigitem(
2511 b'web',
2525 b'web',
2512 b'archivesubrepos',
2526 b'archivesubrepos',
2513 default=False,
2527 default=False,
2514 )
2528 )
2515 coreconfigitem(
2529 coreconfigitem(
2516 b'web',
2530 b'web',
2517 b'cache',
2531 b'cache',
2518 default=True,
2532 default=True,
2519 )
2533 )
2520 coreconfigitem(
2534 coreconfigitem(
2521 b'web',
2535 b'web',
2522 b'comparisoncontext',
2536 b'comparisoncontext',
2523 default=5,
2537 default=5,
2524 )
2538 )
2525 coreconfigitem(
2539 coreconfigitem(
2526 b'web',
2540 b'web',
2527 b'contact',
2541 b'contact',
2528 default=None,
2542 default=None,
2529 )
2543 )
2530 coreconfigitem(
2544 coreconfigitem(
2531 b'web',
2545 b'web',
2532 b'deny_push',
2546 b'deny_push',
2533 default=list,
2547 default=list,
2534 )
2548 )
2535 coreconfigitem(
2549 coreconfigitem(
2536 b'web',
2550 b'web',
2537 b'guessmime',
2551 b'guessmime',
2538 default=False,
2552 default=False,
2539 )
2553 )
2540 coreconfigitem(
2554 coreconfigitem(
2541 b'web',
2555 b'web',
2542 b'hidden',
2556 b'hidden',
2543 default=False,
2557 default=False,
2544 )
2558 )
2545 coreconfigitem(
2559 coreconfigitem(
2546 b'web',
2560 b'web',
2547 b'labels',
2561 b'labels',
2548 default=list,
2562 default=list,
2549 )
2563 )
2550 coreconfigitem(
2564 coreconfigitem(
2551 b'web',
2565 b'web',
2552 b'logoimg',
2566 b'logoimg',
2553 default=b'hglogo.png',
2567 default=b'hglogo.png',
2554 )
2568 )
2555 coreconfigitem(
2569 coreconfigitem(
2556 b'web',
2570 b'web',
2557 b'logourl',
2571 b'logourl',
2558 default=b'https://mercurial-scm.org/',
2572 default=b'https://mercurial-scm.org/',
2559 )
2573 )
2560 coreconfigitem(
2574 coreconfigitem(
2561 b'web',
2575 b'web',
2562 b'accesslog',
2576 b'accesslog',
2563 default=b'-',
2577 default=b'-',
2564 )
2578 )
2565 coreconfigitem(
2579 coreconfigitem(
2566 b'web',
2580 b'web',
2567 b'address',
2581 b'address',
2568 default=b'',
2582 default=b'',
2569 )
2583 )
2570 coreconfigitem(
2584 coreconfigitem(
2571 b'web',
2585 b'web',
2572 b'allow-archive',
2586 b'allow-archive',
2573 alias=[(b'web', b'allow_archive')],
2587 alias=[(b'web', b'allow_archive')],
2574 default=list,
2588 default=list,
2575 )
2589 )
2576 coreconfigitem(
2590 coreconfigitem(
2577 b'web',
2591 b'web',
2578 b'allow_read',
2592 b'allow_read',
2579 default=list,
2593 default=list,
2580 )
2594 )
2581 coreconfigitem(
2595 coreconfigitem(
2582 b'web',
2596 b'web',
2583 b'baseurl',
2597 b'baseurl',
2584 default=None,
2598 default=None,
2585 )
2599 )
2586 coreconfigitem(
2600 coreconfigitem(
2587 b'web',
2601 b'web',
2588 b'cacerts',
2602 b'cacerts',
2589 default=None,
2603 default=None,
2590 )
2604 )
2591 coreconfigitem(
2605 coreconfigitem(
2592 b'web',
2606 b'web',
2593 b'certificate',
2607 b'certificate',
2594 default=None,
2608 default=None,
2595 )
2609 )
2596 coreconfigitem(
2610 coreconfigitem(
2597 b'web',
2611 b'web',
2598 b'collapse',
2612 b'collapse',
2599 default=False,
2613 default=False,
2600 )
2614 )
2601 coreconfigitem(
2615 coreconfigitem(
2602 b'web',
2616 b'web',
2603 b'csp',
2617 b'csp',
2604 default=None,
2618 default=None,
2605 )
2619 )
2606 coreconfigitem(
2620 coreconfigitem(
2607 b'web',
2621 b'web',
2608 b'deny_read',
2622 b'deny_read',
2609 default=list,
2623 default=list,
2610 )
2624 )
2611 coreconfigitem(
2625 coreconfigitem(
2612 b'web',
2626 b'web',
2613 b'descend',
2627 b'descend',
2614 default=True,
2628 default=True,
2615 )
2629 )
2616 coreconfigitem(
2630 coreconfigitem(
2617 b'web',
2631 b'web',
2618 b'description',
2632 b'description',
2619 default=b"",
2633 default=b"",
2620 )
2634 )
2621 coreconfigitem(
2635 coreconfigitem(
2622 b'web',
2636 b'web',
2623 b'encoding',
2637 b'encoding',
2624 default=lambda: encoding.encoding,
2638 default=lambda: encoding.encoding,
2625 )
2639 )
2626 coreconfigitem(
2640 coreconfigitem(
2627 b'web',
2641 b'web',
2628 b'errorlog',
2642 b'errorlog',
2629 default=b'-',
2643 default=b'-',
2630 )
2644 )
2631 coreconfigitem(
2645 coreconfigitem(
2632 b'web',
2646 b'web',
2633 b'ipv6',
2647 b'ipv6',
2634 default=False,
2648 default=False,
2635 )
2649 )
2636 coreconfigitem(
2650 coreconfigitem(
2637 b'web',
2651 b'web',
2638 b'maxchanges',
2652 b'maxchanges',
2639 default=10,
2653 default=10,
2640 )
2654 )
2641 coreconfigitem(
2655 coreconfigitem(
2642 b'web',
2656 b'web',
2643 b'maxfiles',
2657 b'maxfiles',
2644 default=10,
2658 default=10,
2645 )
2659 )
2646 coreconfigitem(
2660 coreconfigitem(
2647 b'web',
2661 b'web',
2648 b'maxshortchanges',
2662 b'maxshortchanges',
2649 default=60,
2663 default=60,
2650 )
2664 )
2651 coreconfigitem(
2665 coreconfigitem(
2652 b'web',
2666 b'web',
2653 b'motd',
2667 b'motd',
2654 default=b'',
2668 default=b'',
2655 )
2669 )
2656 coreconfigitem(
2670 coreconfigitem(
2657 b'web',
2671 b'web',
2658 b'name',
2672 b'name',
2659 default=dynamicdefault,
2673 default=dynamicdefault,
2660 )
2674 )
2661 coreconfigitem(
2675 coreconfigitem(
2662 b'web',
2676 b'web',
2663 b'port',
2677 b'port',
2664 default=8000,
2678 default=8000,
2665 )
2679 )
2666 coreconfigitem(
2680 coreconfigitem(
2667 b'web',
2681 b'web',
2668 b'prefix',
2682 b'prefix',
2669 default=b'',
2683 default=b'',
2670 )
2684 )
2671 coreconfigitem(
2685 coreconfigitem(
2672 b'web',
2686 b'web',
2673 b'push_ssl',
2687 b'push_ssl',
2674 default=True,
2688 default=True,
2675 )
2689 )
2676 coreconfigitem(
2690 coreconfigitem(
2677 b'web',
2691 b'web',
2678 b'refreshinterval',
2692 b'refreshinterval',
2679 default=20,
2693 default=20,
2680 )
2694 )
2681 coreconfigitem(
2695 coreconfigitem(
2682 b'web',
2696 b'web',
2683 b'server-header',
2697 b'server-header',
2684 default=None,
2698 default=None,
2685 )
2699 )
2686 coreconfigitem(
2700 coreconfigitem(
2687 b'web',
2701 b'web',
2688 b'static',
2702 b'static',
2689 default=None,
2703 default=None,
2690 )
2704 )
2691 coreconfigitem(
2705 coreconfigitem(
2692 b'web',
2706 b'web',
2693 b'staticurl',
2707 b'staticurl',
2694 default=None,
2708 default=None,
2695 )
2709 )
2696 coreconfigitem(
2710 coreconfigitem(
2697 b'web',
2711 b'web',
2698 b'stripes',
2712 b'stripes',
2699 default=1,
2713 default=1,
2700 )
2714 )
2701 coreconfigitem(
2715 coreconfigitem(
2702 b'web',
2716 b'web',
2703 b'style',
2717 b'style',
2704 default=b'paper',
2718 default=b'paper',
2705 )
2719 )
2706 coreconfigitem(
2720 coreconfigitem(
2707 b'web',
2721 b'web',
2708 b'templates',
2722 b'templates',
2709 default=None,
2723 default=None,
2710 )
2724 )
2711 coreconfigitem(
2725 coreconfigitem(
2712 b'web',
2726 b'web',
2713 b'view',
2727 b'view',
2714 default=b'served',
2728 default=b'served',
2715 experimental=True,
2729 experimental=True,
2716 )
2730 )
2717 coreconfigitem(
2731 coreconfigitem(
2718 b'worker',
2732 b'worker',
2719 b'backgroundclose',
2733 b'backgroundclose',
2720 default=dynamicdefault,
2734 default=dynamicdefault,
2721 )
2735 )
2722 # Windows defaults to a limit of 512 open files. A buffer of 128
2736 # Windows defaults to a limit of 512 open files. A buffer of 128
2723 # should give us enough headway.
2737 # should give us enough headway.
2724 coreconfigitem(
2738 coreconfigitem(
2725 b'worker',
2739 b'worker',
2726 b'backgroundclosemaxqueue',
2740 b'backgroundclosemaxqueue',
2727 default=384,
2741 default=384,
2728 )
2742 )
2729 coreconfigitem(
2743 coreconfigitem(
2730 b'worker',
2744 b'worker',
2731 b'backgroundcloseminfilecount',
2745 b'backgroundcloseminfilecount',
2732 default=2048,
2746 default=2048,
2733 )
2747 )
2734 coreconfigitem(
2748 coreconfigitem(
2735 b'worker',
2749 b'worker',
2736 b'backgroundclosethreadcount',
2750 b'backgroundclosethreadcount',
2737 default=4,
2751 default=4,
2738 )
2752 )
2739 coreconfigitem(
2753 coreconfigitem(
2740 b'worker',
2754 b'worker',
2741 b'enabled',
2755 b'enabled',
2742 default=True,
2756 default=True,
2743 )
2757 )
2744 coreconfigitem(
2758 coreconfigitem(
2745 b'worker',
2759 b'worker',
2746 b'numcpus',
2760 b'numcpus',
2747 default=None,
2761 default=None,
2748 )
2762 )
2749
2763
2750 # Rebase related configuration moved to core because other extension are doing
2764 # Rebase related configuration moved to core because other extension are doing
2751 # strange things. For example, shelve import the extensions to reuse some bit
2765 # strange things. For example, shelve import the extensions to reuse some bit
2752 # without formally loading it.
2766 # without formally loading it.
2753 coreconfigitem(
2767 coreconfigitem(
2754 b'commands',
2768 b'commands',
2755 b'rebase.requiredest',
2769 b'rebase.requiredest',
2756 default=False,
2770 default=False,
2757 )
2771 )
2758 coreconfigitem(
2772 coreconfigitem(
2759 b'experimental',
2773 b'experimental',
2760 b'rebaseskipobsolete',
2774 b'rebaseskipobsolete',
2761 default=True,
2775 default=True,
2762 )
2776 )
2763 coreconfigitem(
2777 coreconfigitem(
2764 b'rebase',
2778 b'rebase',
2765 b'singletransaction',
2779 b'singletransaction',
2766 default=False,
2780 default=False,
2767 )
2781 )
2768 coreconfigitem(
2782 coreconfigitem(
2769 b'rebase',
2783 b'rebase',
2770 b'experimental.inmemory',
2784 b'experimental.inmemory',
2771 default=False,
2785 default=False,
2772 )
2786 )
@@ -1,1299 +1,1303 b''
1 # filemerge.py - file-level merge handling for Mercurial
1 # filemerge.py - file-level merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007, 2008 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2006, 2007, 2008 Olivia Mackall <olivia@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import contextlib
9 import contextlib
10 import os
10 import os
11 import re
11 import re
12 import shutil
12 import shutil
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 hex,
16 hex,
17 short,
17 short,
18 )
18 )
19 from .pycompat import (
19 from .pycompat import (
20 getattr,
20 getattr,
21 )
21 )
22
22
23 from . import (
23 from . import (
24 encoding,
24 encoding,
25 error,
25 error,
26 formatter,
26 formatter,
27 match,
27 match,
28 pycompat,
28 pycompat,
29 registrar,
29 registrar,
30 scmutil,
30 scmutil,
31 simplemerge,
31 simplemerge,
32 tagmerge,
32 tagmerge,
33 templatekw,
33 templatekw,
34 templater,
34 templater,
35 templateutil,
35 templateutil,
36 util,
36 util,
37 )
37 )
38
38
39 from .utils import (
39 from .utils import (
40 procutil,
40 procutil,
41 stringutil,
41 stringutil,
42 )
42 )
43
43
44
44
45 def _toolstr(ui, tool, part, *args):
45 def _toolstr(ui, tool, part, *args):
46 return ui.config(b"merge-tools", tool + b"." + part, *args)
46 return ui.config(b"merge-tools", tool + b"." + part, *args)
47
47
48
48
49 def _toolbool(ui, tool, part, *args):
49 def _toolbool(ui, tool, part, *args):
50 return ui.configbool(b"merge-tools", tool + b"." + part, *args)
50 return ui.configbool(b"merge-tools", tool + b"." + part, *args)
51
51
52
52
53 def _toollist(ui, tool, part):
53 def _toollist(ui, tool, part):
54 return ui.configlist(b"merge-tools", tool + b"." + part)
54 return ui.configlist(b"merge-tools", tool + b"." + part)
55
55
56
56
57 internals = {}
57 internals = {}
58 # Merge tools to document.
58 # Merge tools to document.
59 internalsdoc = {}
59 internalsdoc = {}
60
60
61 internaltool = registrar.internalmerge()
61 internaltool = registrar.internalmerge()
62
62
63 # internal tool merge types
63 # internal tool merge types
64 nomerge = internaltool.nomerge
64 nomerge = internaltool.nomerge
65 mergeonly = internaltool.mergeonly # just the full merge, no premerge
65 mergeonly = internaltool.mergeonly # just the full merge, no premerge
66 fullmerge = internaltool.fullmerge # both premerge and merge
66 fullmerge = internaltool.fullmerge # both premerge and merge
67
67
68 # IMPORTANT: keep the last line of this prompt very short ("What do you want to
68 # IMPORTANT: keep the last line of this prompt very short ("What do you want to
69 # do?") because of issue6158, ideally to <40 English characters (to allow other
69 # do?") because of issue6158, ideally to <40 English characters (to allow other
70 # languages that may take more columns to still have a chance to fit in an
70 # languages that may take more columns to still have a chance to fit in an
71 # 80-column screen).
71 # 80-column screen).
72 _localchangedotherdeletedmsg = _(
72 _localchangedotherdeletedmsg = _(
73 b"file '%(fd)s' was deleted in other%(o)s but was modified in local%(l)s.\n"
73 b"file '%(fd)s' was deleted in other%(o)s but was modified in local%(l)s.\n"
74 b"You can use (c)hanged version, (d)elete, or leave (u)nresolved.\n"
74 b"You can use (c)hanged version, (d)elete, or leave (u)nresolved.\n"
75 b"What do you want to do?"
75 b"What do you want to do?"
76 b"$$ &Changed $$ &Delete $$ &Unresolved"
76 b"$$ &Changed $$ &Delete $$ &Unresolved"
77 )
77 )
78
78
79 _otherchangedlocaldeletedmsg = _(
79 _otherchangedlocaldeletedmsg = _(
80 b"file '%(fd)s' was deleted in local%(l)s but was modified in other%(o)s.\n"
80 b"file '%(fd)s' was deleted in local%(l)s but was modified in other%(o)s.\n"
81 b"You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.\n"
81 b"You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.\n"
82 b"What do you want to do?"
82 b"What do you want to do?"
83 b"$$ &Changed $$ &Deleted $$ &Unresolved"
83 b"$$ &Changed $$ &Deleted $$ &Unresolved"
84 )
84 )
85
85
86
86
87 class absentfilectx:
87 class absentfilectx:
88 """Represents a file that's ostensibly in a context but is actually not
88 """Represents a file that's ostensibly in a context but is actually not
89 present in it.
89 present in it.
90
90
91 This is here because it's very specific to the filemerge code for now --
91 This is here because it's very specific to the filemerge code for now --
92 other code is likely going to break with the values this returns."""
92 other code is likely going to break with the values this returns."""
93
93
94 def __init__(self, ctx, f):
94 def __init__(self, ctx, f):
95 self._ctx = ctx
95 self._ctx = ctx
96 self._f = f
96 self._f = f
97
97
98 def __bytes__(self):
98 def __bytes__(self):
99 return b'absent file %s@%s' % (self._f, self._ctx)
99 return b'absent file %s@%s' % (self._f, self._ctx)
100
100
101 def path(self):
101 def path(self):
102 return self._f
102 return self._f
103
103
104 def size(self):
104 def size(self):
105 return None
105 return None
106
106
107 def data(self):
107 def data(self):
108 return None
108 return None
109
109
110 def filenode(self):
110 def filenode(self):
111 return self._ctx.repo().nullid
111 return self._ctx.repo().nullid
112
112
113 _customcmp = True
113 _customcmp = True
114
114
115 def cmp(self, fctx):
115 def cmp(self, fctx):
116 """compare with other file context
116 """compare with other file context
117
117
118 returns True if different from fctx.
118 returns True if different from fctx.
119 """
119 """
120 return not (
120 return not (
121 fctx.isabsent()
121 fctx.isabsent()
122 and fctx.changectx() == self.changectx()
122 and fctx.changectx() == self.changectx()
123 and fctx.path() == self.path()
123 and fctx.path() == self.path()
124 )
124 )
125
125
126 def flags(self):
126 def flags(self):
127 return b''
127 return b''
128
128
129 def changectx(self):
129 def changectx(self):
130 return self._ctx
130 return self._ctx
131
131
132 def isbinary(self):
132 def isbinary(self):
133 return False
133 return False
134
134
135 def isabsent(self):
135 def isabsent(self):
136 return True
136 return True
137
137
138
138
139 def _findtool(ui, tool):
139 def _findtool(ui, tool):
140 if tool in internals:
140 if tool in internals:
141 return tool
141 return tool
142 cmd = _toolstr(ui, tool, b"executable", tool)
142 cmd = _toolstr(ui, tool, b"executable", tool)
143 if cmd.startswith(b'python:'):
143 if cmd.startswith(b'python:'):
144 return cmd
144 return cmd
145 return findexternaltool(ui, tool)
145 return findexternaltool(ui, tool)
146
146
147
147
148 def _quotetoolpath(cmd):
148 def _quotetoolpath(cmd):
149 if cmd.startswith(b'python:'):
149 if cmd.startswith(b'python:'):
150 return cmd
150 return cmd
151 return procutil.shellquote(cmd)
151 return procutil.shellquote(cmd)
152
152
153
153
154 def findexternaltool(ui, tool):
154 def findexternaltool(ui, tool):
155 for kn in (b"regkey", b"regkeyalt"):
155 for kn in (b"regkey", b"regkeyalt"):
156 k = _toolstr(ui, tool, kn)
156 k = _toolstr(ui, tool, kn)
157 if not k:
157 if not k:
158 continue
158 continue
159 p = util.lookupreg(k, _toolstr(ui, tool, b"regname"))
159 p = util.lookupreg(k, _toolstr(ui, tool, b"regname"))
160 if p:
160 if p:
161 p = procutil.findexe(p + _toolstr(ui, tool, b"regappend", b""))
161 p = procutil.findexe(p + _toolstr(ui, tool, b"regappend", b""))
162 if p:
162 if p:
163 return p
163 return p
164 exe = _toolstr(ui, tool, b"executable", tool)
164 exe = _toolstr(ui, tool, b"executable", tool)
165 return procutil.findexe(util.expandpath(exe))
165 return procutil.findexe(util.expandpath(exe))
166
166
167
167
168 def _picktool(repo, ui, path, binary, symlink, changedelete):
168 def _picktool(repo, ui, path, binary, symlink, changedelete):
169 strictcheck = ui.configbool(b'merge', b'strict-capability-check')
169 strictcheck = ui.configbool(b'merge', b'strict-capability-check')
170
170
171 def hascapability(tool, capability, strict=False):
171 def hascapability(tool, capability, strict=False):
172 if tool in internals:
172 if tool in internals:
173 return strict and internals[tool].capabilities.get(capability)
173 return strict and internals[tool].capabilities.get(capability)
174 return _toolbool(ui, tool, capability)
174 return _toolbool(ui, tool, capability)
175
175
176 def supportscd(tool):
176 def supportscd(tool):
177 return tool in internals and internals[tool].mergetype == nomerge
177 return tool in internals and internals[tool].mergetype == nomerge
178
178
179 def check(tool, pat, symlink, binary, changedelete):
179 def check(tool, pat, symlink, binary, changedelete):
180 tmsg = tool
180 tmsg = tool
181 if pat:
181 if pat:
182 tmsg = _(b"%s (for pattern %s)") % (tool, pat)
182 tmsg = _(b"%s (for pattern %s)") % (tool, pat)
183 if not _findtool(ui, tool):
183 if not _findtool(ui, tool):
184 if pat: # explicitly requested tool deserves a warning
184 if pat: # explicitly requested tool deserves a warning
185 ui.warn(_(b"couldn't find merge tool %s\n") % tmsg)
185 ui.warn(_(b"couldn't find merge tool %s\n") % tmsg)
186 else: # configured but non-existing tools are more silent
186 else: # configured but non-existing tools are more silent
187 ui.note(_(b"couldn't find merge tool %s\n") % tmsg)
187 ui.note(_(b"couldn't find merge tool %s\n") % tmsg)
188 elif symlink and not hascapability(tool, b"symlink", strictcheck):
188 elif symlink and not hascapability(tool, b"symlink", strictcheck):
189 ui.warn(_(b"tool %s can't handle symlinks\n") % tmsg)
189 ui.warn(_(b"tool %s can't handle symlinks\n") % tmsg)
190 elif binary and not hascapability(tool, b"binary", strictcheck):
190 elif binary and not hascapability(tool, b"binary", strictcheck):
191 ui.warn(_(b"tool %s can't handle binary\n") % tmsg)
191 ui.warn(_(b"tool %s can't handle binary\n") % tmsg)
192 elif changedelete and not supportscd(tool):
192 elif changedelete and not supportscd(tool):
193 # the nomerge tools are the only tools that support change/delete
193 # the nomerge tools are the only tools that support change/delete
194 # conflicts
194 # conflicts
195 pass
195 pass
196 elif not procutil.gui() and _toolbool(ui, tool, b"gui"):
196 elif not procutil.gui() and _toolbool(ui, tool, b"gui"):
197 ui.warn(_(b"tool %s requires a GUI\n") % tmsg)
197 ui.warn(_(b"tool %s requires a GUI\n") % tmsg)
198 else:
198 else:
199 return True
199 return True
200 return False
200 return False
201
201
202 # internal config: ui.forcemerge
202 # internal config: ui.forcemerge
203 # forcemerge comes from command line arguments, highest priority
203 # forcemerge comes from command line arguments, highest priority
204 force = ui.config(b'ui', b'forcemerge')
204 force = ui.config(b'ui', b'forcemerge')
205 if force:
205 if force:
206 toolpath = _findtool(ui, force)
206 toolpath = _findtool(ui, force)
207 if changedelete and not supportscd(toolpath):
207 if changedelete and not supportscd(toolpath):
208 return b":prompt", None
208 return b":prompt", None
209 else:
209 else:
210 if toolpath:
210 if toolpath:
211 return (force, _quotetoolpath(toolpath))
211 return (force, _quotetoolpath(toolpath))
212 else:
212 else:
213 # mimic HGMERGE if given tool not found
213 # mimic HGMERGE if given tool not found
214 return (force, force)
214 return (force, force)
215
215
216 # HGMERGE takes next precedence
216 # HGMERGE takes next precedence
217 hgmerge = encoding.environ.get(b"HGMERGE")
217 hgmerge = encoding.environ.get(b"HGMERGE")
218 if hgmerge:
218 if hgmerge:
219 if changedelete and not supportscd(hgmerge):
219 if changedelete and not supportscd(hgmerge):
220 return b":prompt", None
220 return b":prompt", None
221 else:
221 else:
222 return (hgmerge, hgmerge)
222 return (hgmerge, hgmerge)
223
223
224 # then patterns
224 # then patterns
225
225
226 # whether binary capability should be checked strictly
226 # whether binary capability should be checked strictly
227 binarycap = binary and strictcheck
227 binarycap = binary and strictcheck
228
228
229 for pat, tool in ui.configitems(b"merge-patterns"):
229 for pat, tool in ui.configitems(b"merge-patterns"):
230 mf = match.match(repo.root, b'', [pat])
230 mf = match.match(repo.root, b'', [pat])
231 if mf(path) and check(tool, pat, symlink, binarycap, changedelete):
231 if mf(path) and check(tool, pat, symlink, binarycap, changedelete):
232 if binary and not hascapability(tool, b"binary", strict=True):
232 if binary and not hascapability(tool, b"binary", strict=True):
233 ui.warn(
233 ui.warn(
234 _(
234 _(
235 b"warning: check merge-patterns configurations,"
235 b"warning: check merge-patterns configurations,"
236 b" if %r for binary file %r is unintentional\n"
236 b" if %r for binary file %r is unintentional\n"
237 b"(see 'hg help merge-tools'"
237 b"(see 'hg help merge-tools'"
238 b" for binary files capability)\n"
238 b" for binary files capability)\n"
239 )
239 )
240 % (pycompat.bytestr(tool), pycompat.bytestr(path))
240 % (pycompat.bytestr(tool), pycompat.bytestr(path))
241 )
241 )
242 toolpath = _findtool(ui, tool)
242 toolpath = _findtool(ui, tool)
243 return (tool, _quotetoolpath(toolpath))
243 return (tool, _quotetoolpath(toolpath))
244
244
245 # then merge tools
245 # then merge tools
246 tools = {}
246 tools = {}
247 disabled = set()
247 disabled = set()
248 for k, v in ui.configitems(b"merge-tools"):
248 for k, v in ui.configitems(b"merge-tools"):
249 t = k.split(b'.')[0]
249 t = k.split(b'.')[0]
250 if t not in tools:
250 if t not in tools:
251 tools[t] = int(_toolstr(ui, t, b"priority"))
251 tools[t] = int(_toolstr(ui, t, b"priority"))
252 if _toolbool(ui, t, b"disabled"):
252 if _toolbool(ui, t, b"disabled"):
253 disabled.add(t)
253 disabled.add(t)
254 names = tools.keys()
254 names = tools.keys()
255 tools = sorted(
255 tools = sorted(
256 [(-p, tool) for tool, p in tools.items() if tool not in disabled]
256 [(-p, tool) for tool, p in tools.items() if tool not in disabled]
257 )
257 )
258 uimerge = ui.config(b"ui", b"merge")
258 uimerge = ui.config(b"ui", b"merge")
259 if uimerge:
259 if uimerge:
260 # external tools defined in uimerge won't be able to handle
260 # external tools defined in uimerge won't be able to handle
261 # change/delete conflicts
261 # change/delete conflicts
262 if check(uimerge, path, symlink, binary, changedelete):
262 if check(uimerge, path, symlink, binary, changedelete):
263 if uimerge not in names and not changedelete:
263 if uimerge not in names and not changedelete:
264 return (uimerge, uimerge)
264 return (uimerge, uimerge)
265 tools.insert(0, (None, uimerge)) # highest priority
265 tools.insert(0, (None, uimerge)) # highest priority
266 tools.append((None, b"hgmerge")) # the old default, if found
266 tools.append((None, b"hgmerge")) # the old default, if found
267 for p, t in tools:
267 for p, t in tools:
268 if check(t, None, symlink, binary, changedelete):
268 if check(t, None, symlink, binary, changedelete):
269 toolpath = _findtool(ui, t)
269 toolpath = _findtool(ui, t)
270 return (t, _quotetoolpath(toolpath))
270 return (t, _quotetoolpath(toolpath))
271
271
272 # internal merge or prompt as last resort
272 # internal merge or prompt as last resort
273 if symlink or binary or changedelete:
273 if symlink or binary or changedelete:
274 if not changedelete and len(tools):
274 if not changedelete and len(tools):
275 # any tool is rejected by capability for symlink or binary
275 # any tool is rejected by capability for symlink or binary
276 ui.warn(_(b"no tool found to merge %s\n") % path)
276 ui.warn(_(b"no tool found to merge %s\n") % path)
277 return b":prompt", None
277 return b":prompt", None
278 return b":merge", None
278 return b":merge", None
279
279
280
280
281 def _eoltype(data):
281 def _eoltype(data):
282 """Guess the EOL type of a file"""
282 """Guess the EOL type of a file"""
283 if b'\0' in data: # binary
283 if b'\0' in data: # binary
284 return None
284 return None
285 if b'\r\n' in data: # Windows
285 if b'\r\n' in data: # Windows
286 return b'\r\n'
286 return b'\r\n'
287 if b'\r' in data: # Old Mac
287 if b'\r' in data: # Old Mac
288 return b'\r'
288 return b'\r'
289 if b'\n' in data: # UNIX
289 if b'\n' in data: # UNIX
290 return b'\n'
290 return b'\n'
291 return None # unknown
291 return None # unknown
292
292
293
293
294 def _matcheol(file, backup):
294 def _matcheol(file, backup):
295 """Convert EOL markers in a file to match origfile"""
295 """Convert EOL markers in a file to match origfile"""
296 tostyle = _eoltype(backup.data()) # No repo.wread filters?
296 tostyle = _eoltype(backup.data()) # No repo.wread filters?
297 if tostyle:
297 if tostyle:
298 data = util.readfile(file)
298 data = util.readfile(file)
299 style = _eoltype(data)
299 style = _eoltype(data)
300 if style:
300 if style:
301 newdata = data.replace(style, tostyle)
301 newdata = data.replace(style, tostyle)
302 if newdata != data:
302 if newdata != data:
303 util.writefile(file, newdata)
303 util.writefile(file, newdata)
304
304
305
305
306 @internaltool(b'prompt', nomerge)
306 @internaltool(b'prompt', nomerge)
307 def _iprompt(repo, mynode, local, other, base, toolconf):
307 def _iprompt(repo, mynode, local, other, base, toolconf):
308 """Asks the user which of the local `p1()` or the other `p2()` version to
308 """Asks the user which of the local `p1()` or the other `p2()` version to
309 keep as the merged version."""
309 keep as the merged version."""
310 ui = repo.ui
310 ui = repo.ui
311 fd = local.fctx.path()
311 fd = local.fctx.path()
312 uipathfn = scmutil.getuipathfn(repo)
312 uipathfn = scmutil.getuipathfn(repo)
313
313
314 # Avoid prompting during an in-memory merge since it doesn't support merge
314 # Avoid prompting during an in-memory merge since it doesn't support merge
315 # conflicts.
315 # conflicts.
316 if local.fctx.changectx().isinmemory():
316 if local.fctx.changectx().isinmemory():
317 raise error.InMemoryMergeConflictsError(
317 raise error.InMemoryMergeConflictsError(
318 b'in-memory merge does not support file conflicts'
318 b'in-memory merge does not support file conflicts'
319 )
319 )
320
320
321 prompts = partextras([local.label, other.label])
321 prompts = partextras([local.label, other.label])
322 prompts[b'fd'] = uipathfn(fd)
322 prompts[b'fd'] = uipathfn(fd)
323 try:
323 try:
324 if other.fctx.isabsent():
324 if other.fctx.isabsent():
325 index = ui.promptchoice(_localchangedotherdeletedmsg % prompts, 2)
325 index = ui.promptchoice(_localchangedotherdeletedmsg % prompts, 2)
326 choice = [b'local', b'other', b'unresolved'][index]
326 choice = [b'local', b'other', b'unresolved'][index]
327 elif local.fctx.isabsent():
327 elif local.fctx.isabsent():
328 index = ui.promptchoice(_otherchangedlocaldeletedmsg % prompts, 2)
328 index = ui.promptchoice(_otherchangedlocaldeletedmsg % prompts, 2)
329 choice = [b'other', b'local', b'unresolved'][index]
329 choice = [b'other', b'local', b'unresolved'][index]
330 else:
330 else:
331 # IMPORTANT: keep the last line of this prompt ("What do you want to
331 # IMPORTANT: keep the last line of this prompt ("What do you want to
332 # do?") very short, see comment next to _localchangedotherdeletedmsg
332 # do?") very short, see comment next to _localchangedotherdeletedmsg
333 # at the top of the file for details.
333 # at the top of the file for details.
334 index = ui.promptchoice(
334 index = ui.promptchoice(
335 _(
335 _(
336 b"file '%(fd)s' needs to be resolved.\n"
336 b"file '%(fd)s' needs to be resolved.\n"
337 b"You can keep (l)ocal%(l)s, take (o)ther%(o)s, or leave "
337 b"You can keep (l)ocal%(l)s, take (o)ther%(o)s, or leave "
338 b"(u)nresolved.\n"
338 b"(u)nresolved.\n"
339 b"What do you want to do?"
339 b"What do you want to do?"
340 b"$$ &Local $$ &Other $$ &Unresolved"
340 b"$$ &Local $$ &Other $$ &Unresolved"
341 )
341 )
342 % prompts,
342 % prompts,
343 2,
343 2,
344 )
344 )
345 choice = [b'local', b'other', b'unresolved'][index]
345 choice = [b'local', b'other', b'unresolved'][index]
346
346
347 if choice == b'other':
347 if choice == b'other':
348 return _iother(repo, mynode, local, other, base, toolconf)
348 return _iother(repo, mynode, local, other, base, toolconf)
349 elif choice == b'local':
349 elif choice == b'local':
350 return _ilocal(repo, mynode, local, other, base, toolconf)
350 return _ilocal(repo, mynode, local, other, base, toolconf)
351 elif choice == b'unresolved':
351 elif choice == b'unresolved':
352 return _ifail(repo, mynode, local, other, base, toolconf)
352 return _ifail(repo, mynode, local, other, base, toolconf)
353 except error.ResponseExpected:
353 except error.ResponseExpected:
354 ui.write(b"\n")
354 ui.write(b"\n")
355 return _ifail(repo, mynode, local, other, base, toolconf)
355 return _ifail(repo, mynode, local, other, base, toolconf)
356
356
357
357
358 @internaltool(b'local', nomerge)
358 @internaltool(b'local', nomerge)
359 def _ilocal(repo, mynode, local, other, base, toolconf):
359 def _ilocal(repo, mynode, local, other, base, toolconf):
360 """Uses the local `p1()` version of files as the merged version."""
360 """Uses the local `p1()` version of files as the merged version."""
361 return 0, local.fctx.isabsent()
361 return 0, local.fctx.isabsent()
362
362
363
363
364 @internaltool(b'other', nomerge)
364 @internaltool(b'other', nomerge)
365 def _iother(repo, mynode, local, other, base, toolconf):
365 def _iother(repo, mynode, local, other, base, toolconf):
366 """Uses the other `p2()` version of files as the merged version."""
366 """Uses the other `p2()` version of files as the merged version."""
367 if other.fctx.isabsent():
367 if other.fctx.isabsent():
368 # local changed, remote deleted -- 'deleted' picked
368 # local changed, remote deleted -- 'deleted' picked
369 _underlyingfctxifabsent(local.fctx).remove()
369 _underlyingfctxifabsent(local.fctx).remove()
370 deleted = True
370 deleted = True
371 else:
371 else:
372 _underlyingfctxifabsent(local.fctx).write(
372 _underlyingfctxifabsent(local.fctx).write(
373 other.fctx.data(), other.fctx.flags()
373 other.fctx.data(), other.fctx.flags()
374 )
374 )
375 deleted = False
375 deleted = False
376 return 0, deleted
376 return 0, deleted
377
377
378
378
379 @internaltool(b'fail', nomerge)
379 @internaltool(b'fail', nomerge)
380 def _ifail(repo, mynode, local, other, base, toolconf):
380 def _ifail(repo, mynode, local, other, base, toolconf):
381 """
381 """
382 Rather than attempting to merge files that were modified on both
382 Rather than attempting to merge files that were modified on both
383 branches, it marks them as unresolved. The resolve command must be
383 branches, it marks them as unresolved. The resolve command must be
384 used to resolve these conflicts."""
384 used to resolve these conflicts."""
385 # for change/delete conflicts write out the changed version, then fail
385 # for change/delete conflicts write out the changed version, then fail
386 if local.fctx.isabsent():
386 if local.fctx.isabsent():
387 _underlyingfctxifabsent(local.fctx).write(
387 _underlyingfctxifabsent(local.fctx).write(
388 other.fctx.data(), other.fctx.flags()
388 other.fctx.data(), other.fctx.flags()
389 )
389 )
390 return 1, False
390 return 1, False
391
391
392
392
393 def _underlyingfctxifabsent(filectx):
393 def _underlyingfctxifabsent(filectx):
394 """Sometimes when resolving, our fcd is actually an absentfilectx, but
394 """Sometimes when resolving, our fcd is actually an absentfilectx, but
395 we want to write to it (to do the resolve). This helper returns the
395 we want to write to it (to do the resolve). This helper returns the
396 underyling workingfilectx in that case.
396 underyling workingfilectx in that case.
397 """
397 """
398 if filectx.isabsent():
398 if filectx.isabsent():
399 return filectx.changectx()[filectx.path()]
399 return filectx.changectx()[filectx.path()]
400 else:
400 else:
401 return filectx
401 return filectx
402
402
403
403
404 def _verifytext(input, ui):
404 def _verifytext(input, ui):
405 """verifies that text is non-binary"""
405 """verifies that text is non-binary"""
406 if stringutil.binary(input.text()):
406 if stringutil.binary(input.text()):
407 msg = _(b"%s looks like a binary file.") % input.fctx.path()
407 msg = _(b"%s looks like a binary file.") % input.fctx.path()
408 ui.warn(_(b'warning: %s\n') % msg)
408 ui.warn(_(b'warning: %s\n') % msg)
409 raise error.Abort(msg)
409 raise error.Abort(msg)
410
410
411
411
412 def _premerge(repo, local, other, base, toolconf):
412 def _premerge(repo, local, other, base, toolconf):
413 tool, toolpath, binary, symlink, scriptfn = toolconf
413 tool, toolpath, binary, symlink, scriptfn = toolconf
414 if symlink or local.fctx.isabsent() or other.fctx.isabsent():
414 if symlink or local.fctx.isabsent() or other.fctx.isabsent():
415 return 1
415 return 1
416
416
417 ui = repo.ui
417 ui = repo.ui
418
418
419 validkeep = [b'keep', b'keep-merge3', b'keep-mergediff']
419 validkeep = [b'keep', b'keep-merge3', b'keep-mergediff']
420
420
421 # do we attempt to simplemerge first?
421 # do we attempt to simplemerge first?
422 try:
422 try:
423 premerge = _toolbool(ui, tool, b"premerge", not binary)
423 premerge = _toolbool(ui, tool, b"premerge", not binary)
424 except error.ConfigError:
424 except error.ConfigError:
425 premerge = _toolstr(ui, tool, b"premerge", b"").lower()
425 premerge = _toolstr(ui, tool, b"premerge", b"").lower()
426 if premerge not in validkeep:
426 if premerge not in validkeep:
427 _valid = b', '.join([b"'" + v + b"'" for v in validkeep])
427 _valid = b', '.join([b"'" + v + b"'" for v in validkeep])
428 raise error.ConfigError(
428 raise error.ConfigError(
429 _(b"%s.premerge not valid ('%s' is neither boolean nor %s)")
429 _(b"%s.premerge not valid ('%s' is neither boolean nor %s)")
430 % (tool, premerge, _valid)
430 % (tool, premerge, _valid)
431 )
431 )
432
432
433 if premerge:
433 if premerge:
434 mode = b'merge'
434 mode = b'merge'
435 if premerge == b'keep-mergediff':
435 if premerge == b'keep-mergediff':
436 mode = b'mergediff'
436 mode = b'mergediff'
437 elif premerge == b'keep-merge3':
437 elif premerge == b'keep-merge3':
438 mode = b'merge3'
438 mode = b'merge3'
439 if any(
439 if any(
440 stringutil.binary(input.text()) for input in (local, base, other)
440 stringutil.binary(input.text()) for input in (local, base, other)
441 ):
441 ):
442 return 1 # continue merging
442 return 1 # continue merging
443 merged_text, conflicts = simplemerge.simplemerge(
443 merged_text, conflicts = simplemerge.simplemerge(
444 local, base, other, mode=mode
444 local, base, other, mode=mode
445 )
445 )
446 if not conflicts or premerge in validkeep:
446 if not conflicts or premerge in validkeep:
447 # fcd.flags() already has the merged flags (done in
447 # fcd.flags() already has the merged flags (done in
448 # mergestate.resolve())
448 # mergestate.resolve())
449 local.fctx.write(merged_text, local.fctx.flags())
449 local.fctx.write(merged_text, local.fctx.flags())
450 if not conflicts:
450 if not conflicts:
451 ui.debug(b" premerge successful\n")
451 ui.debug(b" premerge successful\n")
452 return 0
452 return 0
453 return 1 # continue merging
453 return 1 # continue merging
454
454
455
455
456 def _mergecheck(repo, mynode, fcd, fco, fca, toolconf):
456 def _mergecheck(repo, mynode, fcd, fco, fca, toolconf):
457 tool, toolpath, binary, symlink, scriptfn = toolconf
457 tool, toolpath, binary, symlink, scriptfn = toolconf
458 uipathfn = scmutil.getuipathfn(repo)
458 uipathfn = scmutil.getuipathfn(repo)
459 if symlink:
459 if symlink:
460 repo.ui.warn(
460 repo.ui.warn(
461 _(b'warning: internal %s cannot merge symlinks for %s\n')
461 _(b'warning: internal %s cannot merge symlinks for %s\n')
462 % (tool, uipathfn(fcd.path()))
462 % (tool, uipathfn(fcd.path()))
463 )
463 )
464 return False
464 return False
465 if fcd.isabsent() or fco.isabsent():
465 if fcd.isabsent() or fco.isabsent():
466 repo.ui.warn(
466 repo.ui.warn(
467 _(
467 _(
468 b'warning: internal %s cannot merge change/delete '
468 b'warning: internal %s cannot merge change/delete '
469 b'conflict for %s\n'
469 b'conflict for %s\n'
470 )
470 )
471 % (tool, uipathfn(fcd.path()))
471 % (tool, uipathfn(fcd.path()))
472 )
472 )
473 return False
473 return False
474 return True
474 return True
475
475
476
476
477 def _merge(repo, local, other, base, mode):
477 def _merge(repo, local, other, base, mode):
478 """
478 """
479 Uses the internal non-interactive simple merge algorithm for merging
479 Uses the internal non-interactive simple merge algorithm for merging
480 files. It will fail if there are any conflicts and leave markers in
480 files. It will fail if there are any conflicts and leave markers in
481 the partially merged file. Markers will have two sections, one for each side
481 the partially merged file. Markers will have two sections, one for each side
482 of merge, unless mode equals 'union' which suppresses the markers."""
482 of merge, unless mode equals 'union' which suppresses the markers."""
483 ui = repo.ui
483 ui = repo.ui
484
484
485 try:
485 try:
486 _verifytext(local, ui)
486 _verifytext(local, ui)
487 _verifytext(base, ui)
487 _verifytext(base, ui)
488 _verifytext(other, ui)
488 _verifytext(other, ui)
489 except error.Abort:
489 except error.Abort:
490 return True, True, False
490 return True, True, False
491 else:
491 else:
492 merged_text, conflicts = simplemerge.simplemerge(
492 merged_text, conflicts = simplemerge.simplemerge(
493 local, base, other, mode=mode
493 local, base, other, mode=mode
494 )
494 )
495 # fcd.flags() already has the merged flags (done in
495 # fcd.flags() already has the merged flags (done in
496 # mergestate.resolve())
496 # mergestate.resolve())
497 local.fctx.write(merged_text, local.fctx.flags())
497 local.fctx.write(merged_text, local.fctx.flags())
498 return True, conflicts, False
498 return True, conflicts, False
499
499
500
500
501 @internaltool(
501 @internaltool(
502 b'union',
502 b'union',
503 fullmerge,
503 fullmerge,
504 _(
504 _(
505 b"warning: conflicts while merging %s! "
505 b"warning: conflicts while merging %s! "
506 b"(edit, then use 'hg resolve --mark')\n"
506 b"(edit, then use 'hg resolve --mark')\n"
507 ),
507 ),
508 precheck=_mergecheck,
508 precheck=_mergecheck,
509 )
509 )
510 def _iunion(repo, mynode, local, other, base, toolconf, backup):
510 def _iunion(repo, mynode, local, other, base, toolconf, backup):
511 """
511 """
512 Uses the internal non-interactive simple merge algorithm for merging
512 Uses the internal non-interactive simple merge algorithm for merging
513 files. It will use both left and right sides for conflict regions.
513 files. It will use both left and right sides for conflict regions.
514 No markers are inserted."""
514 No markers are inserted."""
515 return _merge(repo, local, other, base, b'union')
515 return _merge(repo, local, other, base, b'union')
516
516
517
517
518 @internaltool(
518 @internaltool(
519 b'merge',
519 b'merge',
520 fullmerge,
520 fullmerge,
521 _(
521 _(
522 b"warning: conflicts while merging %s! "
522 b"warning: conflicts while merging %s! "
523 b"(edit, then use 'hg resolve --mark')\n"
523 b"(edit, then use 'hg resolve --mark')\n"
524 ),
524 ),
525 precheck=_mergecheck,
525 precheck=_mergecheck,
526 )
526 )
527 def _imerge(repo, mynode, local, other, base, toolconf, backup):
527 def _imerge(repo, mynode, local, other, base, toolconf, backup):
528 """
528 """
529 Uses the internal non-interactive simple merge algorithm for merging
529 Uses the internal non-interactive simple merge algorithm for merging
530 files. It will fail if there are any conflicts and leave markers in
530 files. It will fail if there are any conflicts and leave markers in
531 the partially merged file. Markers will have two sections, one for each side
531 the partially merged file. Markers will have two sections, one for each side
532 of merge."""
532 of merge."""
533 return _merge(repo, local, other, base, b'merge')
533 return _merge(repo, local, other, base, b'merge')
534
534
535
535
536 @internaltool(
536 @internaltool(
537 b'merge3',
537 b'merge3',
538 fullmerge,
538 fullmerge,
539 _(
539 _(
540 b"warning: conflicts while merging %s! "
540 b"warning: conflicts while merging %s! "
541 b"(edit, then use 'hg resolve --mark')\n"
541 b"(edit, then use 'hg resolve --mark')\n"
542 ),
542 ),
543 precheck=_mergecheck,
543 precheck=_mergecheck,
544 )
544 )
545 def _imerge3(repo, mynode, local, other, base, toolconf, backup):
545 def _imerge3(repo, mynode, local, other, base, toolconf, backup):
546 """
546 """
547 Uses the internal non-interactive simple merge algorithm for merging
547 Uses the internal non-interactive simple merge algorithm for merging
548 files. It will fail if there are any conflicts and leave markers in
548 files. It will fail if there are any conflicts and leave markers in
549 the partially merged file. Marker will have three sections, one from each
549 the partially merged file. Marker will have three sections, one from each
550 side of the merge and one for the base content."""
550 side of the merge and one for the base content."""
551 return _merge(repo, local, other, base, b'merge3')
551 return _merge(repo, local, other, base, b'merge3')
552
552
553
553
554 @internaltool(
554 @internaltool(
555 b'merge3-lie-about-conflicts',
555 b'merge3-lie-about-conflicts',
556 fullmerge,
556 fullmerge,
557 b'',
557 b'',
558 precheck=_mergecheck,
558 precheck=_mergecheck,
559 )
559 )
560 def _imerge3alwaysgood(*args, **kwargs):
560 def _imerge3alwaysgood(*args, **kwargs):
561 # Like merge3, but record conflicts as resolved with markers in place.
561 # Like merge3, but record conflicts as resolved with markers in place.
562 #
562 #
563 # This is used for `diff.merge` to show the differences between
563 # This is used for `diff.merge` to show the differences between
564 # the auto-merge state and the committed merge state. It may be
564 # the auto-merge state and the committed merge state. It may be
565 # useful for other things.
565 # useful for other things.
566 b1, junk, b2 = _imerge3(*args, **kwargs)
566 b1, junk, b2 = _imerge3(*args, **kwargs)
567 # TODO is this right? I'm not sure what these return values mean,
567 # TODO is this right? I'm not sure what these return values mean,
568 # but as far as I can tell this will indicate to callers tha the
568 # but as far as I can tell this will indicate to callers tha the
569 # merge succeeded.
569 # merge succeeded.
570 return b1, False, b2
570 return b1, False, b2
571
571
572
572
573 @internaltool(
573 @internaltool(
574 b'mergediff',
574 b'mergediff',
575 fullmerge,
575 fullmerge,
576 _(
576 _(
577 b"warning: conflicts while merging %s! "
577 b"warning: conflicts while merging %s! "
578 b"(edit, then use 'hg resolve --mark')\n"
578 b"(edit, then use 'hg resolve --mark')\n"
579 ),
579 ),
580 precheck=_mergecheck,
580 precheck=_mergecheck,
581 )
581 )
582 def _imerge_diff(repo, mynode, local, other, base, toolconf, backup):
582 def _imerge_diff(repo, mynode, local, other, base, toolconf, backup):
583 """
583 """
584 Uses the internal non-interactive simple merge algorithm for merging
584 Uses the internal non-interactive simple merge algorithm for merging
585 files. It will fail if there are any conflicts and leave markers in
585 files. It will fail if there are any conflicts and leave markers in
586 the partially merged file. The marker will have two sections, one with the
586 the partially merged file. The marker will have two sections, one with the
587 content from one side of the merge, and one with a diff from the base
587 content from one side of the merge, and one with a diff from the base
588 content to the content on the other side. (experimental)"""
588 content to the content on the other side. (experimental)"""
589 return _merge(repo, local, other, base, b'mergediff')
589 return _merge(repo, local, other, base, b'mergediff')
590
590
591
591
592 @internaltool(b'merge-local', mergeonly, precheck=_mergecheck)
592 @internaltool(b'merge-local', mergeonly, precheck=_mergecheck)
593 def _imergelocal(repo, mynode, local, other, base, toolconf, backup):
593 def _imergelocal(repo, mynode, local, other, base, toolconf, backup):
594 """
594 """
595 Like :merge, but resolve all conflicts non-interactively in favor
595 Like :merge, but resolve all conflicts non-interactively in favor
596 of the local `p1()` changes."""
596 of the local `p1()` changes."""
597 return _merge(repo, local, other, base, b'local')
597 return _merge(repo, local, other, base, b'local')
598
598
599
599
600 @internaltool(b'merge-other', mergeonly, precheck=_mergecheck)
600 @internaltool(b'merge-other', mergeonly, precheck=_mergecheck)
601 def _imergeother(repo, mynode, local, other, base, toolconf, backup):
601 def _imergeother(repo, mynode, local, other, base, toolconf, backup):
602 """
602 """
603 Like :merge, but resolve all conflicts non-interactively in favor
603 Like :merge, but resolve all conflicts non-interactively in favor
604 of the other `p2()` changes."""
604 of the other `p2()` changes."""
605 return _merge(repo, local, other, base, b'other')
605 return _merge(repo, local, other, base, b'other')
606
606
607
607
608 @internaltool(
608 @internaltool(
609 b'tagmerge',
609 b'tagmerge',
610 mergeonly,
610 mergeonly,
611 _(
611 _(
612 b"automatic tag merging of %s failed! "
612 b"automatic tag merging of %s failed! "
613 b"(use 'hg resolve --tool :merge' or another merge "
613 b"(use 'hg resolve --tool :merge' or another merge "
614 b"tool of your choice)\n"
614 b"tool of your choice)\n"
615 ),
615 ),
616 )
616 )
617 def _itagmerge(repo, mynode, local, other, base, toolconf, backup):
617 def _itagmerge(repo, mynode, local, other, base, toolconf, backup):
618 """
618 """
619 Uses the internal tag merge algorithm (experimental).
619 Uses the internal tag merge algorithm (experimental).
620 """
620 """
621 success, status = tagmerge.merge(repo, local.fctx, other.fctx, base.fctx)
621 success, status = tagmerge.merge(repo, local.fctx, other.fctx, base.fctx)
622 return success, status, False
622 return success, status, False
623
623
624
624
625 @internaltool(b'dump', fullmerge, binary=True, symlink=True)
625 @internaltool(b'dump', fullmerge, binary=True, symlink=True)
626 def _idump(repo, mynode, local, other, base, toolconf, backup):
626 def _idump(repo, mynode, local, other, base, toolconf, backup):
627 """
627 """
628 Creates three versions of the files to merge, containing the
628 Creates three versions of the files to merge, containing the
629 contents of local, other and base. These files can then be used to
629 contents of local, other and base. These files can then be used to
630 perform a merge manually. If the file to be merged is named
630 perform a merge manually. If the file to be merged is named
631 ``a.txt``, these files will accordingly be named ``a.txt.local``,
631 ``a.txt``, these files will accordingly be named ``a.txt.local``,
632 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
632 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
633 same directory as ``a.txt``.
633 same directory as ``a.txt``.
634
634
635 This implies premerge. Therefore, files aren't dumped, if premerge
635 This implies premerge. Therefore, files aren't dumped, if premerge
636 runs successfully. Use :forcedump to forcibly write files out.
636 runs successfully. Use :forcedump to forcibly write files out.
637 """
637 """
638 a = _workingpath(repo, local.fctx)
638 a = _workingpath(repo, local.fctx)
639 fd = local.fctx.path()
639 fd = local.fctx.path()
640
640
641 from . import context
641 from . import context
642
642
643 if isinstance(local.fctx, context.overlayworkingfilectx):
643 if isinstance(local.fctx, context.overlayworkingfilectx):
644 raise error.InMemoryMergeConflictsError(
644 raise error.InMemoryMergeConflictsError(
645 b'in-memory merge does not support the :dump tool.'
645 b'in-memory merge does not support the :dump tool.'
646 )
646 )
647
647
648 util.writefile(a + b".local", local.fctx.decodeddata())
648 util.writefile(a + b".local", local.fctx.decodeddata())
649 repo.wwrite(fd + b".other", other.fctx.data(), other.fctx.flags())
649 repo.wwrite(fd + b".other", other.fctx.data(), other.fctx.flags())
650 repo.wwrite(fd + b".base", base.fctx.data(), base.fctx.flags())
650 repo.wwrite(fd + b".base", base.fctx.data(), base.fctx.flags())
651 return False, 1, False
651 return False, 1, False
652
652
653
653
654 @internaltool(b'forcedump', mergeonly, binary=True, symlink=True)
654 @internaltool(b'forcedump', mergeonly, binary=True, symlink=True)
655 def _forcedump(repo, mynode, local, other, base, toolconf, backup):
655 def _forcedump(repo, mynode, local, other, base, toolconf, backup):
656 """
656 """
657 Creates three versions of the files as same as :dump, but omits premerge.
657 Creates three versions of the files as same as :dump, but omits premerge.
658 """
658 """
659 return _idump(repo, mynode, local, other, base, toolconf, backup)
659 return _idump(repo, mynode, local, other, base, toolconf, backup)
660
660
661
661
662 def _xmergeimm(repo, mynode, local, other, base, toolconf, backup):
662 def _xmergeimm(repo, mynode, local, other, base, toolconf, backup):
663 # In-memory merge simply raises an exception on all external merge tools,
663 # In-memory merge simply raises an exception on all external merge tools,
664 # for now.
664 # for now.
665 #
665 #
666 # It would be possible to run most tools with temporary files, but this
666 # It would be possible to run most tools with temporary files, but this
667 # raises the question of what to do if the user only partially resolves the
667 # raises the question of what to do if the user only partially resolves the
668 # file -- we can't leave a merge state. (Copy to somewhere in the .hg/
668 # file -- we can't leave a merge state. (Copy to somewhere in the .hg/
669 # directory and tell the user how to get it is my best idea, but it's
669 # directory and tell the user how to get it is my best idea, but it's
670 # clunky.)
670 # clunky.)
671 raise error.InMemoryMergeConflictsError(
671 raise error.InMemoryMergeConflictsError(
672 b'in-memory merge does not support external merge tools'
672 b'in-memory merge does not support external merge tools'
673 )
673 )
674
674
675
675
676 def _describemerge(ui, repo, mynode, fcl, fcb, fco, env, toolpath, args):
676 def _describemerge(ui, repo, mynode, fcl, fcb, fco, env, toolpath, args):
677 tmpl = ui.config(b'command-templates', b'pre-merge-tool-output')
677 tmpl = ui.config(b'command-templates', b'pre-merge-tool-output')
678 if not tmpl:
678 if not tmpl:
679 return
679 return
680
680
681 mappingdict = templateutil.mappingdict
681 mappingdict = templateutil.mappingdict
682 props = {
682 props = {
683 b'ctx': fcl.changectx(),
683 b'ctx': fcl.changectx(),
684 b'node': hex(mynode),
684 b'node': hex(mynode),
685 b'path': fcl.path(),
685 b'path': fcl.path(),
686 b'local': mappingdict(
686 b'local': mappingdict(
687 {
687 {
688 b'ctx': fcl.changectx(),
688 b'ctx': fcl.changectx(),
689 b'fctx': fcl,
689 b'fctx': fcl,
690 b'node': hex(mynode),
690 b'node': hex(mynode),
691 b'name': _(b'local'),
691 b'name': _(b'local'),
692 b'islink': b'l' in fcl.flags(),
692 b'islink': b'l' in fcl.flags(),
693 b'label': env[b'HG_MY_LABEL'],
693 b'label': env[b'HG_MY_LABEL'],
694 }
694 }
695 ),
695 ),
696 b'base': mappingdict(
696 b'base': mappingdict(
697 {
697 {
698 b'ctx': fcb.changectx(),
698 b'ctx': fcb.changectx(),
699 b'fctx': fcb,
699 b'fctx': fcb,
700 b'name': _(b'base'),
700 b'name': _(b'base'),
701 b'islink': b'l' in fcb.flags(),
701 b'islink': b'l' in fcb.flags(),
702 b'label': env[b'HG_BASE_LABEL'],
702 b'label': env[b'HG_BASE_LABEL'],
703 }
703 }
704 ),
704 ),
705 b'other': mappingdict(
705 b'other': mappingdict(
706 {
706 {
707 b'ctx': fco.changectx(),
707 b'ctx': fco.changectx(),
708 b'fctx': fco,
708 b'fctx': fco,
709 b'name': _(b'other'),
709 b'name': _(b'other'),
710 b'islink': b'l' in fco.flags(),
710 b'islink': b'l' in fco.flags(),
711 b'label': env[b'HG_OTHER_LABEL'],
711 b'label': env[b'HG_OTHER_LABEL'],
712 }
712 }
713 ),
713 ),
714 b'toolpath': toolpath,
714 b'toolpath': toolpath,
715 b'toolargs': args,
715 b'toolargs': args,
716 }
716 }
717
717
718 # TODO: make all of this something that can be specified on a per-tool basis
718 # TODO: make all of this something that can be specified on a per-tool basis
719 tmpl = templater.unquotestring(tmpl)
719 tmpl = templater.unquotestring(tmpl)
720
720
721 # Not using cmdutil.rendertemplate here since it causes errors importing
721 # Not using cmdutil.rendertemplate here since it causes errors importing
722 # things for us to import cmdutil.
722 # things for us to import cmdutil.
723 tres = formatter.templateresources(ui, repo)
723 tres = formatter.templateresources(ui, repo)
724 t = formatter.maketemplater(
724 t = formatter.maketemplater(
725 ui, tmpl, defaults=templatekw.keywords, resources=tres
725 ui, tmpl, defaults=templatekw.keywords, resources=tres
726 )
726 )
727 ui.status(t.renderdefault(props))
727 ui.status(t.renderdefault(props))
728
728
729
729
730 def _xmerge(repo, mynode, local, other, base, toolconf, backup):
730 def _xmerge(repo, mynode, local, other, base, toolconf, backup):
731 fcd = local.fctx
731 fcd = local.fctx
732 fco = other.fctx
732 fco = other.fctx
733 fca = base.fctx
733 fca = base.fctx
734 tool, toolpath, binary, symlink, scriptfn = toolconf
734 tool, toolpath, binary, symlink, scriptfn = toolconf
735 uipathfn = scmutil.getuipathfn(repo)
735 uipathfn = scmutil.getuipathfn(repo)
736 if fcd.isabsent() or fco.isabsent():
736 if fcd.isabsent() or fco.isabsent():
737 repo.ui.warn(
737 repo.ui.warn(
738 _(b'warning: %s cannot merge change/delete conflict for %s\n')
738 _(b'warning: %s cannot merge change/delete conflict for %s\n')
739 % (tool, uipathfn(fcd.path()))
739 % (tool, uipathfn(fcd.path()))
740 )
740 )
741 return False, 1, None
741 return False, 1, None
742 localpath = _workingpath(repo, fcd)
742 localpath = _workingpath(repo, fcd)
743 args = _toolstr(repo.ui, tool, b"args")
743 args = _toolstr(repo.ui, tool, b"args")
744
744
745 files = [
745 files = [
746 (b"base", fca.path(), fca.decodeddata()),
746 (b"base", fca.path(), fca.decodeddata()),
747 (b"other", fco.path(), fco.decodeddata()),
747 (b"other", fco.path(), fco.decodeddata()),
748 ]
748 ]
749 outpath = b""
749 outpath = b""
750 if b"$output" in args:
750 if b"$output" in args:
751 # read input from backup, write to original
751 # read input from backup, write to original
752 outpath = localpath
752 outpath = localpath
753 localoutputpath = backup.path()
753 localoutputpath = backup.path()
754 # Remove the .orig to make syntax-highlighting more likely.
754 # Remove the .orig to make syntax-highlighting more likely.
755 if localoutputpath.endswith(b'.orig'):
755 if localoutputpath.endswith(b'.orig'):
756 localoutputpath, ext = os.path.splitext(localoutputpath)
756 localoutputpath, ext = os.path.splitext(localoutputpath)
757 files.append((b"local", localoutputpath, backup.data()))
757 files.append((b"local", localoutputpath, backup.data()))
758
758
759 with _maketempfiles(files) as temppaths:
759 with _maketempfiles(files) as temppaths:
760 basepath, otherpath = temppaths[:2]
760 basepath, otherpath = temppaths[:2]
761 if len(temppaths) == 3:
761 if len(temppaths) == 3:
762 localpath = temppaths[2]
762 localpath = temppaths[2]
763
763
764 def format_label(input):
764 def format_label(input):
765 if input.label_detail:
765 if input.label_detail:
766 return b'%s: %s' % (input.label, input.label_detail)
766 return b'%s: %s' % (input.label, input.label_detail)
767 else:
767 else:
768 return input.label
768 return input.label
769
769
770 env = {
770 env = {
771 b'HG_FILE': fcd.path(),
771 b'HG_FILE': fcd.path(),
772 b'HG_MY_NODE': short(mynode),
772 b'HG_MY_NODE': short(mynode),
773 b'HG_OTHER_NODE': short(fco.changectx().node()),
773 b'HG_OTHER_NODE': short(fco.changectx().node()),
774 b'HG_BASE_NODE': short(fca.changectx().node()),
774 b'HG_BASE_NODE': short(fca.changectx().node()),
775 b'HG_MY_ISLINK': b'l' in fcd.flags(),
775 b'HG_MY_ISLINK': b'l' in fcd.flags(),
776 b'HG_OTHER_ISLINK': b'l' in fco.flags(),
776 b'HG_OTHER_ISLINK': b'l' in fco.flags(),
777 b'HG_BASE_ISLINK': b'l' in fca.flags(),
777 b'HG_BASE_ISLINK': b'l' in fca.flags(),
778 b'HG_MY_LABEL': format_label(local),
778 b'HG_MY_LABEL': format_label(local),
779 b'HG_OTHER_LABEL': format_label(other),
779 b'HG_OTHER_LABEL': format_label(other),
780 b'HG_BASE_LABEL': format_label(base),
780 b'HG_BASE_LABEL': format_label(base),
781 }
781 }
782 ui = repo.ui
782 ui = repo.ui
783
783
784 replace = {
784 replace = {
785 b'local': localpath,
785 b'local': localpath,
786 b'base': basepath,
786 b'base': basepath,
787 b'other': otherpath,
787 b'other': otherpath,
788 b'output': outpath,
788 b'output': outpath,
789 b'labellocal': format_label(local),
789 b'labellocal': format_label(local),
790 b'labelother': format_label(other),
790 b'labelother': format_label(other),
791 b'labelbase': format_label(base),
791 b'labelbase': format_label(base),
792 }
792 }
793 args = util.interpolate(
793 args = util.interpolate(
794 br'\$',
794 br'\$',
795 replace,
795 replace,
796 args,
796 args,
797 lambda s: procutil.shellquote(util.localpath(s)),
797 lambda s: procutil.shellquote(util.localpath(s)),
798 )
798 )
799 if _toolbool(ui, tool, b"gui"):
799 if _toolbool(ui, tool, b"gui"):
800 repo.ui.status(
800 repo.ui.status(
801 _(b'running merge tool %s for file %s\n')
801 _(b'running merge tool %s for file %s\n')
802 % (tool, uipathfn(fcd.path()))
802 % (tool, uipathfn(fcd.path()))
803 )
803 )
804 if scriptfn is None:
804 if scriptfn is None:
805 cmd = toolpath + b' ' + args
805 cmd = toolpath + b' ' + args
806 repo.ui.debug(b'launching merge tool: %s\n' % cmd)
806 repo.ui.debug(b'launching merge tool: %s\n' % cmd)
807 _describemerge(ui, repo, mynode, fcd, fca, fco, env, toolpath, args)
807 _describemerge(ui, repo, mynode, fcd, fca, fco, env, toolpath, args)
808 r = ui.system(
808 r = ui.system(
809 cmd, cwd=repo.root, environ=env, blockedtag=b'mergetool'
809 cmd, cwd=repo.root, environ=env, blockedtag=b'mergetool'
810 )
810 )
811 else:
811 else:
812 repo.ui.debug(
812 repo.ui.debug(
813 b'launching python merge script: %s:%s\n' % (toolpath, scriptfn)
813 b'launching python merge script: %s:%s\n' % (toolpath, scriptfn)
814 )
814 )
815 r = 0
815 r = 0
816 try:
816 try:
817 # avoid cycle cmdutil->merge->filemerge->extensions->cmdutil
817 # avoid cycle cmdutil->merge->filemerge->extensions->cmdutil
818 from . import extensions
818 from . import extensions
819
819
820 mod = extensions.loadpath(toolpath, b'hgmerge.%s' % tool)
820 mod = extensions.loadpath(toolpath, b'hgmerge.%s' % tool)
821 except Exception:
821 except Exception:
822 raise error.Abort(
822 raise error.Abort(
823 _(b"loading python merge script failed: %s") % toolpath
823 _(b"loading python merge script failed: %s") % toolpath
824 )
824 )
825 mergefn = getattr(mod, scriptfn, None)
825 mergefn = getattr(mod, scriptfn, None)
826 if mergefn is None:
826 if mergefn is None:
827 raise error.Abort(
827 raise error.Abort(
828 _(b"%s does not have function: %s") % (toolpath, scriptfn)
828 _(b"%s does not have function: %s") % (toolpath, scriptfn)
829 )
829 )
830 argslist = procutil.shellsplit(args)
830 argslist = procutil.shellsplit(args)
831 # avoid cycle cmdutil->merge->filemerge->hook->extensions->cmdutil
831 # avoid cycle cmdutil->merge->filemerge->hook->extensions->cmdutil
832 from . import hook
832 from . import hook
833
833
834 ret, raised = hook.pythonhook(
834 ret, raised = hook.pythonhook(
835 ui, repo, b"merge", toolpath, mergefn, {b'args': argslist}, True
835 ui, repo, b"merge", toolpath, mergefn, {b'args': argslist}, True
836 )
836 )
837 if raised:
837 if raised:
838 r = 1
838 r = 1
839 repo.ui.debug(b'merge tool returned: %d\n' % r)
839 repo.ui.debug(b'merge tool returned: %d\n' % r)
840 return True, r, False
840 return True, r, False
841
841
842
842
843 def _populate_label_detail(input, template):
843 def _populate_label_detail(input, template):
844 """Applies the given template to the ctx and stores it in the input."""
844 """Applies the given template to the ctx and stores it in the input."""
845 ctx = input.fctx.changectx()
845 ctx = input.fctx.changectx()
846 if ctx.node() is None:
846 if ctx.node() is None:
847 ctx = ctx.p1()
847 ctx = ctx.p1()
848
848
849 props = {b'ctx': ctx}
849 props = {b'ctx': ctx}
850 templateresult = template.renderdefault(props)
850 templateresult = template.renderdefault(props)
851 input.label_detail = stringutil.firstline(templateresult) # avoid '\n'
851 input.label_detail = stringutil.firstline(templateresult) # avoid '\n'
852
852
853
853
854 def _populate_label_details(repo, inputs, tool=None):
854 def _populate_label_details(repo, inputs, tool=None):
855 """Populates the label details using the conflict marker template."""
855 """Populates the label details using the conflict marker template."""
856 ui = repo.ui
856 ui = repo.ui
857 template = ui.config(b'command-templates', b'mergemarker')
857 template = ui.config(b'command-templates', b'mergemarker')
858 if tool is not None:
858 if tool is not None:
859 template = _toolstr(ui, tool, b'mergemarkertemplate', template)
859 template = _toolstr(ui, tool, b'mergemarkertemplate', template)
860 template = templater.unquotestring(template)
860 template = templater.unquotestring(template)
861 tres = formatter.templateresources(ui, repo)
861 tres = formatter.templateresources(ui, repo)
862 tmpl = formatter.maketemplater(
862 tmpl = formatter.maketemplater(
863 ui, template, defaults=templatekw.keywords, resources=tres
863 ui, template, defaults=templatekw.keywords, resources=tres
864 )
864 )
865
865
866 for input in inputs:
866 for input in inputs:
867 _populate_label_detail(input, tmpl)
867 _populate_label_detail(input, tmpl)
868
868
869
869
870 def partextras(labels):
870 def partextras(labels):
871 """Return a dictionary of extra labels for use in prompts to the user
871 """Return a dictionary of extra labels for use in prompts to the user
872
872
873 Intended use is in strings of the form "(l)ocal%(l)s".
873 Intended use is in strings of the form "(l)ocal%(l)s".
874 """
874 """
875 if labels is None:
875 if labels is None:
876 return {
876 return {
877 b"l": b"",
877 b"l": b"",
878 b"o": b"",
878 b"o": b"",
879 }
879 }
880
880
881 return {
881 return {
882 b"l": b" [%s]" % labels[0],
882 b"l": b" [%s]" % labels[0],
883 b"o": b" [%s]" % labels[1],
883 b"o": b" [%s]" % labels[1],
884 }
884 }
885
885
886
886
887 def _makebackup(repo, ui, fcd):
887 def _makebackup(repo, ui, fcd):
888 """Makes and returns a filectx-like object for ``fcd``'s backup file.
888 """Makes and returns a filectx-like object for ``fcd``'s backup file.
889
889
890 In addition to preserving the user's pre-existing modifications to `fcd`
890 In addition to preserving the user's pre-existing modifications to `fcd`
891 (if any), the backup is used to undo certain premerges, confirm whether a
891 (if any), the backup is used to undo certain premerges, confirm whether a
892 merge changed anything, and determine what line endings the new file should
892 merge changed anything, and determine what line endings the new file should
893 have.
893 have.
894
894
895 Backups only need to be written once since their content doesn't change
895 Backups only need to be written once since their content doesn't change
896 afterwards.
896 afterwards.
897 """
897 """
898 if fcd.isabsent():
898 if fcd.isabsent():
899 return None
899 return None
900 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset ->
900 # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset ->
901 # merge -> filemerge). (I suspect the fileset import is the weakest link)
901 # merge -> filemerge). (I suspect the fileset import is the weakest link)
902 from . import context
902 from . import context
903
903
904 if isinstance(fcd, context.overlayworkingfilectx):
904 if isinstance(fcd, context.overlayworkingfilectx):
905 # If we're merging in-memory, we're free to put the backup anywhere.
905 # If we're merging in-memory, we're free to put the backup anywhere.
906 fd, backup = pycompat.mkstemp(b'hg-merge-backup')
906 fd, backup = pycompat.mkstemp(b'hg-merge-backup')
907 with os.fdopen(fd, 'wb') as f:
907 with os.fdopen(fd, 'wb') as f:
908 f.write(fcd.data())
908 f.write(fcd.data())
909 else:
909 else:
910 backup = scmutil.backuppath(ui, repo, fcd.path())
910 backup = scmutil.backuppath(ui, repo, fcd.path())
911 a = _workingpath(repo, fcd)
911 a = _workingpath(repo, fcd)
912 util.copyfile(a, backup)
912 util.copyfile(a, backup)
913
913
914 return context.arbitraryfilectx(backup, repo=repo)
914 return context.arbitraryfilectx(backup, repo=repo)
915
915
916
916
917 @contextlib.contextmanager
917 @contextlib.contextmanager
918 def _maketempfiles(files):
918 def _maketempfiles(files):
919 """Creates a temporary file for each (prefix, path, data) tuple in `files`,
919 """Creates a temporary file for each (prefix, path, data) tuple in `files`,
920 so an external merge tool may use them.
920 so an external merge tool may use them.
921 """
921 """
922 tmproot = pycompat.mkdtemp(prefix=b'hgmerge-')
922 tmproot = pycompat.mkdtemp(prefix=b'hgmerge-')
923
923
924 def maketempfrompath(prefix, path, data):
924 def maketempfrompath(prefix, path, data):
925 fullbase, ext = os.path.splitext(path)
925 fullbase, ext = os.path.splitext(path)
926 pre = b"%s~%s" % (os.path.basename(fullbase), prefix)
926 pre = b"%s~%s" % (os.path.basename(fullbase), prefix)
927 name = os.path.join(tmproot, pre)
927 name = os.path.join(tmproot, pre)
928 if ext:
928 if ext:
929 name += ext
929 name += ext
930 util.writefile(name, data)
930 util.writefile(name, data)
931 return name
931 return name
932
932
933 temp_files = []
933 temp_files = []
934 for prefix, path, data in files:
934 for prefix, path, data in files:
935 temp_files.append(maketempfrompath(prefix, path, data))
935 temp_files.append(maketempfrompath(prefix, path, data))
936 try:
936 try:
937 yield temp_files
937 yield temp_files
938 finally:
938 finally:
939 shutil.rmtree(tmproot)
939 shutil.rmtree(tmproot)
940
940
941
941
942 def filemerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None):
942 def filemerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None):
943 """perform a 3-way merge in the working directory
943 """perform a 3-way merge in the working directory
944
944
945 mynode = parent node before merge
945 mynode = parent node before merge
946 orig = original local filename before merge
946 orig = original local filename before merge
947 fco = other file context
947 fco = other file context
948 fca = ancestor file context
948 fca = ancestor file context
949 fcd = local file context for current/destination file
949 fcd = local file context for current/destination file
950
950
951 Returns whether the merge is complete, the return value of the merge, and
951 Returns whether the merge is complete, the return value of the merge, and
952 a boolean indicating whether the file was deleted from disk."""
952 a boolean indicating whether the file was deleted from disk."""
953 ui = repo.ui
953 ui = repo.ui
954 fd = fcd.path()
954 fd = fcd.path()
955 uipathfn = scmutil.getuipathfn(repo)
955 uipathfn = scmutil.getuipathfn(repo)
956 fduipath = uipathfn(fd)
956 fduipath = uipathfn(fd)
957 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
957 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
958 symlink = b'l' in fcd.flags() + fco.flags()
958 symlink = b'l' in fcd.flags() + fco.flags()
959 changedelete = fcd.isabsent() or fco.isabsent()
959 changedelete = fcd.isabsent() or fco.isabsent()
960 tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete)
960 tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete)
961 scriptfn = None
961 scriptfn = None
962 if tool in internals and tool.startswith(b'internal:'):
962 if tool in internals and tool.startswith(b'internal:'):
963 # normalize to new-style names (':merge' etc)
963 # normalize to new-style names (':merge' etc)
964 tool = tool[len(b'internal') :]
964 tool = tool[len(b'internal') :]
965 if toolpath and toolpath.startswith(b'python:'):
965 if toolpath and toolpath.startswith(b'python:'):
966 invalidsyntax = False
966 invalidsyntax = False
967 if toolpath.count(b':') >= 2:
967 if toolpath.count(b':') >= 2:
968 script, scriptfn = toolpath[7:].rsplit(b':', 1)
968 script, scriptfn = toolpath[7:].rsplit(b':', 1)
969 if not scriptfn:
969 if not scriptfn:
970 invalidsyntax = True
970 invalidsyntax = True
971 # missing :callable can lead to spliting on windows drive letter
971 # missing :callable can lead to spliting on windows drive letter
972 if b'\\' in scriptfn or b'/' in scriptfn:
972 if b'\\' in scriptfn or b'/' in scriptfn:
973 invalidsyntax = True
973 invalidsyntax = True
974 else:
974 else:
975 invalidsyntax = True
975 invalidsyntax = True
976 if invalidsyntax:
976 if invalidsyntax:
977 raise error.Abort(_(b"invalid 'python:' syntax: %s") % toolpath)
977 raise error.Abort(_(b"invalid 'python:' syntax: %s") % toolpath)
978 toolpath = script
978 toolpath = script
979 ui.debug(
979 ui.debug(
980 b"picked tool '%s' for %s (binary %s symlink %s changedelete %s)\n"
980 b"picked tool '%s' for %s (binary %s symlink %s changedelete %s)\n"
981 % (
981 % (
982 tool,
982 tool,
983 fduipath,
983 fduipath,
984 pycompat.bytestr(binary),
984 pycompat.bytestr(binary),
985 pycompat.bytestr(symlink),
985 pycompat.bytestr(symlink),
986 pycompat.bytestr(changedelete),
986 pycompat.bytestr(changedelete),
987 )
987 )
988 )
988 )
989
989
990 if tool in internals:
990 if tool in internals:
991 func = internals[tool]
991 func = internals[tool]
992 mergetype = func.mergetype
992 mergetype = func.mergetype
993 onfailure = func.onfailure
993 onfailure = func.onfailure
994 precheck = func.precheck
994 precheck = func.precheck
995 isexternal = False
995 isexternal = False
996 else:
996 else:
997 if wctx.isinmemory():
997 if wctx.isinmemory():
998 func = _xmergeimm
998 func = _xmergeimm
999 else:
999 else:
1000 func = _xmerge
1000 func = _xmerge
1001 mergetype = fullmerge
1001 mergetype = fullmerge
1002 onfailure = _(b"merging %s failed!\n")
1002 onfailure = _(b"merging %s failed!\n")
1003 precheck = None
1003 precheck = None
1004 isexternal = True
1004 isexternal = True
1005
1005
1006 toolconf = tool, toolpath, binary, symlink, scriptfn
1006 toolconf = tool, toolpath, binary, symlink, scriptfn
1007
1007
1008 if not labels:
1008 if not labels:
1009 labels = [b'local', b'other']
1009 labels = [b'local', b'other']
1010 if len(labels) < 3:
1010 if len(labels) < 3:
1011 labels.append(b'base')
1011 labels.append(b'base')
1012 local = simplemerge.MergeInput(fcd, labels[0])
1012 local = simplemerge.MergeInput(fcd, labels[0])
1013 other = simplemerge.MergeInput(fco, labels[1])
1013 other = simplemerge.MergeInput(fco, labels[1])
1014 base = simplemerge.MergeInput(fca, labels[2])
1014 base = simplemerge.MergeInput(fca, labels[2])
1015 if mergetype == nomerge:
1015 if mergetype == nomerge:
1016 return func(
1016 return func(
1017 repo,
1017 repo,
1018 mynode,
1018 mynode,
1019 local,
1019 local,
1020 other,
1020 other,
1021 base,
1021 base,
1022 toolconf,
1022 toolconf,
1023 )
1023 )
1024
1024
1025 if orig != fco.path():
1025 if orig != fco.path():
1026 ui.status(
1026 ui.status(
1027 _(b"merging %s and %s to %s\n")
1027 _(b"merging %s and %s to %s\n")
1028 % (uipathfn(orig), uipathfn(fco.path()), fduipath)
1028 % (uipathfn(orig), uipathfn(fco.path()), fduipath)
1029 )
1029 )
1030 else:
1030 else:
1031 ui.status(_(b"merging %s\n") % fduipath)
1031 ui.status(_(b"merging %s\n") % fduipath)
1032
1032
1033 ui.debug(b"my %s other %s ancestor %s\n" % (fcd, fco, fca))
1033 ui.debug(b"my %s other %s ancestor %s\n" % (fcd, fco, fca))
1034
1034
1035 if precheck and not precheck(repo, mynode, fcd, fco, fca, toolconf):
1035 if precheck and not precheck(repo, mynode, fcd, fco, fca, toolconf):
1036 if onfailure:
1036 if onfailure:
1037 if wctx.isinmemory():
1037 if wctx.isinmemory():
1038 raise error.InMemoryMergeConflictsError(
1038 raise error.InMemoryMergeConflictsError(
1039 b'in-memory merge does not support merge conflicts'
1039 b'in-memory merge does not support merge conflicts'
1040 )
1040 )
1041 ui.warn(onfailure % fduipath)
1041 ui.warn(onfailure % fduipath)
1042 return 1, False
1042 return 1, False
1043
1043
1044 backup = _makebackup(repo, ui, fcd)
1044 backup = _makebackup(repo, ui, fcd)
1045 r = 1
1045 r = 1
1046 try:
1046 try:
1047 internalmarkerstyle = ui.config(b'ui', b'mergemarkers')
1047 internalmarkerstyle = ui.config(b'ui', b'mergemarkers')
1048 if isexternal:
1048 if isexternal:
1049 markerstyle = _toolstr(ui, tool, b'mergemarkers')
1049 markerstyle = _toolstr(ui, tool, b'mergemarkers')
1050 else:
1050 else:
1051 markerstyle = internalmarkerstyle
1051 markerstyle = internalmarkerstyle
1052
1052
1053 if mergetype == fullmerge:
1053 if mergetype == fullmerge:
1054 _run_partial_resolution_tools(repo, local, other, base)
1054 _run_partial_resolution_tools(repo, local, other, base)
1055 # conflict markers generated by premerge will use 'detailed'
1055 # conflict markers generated by premerge will use 'detailed'
1056 # settings if either ui.mergemarkers or the tool's mergemarkers
1056 # settings if either ui.mergemarkers or the tool's mergemarkers
1057 # setting is 'detailed'. This way tools can have basic labels in
1057 # setting is 'detailed'. This way tools can have basic labels in
1058 # space-constrained areas of the UI, but still get full information
1058 # space-constrained areas of the UI, but still get full information
1059 # in conflict markers if premerge is 'keep' or 'keep-merge3'.
1059 # in conflict markers if premerge is 'keep' or 'keep-merge3'.
1060 labeltool = None
1060 labeltool = None
1061 if markerstyle != b'basic':
1061 if markerstyle != b'basic':
1062 # respect 'tool's mergemarkertemplate (which defaults to
1062 # respect 'tool's mergemarkertemplate (which defaults to
1063 # command-templates.mergemarker)
1063 # command-templates.mergemarker)
1064 labeltool = tool
1064 labeltool = tool
1065 if internalmarkerstyle != b'basic' or markerstyle != b'basic':
1065 if internalmarkerstyle != b'basic' or markerstyle != b'basic':
1066 _populate_label_details(
1066 _populate_label_details(
1067 repo, [local, other, base], tool=labeltool
1067 repo, [local, other, base], tool=labeltool
1068 )
1068 )
1069
1069
1070 r = _premerge(
1070 r = _premerge(
1071 repo,
1071 repo,
1072 local,
1072 local,
1073 other,
1073 other,
1074 base,
1074 base,
1075 toolconf,
1075 toolconf,
1076 )
1076 )
1077 # we're done if premerge was successful (r is 0)
1077 # we're done if premerge was successful (r is 0)
1078 if not r:
1078 if not r:
1079 return r, False
1079 return r, False
1080
1080
1081 # Reset to basic labels
1081 # Reset to basic labels
1082 local.label_detail = None
1082 local.label_detail = None
1083 other.label_detail = None
1083 other.label_detail = None
1084 base.label_detail = None
1084 base.label_detail = None
1085
1085
1086 if markerstyle != b'basic':
1086 if markerstyle != b'basic':
1087 _populate_label_details(repo, [local, other, base], tool=tool)
1087 _populate_label_details(repo, [local, other, base], tool=tool)
1088
1088
1089 needcheck, r, deleted = func(
1089 needcheck, r, deleted = func(
1090 repo,
1090 repo,
1091 mynode,
1091 mynode,
1092 local,
1092 local,
1093 other,
1093 other,
1094 base,
1094 base,
1095 toolconf,
1095 toolconf,
1096 backup,
1096 backup,
1097 )
1097 )
1098
1098
1099 if needcheck:
1099 if needcheck:
1100 r = _check(repo, r, ui, tool, fcd, backup)
1100 r = _check(repo, r, ui, tool, fcd, backup)
1101
1101
1102 if r:
1102 if r:
1103 if onfailure:
1103 if onfailure:
1104 if wctx.isinmemory():
1104 if wctx.isinmemory():
1105 raise error.InMemoryMergeConflictsError(
1105 raise error.InMemoryMergeConflictsError(
1106 b'in-memory merge '
1106 b'in-memory merge '
1107 b'does not support '
1107 b'does not support '
1108 b'merge conflicts'
1108 b'merge conflicts'
1109 )
1109 )
1110 ui.warn(onfailure % fduipath)
1110 ui.warn(onfailure % fduipath)
1111 _onfilemergefailure(ui)
1111 _onfilemergefailure(ui)
1112
1112
1113 return r, deleted
1113 return r, deleted
1114 finally:
1114 finally:
1115 if not r and backup is not None:
1115 if not r and backup is not None:
1116 backup.remove()
1116 backup.remove()
1117
1117
1118
1118
1119 def _run_partial_resolution_tools(repo, local, other, base):
1119 def _run_partial_resolution_tools(repo, local, other, base):
1120 """Runs partial-resolution tools on the three inputs and updates them."""
1120 """Runs partial-resolution tools on the three inputs and updates them."""
1121 ui = repo.ui
1121 ui = repo.ui
1122 if ui.configbool(b'merge', b'disable-partial-tools'):
1123 return
1122 # Tuples of (order, name, executable path, args)
1124 # Tuples of (order, name, executable path, args)
1123 tools = []
1125 tools = []
1124 seen = set()
1126 seen = set()
1125 section = b"partial-merge-tools"
1127 section = b"partial-merge-tools"
1126 for k, v in ui.configitems(section):
1128 for k, v in ui.configitems(section):
1127 name = k.split(b'.')[0]
1129 name = k.split(b'.')[0]
1128 if name in seen:
1130 if name in seen:
1129 continue
1131 continue
1130 patterns = ui.configlist(section, b'%s.patterns' % name, [])
1132 patterns = ui.configlist(section, b'%s.patterns' % name, [])
1131 is_match = True
1133 is_match = True
1132 if patterns:
1134 if patterns:
1133 m = match.match(repo.root, b'', patterns)
1135 m = match.match(repo.root, b'', patterns)
1134 is_match = m(local.fctx.path())
1136 is_match = m(local.fctx.path())
1135 if is_match:
1137 if is_match:
1138 if ui.configbool(section, b'%s.disable' % name):
1139 continue
1136 order = ui.configint(section, b'%s.order' % name, 0)
1140 order = ui.configint(section, b'%s.order' % name, 0)
1137 executable = ui.config(section, b'%s.executable' % name, name)
1141 executable = ui.config(section, b'%s.executable' % name, name)
1138 args = ui.config(section, b'%s.args' % name)
1142 args = ui.config(section, b'%s.args' % name)
1139 tools.append((order, name, executable, args))
1143 tools.append((order, name, executable, args))
1140
1144
1141 if not tools:
1145 if not tools:
1142 return
1146 return
1143 # Sort in configured order (first in tuple)
1147 # Sort in configured order (first in tuple)
1144 tools.sort()
1148 tools.sort()
1145
1149
1146 files = [
1150 files = [
1147 (b"local", local.fctx.path(), local.text()),
1151 (b"local", local.fctx.path(), local.text()),
1148 (b"base", base.fctx.path(), base.text()),
1152 (b"base", base.fctx.path(), base.text()),
1149 (b"other", other.fctx.path(), other.text()),
1153 (b"other", other.fctx.path(), other.text()),
1150 ]
1154 ]
1151
1155
1152 with _maketempfiles(files) as temppaths:
1156 with _maketempfiles(files) as temppaths:
1153 localpath, basepath, otherpath = temppaths
1157 localpath, basepath, otherpath = temppaths
1154
1158
1155 for order, name, executable, args in tools:
1159 for order, name, executable, args in tools:
1156 cmd = procutil.shellquote(executable)
1160 cmd = procutil.shellquote(executable)
1157 replace = {
1161 replace = {
1158 b'local': localpath,
1162 b'local': localpath,
1159 b'base': basepath,
1163 b'base': basepath,
1160 b'other': otherpath,
1164 b'other': otherpath,
1161 }
1165 }
1162 args = util.interpolate(
1166 args = util.interpolate(
1163 br'\$',
1167 br'\$',
1164 replace,
1168 replace,
1165 args,
1169 args,
1166 lambda s: procutil.shellquote(util.localpath(s)),
1170 lambda s: procutil.shellquote(util.localpath(s)),
1167 )
1171 )
1168
1172
1169 cmd = b'%s %s' % (cmd, args)
1173 cmd = b'%s %s' % (cmd, args)
1170 r = ui.system(cmd, cwd=repo.root, blockedtag=b'partial-mergetool')
1174 r = ui.system(cmd, cwd=repo.root, blockedtag=b'partial-mergetool')
1171 if r:
1175 if r:
1172 raise error.StateError(
1176 raise error.StateError(
1173 b'partial merge tool %s exited with code %d' % (name, r)
1177 b'partial merge tool %s exited with code %d' % (name, r)
1174 )
1178 )
1175 local_text = util.readfile(localpath)
1179 local_text = util.readfile(localpath)
1176 other_text = util.readfile(otherpath)
1180 other_text = util.readfile(otherpath)
1177 if local_text == other_text:
1181 if local_text == other_text:
1178 # No need to run other tools if all conflicts have been resolved
1182 # No need to run other tools if all conflicts have been resolved
1179 break
1183 break
1180
1184
1181 local.set_text(local_text)
1185 local.set_text(local_text)
1182 base.set_text(util.readfile(basepath))
1186 base.set_text(util.readfile(basepath))
1183 other.set_text(other_text)
1187 other.set_text(other_text)
1184
1188
1185
1189
1186 def _haltmerge():
1190 def _haltmerge():
1187 msg = _(b'merge halted after failed merge (see hg resolve)')
1191 msg = _(b'merge halted after failed merge (see hg resolve)')
1188 raise error.InterventionRequired(msg)
1192 raise error.InterventionRequired(msg)
1189
1193
1190
1194
1191 def _onfilemergefailure(ui):
1195 def _onfilemergefailure(ui):
1192 action = ui.config(b'merge', b'on-failure')
1196 action = ui.config(b'merge', b'on-failure')
1193 if action == b'prompt':
1197 if action == b'prompt':
1194 msg = _(b'continue merge operation (yn)?$$ &Yes $$ &No')
1198 msg = _(b'continue merge operation (yn)?$$ &Yes $$ &No')
1195 if ui.promptchoice(msg, 0) == 1:
1199 if ui.promptchoice(msg, 0) == 1:
1196 _haltmerge()
1200 _haltmerge()
1197 if action == b'halt':
1201 if action == b'halt':
1198 _haltmerge()
1202 _haltmerge()
1199 # default action is 'continue', in which case we neither prompt nor halt
1203 # default action is 'continue', in which case we neither prompt nor halt
1200
1204
1201
1205
1202 def hasconflictmarkers(data):
1206 def hasconflictmarkers(data):
1203 # Detect lines starting with a string of 7 identical characters from the
1207 # Detect lines starting with a string of 7 identical characters from the
1204 # subset Mercurial uses for conflict markers, followed by either the end of
1208 # subset Mercurial uses for conflict markers, followed by either the end of
1205 # line or a space and some text. Note that using [<>=+|-]{7} would detect
1209 # line or a space and some text. Note that using [<>=+|-]{7} would detect
1206 # `<><><><><` as a conflict marker, which we don't want.
1210 # `<><><><><` as a conflict marker, which we don't want.
1207 return bool(
1211 return bool(
1208 re.search(
1212 re.search(
1209 br"^([<>=+|-])\1{6}( .*)$",
1213 br"^([<>=+|-])\1{6}( .*)$",
1210 data,
1214 data,
1211 re.MULTILINE,
1215 re.MULTILINE,
1212 )
1216 )
1213 )
1217 )
1214
1218
1215
1219
1216 def _check(repo, r, ui, tool, fcd, backup):
1220 def _check(repo, r, ui, tool, fcd, backup):
1217 fd = fcd.path()
1221 fd = fcd.path()
1218 uipathfn = scmutil.getuipathfn(repo)
1222 uipathfn = scmutil.getuipathfn(repo)
1219
1223
1220 if not r and (
1224 if not r and (
1221 _toolbool(ui, tool, b"checkconflicts")
1225 _toolbool(ui, tool, b"checkconflicts")
1222 or b'conflicts' in _toollist(ui, tool, b"check")
1226 or b'conflicts' in _toollist(ui, tool, b"check")
1223 ):
1227 ):
1224 if hasconflictmarkers(fcd.data()):
1228 if hasconflictmarkers(fcd.data()):
1225 r = 1
1229 r = 1
1226
1230
1227 checked = False
1231 checked = False
1228 if b'prompt' in _toollist(ui, tool, b"check"):
1232 if b'prompt' in _toollist(ui, tool, b"check"):
1229 checked = True
1233 checked = True
1230 if ui.promptchoice(
1234 if ui.promptchoice(
1231 _(b"was merge of '%s' successful (yn)?$$ &Yes $$ &No")
1235 _(b"was merge of '%s' successful (yn)?$$ &Yes $$ &No")
1232 % uipathfn(fd),
1236 % uipathfn(fd),
1233 1,
1237 1,
1234 ):
1238 ):
1235 r = 1
1239 r = 1
1236
1240
1237 if (
1241 if (
1238 not r
1242 not r
1239 and not checked
1243 and not checked
1240 and (
1244 and (
1241 _toolbool(ui, tool, b"checkchanged")
1245 _toolbool(ui, tool, b"checkchanged")
1242 or b'changed' in _toollist(ui, tool, b"check")
1246 or b'changed' in _toollist(ui, tool, b"check")
1243 )
1247 )
1244 ):
1248 ):
1245 if backup is not None and not fcd.cmp(backup):
1249 if backup is not None and not fcd.cmp(backup):
1246 if ui.promptchoice(
1250 if ui.promptchoice(
1247 _(
1251 _(
1248 b" output file %s appears unchanged\n"
1252 b" output file %s appears unchanged\n"
1249 b"was merge successful (yn)?"
1253 b"was merge successful (yn)?"
1250 b"$$ &Yes $$ &No"
1254 b"$$ &Yes $$ &No"
1251 )
1255 )
1252 % uipathfn(fd),
1256 % uipathfn(fd),
1253 1,
1257 1,
1254 ):
1258 ):
1255 r = 1
1259 r = 1
1256
1260
1257 if backup is not None and _toolbool(ui, tool, b"fixeol"):
1261 if backup is not None and _toolbool(ui, tool, b"fixeol"):
1258 _matcheol(_workingpath(repo, fcd), backup)
1262 _matcheol(_workingpath(repo, fcd), backup)
1259
1263
1260 return r
1264 return r
1261
1265
1262
1266
1263 def _workingpath(repo, ctx):
1267 def _workingpath(repo, ctx):
1264 return repo.wjoin(ctx.path())
1268 return repo.wjoin(ctx.path())
1265
1269
1266
1270
1267 def loadinternalmerge(ui, extname, registrarobj):
1271 def loadinternalmerge(ui, extname, registrarobj):
1268 """Load internal merge tool from specified registrarobj"""
1272 """Load internal merge tool from specified registrarobj"""
1269 for name, func in registrarobj._table.items():
1273 for name, func in registrarobj._table.items():
1270 fullname = b':' + name
1274 fullname = b':' + name
1271 internals[fullname] = func
1275 internals[fullname] = func
1272 internals[b'internal:' + name] = func
1276 internals[b'internal:' + name] = func
1273 internalsdoc[fullname] = func
1277 internalsdoc[fullname] = func
1274
1278
1275 capabilities = sorted([k for k, v in func.capabilities.items() if v])
1279 capabilities = sorted([k for k, v in func.capabilities.items() if v])
1276 if capabilities:
1280 if capabilities:
1277 capdesc = b" (actual capabilities: %s)" % b', '.join(
1281 capdesc = b" (actual capabilities: %s)" % b', '.join(
1278 capabilities
1282 capabilities
1279 )
1283 )
1280 func.__doc__ = func.__doc__ + pycompat.sysstr(b"\n\n%s" % capdesc)
1284 func.__doc__ = func.__doc__ + pycompat.sysstr(b"\n\n%s" % capdesc)
1281
1285
1282 # to put i18n comments into hg.pot for automatically generated texts
1286 # to put i18n comments into hg.pot for automatically generated texts
1283
1287
1284 # i18n: "binary" and "symlink" are keywords
1288 # i18n: "binary" and "symlink" are keywords
1285 # i18n: this text is added automatically
1289 # i18n: this text is added automatically
1286 _(b" (actual capabilities: binary, symlink)")
1290 _(b" (actual capabilities: binary, symlink)")
1287 # i18n: "binary" is keyword
1291 # i18n: "binary" is keyword
1288 # i18n: this text is added automatically
1292 # i18n: this text is added automatically
1289 _(b" (actual capabilities: binary)")
1293 _(b" (actual capabilities: binary)")
1290 # i18n: "symlink" is keyword
1294 # i18n: "symlink" is keyword
1291 # i18n: this text is added automatically
1295 # i18n: this text is added automatically
1292 _(b" (actual capabilities: symlink)")
1296 _(b" (actual capabilities: symlink)")
1293
1297
1294
1298
1295 # load built-in merge tools explicitly to setup internalsdoc
1299 # load built-in merge tools explicitly to setup internalsdoc
1296 loadinternalmerge(None, None, internaltool)
1300 loadinternalmerge(None, None, internaltool)
1297
1301
1298 # tell hggettext to extract docstrings from these functions:
1302 # tell hggettext to extract docstrings from these functions:
1299 i18nfunctions = internals.values()
1303 i18nfunctions = internals.values()
@@ -1,241 +1,292 b''
1 Test support for partial-resolution tools
1 Test support for partial-resolution tools
2
2
3 Create a tool that resolves conflicts after line 5 by simply dropping those
3 Create a tool that resolves conflicts after line 5 by simply dropping those
4 lines (even if there are no conflicts there)
4 lines (even if there are no conflicts there)
5 $ cat >> "$TESTTMP/head.sh" <<'EOF'
5 $ cat >> "$TESTTMP/head.sh" <<'EOF'
6 > #!/bin/sh
6 > #!/bin/sh
7 > for f in "$@"; do
7 > for f in "$@"; do
8 > head -5 $f > tmp
8 > head -5 $f > tmp
9 > mv -f tmp $f
9 > mv -f tmp $f
10 > done
10 > done
11 > EOF
11 > EOF
12 $ chmod +x "$TESTTMP/head.sh"
12 $ chmod +x "$TESTTMP/head.sh"
13 ...and another tool that keeps only the last 5 lines instead of the first 5.
13 ...and another tool that keeps only the last 5 lines instead of the first 5.
14 $ cat >> "$TESTTMP/tail.sh" <<'EOF'
14 $ cat >> "$TESTTMP/tail.sh" <<'EOF'
15 > #!/bin/sh
15 > #!/bin/sh
16 > for f in "$@"; do
16 > for f in "$@"; do
17 > tail -5 $f > tmp
17 > tail -5 $f > tmp
18 > mv -f tmp $f
18 > mv -f tmp $f
19 > done
19 > done
20 > EOF
20 > EOF
21 $ chmod +x "$TESTTMP/tail.sh"
21 $ chmod +x "$TESTTMP/tail.sh"
22
22
23 Set up both tools to run on all patterns (the default), and let the `tail` tool
23 Set up both tools to run on all patterns (the default), and let the `tail` tool
24 run after the `head` tool, which means it will have no effect (we'll override it
24 run after the `head` tool, which means it will have no effect (we'll override it
25 to test order later)
25 to test order later)
26 $ cat >> "$HGRCPATH" <<EOF
26 $ cat >> "$HGRCPATH" <<EOF
27 > [partial-merge-tools]
27 > [partial-merge-tools]
28 > head.executable=$TESTTMP/head.sh
28 > head.executable=$TESTTMP/head.sh
29 > tail.executable=$TESTTMP/tail.sh
29 > tail.executable=$TESTTMP/tail.sh
30 > tail.order=1
30 > tail.order=1
31 > EOF
31 > EOF
32
32
33 $ make_commit() {
33 $ make_commit() {
34 > echo "$@" | xargs -n1 > file
34 > echo "$@" | xargs -n1 > file
35 > hg add file 2> /dev/null
35 > hg add file 2> /dev/null
36 > hg ci -m "$*"
36 > hg ci -m "$*"
37 > }
37 > }
38
38
39
39
40 Let a partial-resolution tool resolve some conflicts and leave other conflicts
40 Let a partial-resolution tool resolve some conflicts and leave other conflicts
41 for the regular merge tool (:merge3 here)
41 for the regular merge tool (:merge3 here)
42
42
43 $ hg init repo
43 $ hg init repo
44 $ cd repo
44 $ cd repo
45 $ make_commit a b c d e f
45 $ make_commit a b c d e f
46 $ make_commit a b2 c d e f2
46 $ make_commit a b2 c d e f2
47 $ hg up 0
47 $ hg up 0
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ make_commit a b3 c d e f3
49 $ make_commit a b3 c d e f3
50 created new head
50 created new head
51 $ hg merge 1 -t :merge3
51 $ hg merge 1 -t :merge3
52 merging file
52 merging file
53 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
53 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
54 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
54 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
55 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
55 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
56 [1]
56 [1]
57 $ cat file
57 $ cat file
58 a
58 a
59 <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
59 <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
60 b3
60 b3
61 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
61 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
62 b
62 b
63 =======
63 =======
64 b2
64 b2
65 >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
65 >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
66 c
66 c
67 d
67 d
68 e
68 e
69
69
70
70
71 With premerge=keep, the partial-resolution tools runs before and doesn't see
71 With premerge=keep, the partial-resolution tools runs before and doesn't see
72 the conflict markers
72 the conflict markers
73
73
74 $ hg up -C 2
74 $ hg up -C 2
75 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 $ cat >> .hg/hgrc <<EOF
76 $ cat >> .hg/hgrc <<EOF
77 > [merge-tools]
77 > [merge-tools]
78 > my-local.executable = cat
78 > my-local.executable = cat
79 > my-local.args = $local
79 > my-local.args = $local
80 > my-local.premerge = keep-merge3
80 > my-local.premerge = keep-merge3
81 > EOF
81 > EOF
82 $ hg merge 1 -t my-local
82 $ hg merge 1 -t my-local
83 merging file
83 merging file
84 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
84 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
85 (branch merge, don't forget to commit)
85 (branch merge, don't forget to commit)
86 $ cat file
86 $ cat file
87 a
87 a
88 <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
88 <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
89 b3
89 b3
90 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
90 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
91 b
91 b
92 =======
92 =======
93 b2
93 b2
94 >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
94 >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
95 c
95 c
96 d
96 d
97 e
97 e
98
98
99
99
100 When a partial-resolution tool resolves all conflicts, the resolution should
100 When a partial-resolution tool resolves all conflicts, the resolution should
101 be recorded and the regular merge tool should not be invoked for the file.
101 be recorded and the regular merge tool should not be invoked for the file.
102
102
103 $ hg up -C 0
103 $ hg up -C 0
104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 $ make_commit a b c d e f2
105 $ make_commit a b c d e f2
106 created new head
106 created new head
107 $ hg up 0
107 $ hg up 0
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ make_commit a b c d e f3
109 $ make_commit a b c d e f3
110 created new head
110 created new head
111 $ hg merge 3 -t false
111 $ hg merge 3 -t false
112 merging file
112 merging file
113 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
113 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
114 (branch merge, don't forget to commit)
114 (branch merge, don't forget to commit)
115 $ cat file
115 $ cat file
116 a
116 a
117 b
117 b
118 c
118 c
119 d
119 d
120 e
120 e
121
121
122
122
123 Can disable all partial merge tools (the `head` tool would have resolved this
124 conflict it had been enabled)
125
126 $ hg up -C 4
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 $ hg merge 3 -t :merge3 --config merge.disable-partial-tools=yes
129 merging file
130 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
131 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
132 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
133 [1]
134 $ cat file
135 a
136 b
137 c
138 d
139 e
140 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
141 f3
142 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
143 f
144 =======
145 f2
146 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
147
148
149 Can disable one partial merge tool (the `head` tool would have resolved this
150 conflict it had been enabled)
151
152 $ hg up -C 4
153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 $ hg merge 3 -t :merge3 --config partial-merge-tools.head.disable=yes
155 merging file
156 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
158 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
159 [1]
160 $ cat file
161 b
162 c
163 d
164 e
165 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
166 f3
167 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
168 f
169 =======
170 f2
171 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
172
173
123 Only tools whose patterns match are run. We make `head` not match here, so
174 Only tools whose patterns match are run. We make `head` not match here, so
124 only `tail` should run
175 only `tail` should run
125
176
126 $ hg up -C 4
177 $ hg up -C 4
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 $ hg merge 3 -t :merge3 --config partial-merge-tools.head.patterns=other
179 $ hg merge 3 -t :merge3 --config partial-merge-tools.head.patterns=other
129 merging file
180 merging file
130 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
181 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
131 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
182 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
132 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
183 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
133 [1]
184 [1]
134 $ cat file
185 $ cat file
135 b
186 b
136 c
187 c
137 d
188 d
138 e
189 e
139 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
190 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
140 f3
191 f3
141 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
192 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
142 f
193 f
143 =======
194 =======
144 f2
195 f2
145 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
196 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
146
197
147
198
148 If there are several matching tools, they are run in requested order. We move
199 If there are several matching tools, they are run in requested order. We move
149 `head` after `tail` in order here so it has no effect (the conflict in "f" thus
200 `head` after `tail` in order here so it has no effect (the conflict in "f" thus
150 remains).
201 remains).
151
202
152 $ hg up -C 4
203 $ hg up -C 4
153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 $ hg merge 3 -t :merge3 --config partial-merge-tools.head.order=2
205 $ hg merge 3 -t :merge3 --config partial-merge-tools.head.order=2
155 merging file
206 merging file
156 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
207 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
208 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
158 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
209 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
159 [1]
210 [1]
160 $ cat file
211 $ cat file
161 b
212 b
162 c
213 c
163 d
214 d
164 e
215 e
165 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
216 <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
166 f3
217 f3
167 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
218 ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
168 f
219 f
169 =======
220 =======
170 f2
221 f2
171 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
222 >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
172
223
173
224
174 When using "nomerge" tools (e.g. `:other`), the partial-resolution tools
225 When using "nomerge" tools (e.g. `:other`), the partial-resolution tools
175 should not be run.
226 should not be run.
176
227
177 $ hg up -C 4
228 $ hg up -C 4
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 $ hg merge 3 -t :other
230 $ hg merge 3 -t :other
180 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
231 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
181 (branch merge, don't forget to commit)
232 (branch merge, don't forget to commit)
182 $ cat file
233 $ cat file
183 a
234 a
184 b
235 b
185 c
236 c
186 d
237 d
187 e
238 e
188 f2
239 f2
189
240
190
241
191 If a partial-resolution tool resolved some conflict and simplemerge can
242 If a partial-resolution tool resolved some conflict and simplemerge can
192 merge the rest, then the regular merge tool should not be used. Here we merge
243 merge the rest, then the regular merge tool should not be used. Here we merge
193 "a b c d e3 f3" with "a b2 c d e f2". The `head` tool resolves the conflict in
244 "a b c d e3 f3" with "a b2 c d e f2". The `head` tool resolves the conflict in
194 "f" and the internal simplemerge merges the remaining changes in "b" and "e".
245 "f" and the internal simplemerge merges the remaining changes in "b" and "e".
195
246
196 $ hg up -C 0
247 $ hg up -C 0
197 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 $ make_commit a b c d e3 f3
249 $ make_commit a b c d e3 f3
199 created new head
250 created new head
200 $ hg merge 1 -t false
251 $ hg merge 1 -t false
201 merging file
252 merging file
202 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
253 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
203 (branch merge, don't forget to commit)
254 (branch merge, don't forget to commit)
204 $ cat file
255 $ cat file
205 a
256 a
206 b2
257 b2
207 c
258 c
208 d
259 d
209 e3
260 e3
210
261
211 Test that arguments get passed as expected.
262 Test that arguments get passed as expected.
212
263
213 $ cat >> "$TESTTMP/log-args.sh" <<'EOF'
264 $ cat >> "$TESTTMP/log-args.sh" <<'EOF'
214 > #!/bin/sh
265 > #!/bin/sh
215 > echo "$@" > args.log
266 > echo "$@" > args.log
216 > EOF
267 > EOF
217 $ chmod +x "$TESTTMP/log-args.sh"
268 $ chmod +x "$TESTTMP/log-args.sh"
218 $ cat >> "$HGRCPATH" <<EOF
269 $ cat >> "$HGRCPATH" <<EOF
219 > [partial-merge-tools]
270 > [partial-merge-tools]
220 > log-args.executable=$TESTTMP/log-args.sh
271 > log-args.executable=$TESTTMP/log-args.sh
221 > EOF
272 > EOF
222 $ hg up -C 2
273 $ hg up -C 2
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
224 $ hg merge 1
275 $ hg merge 1
225 merging file
276 merging file
226 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
277 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
227 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
278 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
228 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
279 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
229 [1]
280 [1]
230 $ cat args.log
281 $ cat args.log
231 */hgmerge-*/file~local */hgmerge-*/file~base */hgmerge-*/file~other (glob)
282 */hgmerge-*/file~local */hgmerge-*/file~base */hgmerge-*/file~other (glob)
232 $ hg up -C 2
283 $ hg up -C 2
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 $ hg merge 1 --config partial-merge-tools.log-args.args='--other $other $base --foo --local $local --also-other $other'
285 $ hg merge 1 --config partial-merge-tools.log-args.args='--other $other $base --foo --local $local --also-other $other'
235 merging file
286 merging file
236 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
287 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
237 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
288 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
238 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
289 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
239 [1]
290 [1]
240 $ cat args.log
291 $ cat args.log
241 --other */hgmerge-*/file~other */hgmerge-*/file~base --foo --local */hgmerge-*/file~local --also-other */hgmerge-*/file~other (glob)
292 --other */hgmerge-*/file~other */hgmerge-*/file~base --foo --local */hgmerge-*/file~local --also-other */hgmerge-*/file~other (glob)
General Comments 0
You need to be logged in to leave comments. Login now