##// END OF EJS Templates
copies: add an devel option to trace all files...
marmoute -
r47137:e948ad0d default
parent child Browse files
Show More
@@ -1,2599 +1,2605 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18
18
19 def loadconfigtable(ui, extname, configtable):
19 def loadconfigtable(ui, extname, configtable):
20 """update config item known to the ui with the extension ones"""
20 """update config item known to the ui with the extension ones"""
21 for section, items in sorted(configtable.items()):
21 for section, items in sorted(configtable.items()):
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownitems = ui._knownconfig.setdefault(section, itemregister())
23 knownkeys = set(knownitems)
23 knownkeys = set(knownitems)
24 newkeys = set(items)
24 newkeys = set(items)
25 for key in sorted(knownkeys & newkeys):
25 for key in sorted(knownkeys & newkeys):
26 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg = b"extension '%s' overwrite config item '%s.%s'"
27 msg %= (extname, section, key)
27 msg %= (extname, section, key)
28 ui.develwarn(msg, config=b'warn-config')
28 ui.develwarn(msg, config=b'warn-config')
29
29
30 knownitems.update(items)
30 knownitems.update(items)
31
31
32
32
33 class configitem(object):
33 class configitem(object):
34 """represent a known config item
34 """represent a known config item
35
35
36 :section: the official config section where to find this item,
36 :section: the official config section where to find this item,
37 :name: the official name within the section,
37 :name: the official name within the section,
38 :default: default value for this item,
38 :default: default value for this item,
39 :alias: optional list of tuples as alternatives,
39 :alias: optional list of tuples as alternatives,
40 :generic: this is a generic definition, match name using regular expression.
40 :generic: this is a generic definition, match name using regular expression.
41 """
41 """
42
42
43 def __init__(
43 def __init__(
44 self,
44 self,
45 section,
45 section,
46 name,
46 name,
47 default=None,
47 default=None,
48 alias=(),
48 alias=(),
49 generic=False,
49 generic=False,
50 priority=0,
50 priority=0,
51 experimental=False,
51 experimental=False,
52 ):
52 ):
53 self.section = section
53 self.section = section
54 self.name = name
54 self.name = name
55 self.default = default
55 self.default = default
56 self.alias = list(alias)
56 self.alias = list(alias)
57 self.generic = generic
57 self.generic = generic
58 self.priority = priority
58 self.priority = priority
59 self.experimental = experimental
59 self.experimental = experimental
60 self._re = None
60 self._re = None
61 if generic:
61 if generic:
62 self._re = re.compile(self.name)
62 self._re = re.compile(self.name)
63
63
64
64
65 class itemregister(dict):
65 class itemregister(dict):
66 """A specialized dictionary that can handle wild-card selection"""
66 """A specialized dictionary that can handle wild-card selection"""
67
67
68 def __init__(self):
68 def __init__(self):
69 super(itemregister, self).__init__()
69 super(itemregister, self).__init__()
70 self._generics = set()
70 self._generics = set()
71
71
72 def update(self, other):
72 def update(self, other):
73 super(itemregister, self).update(other)
73 super(itemregister, self).update(other)
74 self._generics.update(other._generics)
74 self._generics.update(other._generics)
75
75
76 def __setitem__(self, key, item):
76 def __setitem__(self, key, item):
77 super(itemregister, self).__setitem__(key, item)
77 super(itemregister, self).__setitem__(key, item)
78 if item.generic:
78 if item.generic:
79 self._generics.add(item)
79 self._generics.add(item)
80
80
81 def get(self, key):
81 def get(self, key):
82 baseitem = super(itemregister, self).get(key)
82 baseitem = super(itemregister, self).get(key)
83 if baseitem is not None and not baseitem.generic:
83 if baseitem is not None and not baseitem.generic:
84 return baseitem
84 return baseitem
85
85
86 # search for a matching generic item
86 # search for a matching generic item
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
88 for item in generics:
88 for item in generics:
89 # we use 'match' instead of 'search' to make the matching simpler
89 # we use 'match' instead of 'search' to make the matching simpler
90 # for people unfamiliar with regular expression. Having the match
90 # for people unfamiliar with regular expression. Having the match
91 # rooted to the start of the string will produce less surprising
91 # rooted to the start of the string will produce less surprising
92 # result for user writing simple regex for sub-attribute.
92 # result for user writing simple regex for sub-attribute.
93 #
93 #
94 # For example using "color\..*" match produces an unsurprising
94 # For example using "color\..*" match produces an unsurprising
95 # result, while using search could suddenly match apparently
95 # result, while using search could suddenly match apparently
96 # unrelated configuration that happens to contains "color."
96 # unrelated configuration that happens to contains "color."
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # anywhere. This is a tradeoff where we favor requiring ".*" on
98 # some match to avoid the need to prefix most pattern with "^".
98 # some match to avoid the need to prefix most pattern with "^".
99 # The "^" seems more error prone.
99 # The "^" seems more error prone.
100 if item._re.match(key):
100 if item._re.match(key):
101 return item
101 return item
102
102
103 return None
103 return None
104
104
105
105
106 coreitems = {}
106 coreitems = {}
107
107
108
108
109 def _register(configtable, *args, **kwargs):
109 def _register(configtable, *args, **kwargs):
110 item = configitem(*args, **kwargs)
110 item = configitem(*args, **kwargs)
111 section = configtable.setdefault(item.section, itemregister())
111 section = configtable.setdefault(item.section, itemregister())
112 if item.name in section:
112 if item.name in section:
113 msg = b"duplicated config item registration for '%s.%s'"
113 msg = b"duplicated config item registration for '%s.%s'"
114 raise error.ProgrammingError(msg % (item.section, item.name))
114 raise error.ProgrammingError(msg % (item.section, item.name))
115 section[item.name] = item
115 section[item.name] = item
116
116
117
117
118 # special value for case where the default is derived from other values
118 # special value for case where the default is derived from other values
119 dynamicdefault = object()
119 dynamicdefault = object()
120
120
121 # Registering actual config items
121 # Registering actual config items
122
122
123
123
124 def getitemregister(configtable):
124 def getitemregister(configtable):
125 f = functools.partial(_register, configtable)
125 f = functools.partial(_register, configtable)
126 # export pseudo enum as configitem.*
126 # export pseudo enum as configitem.*
127 f.dynamicdefault = dynamicdefault
127 f.dynamicdefault = dynamicdefault
128 return f
128 return f
129
129
130
130
131 coreconfigitem = getitemregister(coreitems)
131 coreconfigitem = getitemregister(coreitems)
132
132
133
133
134 def _registerdiffopts(section, configprefix=b''):
134 def _registerdiffopts(section, configprefix=b''):
135 coreconfigitem(
135 coreconfigitem(
136 section,
136 section,
137 configprefix + b'nodates',
137 configprefix + b'nodates',
138 default=False,
138 default=False,
139 )
139 )
140 coreconfigitem(
140 coreconfigitem(
141 section,
141 section,
142 configprefix + b'showfunc',
142 configprefix + b'showfunc',
143 default=False,
143 default=False,
144 )
144 )
145 coreconfigitem(
145 coreconfigitem(
146 section,
146 section,
147 configprefix + b'unified',
147 configprefix + b'unified',
148 default=None,
148 default=None,
149 )
149 )
150 coreconfigitem(
150 coreconfigitem(
151 section,
151 section,
152 configprefix + b'git',
152 configprefix + b'git',
153 default=False,
153 default=False,
154 )
154 )
155 coreconfigitem(
155 coreconfigitem(
156 section,
156 section,
157 configprefix + b'ignorews',
157 configprefix + b'ignorews',
158 default=False,
158 default=False,
159 )
159 )
160 coreconfigitem(
160 coreconfigitem(
161 section,
161 section,
162 configprefix + b'ignorewsamount',
162 configprefix + b'ignorewsamount',
163 default=False,
163 default=False,
164 )
164 )
165 coreconfigitem(
165 coreconfigitem(
166 section,
166 section,
167 configprefix + b'ignoreblanklines',
167 configprefix + b'ignoreblanklines',
168 default=False,
168 default=False,
169 )
169 )
170 coreconfigitem(
170 coreconfigitem(
171 section,
171 section,
172 configprefix + b'ignorewseol',
172 configprefix + b'ignorewseol',
173 default=False,
173 default=False,
174 )
174 )
175 coreconfigitem(
175 coreconfigitem(
176 section,
176 section,
177 configprefix + b'nobinary',
177 configprefix + b'nobinary',
178 default=False,
178 default=False,
179 )
179 )
180 coreconfigitem(
180 coreconfigitem(
181 section,
181 section,
182 configprefix + b'noprefix',
182 configprefix + b'noprefix',
183 default=False,
183 default=False,
184 )
184 )
185 coreconfigitem(
185 coreconfigitem(
186 section,
186 section,
187 configprefix + b'word-diff',
187 configprefix + b'word-diff',
188 default=False,
188 default=False,
189 )
189 )
190
190
191
191
192 coreconfigitem(
192 coreconfigitem(
193 b'alias',
193 b'alias',
194 b'.*',
194 b'.*',
195 default=dynamicdefault,
195 default=dynamicdefault,
196 generic=True,
196 generic=True,
197 )
197 )
198 coreconfigitem(
198 coreconfigitem(
199 b'auth',
199 b'auth',
200 b'cookiefile',
200 b'cookiefile',
201 default=None,
201 default=None,
202 )
202 )
203 _registerdiffopts(section=b'annotate')
203 _registerdiffopts(section=b'annotate')
204 # bookmarks.pushing: internal hack for discovery
204 # bookmarks.pushing: internal hack for discovery
205 coreconfigitem(
205 coreconfigitem(
206 b'bookmarks',
206 b'bookmarks',
207 b'pushing',
207 b'pushing',
208 default=list,
208 default=list,
209 )
209 )
210 # bundle.mainreporoot: internal hack for bundlerepo
210 # bundle.mainreporoot: internal hack for bundlerepo
211 coreconfigitem(
211 coreconfigitem(
212 b'bundle',
212 b'bundle',
213 b'mainreporoot',
213 b'mainreporoot',
214 default=b'',
214 default=b'',
215 )
215 )
216 coreconfigitem(
216 coreconfigitem(
217 b'censor',
217 b'censor',
218 b'policy',
218 b'policy',
219 default=b'abort',
219 default=b'abort',
220 experimental=True,
220 experimental=True,
221 )
221 )
222 coreconfigitem(
222 coreconfigitem(
223 b'chgserver',
223 b'chgserver',
224 b'idletimeout',
224 b'idletimeout',
225 default=3600,
225 default=3600,
226 )
226 )
227 coreconfigitem(
227 coreconfigitem(
228 b'chgserver',
228 b'chgserver',
229 b'skiphash',
229 b'skiphash',
230 default=False,
230 default=False,
231 )
231 )
232 coreconfigitem(
232 coreconfigitem(
233 b'cmdserver',
233 b'cmdserver',
234 b'log',
234 b'log',
235 default=None,
235 default=None,
236 )
236 )
237 coreconfigitem(
237 coreconfigitem(
238 b'cmdserver',
238 b'cmdserver',
239 b'max-log-files',
239 b'max-log-files',
240 default=7,
240 default=7,
241 )
241 )
242 coreconfigitem(
242 coreconfigitem(
243 b'cmdserver',
243 b'cmdserver',
244 b'max-log-size',
244 b'max-log-size',
245 default=b'1 MB',
245 default=b'1 MB',
246 )
246 )
247 coreconfigitem(
247 coreconfigitem(
248 b'cmdserver',
248 b'cmdserver',
249 b'max-repo-cache',
249 b'max-repo-cache',
250 default=0,
250 default=0,
251 experimental=True,
251 experimental=True,
252 )
252 )
253 coreconfigitem(
253 coreconfigitem(
254 b'cmdserver',
254 b'cmdserver',
255 b'message-encodings',
255 b'message-encodings',
256 default=list,
256 default=list,
257 )
257 )
258 coreconfigitem(
258 coreconfigitem(
259 b'cmdserver',
259 b'cmdserver',
260 b'track-log',
260 b'track-log',
261 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
262 )
262 )
263 coreconfigitem(
263 coreconfigitem(
264 b'cmdserver',
264 b'cmdserver',
265 b'shutdown-on-interrupt',
265 b'shutdown-on-interrupt',
266 default=True,
266 default=True,
267 )
267 )
268 coreconfigitem(
268 coreconfigitem(
269 b'color',
269 b'color',
270 b'.*',
270 b'.*',
271 default=None,
271 default=None,
272 generic=True,
272 generic=True,
273 )
273 )
274 coreconfigitem(
274 coreconfigitem(
275 b'color',
275 b'color',
276 b'mode',
276 b'mode',
277 default=b'auto',
277 default=b'auto',
278 )
278 )
279 coreconfigitem(
279 coreconfigitem(
280 b'color',
280 b'color',
281 b'pagermode',
281 b'pagermode',
282 default=dynamicdefault,
282 default=dynamicdefault,
283 )
283 )
284 coreconfigitem(
284 coreconfigitem(
285 b'command-templates',
285 b'command-templates',
286 b'graphnode',
286 b'graphnode',
287 default=None,
287 default=None,
288 alias=[(b'ui', b'graphnodetemplate')],
288 alias=[(b'ui', b'graphnodetemplate')],
289 )
289 )
290 coreconfigitem(
290 coreconfigitem(
291 b'command-templates',
291 b'command-templates',
292 b'log',
292 b'log',
293 default=None,
293 default=None,
294 alias=[(b'ui', b'logtemplate')],
294 alias=[(b'ui', b'logtemplate')],
295 )
295 )
296 coreconfigitem(
296 coreconfigitem(
297 b'command-templates',
297 b'command-templates',
298 b'mergemarker',
298 b'mergemarker',
299 default=(
299 default=(
300 b'{node|short} '
300 b'{node|short} '
301 b'{ifeq(tags, "tip", "", '
301 b'{ifeq(tags, "tip", "", '
302 b'ifeq(tags, "", "", "{tags} "))}'
302 b'ifeq(tags, "", "", "{tags} "))}'
303 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{if(bookmarks, "{bookmarks} ")}'
304 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'{ifeq(branch, "default", "", "{branch} ")}'
305 b'- {author|user}: {desc|firstline}'
305 b'- {author|user}: {desc|firstline}'
306 ),
306 ),
307 alias=[(b'ui', b'mergemarkertemplate')],
307 alias=[(b'ui', b'mergemarkertemplate')],
308 )
308 )
309 coreconfigitem(
309 coreconfigitem(
310 b'command-templates',
310 b'command-templates',
311 b'pre-merge-tool-output',
311 b'pre-merge-tool-output',
312 default=None,
312 default=None,
313 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 alias=[(b'ui', b'pre-merge-tool-output-template')],
314 )
314 )
315 coreconfigitem(
315 coreconfigitem(
316 b'command-templates',
316 b'command-templates',
317 b'oneline-summary',
317 b'oneline-summary',
318 default=None,
318 default=None,
319 )
319 )
320 coreconfigitem(
320 coreconfigitem(
321 b'command-templates',
321 b'command-templates',
322 b'oneline-summary.*',
322 b'oneline-summary.*',
323 default=dynamicdefault,
323 default=dynamicdefault,
324 generic=True,
324 generic=True,
325 )
325 )
326 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
327 coreconfigitem(
327 coreconfigitem(
328 b'commands',
328 b'commands',
329 b'commit.post-status',
329 b'commit.post-status',
330 default=False,
330 default=False,
331 )
331 )
332 coreconfigitem(
332 coreconfigitem(
333 b'commands',
333 b'commands',
334 b'grep.all-files',
334 b'grep.all-files',
335 default=False,
335 default=False,
336 experimental=True,
336 experimental=True,
337 )
337 )
338 coreconfigitem(
338 coreconfigitem(
339 b'commands',
339 b'commands',
340 b'merge.require-rev',
340 b'merge.require-rev',
341 default=False,
341 default=False,
342 )
342 )
343 coreconfigitem(
343 coreconfigitem(
344 b'commands',
344 b'commands',
345 b'push.require-revs',
345 b'push.require-revs',
346 default=False,
346 default=False,
347 )
347 )
348 coreconfigitem(
348 coreconfigitem(
349 b'commands',
349 b'commands',
350 b'resolve.confirm',
350 b'resolve.confirm',
351 default=False,
351 default=False,
352 )
352 )
353 coreconfigitem(
353 coreconfigitem(
354 b'commands',
354 b'commands',
355 b'resolve.explicit-re-merge',
355 b'resolve.explicit-re-merge',
356 default=False,
356 default=False,
357 )
357 )
358 coreconfigitem(
358 coreconfigitem(
359 b'commands',
359 b'commands',
360 b'resolve.mark-check',
360 b'resolve.mark-check',
361 default=b'none',
361 default=b'none',
362 )
362 )
363 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
364 coreconfigitem(
364 coreconfigitem(
365 b'commands',
365 b'commands',
366 b'show.aliasprefix',
366 b'show.aliasprefix',
367 default=list,
367 default=list,
368 )
368 )
369 coreconfigitem(
369 coreconfigitem(
370 b'commands',
370 b'commands',
371 b'status.relative',
371 b'status.relative',
372 default=False,
372 default=False,
373 )
373 )
374 coreconfigitem(
374 coreconfigitem(
375 b'commands',
375 b'commands',
376 b'status.skipstates',
376 b'status.skipstates',
377 default=[],
377 default=[],
378 experimental=True,
378 experimental=True,
379 )
379 )
380 coreconfigitem(
380 coreconfigitem(
381 b'commands',
381 b'commands',
382 b'status.terse',
382 b'status.terse',
383 default=b'',
383 default=b'',
384 )
384 )
385 coreconfigitem(
385 coreconfigitem(
386 b'commands',
386 b'commands',
387 b'status.verbose',
387 b'status.verbose',
388 default=False,
388 default=False,
389 )
389 )
390 coreconfigitem(
390 coreconfigitem(
391 b'commands',
391 b'commands',
392 b'update.check',
392 b'update.check',
393 default=None,
393 default=None,
394 )
394 )
395 coreconfigitem(
395 coreconfigitem(
396 b'commands',
396 b'commands',
397 b'update.requiredest',
397 b'update.requiredest',
398 default=False,
398 default=False,
399 )
399 )
400 coreconfigitem(
400 coreconfigitem(
401 b'committemplate',
401 b'committemplate',
402 b'.*',
402 b'.*',
403 default=None,
403 default=None,
404 generic=True,
404 generic=True,
405 )
405 )
406 coreconfigitem(
406 coreconfigitem(
407 b'convert',
407 b'convert',
408 b'bzr.saverev',
408 b'bzr.saverev',
409 default=True,
409 default=True,
410 )
410 )
411 coreconfigitem(
411 coreconfigitem(
412 b'convert',
412 b'convert',
413 b'cvsps.cache',
413 b'cvsps.cache',
414 default=True,
414 default=True,
415 )
415 )
416 coreconfigitem(
416 coreconfigitem(
417 b'convert',
417 b'convert',
418 b'cvsps.fuzz',
418 b'cvsps.fuzz',
419 default=60,
419 default=60,
420 )
420 )
421 coreconfigitem(
421 coreconfigitem(
422 b'convert',
422 b'convert',
423 b'cvsps.logencoding',
423 b'cvsps.logencoding',
424 default=None,
424 default=None,
425 )
425 )
426 coreconfigitem(
426 coreconfigitem(
427 b'convert',
427 b'convert',
428 b'cvsps.mergefrom',
428 b'cvsps.mergefrom',
429 default=None,
429 default=None,
430 )
430 )
431 coreconfigitem(
431 coreconfigitem(
432 b'convert',
432 b'convert',
433 b'cvsps.mergeto',
433 b'cvsps.mergeto',
434 default=None,
434 default=None,
435 )
435 )
436 coreconfigitem(
436 coreconfigitem(
437 b'convert',
437 b'convert',
438 b'git.committeractions',
438 b'git.committeractions',
439 default=lambda: [b'messagedifferent'],
439 default=lambda: [b'messagedifferent'],
440 )
440 )
441 coreconfigitem(
441 coreconfigitem(
442 b'convert',
442 b'convert',
443 b'git.extrakeys',
443 b'git.extrakeys',
444 default=list,
444 default=list,
445 )
445 )
446 coreconfigitem(
446 coreconfigitem(
447 b'convert',
447 b'convert',
448 b'git.findcopiesharder',
448 b'git.findcopiesharder',
449 default=False,
449 default=False,
450 )
450 )
451 coreconfigitem(
451 coreconfigitem(
452 b'convert',
452 b'convert',
453 b'git.remoteprefix',
453 b'git.remoteprefix',
454 default=b'remote',
454 default=b'remote',
455 )
455 )
456 coreconfigitem(
456 coreconfigitem(
457 b'convert',
457 b'convert',
458 b'git.renamelimit',
458 b'git.renamelimit',
459 default=400,
459 default=400,
460 )
460 )
461 coreconfigitem(
461 coreconfigitem(
462 b'convert',
462 b'convert',
463 b'git.saverev',
463 b'git.saverev',
464 default=True,
464 default=True,
465 )
465 )
466 coreconfigitem(
466 coreconfigitem(
467 b'convert',
467 b'convert',
468 b'git.similarity',
468 b'git.similarity',
469 default=50,
469 default=50,
470 )
470 )
471 coreconfigitem(
471 coreconfigitem(
472 b'convert',
472 b'convert',
473 b'git.skipsubmodules',
473 b'git.skipsubmodules',
474 default=False,
474 default=False,
475 )
475 )
476 coreconfigitem(
476 coreconfigitem(
477 b'convert',
477 b'convert',
478 b'hg.clonebranches',
478 b'hg.clonebranches',
479 default=False,
479 default=False,
480 )
480 )
481 coreconfigitem(
481 coreconfigitem(
482 b'convert',
482 b'convert',
483 b'hg.ignoreerrors',
483 b'hg.ignoreerrors',
484 default=False,
484 default=False,
485 )
485 )
486 coreconfigitem(
486 coreconfigitem(
487 b'convert',
487 b'convert',
488 b'hg.preserve-hash',
488 b'hg.preserve-hash',
489 default=False,
489 default=False,
490 )
490 )
491 coreconfigitem(
491 coreconfigitem(
492 b'convert',
492 b'convert',
493 b'hg.revs',
493 b'hg.revs',
494 default=None,
494 default=None,
495 )
495 )
496 coreconfigitem(
496 coreconfigitem(
497 b'convert',
497 b'convert',
498 b'hg.saverev',
498 b'hg.saverev',
499 default=False,
499 default=False,
500 )
500 )
501 coreconfigitem(
501 coreconfigitem(
502 b'convert',
502 b'convert',
503 b'hg.sourcename',
503 b'hg.sourcename',
504 default=None,
504 default=None,
505 )
505 )
506 coreconfigitem(
506 coreconfigitem(
507 b'convert',
507 b'convert',
508 b'hg.startrev',
508 b'hg.startrev',
509 default=None,
509 default=None,
510 )
510 )
511 coreconfigitem(
511 coreconfigitem(
512 b'convert',
512 b'convert',
513 b'hg.tagsbranch',
513 b'hg.tagsbranch',
514 default=b'default',
514 default=b'default',
515 )
515 )
516 coreconfigitem(
516 coreconfigitem(
517 b'convert',
517 b'convert',
518 b'hg.usebranchnames',
518 b'hg.usebranchnames',
519 default=True,
519 default=True,
520 )
520 )
521 coreconfigitem(
521 coreconfigitem(
522 b'convert',
522 b'convert',
523 b'ignoreancestorcheck',
523 b'ignoreancestorcheck',
524 default=False,
524 default=False,
525 experimental=True,
525 experimental=True,
526 )
526 )
527 coreconfigitem(
527 coreconfigitem(
528 b'convert',
528 b'convert',
529 b'localtimezone',
529 b'localtimezone',
530 default=False,
530 default=False,
531 )
531 )
532 coreconfigitem(
532 coreconfigitem(
533 b'convert',
533 b'convert',
534 b'p4.encoding',
534 b'p4.encoding',
535 default=dynamicdefault,
535 default=dynamicdefault,
536 )
536 )
537 coreconfigitem(
537 coreconfigitem(
538 b'convert',
538 b'convert',
539 b'p4.startrev',
539 b'p4.startrev',
540 default=0,
540 default=0,
541 )
541 )
542 coreconfigitem(
542 coreconfigitem(
543 b'convert',
543 b'convert',
544 b'skiptags',
544 b'skiptags',
545 default=False,
545 default=False,
546 )
546 )
547 coreconfigitem(
547 coreconfigitem(
548 b'convert',
548 b'convert',
549 b'svn.debugsvnlog',
549 b'svn.debugsvnlog',
550 default=True,
550 default=True,
551 )
551 )
552 coreconfigitem(
552 coreconfigitem(
553 b'convert',
553 b'convert',
554 b'svn.trunk',
554 b'svn.trunk',
555 default=None,
555 default=None,
556 )
556 )
557 coreconfigitem(
557 coreconfigitem(
558 b'convert',
558 b'convert',
559 b'svn.tags',
559 b'svn.tags',
560 default=None,
560 default=None,
561 )
561 )
562 coreconfigitem(
562 coreconfigitem(
563 b'convert',
563 b'convert',
564 b'svn.branches',
564 b'svn.branches',
565 default=None,
565 default=None,
566 )
566 )
567 coreconfigitem(
567 coreconfigitem(
568 b'convert',
568 b'convert',
569 b'svn.startrev',
569 b'svn.startrev',
570 default=0,
570 default=0,
571 )
571 )
572 coreconfigitem(
572 coreconfigitem(
573 b'convert',
573 b'convert',
574 b'svn.dangerous-set-commit-dates',
574 b'svn.dangerous-set-commit-dates',
575 default=False,
575 default=False,
576 )
576 )
577 coreconfigitem(
577 coreconfigitem(
578 b'debug',
578 b'debug',
579 b'dirstate.delaywrite',
579 b'dirstate.delaywrite',
580 default=0,
580 default=0,
581 )
581 )
582 coreconfigitem(
582 coreconfigitem(
583 b'defaults',
583 b'defaults',
584 b'.*',
584 b'.*',
585 default=None,
585 default=None,
586 generic=True,
586 generic=True,
587 )
587 )
588 coreconfigitem(
588 coreconfigitem(
589 b'devel',
589 b'devel',
590 b'all-warnings',
590 b'all-warnings',
591 default=False,
591 default=False,
592 )
592 )
593 coreconfigitem(
593 coreconfigitem(
594 b'devel',
594 b'devel',
595 b'bundle2.debug',
595 b'bundle2.debug',
596 default=False,
596 default=False,
597 )
597 )
598 coreconfigitem(
598 coreconfigitem(
599 b'devel',
599 b'devel',
600 b'bundle.delta',
600 b'bundle.delta',
601 default=b'',
601 default=b'',
602 )
602 )
603 coreconfigitem(
603 coreconfigitem(
604 b'devel',
604 b'devel',
605 b'cache-vfs',
605 b'cache-vfs',
606 default=None,
606 default=None,
607 )
607 )
608 coreconfigitem(
608 coreconfigitem(
609 b'devel',
609 b'devel',
610 b'check-locks',
610 b'check-locks',
611 default=False,
611 default=False,
612 )
612 )
613 coreconfigitem(
613 coreconfigitem(
614 b'devel',
614 b'devel',
615 b'check-relroot',
615 b'check-relroot',
616 default=False,
616 default=False,
617 )
617 )
618 # Track copy information for all file, not just "added" one (very slow)
619 coreconfigitem(
620 b'devel',
621 b'copy-tracing.trace-all-files',
622 default=False,
623 )
618 coreconfigitem(
624 coreconfigitem(
619 b'devel',
625 b'devel',
620 b'default-date',
626 b'default-date',
621 default=None,
627 default=None,
622 )
628 )
623 coreconfigitem(
629 coreconfigitem(
624 b'devel',
630 b'devel',
625 b'deprec-warn',
631 b'deprec-warn',
626 default=False,
632 default=False,
627 )
633 )
628 coreconfigitem(
634 coreconfigitem(
629 b'devel',
635 b'devel',
630 b'disableloaddefaultcerts',
636 b'disableloaddefaultcerts',
631 default=False,
637 default=False,
632 )
638 )
633 coreconfigitem(
639 coreconfigitem(
634 b'devel',
640 b'devel',
635 b'warn-empty-changegroup',
641 b'warn-empty-changegroup',
636 default=False,
642 default=False,
637 )
643 )
638 coreconfigitem(
644 coreconfigitem(
639 b'devel',
645 b'devel',
640 b'legacy.exchange',
646 b'legacy.exchange',
641 default=list,
647 default=list,
642 )
648 )
643 # When True, revlogs use a special reference version of the nodemap, that is not
649 # When True, revlogs use a special reference version of the nodemap, that is not
644 # performant but is "known" to behave properly.
650 # performant but is "known" to behave properly.
645 coreconfigitem(
651 coreconfigitem(
646 b'devel',
652 b'devel',
647 b'persistent-nodemap',
653 b'persistent-nodemap',
648 default=False,
654 default=False,
649 )
655 )
650 coreconfigitem(
656 coreconfigitem(
651 b'devel',
657 b'devel',
652 b'servercafile',
658 b'servercafile',
653 default=b'',
659 default=b'',
654 )
660 )
655 coreconfigitem(
661 coreconfigitem(
656 b'devel',
662 b'devel',
657 b'serverexactprotocol',
663 b'serverexactprotocol',
658 default=b'',
664 default=b'',
659 )
665 )
660 coreconfigitem(
666 coreconfigitem(
661 b'devel',
667 b'devel',
662 b'serverrequirecert',
668 b'serverrequirecert',
663 default=False,
669 default=False,
664 )
670 )
665 coreconfigitem(
671 coreconfigitem(
666 b'devel',
672 b'devel',
667 b'strip-obsmarkers',
673 b'strip-obsmarkers',
668 default=True,
674 default=True,
669 )
675 )
670 coreconfigitem(
676 coreconfigitem(
671 b'devel',
677 b'devel',
672 b'warn-config',
678 b'warn-config',
673 default=None,
679 default=None,
674 )
680 )
675 coreconfigitem(
681 coreconfigitem(
676 b'devel',
682 b'devel',
677 b'warn-config-default',
683 b'warn-config-default',
678 default=None,
684 default=None,
679 )
685 )
680 coreconfigitem(
686 coreconfigitem(
681 b'devel',
687 b'devel',
682 b'user.obsmarker',
688 b'user.obsmarker',
683 default=None,
689 default=None,
684 )
690 )
685 coreconfigitem(
691 coreconfigitem(
686 b'devel',
692 b'devel',
687 b'warn-config-unknown',
693 b'warn-config-unknown',
688 default=None,
694 default=None,
689 )
695 )
690 coreconfigitem(
696 coreconfigitem(
691 b'devel',
697 b'devel',
692 b'debug.copies',
698 b'debug.copies',
693 default=False,
699 default=False,
694 )
700 )
695 coreconfigitem(
701 coreconfigitem(
696 b'devel',
702 b'devel',
697 b'debug.extensions',
703 b'debug.extensions',
698 default=False,
704 default=False,
699 )
705 )
700 coreconfigitem(
706 coreconfigitem(
701 b'devel',
707 b'devel',
702 b'debug.repo-filters',
708 b'debug.repo-filters',
703 default=False,
709 default=False,
704 )
710 )
705 coreconfigitem(
711 coreconfigitem(
706 b'devel',
712 b'devel',
707 b'debug.peer-request',
713 b'debug.peer-request',
708 default=False,
714 default=False,
709 )
715 )
710 # If discovery.exchange-heads is False, the discovery will not start with
716 # If discovery.exchange-heads is False, the discovery will not start with
711 # remote head fetching and local head querying.
717 # remote head fetching and local head querying.
712 coreconfigitem(
718 coreconfigitem(
713 b'devel',
719 b'devel',
714 b'discovery.exchange-heads',
720 b'discovery.exchange-heads',
715 default=True,
721 default=True,
716 )
722 )
717 # If discovery.grow-sample is False, the sample size used in set discovery will
723 # If discovery.grow-sample is False, the sample size used in set discovery will
718 # not be increased through the process
724 # not be increased through the process
719 coreconfigitem(
725 coreconfigitem(
720 b'devel',
726 b'devel',
721 b'discovery.grow-sample',
727 b'discovery.grow-sample',
722 default=True,
728 default=True,
723 )
729 )
724 # discovery.grow-sample.rate control the rate at which the sample grow
730 # discovery.grow-sample.rate control the rate at which the sample grow
725 coreconfigitem(
731 coreconfigitem(
726 b'devel',
732 b'devel',
727 b'discovery.grow-sample.rate',
733 b'discovery.grow-sample.rate',
728 default=1.05,
734 default=1.05,
729 )
735 )
730 # If discovery.randomize is False, random sampling during discovery are
736 # If discovery.randomize is False, random sampling during discovery are
731 # deterministic. It is meant for integration tests.
737 # deterministic. It is meant for integration tests.
732 coreconfigitem(
738 coreconfigitem(
733 b'devel',
739 b'devel',
734 b'discovery.randomize',
740 b'discovery.randomize',
735 default=True,
741 default=True,
736 )
742 )
737 # Control the initial size of the discovery sample
743 # Control the initial size of the discovery sample
738 coreconfigitem(
744 coreconfigitem(
739 b'devel',
745 b'devel',
740 b'discovery.sample-size',
746 b'discovery.sample-size',
741 default=200,
747 default=200,
742 )
748 )
743 # Control the initial size of the discovery for initial change
749 # Control the initial size of the discovery for initial change
744 coreconfigitem(
750 coreconfigitem(
745 b'devel',
751 b'devel',
746 b'discovery.sample-size.initial',
752 b'discovery.sample-size.initial',
747 default=100,
753 default=100,
748 )
754 )
749 _registerdiffopts(section=b'diff')
755 _registerdiffopts(section=b'diff')
750 coreconfigitem(
756 coreconfigitem(
751 b'email',
757 b'email',
752 b'bcc',
758 b'bcc',
753 default=None,
759 default=None,
754 )
760 )
755 coreconfigitem(
761 coreconfigitem(
756 b'email',
762 b'email',
757 b'cc',
763 b'cc',
758 default=None,
764 default=None,
759 )
765 )
760 coreconfigitem(
766 coreconfigitem(
761 b'email',
767 b'email',
762 b'charsets',
768 b'charsets',
763 default=list,
769 default=list,
764 )
770 )
765 coreconfigitem(
771 coreconfigitem(
766 b'email',
772 b'email',
767 b'from',
773 b'from',
768 default=None,
774 default=None,
769 )
775 )
770 coreconfigitem(
776 coreconfigitem(
771 b'email',
777 b'email',
772 b'method',
778 b'method',
773 default=b'smtp',
779 default=b'smtp',
774 )
780 )
775 coreconfigitem(
781 coreconfigitem(
776 b'email',
782 b'email',
777 b'reply-to',
783 b'reply-to',
778 default=None,
784 default=None,
779 )
785 )
780 coreconfigitem(
786 coreconfigitem(
781 b'email',
787 b'email',
782 b'to',
788 b'to',
783 default=None,
789 default=None,
784 )
790 )
785 coreconfigitem(
791 coreconfigitem(
786 b'experimental',
792 b'experimental',
787 b'archivemetatemplate',
793 b'archivemetatemplate',
788 default=dynamicdefault,
794 default=dynamicdefault,
789 )
795 )
790 coreconfigitem(
796 coreconfigitem(
791 b'experimental',
797 b'experimental',
792 b'auto-publish',
798 b'auto-publish',
793 default=b'publish',
799 default=b'publish',
794 )
800 )
795 coreconfigitem(
801 coreconfigitem(
796 b'experimental',
802 b'experimental',
797 b'bundle-phases',
803 b'bundle-phases',
798 default=False,
804 default=False,
799 )
805 )
800 coreconfigitem(
806 coreconfigitem(
801 b'experimental',
807 b'experimental',
802 b'bundle2-advertise',
808 b'bundle2-advertise',
803 default=True,
809 default=True,
804 )
810 )
805 coreconfigitem(
811 coreconfigitem(
806 b'experimental',
812 b'experimental',
807 b'bundle2-output-capture',
813 b'bundle2-output-capture',
808 default=False,
814 default=False,
809 )
815 )
810 coreconfigitem(
816 coreconfigitem(
811 b'experimental',
817 b'experimental',
812 b'bundle2.pushback',
818 b'bundle2.pushback',
813 default=False,
819 default=False,
814 )
820 )
815 coreconfigitem(
821 coreconfigitem(
816 b'experimental',
822 b'experimental',
817 b'bundle2lazylocking',
823 b'bundle2lazylocking',
818 default=False,
824 default=False,
819 )
825 )
820 coreconfigitem(
826 coreconfigitem(
821 b'experimental',
827 b'experimental',
822 b'bundlecomplevel',
828 b'bundlecomplevel',
823 default=None,
829 default=None,
824 )
830 )
825 coreconfigitem(
831 coreconfigitem(
826 b'experimental',
832 b'experimental',
827 b'bundlecomplevel.bzip2',
833 b'bundlecomplevel.bzip2',
828 default=None,
834 default=None,
829 )
835 )
830 coreconfigitem(
836 coreconfigitem(
831 b'experimental',
837 b'experimental',
832 b'bundlecomplevel.gzip',
838 b'bundlecomplevel.gzip',
833 default=None,
839 default=None,
834 )
840 )
835 coreconfigitem(
841 coreconfigitem(
836 b'experimental',
842 b'experimental',
837 b'bundlecomplevel.none',
843 b'bundlecomplevel.none',
838 default=None,
844 default=None,
839 )
845 )
840 coreconfigitem(
846 coreconfigitem(
841 b'experimental',
847 b'experimental',
842 b'bundlecomplevel.zstd',
848 b'bundlecomplevel.zstd',
843 default=None,
849 default=None,
844 )
850 )
845 coreconfigitem(
851 coreconfigitem(
846 b'experimental',
852 b'experimental',
847 b'changegroup3',
853 b'changegroup3',
848 default=False,
854 default=False,
849 )
855 )
850 coreconfigitem(
856 coreconfigitem(
851 b'experimental',
857 b'experimental',
852 b'cleanup-as-archived',
858 b'cleanup-as-archived',
853 default=False,
859 default=False,
854 )
860 )
855 coreconfigitem(
861 coreconfigitem(
856 b'experimental',
862 b'experimental',
857 b'clientcompressionengines',
863 b'clientcompressionengines',
858 default=list,
864 default=list,
859 )
865 )
860 coreconfigitem(
866 coreconfigitem(
861 b'experimental',
867 b'experimental',
862 b'copytrace',
868 b'copytrace',
863 default=b'on',
869 default=b'on',
864 )
870 )
865 coreconfigitem(
871 coreconfigitem(
866 b'experimental',
872 b'experimental',
867 b'copytrace.movecandidateslimit',
873 b'copytrace.movecandidateslimit',
868 default=100,
874 default=100,
869 )
875 )
870 coreconfigitem(
876 coreconfigitem(
871 b'experimental',
877 b'experimental',
872 b'copytrace.sourcecommitlimit',
878 b'copytrace.sourcecommitlimit',
873 default=100,
879 default=100,
874 )
880 )
875 coreconfigitem(
881 coreconfigitem(
876 b'experimental',
882 b'experimental',
877 b'copies.read-from',
883 b'copies.read-from',
878 default=b"filelog-only",
884 default=b"filelog-only",
879 )
885 )
880 coreconfigitem(
886 coreconfigitem(
881 b'experimental',
887 b'experimental',
882 b'copies.write-to',
888 b'copies.write-to',
883 default=b'filelog-only',
889 default=b'filelog-only',
884 )
890 )
885 coreconfigitem(
891 coreconfigitem(
886 b'experimental',
892 b'experimental',
887 b'crecordtest',
893 b'crecordtest',
888 default=None,
894 default=None,
889 )
895 )
890 coreconfigitem(
896 coreconfigitem(
891 b'experimental',
897 b'experimental',
892 b'directaccess',
898 b'directaccess',
893 default=False,
899 default=False,
894 )
900 )
895 coreconfigitem(
901 coreconfigitem(
896 b'experimental',
902 b'experimental',
897 b'directaccess.revnums',
903 b'directaccess.revnums',
898 default=False,
904 default=False,
899 )
905 )
900 coreconfigitem(
906 coreconfigitem(
901 b'experimental',
907 b'experimental',
902 b'editortmpinhg',
908 b'editortmpinhg',
903 default=False,
909 default=False,
904 )
910 )
905 coreconfigitem(
911 coreconfigitem(
906 b'experimental',
912 b'experimental',
907 b'evolution',
913 b'evolution',
908 default=list,
914 default=list,
909 )
915 )
910 coreconfigitem(
916 coreconfigitem(
911 b'experimental',
917 b'experimental',
912 b'evolution.allowdivergence',
918 b'evolution.allowdivergence',
913 default=False,
919 default=False,
914 alias=[(b'experimental', b'allowdivergence')],
920 alias=[(b'experimental', b'allowdivergence')],
915 )
921 )
916 coreconfigitem(
922 coreconfigitem(
917 b'experimental',
923 b'experimental',
918 b'evolution.allowunstable',
924 b'evolution.allowunstable',
919 default=None,
925 default=None,
920 )
926 )
921 coreconfigitem(
927 coreconfigitem(
922 b'experimental',
928 b'experimental',
923 b'evolution.createmarkers',
929 b'evolution.createmarkers',
924 default=None,
930 default=None,
925 )
931 )
926 coreconfigitem(
932 coreconfigitem(
927 b'experimental',
933 b'experimental',
928 b'evolution.effect-flags',
934 b'evolution.effect-flags',
929 default=True,
935 default=True,
930 alias=[(b'experimental', b'effect-flags')],
936 alias=[(b'experimental', b'effect-flags')],
931 )
937 )
932 coreconfigitem(
938 coreconfigitem(
933 b'experimental',
939 b'experimental',
934 b'evolution.exchange',
940 b'evolution.exchange',
935 default=None,
941 default=None,
936 )
942 )
937 coreconfigitem(
943 coreconfigitem(
938 b'experimental',
944 b'experimental',
939 b'evolution.bundle-obsmarker',
945 b'evolution.bundle-obsmarker',
940 default=False,
946 default=False,
941 )
947 )
942 coreconfigitem(
948 coreconfigitem(
943 b'experimental',
949 b'experimental',
944 b'evolution.bundle-obsmarker:mandatory',
950 b'evolution.bundle-obsmarker:mandatory',
945 default=True,
951 default=True,
946 )
952 )
947 coreconfigitem(
953 coreconfigitem(
948 b'experimental',
954 b'experimental',
949 b'log.topo',
955 b'log.topo',
950 default=False,
956 default=False,
951 )
957 )
952 coreconfigitem(
958 coreconfigitem(
953 b'experimental',
959 b'experimental',
954 b'evolution.report-instabilities',
960 b'evolution.report-instabilities',
955 default=True,
961 default=True,
956 )
962 )
957 coreconfigitem(
963 coreconfigitem(
958 b'experimental',
964 b'experimental',
959 b'evolution.track-operation',
965 b'evolution.track-operation',
960 default=True,
966 default=True,
961 )
967 )
962 # repo-level config to exclude a revset visibility
968 # repo-level config to exclude a revset visibility
963 #
969 #
964 # The target use case is to use `share` to expose different subset of the same
970 # The target use case is to use `share` to expose different subset of the same
965 # repository, especially server side. See also `server.view`.
971 # repository, especially server side. See also `server.view`.
966 coreconfigitem(
972 coreconfigitem(
967 b'experimental',
973 b'experimental',
968 b'extra-filter-revs',
974 b'extra-filter-revs',
969 default=None,
975 default=None,
970 )
976 )
971 coreconfigitem(
977 coreconfigitem(
972 b'experimental',
978 b'experimental',
973 b'maxdeltachainspan',
979 b'maxdeltachainspan',
974 default=-1,
980 default=-1,
975 )
981 )
976 # tracks files which were undeleted (merge might delete them but we explicitly
982 # tracks files which were undeleted (merge might delete them but we explicitly
977 # kept/undeleted them) and creates new filenodes for them
983 # kept/undeleted them) and creates new filenodes for them
978 coreconfigitem(
984 coreconfigitem(
979 b'experimental',
985 b'experimental',
980 b'merge-track-salvaged',
986 b'merge-track-salvaged',
981 default=False,
987 default=False,
982 )
988 )
983 coreconfigitem(
989 coreconfigitem(
984 b'experimental',
990 b'experimental',
985 b'mergetempdirprefix',
991 b'mergetempdirprefix',
986 default=None,
992 default=None,
987 )
993 )
988 coreconfigitem(
994 coreconfigitem(
989 b'experimental',
995 b'experimental',
990 b'mmapindexthreshold',
996 b'mmapindexthreshold',
991 default=None,
997 default=None,
992 )
998 )
993 coreconfigitem(
999 coreconfigitem(
994 b'experimental',
1000 b'experimental',
995 b'narrow',
1001 b'narrow',
996 default=False,
1002 default=False,
997 )
1003 )
998 coreconfigitem(
1004 coreconfigitem(
999 b'experimental',
1005 b'experimental',
1000 b'nonnormalparanoidcheck',
1006 b'nonnormalparanoidcheck',
1001 default=False,
1007 default=False,
1002 )
1008 )
1003 coreconfigitem(
1009 coreconfigitem(
1004 b'experimental',
1010 b'experimental',
1005 b'exportableenviron',
1011 b'exportableenviron',
1006 default=list,
1012 default=list,
1007 )
1013 )
1008 coreconfigitem(
1014 coreconfigitem(
1009 b'experimental',
1015 b'experimental',
1010 b'extendedheader.index',
1016 b'extendedheader.index',
1011 default=None,
1017 default=None,
1012 )
1018 )
1013 coreconfigitem(
1019 coreconfigitem(
1014 b'experimental',
1020 b'experimental',
1015 b'extendedheader.similarity',
1021 b'extendedheader.similarity',
1016 default=False,
1022 default=False,
1017 )
1023 )
1018 coreconfigitem(
1024 coreconfigitem(
1019 b'experimental',
1025 b'experimental',
1020 b'graphshorten',
1026 b'graphshorten',
1021 default=False,
1027 default=False,
1022 )
1028 )
1023 coreconfigitem(
1029 coreconfigitem(
1024 b'experimental',
1030 b'experimental',
1025 b'graphstyle.parent',
1031 b'graphstyle.parent',
1026 default=dynamicdefault,
1032 default=dynamicdefault,
1027 )
1033 )
1028 coreconfigitem(
1034 coreconfigitem(
1029 b'experimental',
1035 b'experimental',
1030 b'graphstyle.missing',
1036 b'graphstyle.missing',
1031 default=dynamicdefault,
1037 default=dynamicdefault,
1032 )
1038 )
1033 coreconfigitem(
1039 coreconfigitem(
1034 b'experimental',
1040 b'experimental',
1035 b'graphstyle.grandparent',
1041 b'graphstyle.grandparent',
1036 default=dynamicdefault,
1042 default=dynamicdefault,
1037 )
1043 )
1038 coreconfigitem(
1044 coreconfigitem(
1039 b'experimental',
1045 b'experimental',
1040 b'hook-track-tags',
1046 b'hook-track-tags',
1041 default=False,
1047 default=False,
1042 )
1048 )
1043 coreconfigitem(
1049 coreconfigitem(
1044 b'experimental',
1050 b'experimental',
1045 b'httppeer.advertise-v2',
1051 b'httppeer.advertise-v2',
1046 default=False,
1052 default=False,
1047 )
1053 )
1048 coreconfigitem(
1054 coreconfigitem(
1049 b'experimental',
1055 b'experimental',
1050 b'httppeer.v2-encoder-order',
1056 b'httppeer.v2-encoder-order',
1051 default=None,
1057 default=None,
1052 )
1058 )
1053 coreconfigitem(
1059 coreconfigitem(
1054 b'experimental',
1060 b'experimental',
1055 b'httppostargs',
1061 b'httppostargs',
1056 default=False,
1062 default=False,
1057 )
1063 )
1058 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1064 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1059 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1065 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1060
1066
1061 coreconfigitem(
1067 coreconfigitem(
1062 b'experimental',
1068 b'experimental',
1063 b'obsmarkers-exchange-debug',
1069 b'obsmarkers-exchange-debug',
1064 default=False,
1070 default=False,
1065 )
1071 )
1066 coreconfigitem(
1072 coreconfigitem(
1067 b'experimental',
1073 b'experimental',
1068 b'remotenames',
1074 b'remotenames',
1069 default=False,
1075 default=False,
1070 )
1076 )
1071 coreconfigitem(
1077 coreconfigitem(
1072 b'experimental',
1078 b'experimental',
1073 b'removeemptydirs',
1079 b'removeemptydirs',
1074 default=True,
1080 default=True,
1075 )
1081 )
1076 coreconfigitem(
1082 coreconfigitem(
1077 b'experimental',
1083 b'experimental',
1078 b'revert.interactive.select-to-keep',
1084 b'revert.interactive.select-to-keep',
1079 default=False,
1085 default=False,
1080 )
1086 )
1081 coreconfigitem(
1087 coreconfigitem(
1082 b'experimental',
1088 b'experimental',
1083 b'revisions.prefixhexnode',
1089 b'revisions.prefixhexnode',
1084 default=False,
1090 default=False,
1085 )
1091 )
1086 coreconfigitem(
1092 coreconfigitem(
1087 b'experimental',
1093 b'experimental',
1088 b'revlogv2',
1094 b'revlogv2',
1089 default=None,
1095 default=None,
1090 )
1096 )
1091 coreconfigitem(
1097 coreconfigitem(
1092 b'experimental',
1098 b'experimental',
1093 b'revisions.disambiguatewithin',
1099 b'revisions.disambiguatewithin',
1094 default=None,
1100 default=None,
1095 )
1101 )
1096 coreconfigitem(
1102 coreconfigitem(
1097 b'experimental',
1103 b'experimental',
1098 b'rust.index',
1104 b'rust.index',
1099 default=False,
1105 default=False,
1100 )
1106 )
1101 coreconfigitem(
1107 coreconfigitem(
1102 b'experimental',
1108 b'experimental',
1103 b'server.filesdata.recommended-batch-size',
1109 b'server.filesdata.recommended-batch-size',
1104 default=50000,
1110 default=50000,
1105 )
1111 )
1106 coreconfigitem(
1112 coreconfigitem(
1107 b'experimental',
1113 b'experimental',
1108 b'server.manifestdata.recommended-batch-size',
1114 b'server.manifestdata.recommended-batch-size',
1109 default=100000,
1115 default=100000,
1110 )
1116 )
1111 coreconfigitem(
1117 coreconfigitem(
1112 b'experimental',
1118 b'experimental',
1113 b'server.stream-narrow-clones',
1119 b'server.stream-narrow-clones',
1114 default=False,
1120 default=False,
1115 )
1121 )
1116 coreconfigitem(
1122 coreconfigitem(
1117 b'experimental',
1123 b'experimental',
1118 b'single-head-per-branch',
1124 b'single-head-per-branch',
1119 default=False,
1125 default=False,
1120 )
1126 )
1121 coreconfigitem(
1127 coreconfigitem(
1122 b'experimental',
1128 b'experimental',
1123 b'single-head-per-branch:account-closed-heads',
1129 b'single-head-per-branch:account-closed-heads',
1124 default=False,
1130 default=False,
1125 )
1131 )
1126 coreconfigitem(
1132 coreconfigitem(
1127 b'experimental',
1133 b'experimental',
1128 b'single-head-per-branch:public-changes-only',
1134 b'single-head-per-branch:public-changes-only',
1129 default=False,
1135 default=False,
1130 )
1136 )
1131 coreconfigitem(
1137 coreconfigitem(
1132 b'experimental',
1138 b'experimental',
1133 b'sshserver.support-v2',
1139 b'sshserver.support-v2',
1134 default=False,
1140 default=False,
1135 )
1141 )
1136 coreconfigitem(
1142 coreconfigitem(
1137 b'experimental',
1143 b'experimental',
1138 b'sparse-read',
1144 b'sparse-read',
1139 default=False,
1145 default=False,
1140 )
1146 )
1141 coreconfigitem(
1147 coreconfigitem(
1142 b'experimental',
1148 b'experimental',
1143 b'sparse-read.density-threshold',
1149 b'sparse-read.density-threshold',
1144 default=0.50,
1150 default=0.50,
1145 )
1151 )
1146 coreconfigitem(
1152 coreconfigitem(
1147 b'experimental',
1153 b'experimental',
1148 b'sparse-read.min-gap-size',
1154 b'sparse-read.min-gap-size',
1149 default=b'65K',
1155 default=b'65K',
1150 )
1156 )
1151 coreconfigitem(
1157 coreconfigitem(
1152 b'experimental',
1158 b'experimental',
1153 b'treemanifest',
1159 b'treemanifest',
1154 default=False,
1160 default=False,
1155 )
1161 )
1156 coreconfigitem(
1162 coreconfigitem(
1157 b'experimental',
1163 b'experimental',
1158 b'update.atomic-file',
1164 b'update.atomic-file',
1159 default=False,
1165 default=False,
1160 )
1166 )
1161 coreconfigitem(
1167 coreconfigitem(
1162 b'experimental',
1168 b'experimental',
1163 b'sshpeer.advertise-v2',
1169 b'sshpeer.advertise-v2',
1164 default=False,
1170 default=False,
1165 )
1171 )
1166 coreconfigitem(
1172 coreconfigitem(
1167 b'experimental',
1173 b'experimental',
1168 b'web.apiserver',
1174 b'web.apiserver',
1169 default=False,
1175 default=False,
1170 )
1176 )
1171 coreconfigitem(
1177 coreconfigitem(
1172 b'experimental',
1178 b'experimental',
1173 b'web.api.http-v2',
1179 b'web.api.http-v2',
1174 default=False,
1180 default=False,
1175 )
1181 )
1176 coreconfigitem(
1182 coreconfigitem(
1177 b'experimental',
1183 b'experimental',
1178 b'web.api.debugreflect',
1184 b'web.api.debugreflect',
1179 default=False,
1185 default=False,
1180 )
1186 )
1181 coreconfigitem(
1187 coreconfigitem(
1182 b'experimental',
1188 b'experimental',
1183 b'worker.wdir-get-thread-safe',
1189 b'worker.wdir-get-thread-safe',
1184 default=False,
1190 default=False,
1185 )
1191 )
1186 coreconfigitem(
1192 coreconfigitem(
1187 b'experimental',
1193 b'experimental',
1188 b'worker.repository-upgrade',
1194 b'worker.repository-upgrade',
1189 default=False,
1195 default=False,
1190 )
1196 )
1191 coreconfigitem(
1197 coreconfigitem(
1192 b'experimental',
1198 b'experimental',
1193 b'xdiff',
1199 b'xdiff',
1194 default=False,
1200 default=False,
1195 )
1201 )
1196 coreconfigitem(
1202 coreconfigitem(
1197 b'extensions',
1203 b'extensions',
1198 b'.*',
1204 b'.*',
1199 default=None,
1205 default=None,
1200 generic=True,
1206 generic=True,
1201 )
1207 )
1202 coreconfigitem(
1208 coreconfigitem(
1203 b'extdata',
1209 b'extdata',
1204 b'.*',
1210 b'.*',
1205 default=None,
1211 default=None,
1206 generic=True,
1212 generic=True,
1207 )
1213 )
1208 coreconfigitem(
1214 coreconfigitem(
1209 b'format',
1215 b'format',
1210 b'bookmarks-in-store',
1216 b'bookmarks-in-store',
1211 default=False,
1217 default=False,
1212 )
1218 )
1213 coreconfigitem(
1219 coreconfigitem(
1214 b'format',
1220 b'format',
1215 b'chunkcachesize',
1221 b'chunkcachesize',
1216 default=None,
1222 default=None,
1217 experimental=True,
1223 experimental=True,
1218 )
1224 )
1219 coreconfigitem(
1225 coreconfigitem(
1220 b'format',
1226 b'format',
1221 b'dotencode',
1227 b'dotencode',
1222 default=True,
1228 default=True,
1223 )
1229 )
1224 coreconfigitem(
1230 coreconfigitem(
1225 b'format',
1231 b'format',
1226 b'generaldelta',
1232 b'generaldelta',
1227 default=False,
1233 default=False,
1228 experimental=True,
1234 experimental=True,
1229 )
1235 )
1230 coreconfigitem(
1236 coreconfigitem(
1231 b'format',
1237 b'format',
1232 b'manifestcachesize',
1238 b'manifestcachesize',
1233 default=None,
1239 default=None,
1234 experimental=True,
1240 experimental=True,
1235 )
1241 )
1236 coreconfigitem(
1242 coreconfigitem(
1237 b'format',
1243 b'format',
1238 b'maxchainlen',
1244 b'maxchainlen',
1239 default=dynamicdefault,
1245 default=dynamicdefault,
1240 experimental=True,
1246 experimental=True,
1241 )
1247 )
1242 coreconfigitem(
1248 coreconfigitem(
1243 b'format',
1249 b'format',
1244 b'obsstore-version',
1250 b'obsstore-version',
1245 default=None,
1251 default=None,
1246 )
1252 )
1247 coreconfigitem(
1253 coreconfigitem(
1248 b'format',
1254 b'format',
1249 b'sparse-revlog',
1255 b'sparse-revlog',
1250 default=True,
1256 default=True,
1251 )
1257 )
1252 coreconfigitem(
1258 coreconfigitem(
1253 b'format',
1259 b'format',
1254 b'revlog-compression',
1260 b'revlog-compression',
1255 default=lambda: [b'zlib'],
1261 default=lambda: [b'zlib'],
1256 alias=[(b'experimental', b'format.compression')],
1262 alias=[(b'experimental', b'format.compression')],
1257 )
1263 )
1258 coreconfigitem(
1264 coreconfigitem(
1259 b'format',
1265 b'format',
1260 b'usefncache',
1266 b'usefncache',
1261 default=True,
1267 default=True,
1262 )
1268 )
1263 coreconfigitem(
1269 coreconfigitem(
1264 b'format',
1270 b'format',
1265 b'usegeneraldelta',
1271 b'usegeneraldelta',
1266 default=True,
1272 default=True,
1267 )
1273 )
1268 coreconfigitem(
1274 coreconfigitem(
1269 b'format',
1275 b'format',
1270 b'usestore',
1276 b'usestore',
1271 default=True,
1277 default=True,
1272 )
1278 )
1273 coreconfigitem(
1279 coreconfigitem(
1274 b'format',
1280 b'format',
1275 b'use-persistent-nodemap',
1281 b'use-persistent-nodemap',
1276 default=False,
1282 default=False,
1277 )
1283 )
1278 coreconfigitem(
1284 coreconfigitem(
1279 b'format',
1285 b'format',
1280 b'exp-use-copies-side-data-changeset',
1286 b'exp-use-copies-side-data-changeset',
1281 default=False,
1287 default=False,
1282 experimental=True,
1288 experimental=True,
1283 )
1289 )
1284 coreconfigitem(
1290 coreconfigitem(
1285 b'format',
1291 b'format',
1286 b'exp-use-side-data',
1292 b'exp-use-side-data',
1287 default=False,
1293 default=False,
1288 experimental=True,
1294 experimental=True,
1289 )
1295 )
1290 coreconfigitem(
1296 coreconfigitem(
1291 b'format',
1297 b'format',
1292 b'use-share-safe',
1298 b'use-share-safe',
1293 default=False,
1299 default=False,
1294 )
1300 )
1295 coreconfigitem(
1301 coreconfigitem(
1296 b'format',
1302 b'format',
1297 b'internal-phase',
1303 b'internal-phase',
1298 default=False,
1304 default=False,
1299 experimental=True,
1305 experimental=True,
1300 )
1306 )
1301 coreconfigitem(
1307 coreconfigitem(
1302 b'fsmonitor',
1308 b'fsmonitor',
1303 b'warn_when_unused',
1309 b'warn_when_unused',
1304 default=True,
1310 default=True,
1305 )
1311 )
1306 coreconfigitem(
1312 coreconfigitem(
1307 b'fsmonitor',
1313 b'fsmonitor',
1308 b'warn_update_file_count',
1314 b'warn_update_file_count',
1309 default=50000,
1315 default=50000,
1310 )
1316 )
1311 coreconfigitem(
1317 coreconfigitem(
1312 b'fsmonitor',
1318 b'fsmonitor',
1313 b'warn_update_file_count_rust',
1319 b'warn_update_file_count_rust',
1314 default=400000,
1320 default=400000,
1315 )
1321 )
1316 coreconfigitem(
1322 coreconfigitem(
1317 b'help',
1323 b'help',
1318 br'hidden-command\..*',
1324 br'hidden-command\..*',
1319 default=False,
1325 default=False,
1320 generic=True,
1326 generic=True,
1321 )
1327 )
1322 coreconfigitem(
1328 coreconfigitem(
1323 b'help',
1329 b'help',
1324 br'hidden-topic\..*',
1330 br'hidden-topic\..*',
1325 default=False,
1331 default=False,
1326 generic=True,
1332 generic=True,
1327 )
1333 )
1328 coreconfigitem(
1334 coreconfigitem(
1329 b'hooks',
1335 b'hooks',
1330 b'.*',
1336 b'.*',
1331 default=dynamicdefault,
1337 default=dynamicdefault,
1332 generic=True,
1338 generic=True,
1333 )
1339 )
1334 coreconfigitem(
1340 coreconfigitem(
1335 b'hgweb-paths',
1341 b'hgweb-paths',
1336 b'.*',
1342 b'.*',
1337 default=list,
1343 default=list,
1338 generic=True,
1344 generic=True,
1339 )
1345 )
1340 coreconfigitem(
1346 coreconfigitem(
1341 b'hostfingerprints',
1347 b'hostfingerprints',
1342 b'.*',
1348 b'.*',
1343 default=list,
1349 default=list,
1344 generic=True,
1350 generic=True,
1345 )
1351 )
1346 coreconfigitem(
1352 coreconfigitem(
1347 b'hostsecurity',
1353 b'hostsecurity',
1348 b'ciphers',
1354 b'ciphers',
1349 default=None,
1355 default=None,
1350 )
1356 )
1351 coreconfigitem(
1357 coreconfigitem(
1352 b'hostsecurity',
1358 b'hostsecurity',
1353 b'minimumprotocol',
1359 b'minimumprotocol',
1354 default=dynamicdefault,
1360 default=dynamicdefault,
1355 )
1361 )
1356 coreconfigitem(
1362 coreconfigitem(
1357 b'hostsecurity',
1363 b'hostsecurity',
1358 b'.*:minimumprotocol$',
1364 b'.*:minimumprotocol$',
1359 default=dynamicdefault,
1365 default=dynamicdefault,
1360 generic=True,
1366 generic=True,
1361 )
1367 )
1362 coreconfigitem(
1368 coreconfigitem(
1363 b'hostsecurity',
1369 b'hostsecurity',
1364 b'.*:ciphers$',
1370 b'.*:ciphers$',
1365 default=dynamicdefault,
1371 default=dynamicdefault,
1366 generic=True,
1372 generic=True,
1367 )
1373 )
1368 coreconfigitem(
1374 coreconfigitem(
1369 b'hostsecurity',
1375 b'hostsecurity',
1370 b'.*:fingerprints$',
1376 b'.*:fingerprints$',
1371 default=list,
1377 default=list,
1372 generic=True,
1378 generic=True,
1373 )
1379 )
1374 coreconfigitem(
1380 coreconfigitem(
1375 b'hostsecurity',
1381 b'hostsecurity',
1376 b'.*:verifycertsfile$',
1382 b'.*:verifycertsfile$',
1377 default=None,
1383 default=None,
1378 generic=True,
1384 generic=True,
1379 )
1385 )
1380
1386
1381 coreconfigitem(
1387 coreconfigitem(
1382 b'http_proxy',
1388 b'http_proxy',
1383 b'always',
1389 b'always',
1384 default=False,
1390 default=False,
1385 )
1391 )
1386 coreconfigitem(
1392 coreconfigitem(
1387 b'http_proxy',
1393 b'http_proxy',
1388 b'host',
1394 b'host',
1389 default=None,
1395 default=None,
1390 )
1396 )
1391 coreconfigitem(
1397 coreconfigitem(
1392 b'http_proxy',
1398 b'http_proxy',
1393 b'no',
1399 b'no',
1394 default=list,
1400 default=list,
1395 )
1401 )
1396 coreconfigitem(
1402 coreconfigitem(
1397 b'http_proxy',
1403 b'http_proxy',
1398 b'passwd',
1404 b'passwd',
1399 default=None,
1405 default=None,
1400 )
1406 )
1401 coreconfigitem(
1407 coreconfigitem(
1402 b'http_proxy',
1408 b'http_proxy',
1403 b'user',
1409 b'user',
1404 default=None,
1410 default=None,
1405 )
1411 )
1406
1412
1407 coreconfigitem(
1413 coreconfigitem(
1408 b'http',
1414 b'http',
1409 b'timeout',
1415 b'timeout',
1410 default=None,
1416 default=None,
1411 )
1417 )
1412
1418
1413 coreconfigitem(
1419 coreconfigitem(
1414 b'logtoprocess',
1420 b'logtoprocess',
1415 b'commandexception',
1421 b'commandexception',
1416 default=None,
1422 default=None,
1417 )
1423 )
1418 coreconfigitem(
1424 coreconfigitem(
1419 b'logtoprocess',
1425 b'logtoprocess',
1420 b'commandfinish',
1426 b'commandfinish',
1421 default=None,
1427 default=None,
1422 )
1428 )
1423 coreconfigitem(
1429 coreconfigitem(
1424 b'logtoprocess',
1430 b'logtoprocess',
1425 b'command',
1431 b'command',
1426 default=None,
1432 default=None,
1427 )
1433 )
1428 coreconfigitem(
1434 coreconfigitem(
1429 b'logtoprocess',
1435 b'logtoprocess',
1430 b'develwarn',
1436 b'develwarn',
1431 default=None,
1437 default=None,
1432 )
1438 )
1433 coreconfigitem(
1439 coreconfigitem(
1434 b'logtoprocess',
1440 b'logtoprocess',
1435 b'uiblocked',
1441 b'uiblocked',
1436 default=None,
1442 default=None,
1437 )
1443 )
1438 coreconfigitem(
1444 coreconfigitem(
1439 b'merge',
1445 b'merge',
1440 b'checkunknown',
1446 b'checkunknown',
1441 default=b'abort',
1447 default=b'abort',
1442 )
1448 )
1443 coreconfigitem(
1449 coreconfigitem(
1444 b'merge',
1450 b'merge',
1445 b'checkignored',
1451 b'checkignored',
1446 default=b'abort',
1452 default=b'abort',
1447 )
1453 )
1448 coreconfigitem(
1454 coreconfigitem(
1449 b'experimental',
1455 b'experimental',
1450 b'merge.checkpathconflicts',
1456 b'merge.checkpathconflicts',
1451 default=False,
1457 default=False,
1452 )
1458 )
1453 coreconfigitem(
1459 coreconfigitem(
1454 b'merge',
1460 b'merge',
1455 b'followcopies',
1461 b'followcopies',
1456 default=True,
1462 default=True,
1457 )
1463 )
1458 coreconfigitem(
1464 coreconfigitem(
1459 b'merge',
1465 b'merge',
1460 b'on-failure',
1466 b'on-failure',
1461 default=b'continue',
1467 default=b'continue',
1462 )
1468 )
1463 coreconfigitem(
1469 coreconfigitem(
1464 b'merge',
1470 b'merge',
1465 b'preferancestor',
1471 b'preferancestor',
1466 default=lambda: [b'*'],
1472 default=lambda: [b'*'],
1467 experimental=True,
1473 experimental=True,
1468 )
1474 )
1469 coreconfigitem(
1475 coreconfigitem(
1470 b'merge',
1476 b'merge',
1471 b'strict-capability-check',
1477 b'strict-capability-check',
1472 default=False,
1478 default=False,
1473 )
1479 )
1474 coreconfigitem(
1480 coreconfigitem(
1475 b'merge-tools',
1481 b'merge-tools',
1476 b'.*',
1482 b'.*',
1477 default=None,
1483 default=None,
1478 generic=True,
1484 generic=True,
1479 )
1485 )
1480 coreconfigitem(
1486 coreconfigitem(
1481 b'merge-tools',
1487 b'merge-tools',
1482 br'.*\.args$',
1488 br'.*\.args$',
1483 default=b"$local $base $other",
1489 default=b"$local $base $other",
1484 generic=True,
1490 generic=True,
1485 priority=-1,
1491 priority=-1,
1486 )
1492 )
1487 coreconfigitem(
1493 coreconfigitem(
1488 b'merge-tools',
1494 b'merge-tools',
1489 br'.*\.binary$',
1495 br'.*\.binary$',
1490 default=False,
1496 default=False,
1491 generic=True,
1497 generic=True,
1492 priority=-1,
1498 priority=-1,
1493 )
1499 )
1494 coreconfigitem(
1500 coreconfigitem(
1495 b'merge-tools',
1501 b'merge-tools',
1496 br'.*\.check$',
1502 br'.*\.check$',
1497 default=list,
1503 default=list,
1498 generic=True,
1504 generic=True,
1499 priority=-1,
1505 priority=-1,
1500 )
1506 )
1501 coreconfigitem(
1507 coreconfigitem(
1502 b'merge-tools',
1508 b'merge-tools',
1503 br'.*\.checkchanged$',
1509 br'.*\.checkchanged$',
1504 default=False,
1510 default=False,
1505 generic=True,
1511 generic=True,
1506 priority=-1,
1512 priority=-1,
1507 )
1513 )
1508 coreconfigitem(
1514 coreconfigitem(
1509 b'merge-tools',
1515 b'merge-tools',
1510 br'.*\.executable$',
1516 br'.*\.executable$',
1511 default=dynamicdefault,
1517 default=dynamicdefault,
1512 generic=True,
1518 generic=True,
1513 priority=-1,
1519 priority=-1,
1514 )
1520 )
1515 coreconfigitem(
1521 coreconfigitem(
1516 b'merge-tools',
1522 b'merge-tools',
1517 br'.*\.fixeol$',
1523 br'.*\.fixeol$',
1518 default=False,
1524 default=False,
1519 generic=True,
1525 generic=True,
1520 priority=-1,
1526 priority=-1,
1521 )
1527 )
1522 coreconfigitem(
1528 coreconfigitem(
1523 b'merge-tools',
1529 b'merge-tools',
1524 br'.*\.gui$',
1530 br'.*\.gui$',
1525 default=False,
1531 default=False,
1526 generic=True,
1532 generic=True,
1527 priority=-1,
1533 priority=-1,
1528 )
1534 )
1529 coreconfigitem(
1535 coreconfigitem(
1530 b'merge-tools',
1536 b'merge-tools',
1531 br'.*\.mergemarkers$',
1537 br'.*\.mergemarkers$',
1532 default=b'basic',
1538 default=b'basic',
1533 generic=True,
1539 generic=True,
1534 priority=-1,
1540 priority=-1,
1535 )
1541 )
1536 coreconfigitem(
1542 coreconfigitem(
1537 b'merge-tools',
1543 b'merge-tools',
1538 br'.*\.mergemarkertemplate$',
1544 br'.*\.mergemarkertemplate$',
1539 default=dynamicdefault, # take from command-templates.mergemarker
1545 default=dynamicdefault, # take from command-templates.mergemarker
1540 generic=True,
1546 generic=True,
1541 priority=-1,
1547 priority=-1,
1542 )
1548 )
1543 coreconfigitem(
1549 coreconfigitem(
1544 b'merge-tools',
1550 b'merge-tools',
1545 br'.*\.priority$',
1551 br'.*\.priority$',
1546 default=0,
1552 default=0,
1547 generic=True,
1553 generic=True,
1548 priority=-1,
1554 priority=-1,
1549 )
1555 )
1550 coreconfigitem(
1556 coreconfigitem(
1551 b'merge-tools',
1557 b'merge-tools',
1552 br'.*\.premerge$',
1558 br'.*\.premerge$',
1553 default=dynamicdefault,
1559 default=dynamicdefault,
1554 generic=True,
1560 generic=True,
1555 priority=-1,
1561 priority=-1,
1556 )
1562 )
1557 coreconfigitem(
1563 coreconfigitem(
1558 b'merge-tools',
1564 b'merge-tools',
1559 br'.*\.symlink$',
1565 br'.*\.symlink$',
1560 default=False,
1566 default=False,
1561 generic=True,
1567 generic=True,
1562 priority=-1,
1568 priority=-1,
1563 )
1569 )
1564 coreconfigitem(
1570 coreconfigitem(
1565 b'pager',
1571 b'pager',
1566 b'attend-.*',
1572 b'attend-.*',
1567 default=dynamicdefault,
1573 default=dynamicdefault,
1568 generic=True,
1574 generic=True,
1569 )
1575 )
1570 coreconfigitem(
1576 coreconfigitem(
1571 b'pager',
1577 b'pager',
1572 b'ignore',
1578 b'ignore',
1573 default=list,
1579 default=list,
1574 )
1580 )
1575 coreconfigitem(
1581 coreconfigitem(
1576 b'pager',
1582 b'pager',
1577 b'pager',
1583 b'pager',
1578 default=dynamicdefault,
1584 default=dynamicdefault,
1579 )
1585 )
1580 coreconfigitem(
1586 coreconfigitem(
1581 b'patch',
1587 b'patch',
1582 b'eol',
1588 b'eol',
1583 default=b'strict',
1589 default=b'strict',
1584 )
1590 )
1585 coreconfigitem(
1591 coreconfigitem(
1586 b'patch',
1592 b'patch',
1587 b'fuzz',
1593 b'fuzz',
1588 default=2,
1594 default=2,
1589 )
1595 )
1590 coreconfigitem(
1596 coreconfigitem(
1591 b'paths',
1597 b'paths',
1592 b'default',
1598 b'default',
1593 default=None,
1599 default=None,
1594 )
1600 )
1595 coreconfigitem(
1601 coreconfigitem(
1596 b'paths',
1602 b'paths',
1597 b'default-push',
1603 b'default-push',
1598 default=None,
1604 default=None,
1599 )
1605 )
1600 coreconfigitem(
1606 coreconfigitem(
1601 b'paths',
1607 b'paths',
1602 b'.*',
1608 b'.*',
1603 default=None,
1609 default=None,
1604 generic=True,
1610 generic=True,
1605 )
1611 )
1606 coreconfigitem(
1612 coreconfigitem(
1607 b'phases',
1613 b'phases',
1608 b'checksubrepos',
1614 b'checksubrepos',
1609 default=b'follow',
1615 default=b'follow',
1610 )
1616 )
1611 coreconfigitem(
1617 coreconfigitem(
1612 b'phases',
1618 b'phases',
1613 b'new-commit',
1619 b'new-commit',
1614 default=b'draft',
1620 default=b'draft',
1615 )
1621 )
1616 coreconfigitem(
1622 coreconfigitem(
1617 b'phases',
1623 b'phases',
1618 b'publish',
1624 b'publish',
1619 default=True,
1625 default=True,
1620 )
1626 )
1621 coreconfigitem(
1627 coreconfigitem(
1622 b'profiling',
1628 b'profiling',
1623 b'enabled',
1629 b'enabled',
1624 default=False,
1630 default=False,
1625 )
1631 )
1626 coreconfigitem(
1632 coreconfigitem(
1627 b'profiling',
1633 b'profiling',
1628 b'format',
1634 b'format',
1629 default=b'text',
1635 default=b'text',
1630 )
1636 )
1631 coreconfigitem(
1637 coreconfigitem(
1632 b'profiling',
1638 b'profiling',
1633 b'freq',
1639 b'freq',
1634 default=1000,
1640 default=1000,
1635 )
1641 )
1636 coreconfigitem(
1642 coreconfigitem(
1637 b'profiling',
1643 b'profiling',
1638 b'limit',
1644 b'limit',
1639 default=30,
1645 default=30,
1640 )
1646 )
1641 coreconfigitem(
1647 coreconfigitem(
1642 b'profiling',
1648 b'profiling',
1643 b'nested',
1649 b'nested',
1644 default=0,
1650 default=0,
1645 )
1651 )
1646 coreconfigitem(
1652 coreconfigitem(
1647 b'profiling',
1653 b'profiling',
1648 b'output',
1654 b'output',
1649 default=None,
1655 default=None,
1650 )
1656 )
1651 coreconfigitem(
1657 coreconfigitem(
1652 b'profiling',
1658 b'profiling',
1653 b'showmax',
1659 b'showmax',
1654 default=0.999,
1660 default=0.999,
1655 )
1661 )
1656 coreconfigitem(
1662 coreconfigitem(
1657 b'profiling',
1663 b'profiling',
1658 b'showmin',
1664 b'showmin',
1659 default=dynamicdefault,
1665 default=dynamicdefault,
1660 )
1666 )
1661 coreconfigitem(
1667 coreconfigitem(
1662 b'profiling',
1668 b'profiling',
1663 b'showtime',
1669 b'showtime',
1664 default=True,
1670 default=True,
1665 )
1671 )
1666 coreconfigitem(
1672 coreconfigitem(
1667 b'profiling',
1673 b'profiling',
1668 b'sort',
1674 b'sort',
1669 default=b'inlinetime',
1675 default=b'inlinetime',
1670 )
1676 )
1671 coreconfigitem(
1677 coreconfigitem(
1672 b'profiling',
1678 b'profiling',
1673 b'statformat',
1679 b'statformat',
1674 default=b'hotpath',
1680 default=b'hotpath',
1675 )
1681 )
1676 coreconfigitem(
1682 coreconfigitem(
1677 b'profiling',
1683 b'profiling',
1678 b'time-track',
1684 b'time-track',
1679 default=dynamicdefault,
1685 default=dynamicdefault,
1680 )
1686 )
1681 coreconfigitem(
1687 coreconfigitem(
1682 b'profiling',
1688 b'profiling',
1683 b'type',
1689 b'type',
1684 default=b'stat',
1690 default=b'stat',
1685 )
1691 )
1686 coreconfigitem(
1692 coreconfigitem(
1687 b'progress',
1693 b'progress',
1688 b'assume-tty',
1694 b'assume-tty',
1689 default=False,
1695 default=False,
1690 )
1696 )
1691 coreconfigitem(
1697 coreconfigitem(
1692 b'progress',
1698 b'progress',
1693 b'changedelay',
1699 b'changedelay',
1694 default=1,
1700 default=1,
1695 )
1701 )
1696 coreconfigitem(
1702 coreconfigitem(
1697 b'progress',
1703 b'progress',
1698 b'clear-complete',
1704 b'clear-complete',
1699 default=True,
1705 default=True,
1700 )
1706 )
1701 coreconfigitem(
1707 coreconfigitem(
1702 b'progress',
1708 b'progress',
1703 b'debug',
1709 b'debug',
1704 default=False,
1710 default=False,
1705 )
1711 )
1706 coreconfigitem(
1712 coreconfigitem(
1707 b'progress',
1713 b'progress',
1708 b'delay',
1714 b'delay',
1709 default=3,
1715 default=3,
1710 )
1716 )
1711 coreconfigitem(
1717 coreconfigitem(
1712 b'progress',
1718 b'progress',
1713 b'disable',
1719 b'disable',
1714 default=False,
1720 default=False,
1715 )
1721 )
1716 coreconfigitem(
1722 coreconfigitem(
1717 b'progress',
1723 b'progress',
1718 b'estimateinterval',
1724 b'estimateinterval',
1719 default=60.0,
1725 default=60.0,
1720 )
1726 )
1721 coreconfigitem(
1727 coreconfigitem(
1722 b'progress',
1728 b'progress',
1723 b'format',
1729 b'format',
1724 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1730 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1725 )
1731 )
1726 coreconfigitem(
1732 coreconfigitem(
1727 b'progress',
1733 b'progress',
1728 b'refresh',
1734 b'refresh',
1729 default=0.1,
1735 default=0.1,
1730 )
1736 )
1731 coreconfigitem(
1737 coreconfigitem(
1732 b'progress',
1738 b'progress',
1733 b'width',
1739 b'width',
1734 default=dynamicdefault,
1740 default=dynamicdefault,
1735 )
1741 )
1736 coreconfigitem(
1742 coreconfigitem(
1737 b'pull',
1743 b'pull',
1738 b'confirm',
1744 b'confirm',
1739 default=False,
1745 default=False,
1740 )
1746 )
1741 coreconfigitem(
1747 coreconfigitem(
1742 b'push',
1748 b'push',
1743 b'pushvars.server',
1749 b'pushvars.server',
1744 default=False,
1750 default=False,
1745 )
1751 )
1746 coreconfigitem(
1752 coreconfigitem(
1747 b'rewrite',
1753 b'rewrite',
1748 b'backup-bundle',
1754 b'backup-bundle',
1749 default=True,
1755 default=True,
1750 alias=[(b'ui', b'history-editing-backup')],
1756 alias=[(b'ui', b'history-editing-backup')],
1751 )
1757 )
1752 coreconfigitem(
1758 coreconfigitem(
1753 b'rewrite',
1759 b'rewrite',
1754 b'update-timestamp',
1760 b'update-timestamp',
1755 default=False,
1761 default=False,
1756 )
1762 )
1757 coreconfigitem(
1763 coreconfigitem(
1758 b'rewrite',
1764 b'rewrite',
1759 b'empty-successor',
1765 b'empty-successor',
1760 default=b'skip',
1766 default=b'skip',
1761 experimental=True,
1767 experimental=True,
1762 )
1768 )
1763 coreconfigitem(
1769 coreconfigitem(
1764 b'storage',
1770 b'storage',
1765 b'new-repo-backend',
1771 b'new-repo-backend',
1766 default=b'revlogv1',
1772 default=b'revlogv1',
1767 experimental=True,
1773 experimental=True,
1768 )
1774 )
1769 coreconfigitem(
1775 coreconfigitem(
1770 b'storage',
1776 b'storage',
1771 b'revlog.optimize-delta-parent-choice',
1777 b'revlog.optimize-delta-parent-choice',
1772 default=True,
1778 default=True,
1773 alias=[(b'format', b'aggressivemergedeltas')],
1779 alias=[(b'format', b'aggressivemergedeltas')],
1774 )
1780 )
1775 # experimental as long as rust is experimental (or a C version is implemented)
1781 # experimental as long as rust is experimental (or a C version is implemented)
1776 coreconfigitem(
1782 coreconfigitem(
1777 b'storage',
1783 b'storage',
1778 b'revlog.persistent-nodemap.mmap',
1784 b'revlog.persistent-nodemap.mmap',
1779 default=True,
1785 default=True,
1780 )
1786 )
1781 # experimental as long as format.use-persistent-nodemap is.
1787 # experimental as long as format.use-persistent-nodemap is.
1782 coreconfigitem(
1788 coreconfigitem(
1783 b'storage',
1789 b'storage',
1784 b'revlog.persistent-nodemap.slow-path',
1790 b'revlog.persistent-nodemap.slow-path',
1785 default=b"abort",
1791 default=b"abort",
1786 )
1792 )
1787
1793
1788 coreconfigitem(
1794 coreconfigitem(
1789 b'storage',
1795 b'storage',
1790 b'revlog.reuse-external-delta',
1796 b'revlog.reuse-external-delta',
1791 default=True,
1797 default=True,
1792 )
1798 )
1793 coreconfigitem(
1799 coreconfigitem(
1794 b'storage',
1800 b'storage',
1795 b'revlog.reuse-external-delta-parent',
1801 b'revlog.reuse-external-delta-parent',
1796 default=None,
1802 default=None,
1797 )
1803 )
1798 coreconfigitem(
1804 coreconfigitem(
1799 b'storage',
1805 b'storage',
1800 b'revlog.zlib.level',
1806 b'revlog.zlib.level',
1801 default=None,
1807 default=None,
1802 )
1808 )
1803 coreconfigitem(
1809 coreconfigitem(
1804 b'storage',
1810 b'storage',
1805 b'revlog.zstd.level',
1811 b'revlog.zstd.level',
1806 default=None,
1812 default=None,
1807 )
1813 )
1808 coreconfigitem(
1814 coreconfigitem(
1809 b'server',
1815 b'server',
1810 b'bookmarks-pushkey-compat',
1816 b'bookmarks-pushkey-compat',
1811 default=True,
1817 default=True,
1812 )
1818 )
1813 coreconfigitem(
1819 coreconfigitem(
1814 b'server',
1820 b'server',
1815 b'bundle1',
1821 b'bundle1',
1816 default=True,
1822 default=True,
1817 )
1823 )
1818 coreconfigitem(
1824 coreconfigitem(
1819 b'server',
1825 b'server',
1820 b'bundle1gd',
1826 b'bundle1gd',
1821 default=None,
1827 default=None,
1822 )
1828 )
1823 coreconfigitem(
1829 coreconfigitem(
1824 b'server',
1830 b'server',
1825 b'bundle1.pull',
1831 b'bundle1.pull',
1826 default=None,
1832 default=None,
1827 )
1833 )
1828 coreconfigitem(
1834 coreconfigitem(
1829 b'server',
1835 b'server',
1830 b'bundle1gd.pull',
1836 b'bundle1gd.pull',
1831 default=None,
1837 default=None,
1832 )
1838 )
1833 coreconfigitem(
1839 coreconfigitem(
1834 b'server',
1840 b'server',
1835 b'bundle1.push',
1841 b'bundle1.push',
1836 default=None,
1842 default=None,
1837 )
1843 )
1838 coreconfigitem(
1844 coreconfigitem(
1839 b'server',
1845 b'server',
1840 b'bundle1gd.push',
1846 b'bundle1gd.push',
1841 default=None,
1847 default=None,
1842 )
1848 )
1843 coreconfigitem(
1849 coreconfigitem(
1844 b'server',
1850 b'server',
1845 b'bundle2.stream',
1851 b'bundle2.stream',
1846 default=True,
1852 default=True,
1847 alias=[(b'experimental', b'bundle2.stream')],
1853 alias=[(b'experimental', b'bundle2.stream')],
1848 )
1854 )
1849 coreconfigitem(
1855 coreconfigitem(
1850 b'server',
1856 b'server',
1851 b'compressionengines',
1857 b'compressionengines',
1852 default=list,
1858 default=list,
1853 )
1859 )
1854 coreconfigitem(
1860 coreconfigitem(
1855 b'server',
1861 b'server',
1856 b'concurrent-push-mode',
1862 b'concurrent-push-mode',
1857 default=b'check-related',
1863 default=b'check-related',
1858 )
1864 )
1859 coreconfigitem(
1865 coreconfigitem(
1860 b'server',
1866 b'server',
1861 b'disablefullbundle',
1867 b'disablefullbundle',
1862 default=False,
1868 default=False,
1863 )
1869 )
1864 coreconfigitem(
1870 coreconfigitem(
1865 b'server',
1871 b'server',
1866 b'maxhttpheaderlen',
1872 b'maxhttpheaderlen',
1867 default=1024,
1873 default=1024,
1868 )
1874 )
1869 coreconfigitem(
1875 coreconfigitem(
1870 b'server',
1876 b'server',
1871 b'pullbundle',
1877 b'pullbundle',
1872 default=False,
1878 default=False,
1873 )
1879 )
1874 coreconfigitem(
1880 coreconfigitem(
1875 b'server',
1881 b'server',
1876 b'preferuncompressed',
1882 b'preferuncompressed',
1877 default=False,
1883 default=False,
1878 )
1884 )
1879 coreconfigitem(
1885 coreconfigitem(
1880 b'server',
1886 b'server',
1881 b'streamunbundle',
1887 b'streamunbundle',
1882 default=False,
1888 default=False,
1883 )
1889 )
1884 coreconfigitem(
1890 coreconfigitem(
1885 b'server',
1891 b'server',
1886 b'uncompressed',
1892 b'uncompressed',
1887 default=True,
1893 default=True,
1888 )
1894 )
1889 coreconfigitem(
1895 coreconfigitem(
1890 b'server',
1896 b'server',
1891 b'uncompressedallowsecret',
1897 b'uncompressedallowsecret',
1892 default=False,
1898 default=False,
1893 )
1899 )
1894 coreconfigitem(
1900 coreconfigitem(
1895 b'server',
1901 b'server',
1896 b'view',
1902 b'view',
1897 default=b'served',
1903 default=b'served',
1898 )
1904 )
1899 coreconfigitem(
1905 coreconfigitem(
1900 b'server',
1906 b'server',
1901 b'validate',
1907 b'validate',
1902 default=False,
1908 default=False,
1903 )
1909 )
1904 coreconfigitem(
1910 coreconfigitem(
1905 b'server',
1911 b'server',
1906 b'zliblevel',
1912 b'zliblevel',
1907 default=-1,
1913 default=-1,
1908 )
1914 )
1909 coreconfigitem(
1915 coreconfigitem(
1910 b'server',
1916 b'server',
1911 b'zstdlevel',
1917 b'zstdlevel',
1912 default=3,
1918 default=3,
1913 )
1919 )
1914 coreconfigitem(
1920 coreconfigitem(
1915 b'share',
1921 b'share',
1916 b'pool',
1922 b'pool',
1917 default=None,
1923 default=None,
1918 )
1924 )
1919 coreconfigitem(
1925 coreconfigitem(
1920 b'share',
1926 b'share',
1921 b'poolnaming',
1927 b'poolnaming',
1922 default=b'identity',
1928 default=b'identity',
1923 )
1929 )
1924 coreconfigitem(
1930 coreconfigitem(
1925 b'share',
1931 b'share',
1926 b'safe-mismatch.source-not-safe',
1932 b'safe-mismatch.source-not-safe',
1927 default=b'abort',
1933 default=b'abort',
1928 )
1934 )
1929 coreconfigitem(
1935 coreconfigitem(
1930 b'share',
1936 b'share',
1931 b'safe-mismatch.source-safe',
1937 b'safe-mismatch.source-safe',
1932 default=b'abort',
1938 default=b'abort',
1933 )
1939 )
1934 coreconfigitem(
1940 coreconfigitem(
1935 b'share',
1941 b'share',
1936 b'safe-mismatch.source-not-safe.warn',
1942 b'safe-mismatch.source-not-safe.warn',
1937 default=True,
1943 default=True,
1938 )
1944 )
1939 coreconfigitem(
1945 coreconfigitem(
1940 b'share',
1946 b'share',
1941 b'safe-mismatch.source-safe.warn',
1947 b'safe-mismatch.source-safe.warn',
1942 default=True,
1948 default=True,
1943 )
1949 )
1944 coreconfigitem(
1950 coreconfigitem(
1945 b'shelve',
1951 b'shelve',
1946 b'maxbackups',
1952 b'maxbackups',
1947 default=10,
1953 default=10,
1948 )
1954 )
1949 coreconfigitem(
1955 coreconfigitem(
1950 b'smtp',
1956 b'smtp',
1951 b'host',
1957 b'host',
1952 default=None,
1958 default=None,
1953 )
1959 )
1954 coreconfigitem(
1960 coreconfigitem(
1955 b'smtp',
1961 b'smtp',
1956 b'local_hostname',
1962 b'local_hostname',
1957 default=None,
1963 default=None,
1958 )
1964 )
1959 coreconfigitem(
1965 coreconfigitem(
1960 b'smtp',
1966 b'smtp',
1961 b'password',
1967 b'password',
1962 default=None,
1968 default=None,
1963 )
1969 )
1964 coreconfigitem(
1970 coreconfigitem(
1965 b'smtp',
1971 b'smtp',
1966 b'port',
1972 b'port',
1967 default=dynamicdefault,
1973 default=dynamicdefault,
1968 )
1974 )
1969 coreconfigitem(
1975 coreconfigitem(
1970 b'smtp',
1976 b'smtp',
1971 b'tls',
1977 b'tls',
1972 default=b'none',
1978 default=b'none',
1973 )
1979 )
1974 coreconfigitem(
1980 coreconfigitem(
1975 b'smtp',
1981 b'smtp',
1976 b'username',
1982 b'username',
1977 default=None,
1983 default=None,
1978 )
1984 )
1979 coreconfigitem(
1985 coreconfigitem(
1980 b'sparse',
1986 b'sparse',
1981 b'missingwarning',
1987 b'missingwarning',
1982 default=True,
1988 default=True,
1983 experimental=True,
1989 experimental=True,
1984 )
1990 )
1985 coreconfigitem(
1991 coreconfigitem(
1986 b'subrepos',
1992 b'subrepos',
1987 b'allowed',
1993 b'allowed',
1988 default=dynamicdefault, # to make backporting simpler
1994 default=dynamicdefault, # to make backporting simpler
1989 )
1995 )
1990 coreconfigitem(
1996 coreconfigitem(
1991 b'subrepos',
1997 b'subrepos',
1992 b'hg:allowed',
1998 b'hg:allowed',
1993 default=dynamicdefault,
1999 default=dynamicdefault,
1994 )
2000 )
1995 coreconfigitem(
2001 coreconfigitem(
1996 b'subrepos',
2002 b'subrepos',
1997 b'git:allowed',
2003 b'git:allowed',
1998 default=dynamicdefault,
2004 default=dynamicdefault,
1999 )
2005 )
2000 coreconfigitem(
2006 coreconfigitem(
2001 b'subrepos',
2007 b'subrepos',
2002 b'svn:allowed',
2008 b'svn:allowed',
2003 default=dynamicdefault,
2009 default=dynamicdefault,
2004 )
2010 )
2005 coreconfigitem(
2011 coreconfigitem(
2006 b'templates',
2012 b'templates',
2007 b'.*',
2013 b'.*',
2008 default=None,
2014 default=None,
2009 generic=True,
2015 generic=True,
2010 )
2016 )
2011 coreconfigitem(
2017 coreconfigitem(
2012 b'templateconfig',
2018 b'templateconfig',
2013 b'.*',
2019 b'.*',
2014 default=dynamicdefault,
2020 default=dynamicdefault,
2015 generic=True,
2021 generic=True,
2016 )
2022 )
2017 coreconfigitem(
2023 coreconfigitem(
2018 b'trusted',
2024 b'trusted',
2019 b'groups',
2025 b'groups',
2020 default=list,
2026 default=list,
2021 )
2027 )
2022 coreconfigitem(
2028 coreconfigitem(
2023 b'trusted',
2029 b'trusted',
2024 b'users',
2030 b'users',
2025 default=list,
2031 default=list,
2026 )
2032 )
2027 coreconfigitem(
2033 coreconfigitem(
2028 b'ui',
2034 b'ui',
2029 b'_usedassubrepo',
2035 b'_usedassubrepo',
2030 default=False,
2036 default=False,
2031 )
2037 )
2032 coreconfigitem(
2038 coreconfigitem(
2033 b'ui',
2039 b'ui',
2034 b'allowemptycommit',
2040 b'allowemptycommit',
2035 default=False,
2041 default=False,
2036 )
2042 )
2037 coreconfigitem(
2043 coreconfigitem(
2038 b'ui',
2044 b'ui',
2039 b'archivemeta',
2045 b'archivemeta',
2040 default=True,
2046 default=True,
2041 )
2047 )
2042 coreconfigitem(
2048 coreconfigitem(
2043 b'ui',
2049 b'ui',
2044 b'askusername',
2050 b'askusername',
2045 default=False,
2051 default=False,
2046 )
2052 )
2047 coreconfigitem(
2053 coreconfigitem(
2048 b'ui',
2054 b'ui',
2049 b'available-memory',
2055 b'available-memory',
2050 default=None,
2056 default=None,
2051 )
2057 )
2052
2058
2053 coreconfigitem(
2059 coreconfigitem(
2054 b'ui',
2060 b'ui',
2055 b'clonebundlefallback',
2061 b'clonebundlefallback',
2056 default=False,
2062 default=False,
2057 )
2063 )
2058 coreconfigitem(
2064 coreconfigitem(
2059 b'ui',
2065 b'ui',
2060 b'clonebundleprefers',
2066 b'clonebundleprefers',
2061 default=list,
2067 default=list,
2062 )
2068 )
2063 coreconfigitem(
2069 coreconfigitem(
2064 b'ui',
2070 b'ui',
2065 b'clonebundles',
2071 b'clonebundles',
2066 default=True,
2072 default=True,
2067 )
2073 )
2068 coreconfigitem(
2074 coreconfigitem(
2069 b'ui',
2075 b'ui',
2070 b'color',
2076 b'color',
2071 default=b'auto',
2077 default=b'auto',
2072 )
2078 )
2073 coreconfigitem(
2079 coreconfigitem(
2074 b'ui',
2080 b'ui',
2075 b'commitsubrepos',
2081 b'commitsubrepos',
2076 default=False,
2082 default=False,
2077 )
2083 )
2078 coreconfigitem(
2084 coreconfigitem(
2079 b'ui',
2085 b'ui',
2080 b'debug',
2086 b'debug',
2081 default=False,
2087 default=False,
2082 )
2088 )
2083 coreconfigitem(
2089 coreconfigitem(
2084 b'ui',
2090 b'ui',
2085 b'debugger',
2091 b'debugger',
2086 default=None,
2092 default=None,
2087 )
2093 )
2088 coreconfigitem(
2094 coreconfigitem(
2089 b'ui',
2095 b'ui',
2090 b'editor',
2096 b'editor',
2091 default=dynamicdefault,
2097 default=dynamicdefault,
2092 )
2098 )
2093 coreconfigitem(
2099 coreconfigitem(
2094 b'ui',
2100 b'ui',
2095 b'detailed-exit-code',
2101 b'detailed-exit-code',
2096 default=False,
2102 default=False,
2097 experimental=True,
2103 experimental=True,
2098 )
2104 )
2099 coreconfigitem(
2105 coreconfigitem(
2100 b'ui',
2106 b'ui',
2101 b'fallbackencoding',
2107 b'fallbackencoding',
2102 default=None,
2108 default=None,
2103 )
2109 )
2104 coreconfigitem(
2110 coreconfigitem(
2105 b'ui',
2111 b'ui',
2106 b'forcecwd',
2112 b'forcecwd',
2107 default=None,
2113 default=None,
2108 )
2114 )
2109 coreconfigitem(
2115 coreconfigitem(
2110 b'ui',
2116 b'ui',
2111 b'forcemerge',
2117 b'forcemerge',
2112 default=None,
2118 default=None,
2113 )
2119 )
2114 coreconfigitem(
2120 coreconfigitem(
2115 b'ui',
2121 b'ui',
2116 b'formatdebug',
2122 b'formatdebug',
2117 default=False,
2123 default=False,
2118 )
2124 )
2119 coreconfigitem(
2125 coreconfigitem(
2120 b'ui',
2126 b'ui',
2121 b'formatjson',
2127 b'formatjson',
2122 default=False,
2128 default=False,
2123 )
2129 )
2124 coreconfigitem(
2130 coreconfigitem(
2125 b'ui',
2131 b'ui',
2126 b'formatted',
2132 b'formatted',
2127 default=None,
2133 default=None,
2128 )
2134 )
2129 coreconfigitem(
2135 coreconfigitem(
2130 b'ui',
2136 b'ui',
2131 b'interactive',
2137 b'interactive',
2132 default=None,
2138 default=None,
2133 )
2139 )
2134 coreconfigitem(
2140 coreconfigitem(
2135 b'ui',
2141 b'ui',
2136 b'interface',
2142 b'interface',
2137 default=None,
2143 default=None,
2138 )
2144 )
2139 coreconfigitem(
2145 coreconfigitem(
2140 b'ui',
2146 b'ui',
2141 b'interface.chunkselector',
2147 b'interface.chunkselector',
2142 default=None,
2148 default=None,
2143 )
2149 )
2144 coreconfigitem(
2150 coreconfigitem(
2145 b'ui',
2151 b'ui',
2146 b'large-file-limit',
2152 b'large-file-limit',
2147 default=10000000,
2153 default=10000000,
2148 )
2154 )
2149 coreconfigitem(
2155 coreconfigitem(
2150 b'ui',
2156 b'ui',
2151 b'logblockedtimes',
2157 b'logblockedtimes',
2152 default=False,
2158 default=False,
2153 )
2159 )
2154 coreconfigitem(
2160 coreconfigitem(
2155 b'ui',
2161 b'ui',
2156 b'merge',
2162 b'merge',
2157 default=None,
2163 default=None,
2158 )
2164 )
2159 coreconfigitem(
2165 coreconfigitem(
2160 b'ui',
2166 b'ui',
2161 b'mergemarkers',
2167 b'mergemarkers',
2162 default=b'basic',
2168 default=b'basic',
2163 )
2169 )
2164 coreconfigitem(
2170 coreconfigitem(
2165 b'ui',
2171 b'ui',
2166 b'message-output',
2172 b'message-output',
2167 default=b'stdio',
2173 default=b'stdio',
2168 )
2174 )
2169 coreconfigitem(
2175 coreconfigitem(
2170 b'ui',
2176 b'ui',
2171 b'nontty',
2177 b'nontty',
2172 default=False,
2178 default=False,
2173 )
2179 )
2174 coreconfigitem(
2180 coreconfigitem(
2175 b'ui',
2181 b'ui',
2176 b'origbackuppath',
2182 b'origbackuppath',
2177 default=None,
2183 default=None,
2178 )
2184 )
2179 coreconfigitem(
2185 coreconfigitem(
2180 b'ui',
2186 b'ui',
2181 b'paginate',
2187 b'paginate',
2182 default=True,
2188 default=True,
2183 )
2189 )
2184 coreconfigitem(
2190 coreconfigitem(
2185 b'ui',
2191 b'ui',
2186 b'patch',
2192 b'patch',
2187 default=None,
2193 default=None,
2188 )
2194 )
2189 coreconfigitem(
2195 coreconfigitem(
2190 b'ui',
2196 b'ui',
2191 b'portablefilenames',
2197 b'portablefilenames',
2192 default=b'warn',
2198 default=b'warn',
2193 )
2199 )
2194 coreconfigitem(
2200 coreconfigitem(
2195 b'ui',
2201 b'ui',
2196 b'promptecho',
2202 b'promptecho',
2197 default=False,
2203 default=False,
2198 )
2204 )
2199 coreconfigitem(
2205 coreconfigitem(
2200 b'ui',
2206 b'ui',
2201 b'quiet',
2207 b'quiet',
2202 default=False,
2208 default=False,
2203 )
2209 )
2204 coreconfigitem(
2210 coreconfigitem(
2205 b'ui',
2211 b'ui',
2206 b'quietbookmarkmove',
2212 b'quietbookmarkmove',
2207 default=False,
2213 default=False,
2208 )
2214 )
2209 coreconfigitem(
2215 coreconfigitem(
2210 b'ui',
2216 b'ui',
2211 b'relative-paths',
2217 b'relative-paths',
2212 default=b'legacy',
2218 default=b'legacy',
2213 )
2219 )
2214 coreconfigitem(
2220 coreconfigitem(
2215 b'ui',
2221 b'ui',
2216 b'remotecmd',
2222 b'remotecmd',
2217 default=b'hg',
2223 default=b'hg',
2218 )
2224 )
2219 coreconfigitem(
2225 coreconfigitem(
2220 b'ui',
2226 b'ui',
2221 b'report_untrusted',
2227 b'report_untrusted',
2222 default=True,
2228 default=True,
2223 )
2229 )
2224 coreconfigitem(
2230 coreconfigitem(
2225 b'ui',
2231 b'ui',
2226 b'rollback',
2232 b'rollback',
2227 default=True,
2233 default=True,
2228 )
2234 )
2229 coreconfigitem(
2235 coreconfigitem(
2230 b'ui',
2236 b'ui',
2231 b'signal-safe-lock',
2237 b'signal-safe-lock',
2232 default=True,
2238 default=True,
2233 )
2239 )
2234 coreconfigitem(
2240 coreconfigitem(
2235 b'ui',
2241 b'ui',
2236 b'slash',
2242 b'slash',
2237 default=False,
2243 default=False,
2238 )
2244 )
2239 coreconfigitem(
2245 coreconfigitem(
2240 b'ui',
2246 b'ui',
2241 b'ssh',
2247 b'ssh',
2242 default=b'ssh',
2248 default=b'ssh',
2243 )
2249 )
2244 coreconfigitem(
2250 coreconfigitem(
2245 b'ui',
2251 b'ui',
2246 b'ssherrorhint',
2252 b'ssherrorhint',
2247 default=None,
2253 default=None,
2248 )
2254 )
2249 coreconfigitem(
2255 coreconfigitem(
2250 b'ui',
2256 b'ui',
2251 b'statuscopies',
2257 b'statuscopies',
2252 default=False,
2258 default=False,
2253 )
2259 )
2254 coreconfigitem(
2260 coreconfigitem(
2255 b'ui',
2261 b'ui',
2256 b'strict',
2262 b'strict',
2257 default=False,
2263 default=False,
2258 )
2264 )
2259 coreconfigitem(
2265 coreconfigitem(
2260 b'ui',
2266 b'ui',
2261 b'style',
2267 b'style',
2262 default=b'',
2268 default=b'',
2263 )
2269 )
2264 coreconfigitem(
2270 coreconfigitem(
2265 b'ui',
2271 b'ui',
2266 b'supportcontact',
2272 b'supportcontact',
2267 default=None,
2273 default=None,
2268 )
2274 )
2269 coreconfigitem(
2275 coreconfigitem(
2270 b'ui',
2276 b'ui',
2271 b'textwidth',
2277 b'textwidth',
2272 default=78,
2278 default=78,
2273 )
2279 )
2274 coreconfigitem(
2280 coreconfigitem(
2275 b'ui',
2281 b'ui',
2276 b'timeout',
2282 b'timeout',
2277 default=b'600',
2283 default=b'600',
2278 )
2284 )
2279 coreconfigitem(
2285 coreconfigitem(
2280 b'ui',
2286 b'ui',
2281 b'timeout.warn',
2287 b'timeout.warn',
2282 default=0,
2288 default=0,
2283 )
2289 )
2284 coreconfigitem(
2290 coreconfigitem(
2285 b'ui',
2291 b'ui',
2286 b'timestamp-output',
2292 b'timestamp-output',
2287 default=False,
2293 default=False,
2288 )
2294 )
2289 coreconfigitem(
2295 coreconfigitem(
2290 b'ui',
2296 b'ui',
2291 b'traceback',
2297 b'traceback',
2292 default=False,
2298 default=False,
2293 )
2299 )
2294 coreconfigitem(
2300 coreconfigitem(
2295 b'ui',
2301 b'ui',
2296 b'tweakdefaults',
2302 b'tweakdefaults',
2297 default=False,
2303 default=False,
2298 )
2304 )
2299 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2305 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2300 coreconfigitem(
2306 coreconfigitem(
2301 b'ui',
2307 b'ui',
2302 b'verbose',
2308 b'verbose',
2303 default=False,
2309 default=False,
2304 )
2310 )
2305 coreconfigitem(
2311 coreconfigitem(
2306 b'verify',
2312 b'verify',
2307 b'skipflags',
2313 b'skipflags',
2308 default=None,
2314 default=None,
2309 )
2315 )
2310 coreconfigitem(
2316 coreconfigitem(
2311 b'web',
2317 b'web',
2312 b'allowbz2',
2318 b'allowbz2',
2313 default=False,
2319 default=False,
2314 )
2320 )
2315 coreconfigitem(
2321 coreconfigitem(
2316 b'web',
2322 b'web',
2317 b'allowgz',
2323 b'allowgz',
2318 default=False,
2324 default=False,
2319 )
2325 )
2320 coreconfigitem(
2326 coreconfigitem(
2321 b'web',
2327 b'web',
2322 b'allow-pull',
2328 b'allow-pull',
2323 alias=[(b'web', b'allowpull')],
2329 alias=[(b'web', b'allowpull')],
2324 default=True,
2330 default=True,
2325 )
2331 )
2326 coreconfigitem(
2332 coreconfigitem(
2327 b'web',
2333 b'web',
2328 b'allow-push',
2334 b'allow-push',
2329 alias=[(b'web', b'allow_push')],
2335 alias=[(b'web', b'allow_push')],
2330 default=list,
2336 default=list,
2331 )
2337 )
2332 coreconfigitem(
2338 coreconfigitem(
2333 b'web',
2339 b'web',
2334 b'allowzip',
2340 b'allowzip',
2335 default=False,
2341 default=False,
2336 )
2342 )
2337 coreconfigitem(
2343 coreconfigitem(
2338 b'web',
2344 b'web',
2339 b'archivesubrepos',
2345 b'archivesubrepos',
2340 default=False,
2346 default=False,
2341 )
2347 )
2342 coreconfigitem(
2348 coreconfigitem(
2343 b'web',
2349 b'web',
2344 b'cache',
2350 b'cache',
2345 default=True,
2351 default=True,
2346 )
2352 )
2347 coreconfigitem(
2353 coreconfigitem(
2348 b'web',
2354 b'web',
2349 b'comparisoncontext',
2355 b'comparisoncontext',
2350 default=5,
2356 default=5,
2351 )
2357 )
2352 coreconfigitem(
2358 coreconfigitem(
2353 b'web',
2359 b'web',
2354 b'contact',
2360 b'contact',
2355 default=None,
2361 default=None,
2356 )
2362 )
2357 coreconfigitem(
2363 coreconfigitem(
2358 b'web',
2364 b'web',
2359 b'deny_push',
2365 b'deny_push',
2360 default=list,
2366 default=list,
2361 )
2367 )
2362 coreconfigitem(
2368 coreconfigitem(
2363 b'web',
2369 b'web',
2364 b'guessmime',
2370 b'guessmime',
2365 default=False,
2371 default=False,
2366 )
2372 )
2367 coreconfigitem(
2373 coreconfigitem(
2368 b'web',
2374 b'web',
2369 b'hidden',
2375 b'hidden',
2370 default=False,
2376 default=False,
2371 )
2377 )
2372 coreconfigitem(
2378 coreconfigitem(
2373 b'web',
2379 b'web',
2374 b'labels',
2380 b'labels',
2375 default=list,
2381 default=list,
2376 )
2382 )
2377 coreconfigitem(
2383 coreconfigitem(
2378 b'web',
2384 b'web',
2379 b'logoimg',
2385 b'logoimg',
2380 default=b'hglogo.png',
2386 default=b'hglogo.png',
2381 )
2387 )
2382 coreconfigitem(
2388 coreconfigitem(
2383 b'web',
2389 b'web',
2384 b'logourl',
2390 b'logourl',
2385 default=b'https://mercurial-scm.org/',
2391 default=b'https://mercurial-scm.org/',
2386 )
2392 )
2387 coreconfigitem(
2393 coreconfigitem(
2388 b'web',
2394 b'web',
2389 b'accesslog',
2395 b'accesslog',
2390 default=b'-',
2396 default=b'-',
2391 )
2397 )
2392 coreconfigitem(
2398 coreconfigitem(
2393 b'web',
2399 b'web',
2394 b'address',
2400 b'address',
2395 default=b'',
2401 default=b'',
2396 )
2402 )
2397 coreconfigitem(
2403 coreconfigitem(
2398 b'web',
2404 b'web',
2399 b'allow-archive',
2405 b'allow-archive',
2400 alias=[(b'web', b'allow_archive')],
2406 alias=[(b'web', b'allow_archive')],
2401 default=list,
2407 default=list,
2402 )
2408 )
2403 coreconfigitem(
2409 coreconfigitem(
2404 b'web',
2410 b'web',
2405 b'allow_read',
2411 b'allow_read',
2406 default=list,
2412 default=list,
2407 )
2413 )
2408 coreconfigitem(
2414 coreconfigitem(
2409 b'web',
2415 b'web',
2410 b'baseurl',
2416 b'baseurl',
2411 default=None,
2417 default=None,
2412 )
2418 )
2413 coreconfigitem(
2419 coreconfigitem(
2414 b'web',
2420 b'web',
2415 b'cacerts',
2421 b'cacerts',
2416 default=None,
2422 default=None,
2417 )
2423 )
2418 coreconfigitem(
2424 coreconfigitem(
2419 b'web',
2425 b'web',
2420 b'certificate',
2426 b'certificate',
2421 default=None,
2427 default=None,
2422 )
2428 )
2423 coreconfigitem(
2429 coreconfigitem(
2424 b'web',
2430 b'web',
2425 b'collapse',
2431 b'collapse',
2426 default=False,
2432 default=False,
2427 )
2433 )
2428 coreconfigitem(
2434 coreconfigitem(
2429 b'web',
2435 b'web',
2430 b'csp',
2436 b'csp',
2431 default=None,
2437 default=None,
2432 )
2438 )
2433 coreconfigitem(
2439 coreconfigitem(
2434 b'web',
2440 b'web',
2435 b'deny_read',
2441 b'deny_read',
2436 default=list,
2442 default=list,
2437 )
2443 )
2438 coreconfigitem(
2444 coreconfigitem(
2439 b'web',
2445 b'web',
2440 b'descend',
2446 b'descend',
2441 default=True,
2447 default=True,
2442 )
2448 )
2443 coreconfigitem(
2449 coreconfigitem(
2444 b'web',
2450 b'web',
2445 b'description',
2451 b'description',
2446 default=b"",
2452 default=b"",
2447 )
2453 )
2448 coreconfigitem(
2454 coreconfigitem(
2449 b'web',
2455 b'web',
2450 b'encoding',
2456 b'encoding',
2451 default=lambda: encoding.encoding,
2457 default=lambda: encoding.encoding,
2452 )
2458 )
2453 coreconfigitem(
2459 coreconfigitem(
2454 b'web',
2460 b'web',
2455 b'errorlog',
2461 b'errorlog',
2456 default=b'-',
2462 default=b'-',
2457 )
2463 )
2458 coreconfigitem(
2464 coreconfigitem(
2459 b'web',
2465 b'web',
2460 b'ipv6',
2466 b'ipv6',
2461 default=False,
2467 default=False,
2462 )
2468 )
2463 coreconfigitem(
2469 coreconfigitem(
2464 b'web',
2470 b'web',
2465 b'maxchanges',
2471 b'maxchanges',
2466 default=10,
2472 default=10,
2467 )
2473 )
2468 coreconfigitem(
2474 coreconfigitem(
2469 b'web',
2475 b'web',
2470 b'maxfiles',
2476 b'maxfiles',
2471 default=10,
2477 default=10,
2472 )
2478 )
2473 coreconfigitem(
2479 coreconfigitem(
2474 b'web',
2480 b'web',
2475 b'maxshortchanges',
2481 b'maxshortchanges',
2476 default=60,
2482 default=60,
2477 )
2483 )
2478 coreconfigitem(
2484 coreconfigitem(
2479 b'web',
2485 b'web',
2480 b'motd',
2486 b'motd',
2481 default=b'',
2487 default=b'',
2482 )
2488 )
2483 coreconfigitem(
2489 coreconfigitem(
2484 b'web',
2490 b'web',
2485 b'name',
2491 b'name',
2486 default=dynamicdefault,
2492 default=dynamicdefault,
2487 )
2493 )
2488 coreconfigitem(
2494 coreconfigitem(
2489 b'web',
2495 b'web',
2490 b'port',
2496 b'port',
2491 default=8000,
2497 default=8000,
2492 )
2498 )
2493 coreconfigitem(
2499 coreconfigitem(
2494 b'web',
2500 b'web',
2495 b'prefix',
2501 b'prefix',
2496 default=b'',
2502 default=b'',
2497 )
2503 )
2498 coreconfigitem(
2504 coreconfigitem(
2499 b'web',
2505 b'web',
2500 b'push_ssl',
2506 b'push_ssl',
2501 default=True,
2507 default=True,
2502 )
2508 )
2503 coreconfigitem(
2509 coreconfigitem(
2504 b'web',
2510 b'web',
2505 b'refreshinterval',
2511 b'refreshinterval',
2506 default=20,
2512 default=20,
2507 )
2513 )
2508 coreconfigitem(
2514 coreconfigitem(
2509 b'web',
2515 b'web',
2510 b'server-header',
2516 b'server-header',
2511 default=None,
2517 default=None,
2512 )
2518 )
2513 coreconfigitem(
2519 coreconfigitem(
2514 b'web',
2520 b'web',
2515 b'static',
2521 b'static',
2516 default=None,
2522 default=None,
2517 )
2523 )
2518 coreconfigitem(
2524 coreconfigitem(
2519 b'web',
2525 b'web',
2520 b'staticurl',
2526 b'staticurl',
2521 default=None,
2527 default=None,
2522 )
2528 )
2523 coreconfigitem(
2529 coreconfigitem(
2524 b'web',
2530 b'web',
2525 b'stripes',
2531 b'stripes',
2526 default=1,
2532 default=1,
2527 )
2533 )
2528 coreconfigitem(
2534 coreconfigitem(
2529 b'web',
2535 b'web',
2530 b'style',
2536 b'style',
2531 default=b'paper',
2537 default=b'paper',
2532 )
2538 )
2533 coreconfigitem(
2539 coreconfigitem(
2534 b'web',
2540 b'web',
2535 b'templates',
2541 b'templates',
2536 default=None,
2542 default=None,
2537 )
2543 )
2538 coreconfigitem(
2544 coreconfigitem(
2539 b'web',
2545 b'web',
2540 b'view',
2546 b'view',
2541 default=b'served',
2547 default=b'served',
2542 experimental=True,
2548 experimental=True,
2543 )
2549 )
2544 coreconfigitem(
2550 coreconfigitem(
2545 b'worker',
2551 b'worker',
2546 b'backgroundclose',
2552 b'backgroundclose',
2547 default=dynamicdefault,
2553 default=dynamicdefault,
2548 )
2554 )
2549 # Windows defaults to a limit of 512 open files. A buffer of 128
2555 # Windows defaults to a limit of 512 open files. A buffer of 128
2550 # should give us enough headway.
2556 # should give us enough headway.
2551 coreconfigitem(
2557 coreconfigitem(
2552 b'worker',
2558 b'worker',
2553 b'backgroundclosemaxqueue',
2559 b'backgroundclosemaxqueue',
2554 default=384,
2560 default=384,
2555 )
2561 )
2556 coreconfigitem(
2562 coreconfigitem(
2557 b'worker',
2563 b'worker',
2558 b'backgroundcloseminfilecount',
2564 b'backgroundcloseminfilecount',
2559 default=2048,
2565 default=2048,
2560 )
2566 )
2561 coreconfigitem(
2567 coreconfigitem(
2562 b'worker',
2568 b'worker',
2563 b'backgroundclosethreadcount',
2569 b'backgroundclosethreadcount',
2564 default=4,
2570 default=4,
2565 )
2571 )
2566 coreconfigitem(
2572 coreconfigitem(
2567 b'worker',
2573 b'worker',
2568 b'enabled',
2574 b'enabled',
2569 default=True,
2575 default=True,
2570 )
2576 )
2571 coreconfigitem(
2577 coreconfigitem(
2572 b'worker',
2578 b'worker',
2573 b'numcpus',
2579 b'numcpus',
2574 default=None,
2580 default=None,
2575 )
2581 )
2576
2582
2577 # Rebase related configuration moved to core because other extension are doing
2583 # Rebase related configuration moved to core because other extension are doing
2578 # strange things. For example, shelve import the extensions to reuse some bit
2584 # strange things. For example, shelve import the extensions to reuse some bit
2579 # without formally loading it.
2585 # without formally loading it.
2580 coreconfigitem(
2586 coreconfigitem(
2581 b'commands',
2587 b'commands',
2582 b'rebase.requiredest',
2588 b'rebase.requiredest',
2583 default=False,
2589 default=False,
2584 )
2590 )
2585 coreconfigitem(
2591 coreconfigitem(
2586 b'experimental',
2592 b'experimental',
2587 b'rebaseskipobsolete',
2593 b'rebaseskipobsolete',
2588 default=True,
2594 default=True,
2589 )
2595 )
2590 coreconfigitem(
2596 coreconfigitem(
2591 b'rebase',
2597 b'rebase',
2592 b'singletransaction',
2598 b'singletransaction',
2593 default=False,
2599 default=False,
2594 )
2600 )
2595 coreconfigitem(
2601 coreconfigitem(
2596 b'rebase',
2602 b'rebase',
2597 b'experimental.inmemory',
2603 b'experimental.inmemory',
2598 default=False,
2604 default=False,
2599 )
2605 )
@@ -1,1230 +1,1238 b''
1 # coding: utf8
1 # coding: utf8
2 # copies.py - copy detection for Mercurial
2 # copies.py - copy detection for Mercurial
3 #
3 #
4 # Copyright 2008 Matt Mackall <mpm@selenic.com>
4 # Copyright 2008 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 import collections
11 import collections
12 import os
12 import os
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 nullid,
16 nullid,
17 nullrev,
17 nullrev,
18 )
18 )
19
19
20 from . import (
20 from . import (
21 match as matchmod,
21 match as matchmod,
22 pathutil,
22 pathutil,
23 policy,
23 policy,
24 pycompat,
24 pycompat,
25 util,
25 util,
26 )
26 )
27
27
28
28
29 from .utils import stringutil
29 from .utils import stringutil
30
30
31 from .revlogutils import (
31 from .revlogutils import (
32 flagutil,
32 flagutil,
33 sidedata as sidedatamod,
33 sidedata as sidedatamod,
34 )
34 )
35
35
36 rustmod = policy.importrust("copy_tracing")
36 rustmod = policy.importrust("copy_tracing")
37
37
38
38
39 def _filter(src, dst, t):
39 def _filter(src, dst, t):
40 """filters out invalid copies after chaining"""
40 """filters out invalid copies after chaining"""
41
41
42 # When _chain()'ing copies in 'a' (from 'src' via some other commit 'mid')
42 # When _chain()'ing copies in 'a' (from 'src' via some other commit 'mid')
43 # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
43 # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
44 # in the following table (not including trivial cases). For example, case 6
44 # in the following table (not including trivial cases). For example, case 6
45 # is where a file existed in 'src' and remained under that name in 'mid' and
45 # is where a file existed in 'src' and remained under that name in 'mid' and
46 # then was renamed between 'mid' and 'dst'.
46 # then was renamed between 'mid' and 'dst'.
47 #
47 #
48 # case src mid dst result
48 # case src mid dst result
49 # 1 x y - -
49 # 1 x y - -
50 # 2 x y y x->y
50 # 2 x y y x->y
51 # 3 x y x -
51 # 3 x y x -
52 # 4 x y z x->z
52 # 4 x y z x->z
53 # 5 - x y -
53 # 5 - x y -
54 # 6 x x y x->y
54 # 6 x x y x->y
55 #
55 #
56 # _chain() takes care of chaining the copies in 'a' and 'b', but it
56 # _chain() takes care of chaining the copies in 'a' and 'b', but it
57 # cannot tell the difference between cases 1 and 2, between 3 and 4, or
57 # cannot tell the difference between cases 1 and 2, between 3 and 4, or
58 # between 5 and 6, so it includes all cases in its result.
58 # between 5 and 6, so it includes all cases in its result.
59 # Cases 1, 3, and 5 are then removed by _filter().
59 # Cases 1, 3, and 5 are then removed by _filter().
60
60
61 for k, v in list(t.items()):
61 for k, v in list(t.items()):
62 if k == v: # case 3
62 if k == v: # case 3
63 del t[k]
63 del t[k]
64 elif v not in src: # case 5
64 elif v not in src: # case 5
65 # remove copies from files that didn't exist
65 # remove copies from files that didn't exist
66 del t[k]
66 del t[k]
67 elif k not in dst: # case 1
67 elif k not in dst: # case 1
68 # remove copies to files that were then removed
68 # remove copies to files that were then removed
69 del t[k]
69 del t[k]
70
70
71
71
72 def _chain(prefix, suffix):
72 def _chain(prefix, suffix):
73 """chain two sets of copies 'prefix' and 'suffix'"""
73 """chain two sets of copies 'prefix' and 'suffix'"""
74 result = prefix.copy()
74 result = prefix.copy()
75 for key, value in pycompat.iteritems(suffix):
75 for key, value in pycompat.iteritems(suffix):
76 result[key] = prefix.get(value, value)
76 result[key] = prefix.get(value, value)
77 return result
77 return result
78
78
79
79
80 def _tracefile(fctx, am, basemf):
80 def _tracefile(fctx, am, basemf):
81 """return file context that is the ancestor of fctx present in ancestor
81 """return file context that is the ancestor of fctx present in ancestor
82 manifest am
82 manifest am
83
83
84 Note: we used to try and stop after a given limit, however checking if that
84 Note: we used to try and stop after a given limit, however checking if that
85 limit is reached turned out to be very expensive. we are better off
85 limit is reached turned out to be very expensive. we are better off
86 disabling that feature."""
86 disabling that feature."""
87
87
88 for f in fctx.ancestors():
88 for f in fctx.ancestors():
89 path = f.path()
89 path = f.path()
90 if am.get(path, None) == f.filenode():
90 if am.get(path, None) == f.filenode():
91 return path
91 return path
92 if basemf and basemf.get(path, None) == f.filenode():
92 if basemf and basemf.get(path, None) == f.filenode():
93 return path
93 return path
94
94
95
95
96 def _dirstatecopies(repo, match=None):
96 def _dirstatecopies(repo, match=None):
97 ds = repo.dirstate
97 ds = repo.dirstate
98 c = ds.copies().copy()
98 c = ds.copies().copy()
99 for k in list(c):
99 for k in list(c):
100 if ds[k] not in b'anm' or (match and not match(k)):
100 if ds[k] not in b'anm' or (match and not match(k)):
101 del c[k]
101 del c[k]
102 return c
102 return c
103
103
104
104
105 def _computeforwardmissing(a, b, match=None):
105 def _computeforwardmissing(a, b, match=None):
106 """Computes which files are in b but not a.
106 """Computes which files are in b but not a.
107 This is its own function so extensions can easily wrap this call to see what
107 This is its own function so extensions can easily wrap this call to see what
108 files _forwardcopies is about to process.
108 files _forwardcopies is about to process.
109 """
109 """
110 ma = a.manifest()
110 ma = a.manifest()
111 mb = b.manifest()
111 mb = b.manifest()
112 return mb.filesnotin(ma, match=match)
112 return mb.filesnotin(ma, match=match)
113
113
114
114
115 def usechangesetcentricalgo(repo):
115 def usechangesetcentricalgo(repo):
116 """Checks if we should use changeset-centric copy algorithms"""
116 """Checks if we should use changeset-centric copy algorithms"""
117 if repo.filecopiesmode == b'changeset-sidedata':
117 if repo.filecopiesmode == b'changeset-sidedata':
118 return True
118 return True
119 readfrom = repo.ui.config(b'experimental', b'copies.read-from')
119 readfrom = repo.ui.config(b'experimental', b'copies.read-from')
120 changesetsource = (b'changeset-only', b'compatibility')
120 changesetsource = (b'changeset-only', b'compatibility')
121 return readfrom in changesetsource
121 return readfrom in changesetsource
122
122
123
123
124 def _committedforwardcopies(a, b, base, match):
124 def _committedforwardcopies(a, b, base, match):
125 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
125 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
126 # files might have to be traced back to the fctx parent of the last
126 # files might have to be traced back to the fctx parent of the last
127 # one-side-only changeset, but not further back than that
127 # one-side-only changeset, but not further back than that
128 repo = a._repo
128 repo = a._repo
129
129
130 if usechangesetcentricalgo(repo):
130 if usechangesetcentricalgo(repo):
131 return _changesetforwardcopies(a, b, match)
131 return _changesetforwardcopies(a, b, match)
132
132
133 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
133 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
134 dbg = repo.ui.debug
134 dbg = repo.ui.debug
135 if debug:
135 if debug:
136 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
136 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
137 am = a.manifest()
137 am = a.manifest()
138 basemf = None if base is None else base.manifest()
138 basemf = None if base is None else base.manifest()
139
139
140 # find where new files came from
140 # find where new files came from
141 # we currently don't try to find where old files went, too expensive
141 # we currently don't try to find where old files went, too expensive
142 # this means we can miss a case like 'hg rm b; hg cp a b'
142 # this means we can miss a case like 'hg rm b; hg cp a b'
143 cm = {}
143 cm = {}
144
144
145 # Computing the forward missing is quite expensive on large manifests, since
145 # Computing the forward missing is quite expensive on large manifests, since
146 # it compares the entire manifests. We can optimize it in the common use
146 # it compares the entire manifests. We can optimize it in the common use
147 # case of computing what copies are in a commit versus its parent (like
147 # case of computing what copies are in a commit versus its parent (like
148 # during a rebase or histedit). Note, we exclude merge commits from this
148 # during a rebase or histedit). Note, we exclude merge commits from this
149 # optimization, since the ctx.files() for a merge commit is not correct for
149 # optimization, since the ctx.files() for a merge commit is not correct for
150 # this comparison.
150 # this comparison.
151 forwardmissingmatch = match
151 forwardmissingmatch = match
152 if b.p1() == a and b.p2().node() == nullid:
152 if b.p1() == a and b.p2().node() == nullid:
153 filesmatcher = matchmod.exact(b.files())
153 filesmatcher = matchmod.exact(b.files())
154 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
154 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
155 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
155 if repo.ui.configbool(b'devel', b'copy-tracing.trace-all-files'):
156 missing = list(b.walk(match))
157 # _computeforwardmissing(a, b, match=forwardmissingmatch)
158 if debug:
159 dbg(b'debug.copies: searching all files: %d\n' % len(missing))
160 else:
161 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
162 if debug:
163 dbg(
164 b'debug.copies: missing files to search: %d\n'
165 % len(missing)
166 )
156
167
157 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
168 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
158
169
159 if debug:
160 dbg(b'debug.copies: missing files to search: %d\n' % len(missing))
161
162 for f in sorted(missing):
170 for f in sorted(missing):
163 if debug:
171 if debug:
164 dbg(b'debug.copies: tracing file: %s\n' % f)
172 dbg(b'debug.copies: tracing file: %s\n' % f)
165 fctx = b[f]
173 fctx = b[f]
166 fctx._ancestrycontext = ancestrycontext
174 fctx._ancestrycontext = ancestrycontext
167
175
168 if debug:
176 if debug:
169 start = util.timer()
177 start = util.timer()
170 opath = _tracefile(fctx, am, basemf)
178 opath = _tracefile(fctx, am, basemf)
171 if opath:
179 if opath:
172 if debug:
180 if debug:
173 dbg(b'debug.copies: rename of: %s\n' % opath)
181 dbg(b'debug.copies: rename of: %s\n' % opath)
174 cm[f] = opath
182 cm[f] = opath
175 if debug:
183 if debug:
176 dbg(
184 dbg(
177 b'debug.copies: time: %f seconds\n'
185 b'debug.copies: time: %f seconds\n'
178 % (util.timer() - start)
186 % (util.timer() - start)
179 )
187 )
180 return cm
188 return cm
181
189
182
190
183 def _revinfo_getter(repo, match):
191 def _revinfo_getter(repo, match):
184 """returns a function that returns the following data given a <rev>"
192 """returns a function that returns the following data given a <rev>"
185
193
186 * p1: revision number of first parent
194 * p1: revision number of first parent
187 * p2: revision number of first parent
195 * p2: revision number of first parent
188 * changes: a ChangingFiles object
196 * changes: a ChangingFiles object
189 """
197 """
190 cl = repo.changelog
198 cl = repo.changelog
191 parents = cl.parentrevs
199 parents = cl.parentrevs
192 flags = cl.flags
200 flags = cl.flags
193
201
194 HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO
202 HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO
195
203
196 changelogrevision = cl.changelogrevision
204 changelogrevision = cl.changelogrevision
197
205
198 if rustmod is not None:
206 if rustmod is not None:
199
207
200 def revinfo(rev):
208 def revinfo(rev):
201 p1, p2 = parents(rev)
209 p1, p2 = parents(rev)
202 if flags(rev) & HASCOPIESINFO:
210 if flags(rev) & HASCOPIESINFO:
203 raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES)
211 raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES)
204 else:
212 else:
205 raw = None
213 raw = None
206 return (p1, p2, raw)
214 return (p1, p2, raw)
207
215
208 else:
216 else:
209
217
210 def revinfo(rev):
218 def revinfo(rev):
211 p1, p2 = parents(rev)
219 p1, p2 = parents(rev)
212 if flags(rev) & HASCOPIESINFO:
220 if flags(rev) & HASCOPIESINFO:
213 changes = changelogrevision(rev).changes
221 changes = changelogrevision(rev).changes
214 else:
222 else:
215 changes = None
223 changes = None
216 return (p1, p2, changes)
224 return (p1, p2, changes)
217
225
218 return revinfo
226 return revinfo
219
227
220
228
221 def cached_is_ancestor(is_ancestor):
229 def cached_is_ancestor(is_ancestor):
222 """return a cached version of is_ancestor"""
230 """return a cached version of is_ancestor"""
223 cache = {}
231 cache = {}
224
232
225 def _is_ancestor(anc, desc):
233 def _is_ancestor(anc, desc):
226 if anc > desc:
234 if anc > desc:
227 return False
235 return False
228 elif anc == desc:
236 elif anc == desc:
229 return True
237 return True
230 key = (anc, desc)
238 key = (anc, desc)
231 ret = cache.get(key)
239 ret = cache.get(key)
232 if ret is None:
240 if ret is None:
233 ret = cache[key] = is_ancestor(anc, desc)
241 ret = cache[key] = is_ancestor(anc, desc)
234 return ret
242 return ret
235
243
236 return _is_ancestor
244 return _is_ancestor
237
245
238
246
239 def _changesetforwardcopies(a, b, match):
247 def _changesetforwardcopies(a, b, match):
240 if a.rev() in (nullrev, b.rev()):
248 if a.rev() in (nullrev, b.rev()):
241 return {}
249 return {}
242
250
243 repo = a.repo().unfiltered()
251 repo = a.repo().unfiltered()
244 children = {}
252 children = {}
245
253
246 cl = repo.changelog
254 cl = repo.changelog
247 isancestor = cl.isancestorrev
255 isancestor = cl.isancestorrev
248
256
249 # To track rename from "A" to B, we need to gather all parent β†’ children
257 # To track rename from "A" to B, we need to gather all parent β†’ children
250 # edges that are contains in `::B` but not in `::A`.
258 # edges that are contains in `::B` but not in `::A`.
251 #
259 #
252 #
260 #
253 # To do so, we need to gather all revisions exclusiveΒΉ to "B" (ieΒΉ: `::b -
261 # To do so, we need to gather all revisions exclusiveΒΉ to "B" (ieΒΉ: `::b -
254 # ::a`) and also all the "roots point", ie the parents of the exclusive set
262 # ::a`) and also all the "roots point", ie the parents of the exclusive set
255 # that belong to ::a. These are exactly all the revisions needed to express
263 # that belong to ::a. These are exactly all the revisions needed to express
256 # the parent β†’ children we need to combine.
264 # the parent β†’ children we need to combine.
257 #
265 #
258 # [1] actually, we need to gather all the edges within `(::a)::b`, ie:
266 # [1] actually, we need to gather all the edges within `(::a)::b`, ie:
259 # excluding paths that leads to roots that are not ancestors of `a`. We
267 # excluding paths that leads to roots that are not ancestors of `a`. We
260 # keep this out of the explanation because it is hard enough without this special case..
268 # keep this out of the explanation because it is hard enough without this special case..
261
269
262 parents = cl._uncheckedparentrevs
270 parents = cl._uncheckedparentrevs
263 graph_roots = (nullrev, nullrev)
271 graph_roots = (nullrev, nullrev)
264
272
265 ancestors = cl.ancestors([a.rev()], inclusive=True)
273 ancestors = cl.ancestors([a.rev()], inclusive=True)
266 revs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
274 revs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
267 roots = set()
275 roots = set()
268 has_graph_roots = False
276 has_graph_roots = False
269
277
270 # iterate over `only(B, A)`
278 # iterate over `only(B, A)`
271 for r in revs:
279 for r in revs:
272 ps = parents(r)
280 ps = parents(r)
273 if ps == graph_roots:
281 if ps == graph_roots:
274 has_graph_roots = True
282 has_graph_roots = True
275 else:
283 else:
276 p1, p2 = ps
284 p1, p2 = ps
277
285
278 # find all the "root points" (see larger comment above)
286 # find all the "root points" (see larger comment above)
279 if p1 != nullrev and p1 in ancestors:
287 if p1 != nullrev and p1 in ancestors:
280 roots.add(p1)
288 roots.add(p1)
281 if p2 != nullrev and p2 in ancestors:
289 if p2 != nullrev and p2 in ancestors:
282 roots.add(p2)
290 roots.add(p2)
283 if not roots:
291 if not roots:
284 # no common revision to track copies from
292 # no common revision to track copies from
285 return {}
293 return {}
286 if has_graph_roots:
294 if has_graph_roots:
287 # this deal with the special case mentionned in the [1] footnotes. We
295 # this deal with the special case mentionned in the [1] footnotes. We
288 # must filter out revisions that leads to non-common graphroots.
296 # must filter out revisions that leads to non-common graphroots.
289 roots = list(roots)
297 roots = list(roots)
290 m = min(roots)
298 m = min(roots)
291 h = [b.rev()]
299 h = [b.rev()]
292 roots_to_head = cl.reachableroots(m, h, roots, includepath=True)
300 roots_to_head = cl.reachableroots(m, h, roots, includepath=True)
293 roots_to_head = set(roots_to_head)
301 roots_to_head = set(roots_to_head)
294 revs = [r for r in revs if r in roots_to_head]
302 revs = [r for r in revs if r in roots_to_head]
295
303
296 if repo.filecopiesmode == b'changeset-sidedata':
304 if repo.filecopiesmode == b'changeset-sidedata':
297 # When using side-data, we will process the edges "from" the children.
305 # When using side-data, we will process the edges "from" the children.
298 # We iterate over the childre, gathering previous collected data for
306 # We iterate over the childre, gathering previous collected data for
299 # the parents. Do know when the parents data is no longer necessary, we
307 # the parents. Do know when the parents data is no longer necessary, we
300 # keep a counter of how many children each revision has.
308 # keep a counter of how many children each revision has.
301 #
309 #
302 # An interresting property of `children_count` is that it only contains
310 # An interresting property of `children_count` is that it only contains
303 # revision that will be relevant for a edge of the graph. So if a
311 # revision that will be relevant for a edge of the graph. So if a
304 # children has parent not in `children_count`, that edges should not be
312 # children has parent not in `children_count`, that edges should not be
305 # processed.
313 # processed.
306 children_count = dict((r, 0) for r in roots)
314 children_count = dict((r, 0) for r in roots)
307 for r in revs:
315 for r in revs:
308 for p in cl.parentrevs(r):
316 for p in cl.parentrevs(r):
309 if p == nullrev:
317 if p == nullrev:
310 continue
318 continue
311 children_count[r] = 0
319 children_count[r] = 0
312 if p in children_count:
320 if p in children_count:
313 children_count[p] += 1
321 children_count[p] += 1
314 revinfo = _revinfo_getter(repo, match)
322 revinfo = _revinfo_getter(repo, match)
315 return _combine_changeset_copies(
323 return _combine_changeset_copies(
316 revs, children_count, b.rev(), revinfo, match, isancestor
324 revs, children_count, b.rev(), revinfo, match, isancestor
317 )
325 )
318 else:
326 else:
319 # When not using side-data, we will process the edges "from" the parent.
327 # When not using side-data, we will process the edges "from" the parent.
320 # so we need a full mapping of the parent -> children relation.
328 # so we need a full mapping of the parent -> children relation.
321 children = dict((r, []) for r in roots)
329 children = dict((r, []) for r in roots)
322 for r in revs:
330 for r in revs:
323 for p in cl.parentrevs(r):
331 for p in cl.parentrevs(r):
324 if p == nullrev:
332 if p == nullrev:
325 continue
333 continue
326 children[r] = []
334 children[r] = []
327 if p in children:
335 if p in children:
328 children[p].append(r)
336 children[p].append(r)
329 x = revs.pop()
337 x = revs.pop()
330 assert x == b.rev()
338 assert x == b.rev()
331 revs.extend(roots)
339 revs.extend(roots)
332 revs.sort()
340 revs.sort()
333
341
334 revinfo = _revinfo_getter_extra(repo)
342 revinfo = _revinfo_getter_extra(repo)
335 return _combine_changeset_copies_extra(
343 return _combine_changeset_copies_extra(
336 revs, children, b.rev(), revinfo, match, isancestor
344 revs, children, b.rev(), revinfo, match, isancestor
337 )
345 )
338
346
339
347
340 def _combine_changeset_copies(
348 def _combine_changeset_copies(
341 revs, children_count, targetrev, revinfo, match, isancestor
349 revs, children_count, targetrev, revinfo, match, isancestor
342 ):
350 ):
343 """combine the copies information for each item of iterrevs
351 """combine the copies information for each item of iterrevs
344
352
345 revs: sorted iterable of revision to visit
353 revs: sorted iterable of revision to visit
346 children_count: a {parent: <number-of-relevant-children>} mapping.
354 children_count: a {parent: <number-of-relevant-children>} mapping.
347 targetrev: the final copies destination revision (not in iterrevs)
355 targetrev: the final copies destination revision (not in iterrevs)
348 revinfo(rev): a function that return (p1, p2, p1copies, p2copies, removed)
356 revinfo(rev): a function that return (p1, p2, p1copies, p2copies, removed)
349 match: a matcher
357 match: a matcher
350
358
351 It returns the aggregated copies information for `targetrev`.
359 It returns the aggregated copies information for `targetrev`.
352 """
360 """
353
361
354 alwaysmatch = match.always()
362 alwaysmatch = match.always()
355
363
356 if rustmod is not None:
364 if rustmod is not None:
357 final_copies = rustmod.combine_changeset_copies(
365 final_copies = rustmod.combine_changeset_copies(
358 list(revs), children_count, targetrev, revinfo, isancestor
366 list(revs), children_count, targetrev, revinfo, isancestor
359 )
367 )
360 else:
368 else:
361 isancestor = cached_is_ancestor(isancestor)
369 isancestor = cached_is_ancestor(isancestor)
362
370
363 all_copies = {}
371 all_copies = {}
364 # iterate over all the "children" side of copy tracing "edge"
372 # iterate over all the "children" side of copy tracing "edge"
365 for current_rev in revs:
373 for current_rev in revs:
366 p1, p2, changes = revinfo(current_rev)
374 p1, p2, changes = revinfo(current_rev)
367 current_copies = None
375 current_copies = None
368 # iterate over all parents to chain the existing data with the
376 # iterate over all parents to chain the existing data with the
369 # data from the parent β†’ child edge.
377 # data from the parent β†’ child edge.
370 for parent, parent_rev in ((1, p1), (2, p2)):
378 for parent, parent_rev in ((1, p1), (2, p2)):
371 if parent_rev == nullrev:
379 if parent_rev == nullrev:
372 continue
380 continue
373 remaining_children = children_count.get(parent_rev)
381 remaining_children = children_count.get(parent_rev)
374 if remaining_children is None:
382 if remaining_children is None:
375 continue
383 continue
376 remaining_children -= 1
384 remaining_children -= 1
377 children_count[parent_rev] = remaining_children
385 children_count[parent_rev] = remaining_children
378 if remaining_children:
386 if remaining_children:
379 copies = all_copies.get(parent_rev, None)
387 copies = all_copies.get(parent_rev, None)
380 else:
388 else:
381 copies = all_copies.pop(parent_rev, None)
389 copies = all_copies.pop(parent_rev, None)
382
390
383 if copies is None:
391 if copies is None:
384 # this is a root
392 # this is a root
385 newcopies = copies = {}
393 newcopies = copies = {}
386 elif remaining_children:
394 elif remaining_children:
387 newcopies = copies.copy()
395 newcopies = copies.copy()
388 else:
396 else:
389 newcopies = copies
397 newcopies = copies
390 # chain the data in the edge with the existing data
398 # chain the data in the edge with the existing data
391 if changes is not None:
399 if changes is not None:
392 childcopies = {}
400 childcopies = {}
393 if parent == 1:
401 if parent == 1:
394 childcopies = changes.copied_from_p1
402 childcopies = changes.copied_from_p1
395 elif parent == 2:
403 elif parent == 2:
396 childcopies = changes.copied_from_p2
404 childcopies = changes.copied_from_p2
397
405
398 if childcopies:
406 if childcopies:
399 newcopies = copies.copy()
407 newcopies = copies.copy()
400 for dest, source in pycompat.iteritems(childcopies):
408 for dest, source in pycompat.iteritems(childcopies):
401 prev = copies.get(source)
409 prev = copies.get(source)
402 if prev is not None and prev[1] is not None:
410 if prev is not None and prev[1] is not None:
403 source = prev[1]
411 source = prev[1]
404 newcopies[dest] = (current_rev, source)
412 newcopies[dest] = (current_rev, source)
405 assert newcopies is not copies
413 assert newcopies is not copies
406 if changes.removed:
414 if changes.removed:
407 for f in changes.removed:
415 for f in changes.removed:
408 if f in newcopies:
416 if f in newcopies:
409 if newcopies is copies:
417 if newcopies is copies:
410 # copy on write to avoid affecting potential other
418 # copy on write to avoid affecting potential other
411 # branches. when there are no other branches, this
419 # branches. when there are no other branches, this
412 # could be avoided.
420 # could be avoided.
413 newcopies = copies.copy()
421 newcopies = copies.copy()
414 newcopies[f] = (current_rev, None)
422 newcopies[f] = (current_rev, None)
415 # check potential need to combine the data from another parent (for
423 # check potential need to combine the data from another parent (for
416 # that child). See comment below for details.
424 # that child). See comment below for details.
417 if current_copies is None:
425 if current_copies is None:
418 current_copies = newcopies
426 current_copies = newcopies
419 else:
427 else:
420 # we are the second parent to work on c, we need to merge our
428 # we are the second parent to work on c, we need to merge our
421 # work with the other.
429 # work with the other.
422 #
430 #
423 # In case of conflict, parent 1 take precedence over parent 2.
431 # In case of conflict, parent 1 take precedence over parent 2.
424 # This is an arbitrary choice made anew when implementing
432 # This is an arbitrary choice made anew when implementing
425 # changeset based copies. It was made without regards with
433 # changeset based copies. It was made without regards with
426 # potential filelog related behavior.
434 # potential filelog related behavior.
427 assert parent == 2
435 assert parent == 2
428 current_copies = _merge_copies_dict(
436 current_copies = _merge_copies_dict(
429 newcopies, current_copies, isancestor, changes
437 newcopies, current_copies, isancestor, changes
430 )
438 )
431 all_copies[current_rev] = current_copies
439 all_copies[current_rev] = current_copies
432
440
433 # filter out internal details and return a {dest: source mapping}
441 # filter out internal details and return a {dest: source mapping}
434 final_copies = {}
442 final_copies = {}
435 for dest, (tt, source) in all_copies[targetrev].items():
443 for dest, (tt, source) in all_copies[targetrev].items():
436 if source is not None:
444 if source is not None:
437 final_copies[dest] = source
445 final_copies[dest] = source
438 if not alwaysmatch:
446 if not alwaysmatch:
439 for filename in list(final_copies.keys()):
447 for filename in list(final_copies.keys()):
440 if not match(filename):
448 if not match(filename):
441 del final_copies[filename]
449 del final_copies[filename]
442 return final_copies
450 return final_copies
443
451
444
452
445 # constant to decide which side to pick with _merge_copies_dict
453 # constant to decide which side to pick with _merge_copies_dict
446 PICK_MINOR = 0
454 PICK_MINOR = 0
447 PICK_MAJOR = 1
455 PICK_MAJOR = 1
448 PICK_EITHER = 2
456 PICK_EITHER = 2
449
457
450
458
451 def _merge_copies_dict(minor, major, isancestor, changes):
459 def _merge_copies_dict(minor, major, isancestor, changes):
452 """merge two copies-mapping together, minor and major
460 """merge two copies-mapping together, minor and major
453
461
454 In case of conflict, value from "major" will be picked.
462 In case of conflict, value from "major" will be picked.
455
463
456 - `isancestors(low_rev, high_rev)`: callable return True if `low_rev` is an
464 - `isancestors(low_rev, high_rev)`: callable return True if `low_rev` is an
457 ancestors of `high_rev`,
465 ancestors of `high_rev`,
458
466
459 - `ismerged(path)`: callable return True if `path` have been merged in the
467 - `ismerged(path)`: callable return True if `path` have been merged in the
460 current revision,
468 current revision,
461
469
462 return the resulting dict (in practice, the "minor" object, updated)
470 return the resulting dict (in practice, the "minor" object, updated)
463 """
471 """
464 for dest, value in major.items():
472 for dest, value in major.items():
465 other = minor.get(dest)
473 other = minor.get(dest)
466 if other is None:
474 if other is None:
467 minor[dest] = value
475 minor[dest] = value
468 else:
476 else:
469 pick = _compare_values(changes, isancestor, dest, other, value)
477 pick = _compare_values(changes, isancestor, dest, other, value)
470 if pick == PICK_MAJOR:
478 if pick == PICK_MAJOR:
471 minor[dest] = value
479 minor[dest] = value
472 return minor
480 return minor
473
481
474
482
475 def _compare_values(changes, isancestor, dest, minor, major):
483 def _compare_values(changes, isancestor, dest, minor, major):
476 """compare two value within a _merge_copies_dict loop iteration"""
484 """compare two value within a _merge_copies_dict loop iteration"""
477 major_tt, major_value = major
485 major_tt, major_value = major
478 minor_tt, minor_value = minor
486 minor_tt, minor_value = minor
479
487
480 # evacuate some simple case first:
488 # evacuate some simple case first:
481 if major_tt == minor_tt:
489 if major_tt == minor_tt:
482 # if it comes from the same revision it must be the same value
490 # if it comes from the same revision it must be the same value
483 assert major_value == minor_value
491 assert major_value == minor_value
484 return PICK_EITHER
492 return PICK_EITHER
485 elif major[1] == minor[1]:
493 elif major[1] == minor[1]:
486 return PICK_EITHER
494 return PICK_EITHER
487
495
488 # actual merging needed: content from "major" wins, unless it is older than
496 # actual merging needed: content from "major" wins, unless it is older than
489 # the branch point or there is a merge
497 # the branch point or there is a merge
490 elif changes is not None and major[1] is None and dest in changes.salvaged:
498 elif changes is not None and major[1] is None and dest in changes.salvaged:
491 return PICK_MINOR
499 return PICK_MINOR
492 elif changes is not None and minor[1] is None and dest in changes.salvaged:
500 elif changes is not None and minor[1] is None and dest in changes.salvaged:
493 return PICK_MAJOR
501 return PICK_MAJOR
494 elif changes is not None and dest in changes.merged:
502 elif changes is not None and dest in changes.merged:
495 return PICK_MAJOR
503 return PICK_MAJOR
496 elif not isancestor(major_tt, minor_tt):
504 elif not isancestor(major_tt, minor_tt):
497 if major[1] is not None:
505 if major[1] is not None:
498 return PICK_MAJOR
506 return PICK_MAJOR
499 elif isancestor(minor_tt, major_tt):
507 elif isancestor(minor_tt, major_tt):
500 return PICK_MAJOR
508 return PICK_MAJOR
501 return PICK_MINOR
509 return PICK_MINOR
502
510
503
511
504 def _revinfo_getter_extra(repo):
512 def _revinfo_getter_extra(repo):
505 """return a function that return multiple data given a <rev>"i
513 """return a function that return multiple data given a <rev>"i
506
514
507 * p1: revision number of first parent
515 * p1: revision number of first parent
508 * p2: revision number of first parent
516 * p2: revision number of first parent
509 * p1copies: mapping of copies from p1
517 * p1copies: mapping of copies from p1
510 * p2copies: mapping of copies from p2
518 * p2copies: mapping of copies from p2
511 * removed: a list of removed files
519 * removed: a list of removed files
512 * ismerged: a callback to know if file was merged in that revision
520 * ismerged: a callback to know if file was merged in that revision
513 """
521 """
514 cl = repo.changelog
522 cl = repo.changelog
515 parents = cl.parentrevs
523 parents = cl.parentrevs
516
524
517 def get_ismerged(rev):
525 def get_ismerged(rev):
518 ctx = repo[rev]
526 ctx = repo[rev]
519
527
520 def ismerged(path):
528 def ismerged(path):
521 if path not in ctx.files():
529 if path not in ctx.files():
522 return False
530 return False
523 fctx = ctx[path]
531 fctx = ctx[path]
524 parents = fctx._filelog.parents(fctx._filenode)
532 parents = fctx._filelog.parents(fctx._filenode)
525 nb_parents = 0
533 nb_parents = 0
526 for n in parents:
534 for n in parents:
527 if n != nullid:
535 if n != nullid:
528 nb_parents += 1
536 nb_parents += 1
529 return nb_parents >= 2
537 return nb_parents >= 2
530
538
531 return ismerged
539 return ismerged
532
540
533 def revinfo(rev):
541 def revinfo(rev):
534 p1, p2 = parents(rev)
542 p1, p2 = parents(rev)
535 ctx = repo[rev]
543 ctx = repo[rev]
536 p1copies, p2copies = ctx._copies
544 p1copies, p2copies = ctx._copies
537 removed = ctx.filesremoved()
545 removed = ctx.filesremoved()
538 return p1, p2, p1copies, p2copies, removed, get_ismerged(rev)
546 return p1, p2, p1copies, p2copies, removed, get_ismerged(rev)
539
547
540 return revinfo
548 return revinfo
541
549
542
550
543 def _combine_changeset_copies_extra(
551 def _combine_changeset_copies_extra(
544 revs, children, targetrev, revinfo, match, isancestor
552 revs, children, targetrev, revinfo, match, isancestor
545 ):
553 ):
546 """version of `_combine_changeset_copies` that works with the Google
554 """version of `_combine_changeset_copies` that works with the Google
547 specific "extra" based storage for copy information"""
555 specific "extra" based storage for copy information"""
548 all_copies = {}
556 all_copies = {}
549 alwaysmatch = match.always()
557 alwaysmatch = match.always()
550 for r in revs:
558 for r in revs:
551 copies = all_copies.pop(r, None)
559 copies = all_copies.pop(r, None)
552 if copies is None:
560 if copies is None:
553 # this is a root
561 # this is a root
554 copies = {}
562 copies = {}
555 for i, c in enumerate(children[r]):
563 for i, c in enumerate(children[r]):
556 p1, p2, p1copies, p2copies, removed, ismerged = revinfo(c)
564 p1, p2, p1copies, p2copies, removed, ismerged = revinfo(c)
557 if r == p1:
565 if r == p1:
558 parent = 1
566 parent = 1
559 childcopies = p1copies
567 childcopies = p1copies
560 else:
568 else:
561 assert r == p2
569 assert r == p2
562 parent = 2
570 parent = 2
563 childcopies = p2copies
571 childcopies = p2copies
564 if not alwaysmatch:
572 if not alwaysmatch:
565 childcopies = {
573 childcopies = {
566 dst: src for dst, src in childcopies.items() if match(dst)
574 dst: src for dst, src in childcopies.items() if match(dst)
567 }
575 }
568 newcopies = copies
576 newcopies = copies
569 if childcopies:
577 if childcopies:
570 newcopies = copies.copy()
578 newcopies = copies.copy()
571 for dest, source in pycompat.iteritems(childcopies):
579 for dest, source in pycompat.iteritems(childcopies):
572 prev = copies.get(source)
580 prev = copies.get(source)
573 if prev is not None and prev[1] is not None:
581 if prev is not None and prev[1] is not None:
574 source = prev[1]
582 source = prev[1]
575 newcopies[dest] = (c, source)
583 newcopies[dest] = (c, source)
576 assert newcopies is not copies
584 assert newcopies is not copies
577 for f in removed:
585 for f in removed:
578 if f in newcopies:
586 if f in newcopies:
579 if newcopies is copies:
587 if newcopies is copies:
580 # copy on write to avoid affecting potential other
588 # copy on write to avoid affecting potential other
581 # branches. when there are no other branches, this
589 # branches. when there are no other branches, this
582 # could be avoided.
590 # could be avoided.
583 newcopies = copies.copy()
591 newcopies = copies.copy()
584 newcopies[f] = (c, None)
592 newcopies[f] = (c, None)
585 othercopies = all_copies.get(c)
593 othercopies = all_copies.get(c)
586 if othercopies is None:
594 if othercopies is None:
587 all_copies[c] = newcopies
595 all_copies[c] = newcopies
588 else:
596 else:
589 # we are the second parent to work on c, we need to merge our
597 # we are the second parent to work on c, we need to merge our
590 # work with the other.
598 # work with the other.
591 #
599 #
592 # In case of conflict, parent 1 take precedence over parent 2.
600 # In case of conflict, parent 1 take precedence over parent 2.
593 # This is an arbitrary choice made anew when implementing
601 # This is an arbitrary choice made anew when implementing
594 # changeset based copies. It was made without regards with
602 # changeset based copies. It was made without regards with
595 # potential filelog related behavior.
603 # potential filelog related behavior.
596 if parent == 1:
604 if parent == 1:
597 _merge_copies_dict_extra(
605 _merge_copies_dict_extra(
598 othercopies, newcopies, isancestor, ismerged
606 othercopies, newcopies, isancestor, ismerged
599 )
607 )
600 else:
608 else:
601 _merge_copies_dict_extra(
609 _merge_copies_dict_extra(
602 newcopies, othercopies, isancestor, ismerged
610 newcopies, othercopies, isancestor, ismerged
603 )
611 )
604 all_copies[c] = newcopies
612 all_copies[c] = newcopies
605
613
606 final_copies = {}
614 final_copies = {}
607 for dest, (tt, source) in all_copies[targetrev].items():
615 for dest, (tt, source) in all_copies[targetrev].items():
608 if source is not None:
616 if source is not None:
609 final_copies[dest] = source
617 final_copies[dest] = source
610 return final_copies
618 return final_copies
611
619
612
620
613 def _merge_copies_dict_extra(minor, major, isancestor, ismerged):
621 def _merge_copies_dict_extra(minor, major, isancestor, ismerged):
614 """version of `_merge_copies_dict` that works with the Google
622 """version of `_merge_copies_dict` that works with the Google
615 specific "extra" based storage for copy information"""
623 specific "extra" based storage for copy information"""
616 for dest, value in major.items():
624 for dest, value in major.items():
617 other = minor.get(dest)
625 other = minor.get(dest)
618 if other is None:
626 if other is None:
619 minor[dest] = value
627 minor[dest] = value
620 else:
628 else:
621 new_tt = value[0]
629 new_tt = value[0]
622 other_tt = other[0]
630 other_tt = other[0]
623 if value[1] == other[1]:
631 if value[1] == other[1]:
624 continue
632 continue
625 # content from "major" wins, unless it is older
633 # content from "major" wins, unless it is older
626 # than the branch point or there is a merge
634 # than the branch point or there is a merge
627 if (
635 if (
628 new_tt == other_tt
636 new_tt == other_tt
629 or not isancestor(new_tt, other_tt)
637 or not isancestor(new_tt, other_tt)
630 or ismerged(dest)
638 or ismerged(dest)
631 ):
639 ):
632 minor[dest] = value
640 minor[dest] = value
633
641
634
642
635 def _forwardcopies(a, b, base=None, match=None):
643 def _forwardcopies(a, b, base=None, match=None):
636 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
644 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
637
645
638 if base is None:
646 if base is None:
639 base = a
647 base = a
640 match = a.repo().narrowmatch(match)
648 match = a.repo().narrowmatch(match)
641 # check for working copy
649 # check for working copy
642 if b.rev() is None:
650 if b.rev() is None:
643 cm = _committedforwardcopies(a, b.p1(), base, match)
651 cm = _committedforwardcopies(a, b.p1(), base, match)
644 # combine copies from dirstate if necessary
652 # combine copies from dirstate if necessary
645 copies = _chain(cm, _dirstatecopies(b._repo, match))
653 copies = _chain(cm, _dirstatecopies(b._repo, match))
646 else:
654 else:
647 copies = _committedforwardcopies(a, b, base, match)
655 copies = _committedforwardcopies(a, b, base, match)
648 return copies
656 return copies
649
657
650
658
651 def _backwardrenames(a, b, match):
659 def _backwardrenames(a, b, match):
652 if a._repo.ui.config(b'experimental', b'copytrace') == b'off':
660 if a._repo.ui.config(b'experimental', b'copytrace') == b'off':
653 return {}
661 return {}
654
662
655 # Even though we're not taking copies into account, 1:n rename situations
663 # Even though we're not taking copies into account, 1:n rename situations
656 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
664 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
657 # arbitrarily pick one of the renames.
665 # arbitrarily pick one of the renames.
658 # We don't want to pass in "match" here, since that would filter
666 # We don't want to pass in "match" here, since that would filter
659 # the destination by it. Since we're reversing the copies, we want
667 # the destination by it. Since we're reversing the copies, we want
660 # to filter the source instead.
668 # to filter the source instead.
661 f = _forwardcopies(b, a)
669 f = _forwardcopies(b, a)
662 r = {}
670 r = {}
663 for k, v in sorted(pycompat.iteritems(f)):
671 for k, v in sorted(pycompat.iteritems(f)):
664 if match and not match(v):
672 if match and not match(v):
665 continue
673 continue
666 # remove copies
674 # remove copies
667 if v in a:
675 if v in a:
668 continue
676 continue
669 r[v] = k
677 r[v] = k
670 return r
678 return r
671
679
672
680
673 def pathcopies(x, y, match=None):
681 def pathcopies(x, y, match=None):
674 """find {dst@y: src@x} copy mapping for directed compare"""
682 """find {dst@y: src@x} copy mapping for directed compare"""
675 repo = x._repo
683 repo = x._repo
676 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
684 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
677 if debug:
685 if debug:
678 repo.ui.debug(
686 repo.ui.debug(
679 b'debug.copies: searching copies from %s to %s\n' % (x, y)
687 b'debug.copies: searching copies from %s to %s\n' % (x, y)
680 )
688 )
681 if x == y or not x or not y:
689 if x == y or not x or not y:
682 return {}
690 return {}
683 if y.rev() is None and x == y.p1():
691 if y.rev() is None and x == y.p1():
684 if debug:
692 if debug:
685 repo.ui.debug(b'debug.copies: search mode: dirstate\n')
693 repo.ui.debug(b'debug.copies: search mode: dirstate\n')
686 # short-circuit to avoid issues with merge states
694 # short-circuit to avoid issues with merge states
687 return _dirstatecopies(repo, match)
695 return _dirstatecopies(repo, match)
688 a = y.ancestor(x)
696 a = y.ancestor(x)
689 if a == x:
697 if a == x:
690 if debug:
698 if debug:
691 repo.ui.debug(b'debug.copies: search mode: forward\n')
699 repo.ui.debug(b'debug.copies: search mode: forward\n')
692 copies = _forwardcopies(x, y, match=match)
700 copies = _forwardcopies(x, y, match=match)
693 elif a == y:
701 elif a == y:
694 if debug:
702 if debug:
695 repo.ui.debug(b'debug.copies: search mode: backward\n')
703 repo.ui.debug(b'debug.copies: search mode: backward\n')
696 copies = _backwardrenames(x, y, match=match)
704 copies = _backwardrenames(x, y, match=match)
697 else:
705 else:
698 if debug:
706 if debug:
699 repo.ui.debug(b'debug.copies: search mode: combined\n')
707 repo.ui.debug(b'debug.copies: search mode: combined\n')
700 base = None
708 base = None
701 if a.rev() != nullrev:
709 if a.rev() != nullrev:
702 base = x
710 base = x
703 copies = _chain(
711 copies = _chain(
704 _backwardrenames(x, a, match=match),
712 _backwardrenames(x, a, match=match),
705 _forwardcopies(a, y, base, match=match),
713 _forwardcopies(a, y, base, match=match),
706 )
714 )
707 _filter(x, y, copies)
715 _filter(x, y, copies)
708 return copies
716 return copies
709
717
710
718
711 def mergecopies(repo, c1, c2, base):
719 def mergecopies(repo, c1, c2, base):
712 """
720 """
713 Finds moves and copies between context c1 and c2 that are relevant for
721 Finds moves and copies between context c1 and c2 that are relevant for
714 merging. 'base' will be used as the merge base.
722 merging. 'base' will be used as the merge base.
715
723
716 Copytracing is used in commands like rebase, merge, unshelve, etc to merge
724 Copytracing is used in commands like rebase, merge, unshelve, etc to merge
717 files that were moved/ copied in one merge parent and modified in another.
725 files that were moved/ copied in one merge parent and modified in another.
718 For example:
726 For example:
719
727
720 o ---> 4 another commit
728 o ---> 4 another commit
721 |
729 |
722 | o ---> 3 commit that modifies a.txt
730 | o ---> 3 commit that modifies a.txt
723 | /
731 | /
724 o / ---> 2 commit that moves a.txt to b.txt
732 o / ---> 2 commit that moves a.txt to b.txt
725 |/
733 |/
726 o ---> 1 merge base
734 o ---> 1 merge base
727
735
728 If we try to rebase revision 3 on revision 4, since there is no a.txt in
736 If we try to rebase revision 3 on revision 4, since there is no a.txt in
729 revision 4, and if user have copytrace disabled, we prints the following
737 revision 4, and if user have copytrace disabled, we prints the following
730 message:
738 message:
731
739
732 ```other changed <file> which local deleted```
740 ```other changed <file> which local deleted```
733
741
734 Returns a tuple where:
742 Returns a tuple where:
735
743
736 "branch_copies" an instance of branch_copies.
744 "branch_copies" an instance of branch_copies.
737
745
738 "diverge" is a mapping of source name -> list of destination names
746 "diverge" is a mapping of source name -> list of destination names
739 for divergent renames.
747 for divergent renames.
740
748
741 This function calls different copytracing algorithms based on config.
749 This function calls different copytracing algorithms based on config.
742 """
750 """
743 # avoid silly behavior for update from empty dir
751 # avoid silly behavior for update from empty dir
744 if not c1 or not c2 or c1 == c2:
752 if not c1 or not c2 or c1 == c2:
745 return branch_copies(), branch_copies(), {}
753 return branch_copies(), branch_copies(), {}
746
754
747 narrowmatch = c1.repo().narrowmatch()
755 narrowmatch = c1.repo().narrowmatch()
748
756
749 # avoid silly behavior for parent -> working dir
757 # avoid silly behavior for parent -> working dir
750 if c2.node() is None and c1.node() == repo.dirstate.p1():
758 if c2.node() is None and c1.node() == repo.dirstate.p1():
751 return (
759 return (
752 branch_copies(_dirstatecopies(repo, narrowmatch)),
760 branch_copies(_dirstatecopies(repo, narrowmatch)),
753 branch_copies(),
761 branch_copies(),
754 {},
762 {},
755 )
763 )
756
764
757 copytracing = repo.ui.config(b'experimental', b'copytrace')
765 copytracing = repo.ui.config(b'experimental', b'copytrace')
758 if stringutil.parsebool(copytracing) is False:
766 if stringutil.parsebool(copytracing) is False:
759 # stringutil.parsebool() returns None when it is unable to parse the
767 # stringutil.parsebool() returns None when it is unable to parse the
760 # value, so we should rely on making sure copytracing is on such cases
768 # value, so we should rely on making sure copytracing is on such cases
761 return branch_copies(), branch_copies(), {}
769 return branch_copies(), branch_copies(), {}
762
770
763 if usechangesetcentricalgo(repo):
771 if usechangesetcentricalgo(repo):
764 # The heuristics don't make sense when we need changeset-centric algos
772 # The heuristics don't make sense when we need changeset-centric algos
765 return _fullcopytracing(repo, c1, c2, base)
773 return _fullcopytracing(repo, c1, c2, base)
766
774
767 # Copy trace disabling is explicitly below the node == p1 logic above
775 # Copy trace disabling is explicitly below the node == p1 logic above
768 # because the logic above is required for a simple copy to be kept across a
776 # because the logic above is required for a simple copy to be kept across a
769 # rebase.
777 # rebase.
770 if copytracing == b'heuristics':
778 if copytracing == b'heuristics':
771 # Do full copytracing if only non-public revisions are involved as
779 # Do full copytracing if only non-public revisions are involved as
772 # that will be fast enough and will also cover the copies which could
780 # that will be fast enough and will also cover the copies which could
773 # be missed by heuristics
781 # be missed by heuristics
774 if _isfullcopytraceable(repo, c1, base):
782 if _isfullcopytraceable(repo, c1, base):
775 return _fullcopytracing(repo, c1, c2, base)
783 return _fullcopytracing(repo, c1, c2, base)
776 return _heuristicscopytracing(repo, c1, c2, base)
784 return _heuristicscopytracing(repo, c1, c2, base)
777 else:
785 else:
778 return _fullcopytracing(repo, c1, c2, base)
786 return _fullcopytracing(repo, c1, c2, base)
779
787
780
788
781 def _isfullcopytraceable(repo, c1, base):
789 def _isfullcopytraceable(repo, c1, base):
782 """Checks that if base, source and destination are all no-public branches,
790 """Checks that if base, source and destination are all no-public branches,
783 if yes let's use the full copytrace algorithm for increased capabilities
791 if yes let's use the full copytrace algorithm for increased capabilities
784 since it will be fast enough.
792 since it will be fast enough.
785
793
786 `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
794 `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
787 number of changesets from c1 to base such that if number of changesets are
795 number of changesets from c1 to base such that if number of changesets are
788 more than the limit, full copytracing algorithm won't be used.
796 more than the limit, full copytracing algorithm won't be used.
789 """
797 """
790 if c1.rev() is None:
798 if c1.rev() is None:
791 c1 = c1.p1()
799 c1 = c1.p1()
792 if c1.mutable() and base.mutable():
800 if c1.mutable() and base.mutable():
793 sourcecommitlimit = repo.ui.configint(
801 sourcecommitlimit = repo.ui.configint(
794 b'experimental', b'copytrace.sourcecommitlimit'
802 b'experimental', b'copytrace.sourcecommitlimit'
795 )
803 )
796 commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
804 commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
797 return commits < sourcecommitlimit
805 return commits < sourcecommitlimit
798 return False
806 return False
799
807
800
808
801 def _checksinglesidecopies(
809 def _checksinglesidecopies(
802 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
810 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
803 ):
811 ):
804 if src not in m2:
812 if src not in m2:
805 # deleted on side 2
813 # deleted on side 2
806 if src not in m1:
814 if src not in m1:
807 # renamed on side 1, deleted on side 2
815 # renamed on side 1, deleted on side 2
808 renamedelete[src] = dsts1
816 renamedelete[src] = dsts1
809 elif src not in mb:
817 elif src not in mb:
810 # Work around the "short-circuit to avoid issues with merge states"
818 # Work around the "short-circuit to avoid issues with merge states"
811 # thing in pathcopies(): pathcopies(x, y) can return a copy where the
819 # thing in pathcopies(): pathcopies(x, y) can return a copy where the
812 # destination doesn't exist in y.
820 # destination doesn't exist in y.
813 pass
821 pass
814 elif mb[src] != m2[src] and not _related(c2[src], base[src]):
822 elif mb[src] != m2[src] and not _related(c2[src], base[src]):
815 return
823 return
816 elif mb[src] != m2[src] or mb.flags(src) != m2.flags(src):
824 elif mb[src] != m2[src] or mb.flags(src) != m2.flags(src):
817 # modified on side 2
825 # modified on side 2
818 for dst in dsts1:
826 for dst in dsts1:
819 copy[dst] = src
827 copy[dst] = src
820
828
821
829
822 class branch_copies(object):
830 class branch_copies(object):
823 """Information about copies made on one side of a merge/graft.
831 """Information about copies made on one side of a merge/graft.
824
832
825 "copy" is a mapping from destination name -> source name,
833 "copy" is a mapping from destination name -> source name,
826 where source is in c1 and destination is in c2 or vice-versa.
834 where source is in c1 and destination is in c2 or vice-versa.
827
835
828 "movewithdir" is a mapping from source name -> destination name,
836 "movewithdir" is a mapping from source name -> destination name,
829 where the file at source present in one context but not the other
837 where the file at source present in one context but not the other
830 needs to be moved to destination by the merge process, because the
838 needs to be moved to destination by the merge process, because the
831 other context moved the directory it is in.
839 other context moved the directory it is in.
832
840
833 "renamedelete" is a mapping of source name -> list of destination
841 "renamedelete" is a mapping of source name -> list of destination
834 names for files deleted in c1 that were renamed in c2 or vice-versa.
842 names for files deleted in c1 that were renamed in c2 or vice-versa.
835
843
836 "dirmove" is a mapping of detected source dir -> destination dir renames.
844 "dirmove" is a mapping of detected source dir -> destination dir renames.
837 This is needed for handling changes to new files previously grafted into
845 This is needed for handling changes to new files previously grafted into
838 renamed directories.
846 renamed directories.
839 """
847 """
840
848
841 def __init__(
849 def __init__(
842 self, copy=None, renamedelete=None, dirmove=None, movewithdir=None
850 self, copy=None, renamedelete=None, dirmove=None, movewithdir=None
843 ):
851 ):
844 self.copy = {} if copy is None else copy
852 self.copy = {} if copy is None else copy
845 self.renamedelete = {} if renamedelete is None else renamedelete
853 self.renamedelete = {} if renamedelete is None else renamedelete
846 self.dirmove = {} if dirmove is None else dirmove
854 self.dirmove = {} if dirmove is None else dirmove
847 self.movewithdir = {} if movewithdir is None else movewithdir
855 self.movewithdir = {} if movewithdir is None else movewithdir
848
856
849 def __repr__(self):
857 def __repr__(self):
850 return '<branch_copies\n copy=%r\n renamedelete=%r\n dirmove=%r\n movewithdir=%r\n>' % (
858 return '<branch_copies\n copy=%r\n renamedelete=%r\n dirmove=%r\n movewithdir=%r\n>' % (
851 self.copy,
859 self.copy,
852 self.renamedelete,
860 self.renamedelete,
853 self.dirmove,
861 self.dirmove,
854 self.movewithdir,
862 self.movewithdir,
855 )
863 )
856
864
857
865
858 def _fullcopytracing(repo, c1, c2, base):
866 def _fullcopytracing(repo, c1, c2, base):
859 """The full copytracing algorithm which finds all the new files that were
867 """The full copytracing algorithm which finds all the new files that were
860 added from merge base up to the top commit and for each file it checks if
868 added from merge base up to the top commit and for each file it checks if
861 this file was copied from another file.
869 this file was copied from another file.
862
870
863 This is pretty slow when a lot of changesets are involved but will track all
871 This is pretty slow when a lot of changesets are involved but will track all
864 the copies.
872 the copies.
865 """
873 """
866 m1 = c1.manifest()
874 m1 = c1.manifest()
867 m2 = c2.manifest()
875 m2 = c2.manifest()
868 mb = base.manifest()
876 mb = base.manifest()
869
877
870 copies1 = pathcopies(base, c1)
878 copies1 = pathcopies(base, c1)
871 copies2 = pathcopies(base, c2)
879 copies2 = pathcopies(base, c2)
872
880
873 if not (copies1 or copies2):
881 if not (copies1 or copies2):
874 return branch_copies(), branch_copies(), {}
882 return branch_copies(), branch_copies(), {}
875
883
876 inversecopies1 = {}
884 inversecopies1 = {}
877 inversecopies2 = {}
885 inversecopies2 = {}
878 for dst, src in copies1.items():
886 for dst, src in copies1.items():
879 inversecopies1.setdefault(src, []).append(dst)
887 inversecopies1.setdefault(src, []).append(dst)
880 for dst, src in copies2.items():
888 for dst, src in copies2.items():
881 inversecopies2.setdefault(src, []).append(dst)
889 inversecopies2.setdefault(src, []).append(dst)
882
890
883 copy1 = {}
891 copy1 = {}
884 copy2 = {}
892 copy2 = {}
885 diverge = {}
893 diverge = {}
886 renamedelete1 = {}
894 renamedelete1 = {}
887 renamedelete2 = {}
895 renamedelete2 = {}
888 allsources = set(inversecopies1) | set(inversecopies2)
896 allsources = set(inversecopies1) | set(inversecopies2)
889 for src in allsources:
897 for src in allsources:
890 dsts1 = inversecopies1.get(src)
898 dsts1 = inversecopies1.get(src)
891 dsts2 = inversecopies2.get(src)
899 dsts2 = inversecopies2.get(src)
892 if dsts1 and dsts2:
900 if dsts1 and dsts2:
893 # copied/renamed on both sides
901 # copied/renamed on both sides
894 if src not in m1 and src not in m2:
902 if src not in m1 and src not in m2:
895 # renamed on both sides
903 # renamed on both sides
896 dsts1 = set(dsts1)
904 dsts1 = set(dsts1)
897 dsts2 = set(dsts2)
905 dsts2 = set(dsts2)
898 # If there's some overlap in the rename destinations, we
906 # If there's some overlap in the rename destinations, we
899 # consider it not divergent. For example, if side 1 copies 'a'
907 # consider it not divergent. For example, if side 1 copies 'a'
900 # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
908 # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
901 # and 'd' and deletes 'a'.
909 # and 'd' and deletes 'a'.
902 if dsts1 & dsts2:
910 if dsts1 & dsts2:
903 for dst in dsts1 & dsts2:
911 for dst in dsts1 & dsts2:
904 copy1[dst] = src
912 copy1[dst] = src
905 copy2[dst] = src
913 copy2[dst] = src
906 else:
914 else:
907 diverge[src] = sorted(dsts1 | dsts2)
915 diverge[src] = sorted(dsts1 | dsts2)
908 elif src in m1 and src in m2:
916 elif src in m1 and src in m2:
909 # copied on both sides
917 # copied on both sides
910 dsts1 = set(dsts1)
918 dsts1 = set(dsts1)
911 dsts2 = set(dsts2)
919 dsts2 = set(dsts2)
912 for dst in dsts1 & dsts2:
920 for dst in dsts1 & dsts2:
913 copy1[dst] = src
921 copy1[dst] = src
914 copy2[dst] = src
922 copy2[dst] = src
915 # TODO: Handle cases where it was renamed on one side and copied
923 # TODO: Handle cases where it was renamed on one side and copied
916 # on the other side
924 # on the other side
917 elif dsts1:
925 elif dsts1:
918 # copied/renamed only on side 1
926 # copied/renamed only on side 1
919 _checksinglesidecopies(
927 _checksinglesidecopies(
920 src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
928 src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
921 )
929 )
922 elif dsts2:
930 elif dsts2:
923 # copied/renamed only on side 2
931 # copied/renamed only on side 2
924 _checksinglesidecopies(
932 _checksinglesidecopies(
925 src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
933 src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
926 )
934 )
927
935
928 # find interesting file sets from manifests
936 # find interesting file sets from manifests
929 cache = []
937 cache = []
930
938
931 def _get_addedfiles(idx):
939 def _get_addedfiles(idx):
932 if not cache:
940 if not cache:
933 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
941 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
934 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
942 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
935 u1 = sorted(addedinm1 - addedinm2)
943 u1 = sorted(addedinm1 - addedinm2)
936 u2 = sorted(addedinm2 - addedinm1)
944 u2 = sorted(addedinm2 - addedinm1)
937 cache.extend((u1, u2))
945 cache.extend((u1, u2))
938 return cache[idx]
946 return cache[idx]
939
947
940 u1fn = lambda: _get_addedfiles(0)
948 u1fn = lambda: _get_addedfiles(0)
941 u2fn = lambda: _get_addedfiles(1)
949 u2fn = lambda: _get_addedfiles(1)
942 if repo.ui.debugflag:
950 if repo.ui.debugflag:
943 u1 = u1fn()
951 u1 = u1fn()
944 u2 = u2fn()
952 u2 = u2fn()
945
953
946 header = b" unmatched files in %s"
954 header = b" unmatched files in %s"
947 if u1:
955 if u1:
948 repo.ui.debug(
956 repo.ui.debug(
949 b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1))
957 b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1))
950 )
958 )
951 if u2:
959 if u2:
952 repo.ui.debug(
960 repo.ui.debug(
953 b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2))
961 b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2))
954 )
962 )
955
963
956 renamedeleteset = set()
964 renamedeleteset = set()
957 divergeset = set()
965 divergeset = set()
958 for dsts in diverge.values():
966 for dsts in diverge.values():
959 divergeset.update(dsts)
967 divergeset.update(dsts)
960 for dsts in renamedelete1.values():
968 for dsts in renamedelete1.values():
961 renamedeleteset.update(dsts)
969 renamedeleteset.update(dsts)
962 for dsts in renamedelete2.values():
970 for dsts in renamedelete2.values():
963 renamedeleteset.update(dsts)
971 renamedeleteset.update(dsts)
964
972
965 repo.ui.debug(
973 repo.ui.debug(
966 b" all copies found (* = to merge, ! = divergent, "
974 b" all copies found (* = to merge, ! = divergent, "
967 b"% = renamed and deleted):\n"
975 b"% = renamed and deleted):\n"
968 )
976 )
969 for side, copies in ((b"local", copies1), (b"remote", copies2)):
977 for side, copies in ((b"local", copies1), (b"remote", copies2)):
970 if not copies:
978 if not copies:
971 continue
979 continue
972 repo.ui.debug(b" on %s side:\n" % side)
980 repo.ui.debug(b" on %s side:\n" % side)
973 for f in sorted(copies):
981 for f in sorted(copies):
974 note = b""
982 note = b""
975 if f in copy1 or f in copy2:
983 if f in copy1 or f in copy2:
976 note += b"*"
984 note += b"*"
977 if f in divergeset:
985 if f in divergeset:
978 note += b"!"
986 note += b"!"
979 if f in renamedeleteset:
987 if f in renamedeleteset:
980 note += b"%"
988 note += b"%"
981 repo.ui.debug(
989 repo.ui.debug(
982 b" src: '%s' -> dst: '%s' %s\n" % (copies[f], f, note)
990 b" src: '%s' -> dst: '%s' %s\n" % (copies[f], f, note)
983 )
991 )
984 del renamedeleteset
992 del renamedeleteset
985 del divergeset
993 del divergeset
986
994
987 repo.ui.debug(b" checking for directory renames\n")
995 repo.ui.debug(b" checking for directory renames\n")
988
996
989 dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2fn)
997 dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2fn)
990 dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
998 dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
991
999
992 branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1)
1000 branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1)
993 branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2)
1001 branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2)
994
1002
995 return branch_copies1, branch_copies2, diverge
1003 return branch_copies1, branch_copies2, diverge
996
1004
997
1005
998 def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
1006 def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
999 """Finds moved directories and files that should move with them.
1007 """Finds moved directories and files that should move with them.
1000
1008
1001 ctx: the context for one of the sides
1009 ctx: the context for one of the sides
1002 copy: files copied on the same side (as ctx)
1010 copy: files copied on the same side (as ctx)
1003 fullcopy: files copied on the same side (as ctx), including those that
1011 fullcopy: files copied on the same side (as ctx), including those that
1004 merge.manifestmerge() won't care about
1012 merge.manifestmerge() won't care about
1005 addedfilesfn: function returning added files on the other side (compared to
1013 addedfilesfn: function returning added files on the other side (compared to
1006 ctx)
1014 ctx)
1007 """
1015 """
1008 # generate a directory move map
1016 # generate a directory move map
1009 invalid = set()
1017 invalid = set()
1010 dirmove = {}
1018 dirmove = {}
1011
1019
1012 # examine each file copy for a potential directory move, which is
1020 # examine each file copy for a potential directory move, which is
1013 # when all the files in a directory are moved to a new directory
1021 # when all the files in a directory are moved to a new directory
1014 for dst, src in pycompat.iteritems(fullcopy):
1022 for dst, src in pycompat.iteritems(fullcopy):
1015 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
1023 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
1016 if dsrc in invalid:
1024 if dsrc in invalid:
1017 # already seen to be uninteresting
1025 # already seen to be uninteresting
1018 continue
1026 continue
1019 elif ctx.hasdir(dsrc) and ctx.hasdir(ddst):
1027 elif ctx.hasdir(dsrc) and ctx.hasdir(ddst):
1020 # directory wasn't entirely moved locally
1028 # directory wasn't entirely moved locally
1021 invalid.add(dsrc)
1029 invalid.add(dsrc)
1022 elif dsrc in dirmove and dirmove[dsrc] != ddst:
1030 elif dsrc in dirmove and dirmove[dsrc] != ddst:
1023 # files from the same directory moved to two different places
1031 # files from the same directory moved to two different places
1024 invalid.add(dsrc)
1032 invalid.add(dsrc)
1025 else:
1033 else:
1026 # looks good so far
1034 # looks good so far
1027 dirmove[dsrc] = ddst
1035 dirmove[dsrc] = ddst
1028
1036
1029 for i in invalid:
1037 for i in invalid:
1030 if i in dirmove:
1038 if i in dirmove:
1031 del dirmove[i]
1039 del dirmove[i]
1032 del invalid
1040 del invalid
1033
1041
1034 if not dirmove:
1042 if not dirmove:
1035 return {}, {}
1043 return {}, {}
1036
1044
1037 dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
1045 dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
1038
1046
1039 for d in dirmove:
1047 for d in dirmove:
1040 repo.ui.debug(
1048 repo.ui.debug(
1041 b" discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
1049 b" discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
1042 )
1050 )
1043
1051
1044 movewithdir = {}
1052 movewithdir = {}
1045 # check unaccounted nonoverlapping files against directory moves
1053 # check unaccounted nonoverlapping files against directory moves
1046 for f in addedfilesfn():
1054 for f in addedfilesfn():
1047 if f not in fullcopy:
1055 if f not in fullcopy:
1048 for d in dirmove:
1056 for d in dirmove:
1049 if f.startswith(d):
1057 if f.startswith(d):
1050 # new file added in a directory that was moved, move it
1058 # new file added in a directory that was moved, move it
1051 df = dirmove[d] + f[len(d) :]
1059 df = dirmove[d] + f[len(d) :]
1052 if df not in copy:
1060 if df not in copy:
1053 movewithdir[f] = df
1061 movewithdir[f] = df
1054 repo.ui.debug(
1062 repo.ui.debug(
1055 b" pending file src: '%s' -> dst: '%s'\n"
1063 b" pending file src: '%s' -> dst: '%s'\n"
1056 % (f, df)
1064 % (f, df)
1057 )
1065 )
1058 break
1066 break
1059
1067
1060 return dirmove, movewithdir
1068 return dirmove, movewithdir
1061
1069
1062
1070
1063 def _heuristicscopytracing(repo, c1, c2, base):
1071 def _heuristicscopytracing(repo, c1, c2, base):
1064 """Fast copytracing using filename heuristics
1072 """Fast copytracing using filename heuristics
1065
1073
1066 Assumes that moves or renames are of following two types:
1074 Assumes that moves or renames are of following two types:
1067
1075
1068 1) Inside a directory only (same directory name but different filenames)
1076 1) Inside a directory only (same directory name but different filenames)
1069 2) Move from one directory to another
1077 2) Move from one directory to another
1070 (same filenames but different directory names)
1078 (same filenames but different directory names)
1071
1079
1072 Works only when there are no merge commits in the "source branch".
1080 Works only when there are no merge commits in the "source branch".
1073 Source branch is commits from base up to c2 not including base.
1081 Source branch is commits from base up to c2 not including base.
1074
1082
1075 If merge is involved it fallbacks to _fullcopytracing().
1083 If merge is involved it fallbacks to _fullcopytracing().
1076
1084
1077 Can be used by setting the following config:
1085 Can be used by setting the following config:
1078
1086
1079 [experimental]
1087 [experimental]
1080 copytrace = heuristics
1088 copytrace = heuristics
1081
1089
1082 In some cases the copy/move candidates found by heuristics can be very large
1090 In some cases the copy/move candidates found by heuristics can be very large
1083 in number and that will make the algorithm slow. The number of possible
1091 in number and that will make the algorithm slow. The number of possible
1084 candidates to check can be limited by using the config
1092 candidates to check can be limited by using the config
1085 `experimental.copytrace.movecandidateslimit` which defaults to 100.
1093 `experimental.copytrace.movecandidateslimit` which defaults to 100.
1086 """
1094 """
1087
1095
1088 if c1.rev() is None:
1096 if c1.rev() is None:
1089 c1 = c1.p1()
1097 c1 = c1.p1()
1090 if c2.rev() is None:
1098 if c2.rev() is None:
1091 c2 = c2.p1()
1099 c2 = c2.p1()
1092
1100
1093 changedfiles = set()
1101 changedfiles = set()
1094 m1 = c1.manifest()
1102 m1 = c1.manifest()
1095 if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
1103 if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
1096 # If base is not in c2 branch, we switch to fullcopytracing
1104 # If base is not in c2 branch, we switch to fullcopytracing
1097 repo.ui.debug(
1105 repo.ui.debug(
1098 b"switching to full copytracing as base is not "
1106 b"switching to full copytracing as base is not "
1099 b"an ancestor of c2\n"
1107 b"an ancestor of c2\n"
1100 )
1108 )
1101 return _fullcopytracing(repo, c1, c2, base)
1109 return _fullcopytracing(repo, c1, c2, base)
1102
1110
1103 ctx = c2
1111 ctx = c2
1104 while ctx != base:
1112 while ctx != base:
1105 if len(ctx.parents()) == 2:
1113 if len(ctx.parents()) == 2:
1106 # To keep things simple let's not handle merges
1114 # To keep things simple let's not handle merges
1107 repo.ui.debug(b"switching to full copytracing because of merges\n")
1115 repo.ui.debug(b"switching to full copytracing because of merges\n")
1108 return _fullcopytracing(repo, c1, c2, base)
1116 return _fullcopytracing(repo, c1, c2, base)
1109 changedfiles.update(ctx.files())
1117 changedfiles.update(ctx.files())
1110 ctx = ctx.p1()
1118 ctx = ctx.p1()
1111
1119
1112 copies2 = {}
1120 copies2 = {}
1113 cp = _forwardcopies(base, c2)
1121 cp = _forwardcopies(base, c2)
1114 for dst, src in pycompat.iteritems(cp):
1122 for dst, src in pycompat.iteritems(cp):
1115 if src in m1:
1123 if src in m1:
1116 copies2[dst] = src
1124 copies2[dst] = src
1117
1125
1118 # file is missing if it isn't present in the destination, but is present in
1126 # file is missing if it isn't present in the destination, but is present in
1119 # the base and present in the source.
1127 # the base and present in the source.
1120 # Presence in the base is important to exclude added files, presence in the
1128 # Presence in the base is important to exclude added files, presence in the
1121 # source is important to exclude removed files.
1129 # source is important to exclude removed files.
1122 filt = lambda f: f not in m1 and f in base and f in c2
1130 filt = lambda f: f not in m1 and f in base and f in c2
1123 missingfiles = [f for f in changedfiles if filt(f)]
1131 missingfiles = [f for f in changedfiles if filt(f)]
1124
1132
1125 copies1 = {}
1133 copies1 = {}
1126 if missingfiles:
1134 if missingfiles:
1127 basenametofilename = collections.defaultdict(list)
1135 basenametofilename = collections.defaultdict(list)
1128 dirnametofilename = collections.defaultdict(list)
1136 dirnametofilename = collections.defaultdict(list)
1129
1137
1130 for f in m1.filesnotin(base.manifest()):
1138 for f in m1.filesnotin(base.manifest()):
1131 basename = os.path.basename(f)
1139 basename = os.path.basename(f)
1132 dirname = os.path.dirname(f)
1140 dirname = os.path.dirname(f)
1133 basenametofilename[basename].append(f)
1141 basenametofilename[basename].append(f)
1134 dirnametofilename[dirname].append(f)
1142 dirnametofilename[dirname].append(f)
1135
1143
1136 for f in missingfiles:
1144 for f in missingfiles:
1137 basename = os.path.basename(f)
1145 basename = os.path.basename(f)
1138 dirname = os.path.dirname(f)
1146 dirname = os.path.dirname(f)
1139 samebasename = basenametofilename[basename]
1147 samebasename = basenametofilename[basename]
1140 samedirname = dirnametofilename[dirname]
1148 samedirname = dirnametofilename[dirname]
1141 movecandidates = samebasename + samedirname
1149 movecandidates = samebasename + samedirname
1142 # f is guaranteed to be present in c2, that's why
1150 # f is guaranteed to be present in c2, that's why
1143 # c2.filectx(f) won't fail
1151 # c2.filectx(f) won't fail
1144 f2 = c2.filectx(f)
1152 f2 = c2.filectx(f)
1145 # we can have a lot of candidates which can slow down the heuristics
1153 # we can have a lot of candidates which can slow down the heuristics
1146 # config value to limit the number of candidates moves to check
1154 # config value to limit the number of candidates moves to check
1147 maxcandidates = repo.ui.configint(
1155 maxcandidates = repo.ui.configint(
1148 b'experimental', b'copytrace.movecandidateslimit'
1156 b'experimental', b'copytrace.movecandidateslimit'
1149 )
1157 )
1150
1158
1151 if len(movecandidates) > maxcandidates:
1159 if len(movecandidates) > maxcandidates:
1152 repo.ui.status(
1160 repo.ui.status(
1153 _(
1161 _(
1154 b"skipping copytracing for '%s', more "
1162 b"skipping copytracing for '%s', more "
1155 b"candidates than the limit: %d\n"
1163 b"candidates than the limit: %d\n"
1156 )
1164 )
1157 % (f, len(movecandidates))
1165 % (f, len(movecandidates))
1158 )
1166 )
1159 continue
1167 continue
1160
1168
1161 for candidate in movecandidates:
1169 for candidate in movecandidates:
1162 f1 = c1.filectx(candidate)
1170 f1 = c1.filectx(candidate)
1163 if _related(f1, f2):
1171 if _related(f1, f2):
1164 # if there are a few related copies then we'll merge
1172 # if there are a few related copies then we'll merge
1165 # changes into all of them. This matches the behaviour
1173 # changes into all of them. This matches the behaviour
1166 # of upstream copytracing
1174 # of upstream copytracing
1167 copies1[candidate] = f
1175 copies1[candidate] = f
1168
1176
1169 return branch_copies(copies1), branch_copies(copies2), {}
1177 return branch_copies(copies1), branch_copies(copies2), {}
1170
1178
1171
1179
1172 def _related(f1, f2):
1180 def _related(f1, f2):
1173 """return True if f1 and f2 filectx have a common ancestor
1181 """return True if f1 and f2 filectx have a common ancestor
1174
1182
1175 Walk back to common ancestor to see if the two files originate
1183 Walk back to common ancestor to see if the two files originate
1176 from the same file. Since workingfilectx's rev() is None it messes
1184 from the same file. Since workingfilectx's rev() is None it messes
1177 up the integer comparison logic, hence the pre-step check for
1185 up the integer comparison logic, hence the pre-step check for
1178 None (f1 and f2 can only be workingfilectx's initially).
1186 None (f1 and f2 can only be workingfilectx's initially).
1179 """
1187 """
1180
1188
1181 if f1 == f2:
1189 if f1 == f2:
1182 return True # a match
1190 return True # a match
1183
1191
1184 g1, g2 = f1.ancestors(), f2.ancestors()
1192 g1, g2 = f1.ancestors(), f2.ancestors()
1185 try:
1193 try:
1186 f1r, f2r = f1.linkrev(), f2.linkrev()
1194 f1r, f2r = f1.linkrev(), f2.linkrev()
1187
1195
1188 if f1r is None:
1196 if f1r is None:
1189 f1 = next(g1)
1197 f1 = next(g1)
1190 if f2r is None:
1198 if f2r is None:
1191 f2 = next(g2)
1199 f2 = next(g2)
1192
1200
1193 while True:
1201 while True:
1194 f1r, f2r = f1.linkrev(), f2.linkrev()
1202 f1r, f2r = f1.linkrev(), f2.linkrev()
1195 if f1r > f2r:
1203 if f1r > f2r:
1196 f1 = next(g1)
1204 f1 = next(g1)
1197 elif f2r > f1r:
1205 elif f2r > f1r:
1198 f2 = next(g2)
1206 f2 = next(g2)
1199 else: # f1 and f2 point to files in the same linkrev
1207 else: # f1 and f2 point to files in the same linkrev
1200 return f1 == f2 # true if they point to the same file
1208 return f1 == f2 # true if they point to the same file
1201 except StopIteration:
1209 except StopIteration:
1202 return False
1210 return False
1203
1211
1204
1212
1205 def graftcopies(wctx, ctx, base):
1213 def graftcopies(wctx, ctx, base):
1206 """reproduce copies between base and ctx in the wctx
1214 """reproduce copies between base and ctx in the wctx
1207
1215
1208 Unlike mergecopies(), this function will only consider copies between base
1216 Unlike mergecopies(), this function will only consider copies between base
1209 and ctx; it will ignore copies between base and wctx. Also unlike
1217 and ctx; it will ignore copies between base and wctx. Also unlike
1210 mergecopies(), this function will apply copies to the working copy (instead
1218 mergecopies(), this function will apply copies to the working copy (instead
1211 of just returning information about the copies). That makes it cheaper
1219 of just returning information about the copies). That makes it cheaper
1212 (especially in the common case of base==ctx.p1()) and useful also when
1220 (especially in the common case of base==ctx.p1()) and useful also when
1213 experimental.copytrace=off.
1221 experimental.copytrace=off.
1214
1222
1215 merge.update() will have already marked most copies, but it will only
1223 merge.update() will have already marked most copies, but it will only
1216 mark copies if it thinks the source files are related (see
1224 mark copies if it thinks the source files are related (see
1217 merge._related()). It will also not mark copies if the file wasn't modified
1225 merge._related()). It will also not mark copies if the file wasn't modified
1218 on the local side. This function adds the copies that were "missed"
1226 on the local side. This function adds the copies that were "missed"
1219 by merge.update().
1227 by merge.update().
1220 """
1228 """
1221 new_copies = pathcopies(base, ctx)
1229 new_copies = pathcopies(base, ctx)
1222 parent = wctx.p1()
1230 parent = wctx.p1()
1223 _filter(parent, wctx, new_copies)
1231 _filter(parent, wctx, new_copies)
1224 # extra filtering to drop copy information for files that existed before
1232 # extra filtering to drop copy information for files that existed before
1225 # the graft (otherwise we would create merge filelog for non-merge commit
1233 # the graft (otherwise we would create merge filelog for non-merge commit
1226 for dest, __ in list(new_copies.items()):
1234 for dest, __ in list(new_copies.items()):
1227 if dest in parent:
1235 if dest in parent:
1228 del new_copies[dest]
1236 del new_copies[dest]
1229 for dst, src in pycompat.iteritems(new_copies):
1237 for dst, src in pycompat.iteritems(new_copies):
1230 wctx[dst].markcopied(src)
1238 wctx[dst].markcopied(src)
@@ -1,721 +1,725 b''
1 #testcases filelog compatibility changeset sidedata
1 #testcases filelog compatibility changeset sidedata
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > rebase=
5 > rebase=
6 > [alias]
6 > [alias]
7 > l = log -G -T '{rev} {desc}\n{files}\n'
7 > l = log -G -T '{rev} {desc}\n{files}\n'
8 > EOF
8 > EOF
9
9
10 #if compatibility
10 #if compatibility
11 $ cat >> $HGRCPATH << EOF
11 $ cat >> $HGRCPATH << EOF
12 > [experimental]
12 > [experimental]
13 > copies.read-from = compatibility
13 > copies.read-from = compatibility
14 > EOF
14 > EOF
15 #endif
15 #endif
16
16
17 #if changeset
17 #if changeset
18 $ cat >> $HGRCPATH << EOF
18 $ cat >> $HGRCPATH << EOF
19 > [experimental]
19 > [experimental]
20 > copies.read-from = changeset-only
20 > copies.read-from = changeset-only
21 > copies.write-to = changeset-only
21 > copies.write-to = changeset-only
22 > EOF
22 > EOF
23 #endif
23 #endif
24
24
25 #if sidedata
25 #if sidedata
26 $ cat >> $HGRCPATH << EOF
26 $ cat >> $HGRCPATH << EOF
27 > [format]
27 > [format]
28 > exp-use-copies-side-data-changeset = yes
28 > exp-use-copies-side-data-changeset = yes
29 > EOF
29 > EOF
30 #endif
30 #endif
31
31
32 $ REPONUM=0
32 $ REPONUM=0
33 $ newrepo() {
33 $ newrepo() {
34 > cd $TESTTMP
34 > cd $TESTTMP
35 > REPONUM=`expr $REPONUM + 1`
35 > REPONUM=`expr $REPONUM + 1`
36 > hg init repo-$REPONUM
36 > hg init repo-$REPONUM
37 > cd repo-$REPONUM
37 > cd repo-$REPONUM
38 > }
38 > }
39
39
40 Simple rename case
40 Simple rename case
41 $ newrepo
41 $ newrepo
42 $ echo x > x
42 $ echo x > x
43 $ hg ci -Aqm 'add x'
43 $ hg ci -Aqm 'add x'
44 $ hg mv x y
44 $ hg mv x y
45 $ hg debugp1copies
45 $ hg debugp1copies
46 x -> y
46 x -> y
47 $ hg debugp2copies
47 $ hg debugp2copies
48 $ hg ci -m 'rename x to y'
48 $ hg ci -m 'rename x to y'
49 $ hg l
49 $ hg l
50 @ 1 rename x to y
50 @ 1 rename x to y
51 | x y
51 | x y
52 o 0 add x
52 o 0 add x
53 x
53 x
54 $ hg debugp1copies -r 1
54 $ hg debugp1copies -r 1
55 x -> y
55 x -> y
56 $ hg debugpathcopies 0 1
56 $ hg debugpathcopies 0 1
57 x -> y
57 x -> y
58 $ hg debugpathcopies 1 0
58 $ hg debugpathcopies 1 0
59 y -> x
59 y -> x
60 Test filtering copies by path. We do filtering by destination.
60 Test filtering copies by path. We do filtering by destination.
61 $ hg debugpathcopies 0 1 x
61 $ hg debugpathcopies 0 1 x
62 $ hg debugpathcopies 1 0 x
62 $ hg debugpathcopies 1 0 x
63 y -> x
63 y -> x
64 $ hg debugpathcopies 0 1 y
64 $ hg debugpathcopies 0 1 y
65 x -> y
65 x -> y
66 $ hg debugpathcopies 1 0 y
66 $ hg debugpathcopies 1 0 y
67
67
68 Copies not including commit changes
68 Copies not including commit changes
69 $ newrepo
69 $ newrepo
70 $ echo x > x
70 $ echo x > x
71 $ hg ci -Aqm 'add x'
71 $ hg ci -Aqm 'add x'
72 $ hg mv x y
72 $ hg mv x y
73 $ hg debugpathcopies . .
73 $ hg debugpathcopies . .
74 $ hg debugpathcopies . 'wdir()'
74 $ hg debugpathcopies . 'wdir()'
75 x -> y
75 x -> y
76 $ hg debugpathcopies 'wdir()' .
76 $ hg debugpathcopies 'wdir()' .
77 y -> x
77 y -> x
78
78
79 Copy a file onto another file
79 Copy a file onto another file
80 $ newrepo
80 $ newrepo
81 $ echo x > x
81 $ echo x > x
82 $ echo y > y
82 $ echo y > y
83 $ hg ci -Aqm 'add x and y'
83 $ hg ci -Aqm 'add x and y'
84 $ hg cp -f x y
84 $ hg cp -f x y
85 $ hg debugp1copies
85 $ hg debugp1copies
86 x -> y
86 x -> y
87 $ hg debugp2copies
87 $ hg debugp2copies
88 $ hg ci -m 'copy x onto y'
88 $ hg ci -m 'copy x onto y'
89 $ hg l
89 $ hg l
90 @ 1 copy x onto y
90 @ 1 copy x onto y
91 | y
91 | y
92 o 0 add x and y
92 o 0 add x and y
93 x y
93 x y
94 $ hg debugp1copies -r 1
94 $ hg debugp1copies -r 1
95 x -> y
95 x -> y
96 $ hg debugpathcopies 0 1
96 $ hg debugpathcopies 0 1
97 x -> y (no-filelog !)
97 x -> y (no-filelog !)
98 $ hg debugpathcopies 0 1 --config devel.copy-tracing.trace-all-files=yes
99 x -> y
98
100
99 Copy a file onto another file with same content. If metadata is stored in changeset, this does not
101 Copy a file onto another file with same content. If metadata is stored in changeset, this does not
100 produce a new filelog entry. The changeset's "files" entry should still list the file.
102 produce a new filelog entry. The changeset's "files" entry should still list the file.
101 $ newrepo
103 $ newrepo
102 $ echo x > x
104 $ echo x > x
103 $ echo x > x2
105 $ echo x > x2
104 $ hg ci -Aqm 'add x and x2 with same content'
106 $ hg ci -Aqm 'add x and x2 with same content'
105 $ hg cp -f x x2
107 $ hg cp -f x x2
106 $ hg ci -m 'copy x onto x2'
108 $ hg ci -m 'copy x onto x2'
107 $ hg l
109 $ hg l
108 @ 1 copy x onto x2
110 @ 1 copy x onto x2
109 | x2
111 | x2
110 o 0 add x and x2 with same content
112 o 0 add x and x2 with same content
111 x x2
113 x x2
112 $ hg debugp1copies -r 1
114 $ hg debugp1copies -r 1
113 x -> x2
115 x -> x2
114 $ hg debugpathcopies 0 1
116 $ hg debugpathcopies 0 1
115 x -> x2 (no-filelog !)
117 x -> x2 (no-filelog !)
118 $ hg debugpathcopies 0 1 --config devel.copy-tracing.trace-all-files=yes
119 x -> x2
116
120
117 Rename file in a loop: x->y->z->x
121 Rename file in a loop: x->y->z->x
118 $ newrepo
122 $ newrepo
119 $ echo x > x
123 $ echo x > x
120 $ hg ci -Aqm 'add x'
124 $ hg ci -Aqm 'add x'
121 $ hg mv x y
125 $ hg mv x y
122 $ hg debugp1copies
126 $ hg debugp1copies
123 x -> y
127 x -> y
124 $ hg debugp2copies
128 $ hg debugp2copies
125 $ hg ci -m 'rename x to y'
129 $ hg ci -m 'rename x to y'
126 $ hg mv y z
130 $ hg mv y z
127 $ hg ci -m 'rename y to z'
131 $ hg ci -m 'rename y to z'
128 $ hg mv z x
132 $ hg mv z x
129 $ hg ci -m 'rename z to x'
133 $ hg ci -m 'rename z to x'
130 $ hg l
134 $ hg l
131 @ 3 rename z to x
135 @ 3 rename z to x
132 | x z
136 | x z
133 o 2 rename y to z
137 o 2 rename y to z
134 | y z
138 | y z
135 o 1 rename x to y
139 o 1 rename x to y
136 | x y
140 | x y
137 o 0 add x
141 o 0 add x
138 x
142 x
139 $ hg debugpathcopies 0 3
143 $ hg debugpathcopies 0 3
140
144
141 Copy x to z, then remove z, then copy x2 (same content as x) to z. With copy metadata in the
145 Copy x to z, then remove z, then copy x2 (same content as x) to z. With copy metadata in the
142 changeset, the two copies here will have the same filelog entry, so ctx['z'].introrev() might point
146 changeset, the two copies here will have the same filelog entry, so ctx['z'].introrev() might point
143 to the first commit that added the file. We should still report the copy as being from x2.
147 to the first commit that added the file. We should still report the copy as being from x2.
144 $ newrepo
148 $ newrepo
145 $ echo x > x
149 $ echo x > x
146 $ echo x > x2
150 $ echo x > x2
147 $ hg ci -Aqm 'add x and x2 with same content'
151 $ hg ci -Aqm 'add x and x2 with same content'
148 $ hg cp x z
152 $ hg cp x z
149 $ hg ci -qm 'copy x to z'
153 $ hg ci -qm 'copy x to z'
150 $ hg rm z
154 $ hg rm z
151 $ hg ci -m 'remove z'
155 $ hg ci -m 'remove z'
152 $ hg cp x2 z
156 $ hg cp x2 z
153 $ hg ci -m 'copy x2 to z'
157 $ hg ci -m 'copy x2 to z'
154 $ hg l
158 $ hg l
155 @ 3 copy x2 to z
159 @ 3 copy x2 to z
156 | z
160 | z
157 o 2 remove z
161 o 2 remove z
158 | z
162 | z
159 o 1 copy x to z
163 o 1 copy x to z
160 | z
164 | z
161 o 0 add x and x2 with same content
165 o 0 add x and x2 with same content
162 x x2
166 x x2
163 $ hg debugp1copies -r 3
167 $ hg debugp1copies -r 3
164 x2 -> z
168 x2 -> z
165 $ hg debugpathcopies 0 3
169 $ hg debugpathcopies 0 3
166 x2 -> z
170 x2 -> z
167
171
168 Create x and y, then rename them both to the same name, but on different sides of a fork
172 Create x and y, then rename them both to the same name, but on different sides of a fork
169 $ newrepo
173 $ newrepo
170 $ echo x > x
174 $ echo x > x
171 $ echo y > y
175 $ echo y > y
172 $ hg ci -Aqm 'add x and y'
176 $ hg ci -Aqm 'add x and y'
173 $ hg mv x z
177 $ hg mv x z
174 $ hg ci -qm 'rename x to z'
178 $ hg ci -qm 'rename x to z'
175 $ hg co -q 0
179 $ hg co -q 0
176 $ hg mv y z
180 $ hg mv y z
177 $ hg ci -qm 'rename y to z'
181 $ hg ci -qm 'rename y to z'
178 $ hg l
182 $ hg l
179 @ 2 rename y to z
183 @ 2 rename y to z
180 | y z
184 | y z
181 | o 1 rename x to z
185 | o 1 rename x to z
182 |/ x z
186 |/ x z
183 o 0 add x and y
187 o 0 add x and y
184 x y
188 x y
185 $ hg debugpathcopies 1 2
189 $ hg debugpathcopies 1 2
186 z -> x
190 z -> x
187 y -> z
191 y -> z
188
192
189 Fork renames x to y on one side and removes x on the other
193 Fork renames x to y on one side and removes x on the other
190 $ newrepo
194 $ newrepo
191 $ echo x > x
195 $ echo x > x
192 $ hg ci -Aqm 'add x'
196 $ hg ci -Aqm 'add x'
193 $ hg mv x y
197 $ hg mv x y
194 $ hg ci -m 'rename x to y'
198 $ hg ci -m 'rename x to y'
195 $ hg co -q 0
199 $ hg co -q 0
196 $ hg rm x
200 $ hg rm x
197 $ hg ci -m 'remove x'
201 $ hg ci -m 'remove x'
198 created new head
202 created new head
199 $ hg l
203 $ hg l
200 @ 2 remove x
204 @ 2 remove x
201 | x
205 | x
202 | o 1 rename x to y
206 | o 1 rename x to y
203 |/ x y
207 |/ x y
204 o 0 add x
208 o 0 add x
205 x
209 x
206 $ hg debugpathcopies 1 2
210 $ hg debugpathcopies 1 2
207
211
208 Merge rename from other branch
212 Merge rename from other branch
209 $ newrepo
213 $ newrepo
210 $ echo x > x
214 $ echo x > x
211 $ hg ci -Aqm 'add x'
215 $ hg ci -Aqm 'add x'
212 $ hg mv x y
216 $ hg mv x y
213 $ hg ci -m 'rename x to y'
217 $ hg ci -m 'rename x to y'
214 $ hg co -q 0
218 $ hg co -q 0
215 $ echo z > z
219 $ echo z > z
216 $ hg ci -Aqm 'add z'
220 $ hg ci -Aqm 'add z'
217 $ hg merge -q 1
221 $ hg merge -q 1
218 $ hg debugp1copies
222 $ hg debugp1copies
219 $ hg debugp2copies
223 $ hg debugp2copies
220 $ hg ci -m 'merge rename from p2'
224 $ hg ci -m 'merge rename from p2'
221 $ hg l
225 $ hg l
222 @ 3 merge rename from p2
226 @ 3 merge rename from p2
223 |\
227 |\
224 | o 2 add z
228 | o 2 add z
225 | | z
229 | | z
226 o | 1 rename x to y
230 o | 1 rename x to y
227 |/ x y
231 |/ x y
228 o 0 add x
232 o 0 add x
229 x
233 x
230 Perhaps we should indicate the rename here, but `hg status` is documented to be weird during
234 Perhaps we should indicate the rename here, but `hg status` is documented to be weird during
231 merges, so...
235 merges, so...
232 $ hg debugp1copies -r 3
236 $ hg debugp1copies -r 3
233 $ hg debugp2copies -r 3
237 $ hg debugp2copies -r 3
234 $ hg debugpathcopies 0 3
238 $ hg debugpathcopies 0 3
235 x -> y
239 x -> y
236 $ hg debugpathcopies 1 2
240 $ hg debugpathcopies 1 2
237 y -> x
241 y -> x
238 $ hg debugpathcopies 1 3
242 $ hg debugpathcopies 1 3
239 $ hg debugpathcopies 2 3
243 $ hg debugpathcopies 2 3
240 x -> y
244 x -> y
241
245
242 Copy file from either side in a merge
246 Copy file from either side in a merge
243 $ newrepo
247 $ newrepo
244 $ echo x > x
248 $ echo x > x
245 $ hg ci -Aqm 'add x'
249 $ hg ci -Aqm 'add x'
246 $ hg co -q null
250 $ hg co -q null
247 $ echo y > y
251 $ echo y > y
248 $ hg ci -Aqm 'add y'
252 $ hg ci -Aqm 'add y'
249 $ hg merge -q 0
253 $ hg merge -q 0
250 $ hg cp y z
254 $ hg cp y z
251 $ hg debugp1copies
255 $ hg debugp1copies
252 y -> z
256 y -> z
253 $ hg debugp2copies
257 $ hg debugp2copies
254 $ hg ci -m 'copy file from p1 in merge'
258 $ hg ci -m 'copy file from p1 in merge'
255 $ hg co -q 1
259 $ hg co -q 1
256 $ hg merge -q 0
260 $ hg merge -q 0
257 $ hg cp x z
261 $ hg cp x z
258 $ hg debugp1copies
262 $ hg debugp1copies
259 $ hg debugp2copies
263 $ hg debugp2copies
260 x -> z
264 x -> z
261 $ hg ci -qm 'copy file from p2 in merge'
265 $ hg ci -qm 'copy file from p2 in merge'
262 $ hg l
266 $ hg l
263 @ 3 copy file from p2 in merge
267 @ 3 copy file from p2 in merge
264 |\ z
268 |\ z
265 +---o 2 copy file from p1 in merge
269 +---o 2 copy file from p1 in merge
266 | |/ z
270 | |/ z
267 | o 1 add y
271 | o 1 add y
268 | y
272 | y
269 o 0 add x
273 o 0 add x
270 x
274 x
271 $ hg debugp1copies -r 2
275 $ hg debugp1copies -r 2
272 y -> z
276 y -> z
273 $ hg debugp2copies -r 2
277 $ hg debugp2copies -r 2
274 $ hg debugpathcopies 1 2
278 $ hg debugpathcopies 1 2
275 y -> z
279 y -> z
276 $ hg debugpathcopies 0 2
280 $ hg debugpathcopies 0 2
277 $ hg debugp1copies -r 3
281 $ hg debugp1copies -r 3
278 $ hg debugp2copies -r 3
282 $ hg debugp2copies -r 3
279 x -> z
283 x -> z
280 $ hg debugpathcopies 1 3
284 $ hg debugpathcopies 1 3
281 $ hg debugpathcopies 0 3
285 $ hg debugpathcopies 0 3
282 x -> z
286 x -> z
283
287
284 Copy file that exists on both sides of the merge, same content on both sides
288 Copy file that exists on both sides of the merge, same content on both sides
285 $ newrepo
289 $ newrepo
286 $ echo x > x
290 $ echo x > x
287 $ hg ci -Aqm 'add x on branch 1'
291 $ hg ci -Aqm 'add x on branch 1'
288 $ hg co -q null
292 $ hg co -q null
289 $ echo x > x
293 $ echo x > x
290 $ hg ci -Aqm 'add x on branch 2'
294 $ hg ci -Aqm 'add x on branch 2'
291 $ hg merge -q 0
295 $ hg merge -q 0
292 $ hg cp x z
296 $ hg cp x z
293 $ hg debugp1copies
297 $ hg debugp1copies
294 x -> z
298 x -> z
295 $ hg debugp2copies
299 $ hg debugp2copies
296 $ hg ci -qm 'merge'
300 $ hg ci -qm 'merge'
297 $ hg l
301 $ hg l
298 @ 2 merge
302 @ 2 merge
299 |\ z
303 |\ z
300 | o 1 add x on branch 2
304 | o 1 add x on branch 2
301 | x
305 | x
302 o 0 add x on branch 1
306 o 0 add x on branch 1
303 x
307 x
304 $ hg debugp1copies -r 2
308 $ hg debugp1copies -r 2
305 x -> z
309 x -> z
306 $ hg debugp2copies -r 2
310 $ hg debugp2copies -r 2
307 It's a little weird that it shows up on both sides
311 It's a little weird that it shows up on both sides
308 $ hg debugpathcopies 1 2
312 $ hg debugpathcopies 1 2
309 x -> z
313 x -> z
310 $ hg debugpathcopies 0 2
314 $ hg debugpathcopies 0 2
311 x -> z (filelog !)
315 x -> z (filelog !)
312
316
313 Copy file that exists on both sides of the merge, different content
317 Copy file that exists on both sides of the merge, different content
314 $ newrepo
318 $ newrepo
315 $ echo branch1 > x
319 $ echo branch1 > x
316 $ hg ci -Aqm 'add x on branch 1'
320 $ hg ci -Aqm 'add x on branch 1'
317 $ hg co -q null
321 $ hg co -q null
318 $ echo branch2 > x
322 $ echo branch2 > x
319 $ hg ci -Aqm 'add x on branch 2'
323 $ hg ci -Aqm 'add x on branch 2'
320 $ hg merge -q 0
324 $ hg merge -q 0
321 warning: conflicts while merging x! (edit, then use 'hg resolve --mark')
325 warning: conflicts while merging x! (edit, then use 'hg resolve --mark')
322 [1]
326 [1]
323 $ echo resolved > x
327 $ echo resolved > x
324 $ hg resolve -m x
328 $ hg resolve -m x
325 (no more unresolved files)
329 (no more unresolved files)
326 $ hg cp x z
330 $ hg cp x z
327 $ hg debugp1copies
331 $ hg debugp1copies
328 x -> z
332 x -> z
329 $ hg debugp2copies
333 $ hg debugp2copies
330 $ hg ci -qm 'merge'
334 $ hg ci -qm 'merge'
331 $ hg l
335 $ hg l
332 @ 2 merge
336 @ 2 merge
333 |\ x z
337 |\ x z
334 | o 1 add x on branch 2
338 | o 1 add x on branch 2
335 | x
339 | x
336 o 0 add x on branch 1
340 o 0 add x on branch 1
337 x
341 x
338 $ hg debugp1copies -r 2
342 $ hg debugp1copies -r 2
339 x -> z (changeset !)
343 x -> z (changeset !)
340 x -> z (sidedata !)
344 x -> z (sidedata !)
341 $ hg debugp2copies -r 2
345 $ hg debugp2copies -r 2
342 x -> z (no-changeset no-sidedata !)
346 x -> z (no-changeset no-sidedata !)
343 $ hg debugpathcopies 1 2
347 $ hg debugpathcopies 1 2
344 x -> z (changeset !)
348 x -> z (changeset !)
345 x -> z (sidedata !)
349 x -> z (sidedata !)
346 $ hg debugpathcopies 0 2
350 $ hg debugpathcopies 0 2
347 x -> z (no-changeset no-sidedata !)
351 x -> z (no-changeset no-sidedata !)
348
352
349 Copy x->y on one side of merge and copy x->z on the other side. Pathcopies from one parent
353 Copy x->y on one side of merge and copy x->z on the other side. Pathcopies from one parent
350 of the merge to the merge should include the copy from the other side.
354 of the merge to the merge should include the copy from the other side.
351 $ newrepo
355 $ newrepo
352 $ echo x > x
356 $ echo x > x
353 $ hg ci -Aqm 'add x'
357 $ hg ci -Aqm 'add x'
354 $ hg cp x y
358 $ hg cp x y
355 $ hg ci -qm 'copy x to y'
359 $ hg ci -qm 'copy x to y'
356 $ hg co -q 0
360 $ hg co -q 0
357 $ hg cp x z
361 $ hg cp x z
358 $ hg ci -qm 'copy x to z'
362 $ hg ci -qm 'copy x to z'
359 $ hg merge -q 1
363 $ hg merge -q 1
360 $ hg ci -m 'merge copy x->y and copy x->z'
364 $ hg ci -m 'merge copy x->y and copy x->z'
361 $ hg l
365 $ hg l
362 @ 3 merge copy x->y and copy x->z
366 @ 3 merge copy x->y and copy x->z
363 |\
367 |\
364 | o 2 copy x to z
368 | o 2 copy x to z
365 | | z
369 | | z
366 o | 1 copy x to y
370 o | 1 copy x to y
367 |/ y
371 |/ y
368 o 0 add x
372 o 0 add x
369 x
373 x
370 $ hg debugp1copies -r 3
374 $ hg debugp1copies -r 3
371 $ hg debugp2copies -r 3
375 $ hg debugp2copies -r 3
372 $ hg debugpathcopies 2 3
376 $ hg debugpathcopies 2 3
373 x -> y
377 x -> y
374 $ hg debugpathcopies 1 3
378 $ hg debugpathcopies 1 3
375 x -> z
379 x -> z
376
380
377 Copy x to y on one side of merge, create y and rename to z on the other side.
381 Copy x to y on one side of merge, create y and rename to z on the other side.
378 $ newrepo
382 $ newrepo
379 $ echo x > x
383 $ echo x > x
380 $ hg ci -Aqm 'add x'
384 $ hg ci -Aqm 'add x'
381 $ hg cp x y
385 $ hg cp x y
382 $ hg ci -qm 'copy x to y'
386 $ hg ci -qm 'copy x to y'
383 $ hg co -q 0
387 $ hg co -q 0
384 $ echo y > y
388 $ echo y > y
385 $ hg ci -Aqm 'add y'
389 $ hg ci -Aqm 'add y'
386 $ hg mv y z
390 $ hg mv y z
387 $ hg ci -m 'rename y to z'
391 $ hg ci -m 'rename y to z'
388 $ hg merge -q 1
392 $ hg merge -q 1
389 $ hg ci -m 'merge'
393 $ hg ci -m 'merge'
390 $ hg l
394 $ hg l
391 @ 4 merge
395 @ 4 merge
392 |\
396 |\
393 | o 3 rename y to z
397 | o 3 rename y to z
394 | | y z
398 | | y z
395 | o 2 add y
399 | o 2 add y
396 | | y
400 | | y
397 o | 1 copy x to y
401 o | 1 copy x to y
398 |/ y
402 |/ y
399 o 0 add x
403 o 0 add x
400 x
404 x
401 $ hg debugp1copies -r 3
405 $ hg debugp1copies -r 3
402 y -> z
406 y -> z
403 $ hg debugp2copies -r 3
407 $ hg debugp2copies -r 3
404 $ hg debugpathcopies 2 3
408 $ hg debugpathcopies 2 3
405 y -> z
409 y -> z
406 $ hg debugpathcopies 1 3
410 $ hg debugpathcopies 1 3
407 y -> z (no-filelog !)
411 y -> z (no-filelog !)
408
412
409 Create x and y, then rename x to z on one side of merge, and rename y to z and
413 Create x and y, then rename x to z on one side of merge, and rename y to z and
410 modify z on the other side. When storing copies in the changeset, we don't
414 modify z on the other side. When storing copies in the changeset, we don't
411 filter out copies whose target was created on the other side of the merge.
415 filter out copies whose target was created on the other side of the merge.
412 $ newrepo
416 $ newrepo
413 $ echo x > x
417 $ echo x > x
414 $ echo y > y
418 $ echo y > y
415 $ hg ci -Aqm 'add x and y'
419 $ hg ci -Aqm 'add x and y'
416 $ hg mv x z
420 $ hg mv x z
417 $ hg ci -qm 'rename x to z'
421 $ hg ci -qm 'rename x to z'
418 $ hg co -q 0
422 $ hg co -q 0
419 $ hg mv y z
423 $ hg mv y z
420 $ hg ci -qm 'rename y to z'
424 $ hg ci -qm 'rename y to z'
421 $ echo z >> z
425 $ echo z >> z
422 $ hg ci -m 'modify z'
426 $ hg ci -m 'modify z'
423 $ hg merge -q 1
427 $ hg merge -q 1
424 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
428 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
425 [1]
429 [1]
426 $ echo z > z
430 $ echo z > z
427 $ hg resolve -qm z
431 $ hg resolve -qm z
428 $ hg ci -m 'merge 1 into 3'
432 $ hg ci -m 'merge 1 into 3'
429 Try merging the other direction too
433 Try merging the other direction too
430 $ hg co -q 1
434 $ hg co -q 1
431 $ hg merge -q 3
435 $ hg merge -q 3
432 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
436 warning: conflicts while merging z! (edit, then use 'hg resolve --mark')
433 [1]
437 [1]
434 $ echo z > z
438 $ echo z > z
435 $ hg resolve -qm z
439 $ hg resolve -qm z
436 $ hg ci -m 'merge 3 into 1'
440 $ hg ci -m 'merge 3 into 1'
437 created new head
441 created new head
438 $ hg l
442 $ hg l
439 @ 5 merge 3 into 1
443 @ 5 merge 3 into 1
440 |\ z
444 |\ z
441 +---o 4 merge 1 into 3
445 +---o 4 merge 1 into 3
442 | |/ z
446 | |/ z
443 | o 3 modify z
447 | o 3 modify z
444 | | z
448 | | z
445 | o 2 rename y to z
449 | o 2 rename y to z
446 | | y z
450 | | y z
447 o | 1 rename x to z
451 o | 1 rename x to z
448 |/ x z
452 |/ x z
449 o 0 add x and y
453 o 0 add x and y
450 x y
454 x y
451 $ hg debugpathcopies 1 4
455 $ hg debugpathcopies 1 4
452 y -> z (no-filelog !)
456 y -> z (no-filelog !)
453 $ hg debugpathcopies 2 4
457 $ hg debugpathcopies 2 4
454 x -> z (no-filelog !)
458 x -> z (no-filelog !)
455 $ hg debugpathcopies 0 4
459 $ hg debugpathcopies 0 4
456 x -> z (filelog !)
460 x -> z (filelog !)
457 y -> z (no-filelog !)
461 y -> z (no-filelog !)
458 $ hg debugpathcopies 1 5
462 $ hg debugpathcopies 1 5
459 y -> z (no-filelog !)
463 y -> z (no-filelog !)
460 $ hg debugpathcopies 2 5
464 $ hg debugpathcopies 2 5
461 x -> z (no-filelog !)
465 x -> z (no-filelog !)
462 $ hg debugpathcopies 0 5
466 $ hg debugpathcopies 0 5
463 x -> z
467 x -> z
464
468
465 Create x and y, then remove y and rename x to y on one side of merge, and
469 Create x and y, then remove y and rename x to y on one side of merge, and
466 modify x on the other side. The modification to x from the second side
470 modify x on the other side. The modification to x from the second side
467 should be propagated to y.
471 should be propagated to y.
468 $ newrepo
472 $ newrepo
469 $ echo original > x
473 $ echo original > x
470 $ hg add x
474 $ hg add x
471 $ echo unrelated > y
475 $ echo unrelated > y
472 $ hg add y
476 $ hg add y
473 $ hg commit -m 'add x and y'
477 $ hg commit -m 'add x and y'
474 $ hg remove y
478 $ hg remove y
475 $ hg commit -m 'remove y'
479 $ hg commit -m 'remove y'
476 $ hg rename x y
480 $ hg rename x y
477 $ hg commit -m 'rename x to y'
481 $ hg commit -m 'rename x to y'
478 $ hg checkout -q 0
482 $ hg checkout -q 0
479 $ echo modified > x
483 $ echo modified > x
480 $ hg commit -m 'modify x'
484 $ hg commit -m 'modify x'
481 created new head
485 created new head
482 $ hg l
486 $ hg l
483 @ 3 modify x
487 @ 3 modify x
484 | x
488 | x
485 | o 2 rename x to y
489 | o 2 rename x to y
486 | | x y
490 | | x y
487 | o 1 remove y
491 | o 1 remove y
488 |/ y
492 |/ y
489 o 0 add x and y
493 o 0 add x and y
490 x y
494 x y
491 #if filelog
495 #if filelog
492 $ hg merge 2
496 $ hg merge 2
493 file 'x' was deleted in other [merge rev] but was modified in local [working copy].
497 file 'x' was deleted in other [merge rev] but was modified in local [working copy].
494 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
498 You can use (c)hanged version, (d)elete, or leave (u)nresolved.
495 What do you want to do? u
499 What do you want to do? u
496 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
500 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
497 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
501 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
498 [1]
502 [1]
499 This should ideally be "modified", but we will probably not be able to fix
503 This should ideally be "modified", but we will probably not be able to fix
500 that in the filelog case.
504 that in the filelog case.
501 $ cat y
505 $ cat y
502 original
506 original
503 #else
507 #else
504 $ hg merge 2
508 $ hg merge 2
505 merging x and y to y
509 merging x and y to y
506 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
510 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
507 (branch merge, don't forget to commit)
511 (branch merge, don't forget to commit)
508 $ cat y
512 $ cat y
509 modified
513 modified
510 #endif
514 #endif
511 Same as above, but in the opposite direction
515 Same as above, but in the opposite direction
512 #if filelog
516 #if filelog
513 $ hg co -qC 2
517 $ hg co -qC 2
514 $ hg merge 3
518 $ hg merge 3
515 file 'x' was deleted in local [working copy] but was modified in other [merge rev].
519 file 'x' was deleted in local [working copy] but was modified in other [merge rev].
516 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
520 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
517 What do you want to do? u
521 What do you want to do? u
518 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
522 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
519 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
523 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
520 [1]
524 [1]
521 BROKEN: should be "modified"
525 BROKEN: should be "modified"
522 $ cat y
526 $ cat y
523 original
527 original
524 #else
528 #else
525 $ hg co -qC 2
529 $ hg co -qC 2
526 $ hg merge 3
530 $ hg merge 3
527 merging y and x to y
531 merging y and x to y
528 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
532 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
529 (branch merge, don't forget to commit)
533 (branch merge, don't forget to commit)
530 $ cat y
534 $ cat y
531 modified
535 modified
532 #endif
536 #endif
533
537
534 Create x and y, then rename x to z on one side of merge, and rename y to z and
538 Create x and y, then rename x to z on one side of merge, and rename y to z and
535 then delete z on the other side.
539 then delete z on the other side.
536 $ newrepo
540 $ newrepo
537 $ echo x > x
541 $ echo x > x
538 $ echo y > y
542 $ echo y > y
539 $ hg ci -Aqm 'add x and y'
543 $ hg ci -Aqm 'add x and y'
540 $ hg mv x z
544 $ hg mv x z
541 $ hg ci -qm 'rename x to z'
545 $ hg ci -qm 'rename x to z'
542 $ hg co -q 0
546 $ hg co -q 0
543 $ hg mv y z
547 $ hg mv y z
544 $ hg ci -qm 'rename y to z'
548 $ hg ci -qm 'rename y to z'
545 $ hg rm z
549 $ hg rm z
546 $ hg ci -m 'delete z'
550 $ hg ci -m 'delete z'
547 $ hg merge -q 1
551 $ hg merge -q 1
548 $ echo z > z
552 $ echo z > z
549 $ hg ci -m 'merge 1 into 3'
553 $ hg ci -m 'merge 1 into 3'
550 Try merging the other direction too
554 Try merging the other direction too
551 $ hg co -q 1
555 $ hg co -q 1
552 $ hg merge -q 3
556 $ hg merge -q 3
553 $ echo z > z
557 $ echo z > z
554 $ hg ci -m 'merge 3 into 1'
558 $ hg ci -m 'merge 3 into 1'
555 created new head
559 created new head
556 $ hg l
560 $ hg l
557 @ 5 merge 3 into 1
561 @ 5 merge 3 into 1
558 |\ z
562 |\ z
559 +---o 4 merge 1 into 3
563 +---o 4 merge 1 into 3
560 | |/ z
564 | |/ z
561 | o 3 delete z
565 | o 3 delete z
562 | | z
566 | | z
563 | o 2 rename y to z
567 | o 2 rename y to z
564 | | y z
568 | | y z
565 o | 1 rename x to z
569 o | 1 rename x to z
566 |/ x z
570 |/ x z
567 o 0 add x and y
571 o 0 add x and y
568 x y
572 x y
569 $ hg debugpathcopies 1 4
573 $ hg debugpathcopies 1 4
570 $ hg debugpathcopies 2 4
574 $ hg debugpathcopies 2 4
571 x -> z (no-filelog !)
575 x -> z (no-filelog !)
572 $ hg debugpathcopies 0 4
576 $ hg debugpathcopies 0 4
573 x -> z (no-changeset no-compatibility !)
577 x -> z (no-changeset no-compatibility !)
574 $ hg debugpathcopies 1 5
578 $ hg debugpathcopies 1 5
575 $ hg debugpathcopies 2 5
579 $ hg debugpathcopies 2 5
576 x -> z (no-filelog !)
580 x -> z (no-filelog !)
577 $ hg debugpathcopies 0 5
581 $ hg debugpathcopies 0 5
578 x -> z
582 x -> z
579
583
580
584
581 Test for a case in fullcopytracing algorithm where neither of the merging csets
585 Test for a case in fullcopytracing algorithm where neither of the merging csets
582 is a descendant of the merge base. This test reflects that the algorithm
586 is a descendant of the merge base. This test reflects that the algorithm
583 correctly finds the copies:
587 correctly finds the copies:
584
588
585 $ cat >> $HGRCPATH << EOF
589 $ cat >> $HGRCPATH << EOF
586 > [experimental]
590 > [experimental]
587 > evolution.createmarkers=True
591 > evolution.createmarkers=True
588 > evolution.allowunstable=True
592 > evolution.allowunstable=True
589 > EOF
593 > EOF
590
594
591 $ newrepo
595 $ newrepo
592 $ echo a > a
596 $ echo a > a
593 $ hg add a
597 $ hg add a
594 $ hg ci -m "added a"
598 $ hg ci -m "added a"
595 $ echo b > b
599 $ echo b > b
596 $ hg add b
600 $ hg add b
597 $ hg ci -m "added b"
601 $ hg ci -m "added b"
598
602
599 $ hg mv b b1
603 $ hg mv b b1
600 $ hg ci -m "rename b to b1"
604 $ hg ci -m "rename b to b1"
601
605
602 $ hg up ".^"
606 $ hg up ".^"
603 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
607 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
604 $ echo d > d
608 $ echo d > d
605 $ hg add d
609 $ hg add d
606 $ hg ci -m "added d"
610 $ hg ci -m "added d"
607 created new head
611 created new head
608
612
609 $ echo baba >> b
613 $ echo baba >> b
610 $ hg ci --amend -m "added d, modified b"
614 $ hg ci --amend -m "added d, modified b"
611
615
612 $ hg l --hidden
616 $ hg l --hidden
613 @ 4 added d, modified b
617 @ 4 added d, modified b
614 | b d
618 | b d
615 | x 3 added d
619 | x 3 added d
616 |/ d
620 |/ d
617 | o 2 rename b to b1
621 | o 2 rename b to b1
618 |/ b b1
622 |/ b b1
619 o 1 added b
623 o 1 added b
620 | b
624 | b
621 o 0 added a
625 o 0 added a
622 a
626 a
623
627
624 Grafting revision 4 on top of revision 2, showing that it respect the rename:
628 Grafting revision 4 on top of revision 2, showing that it respect the rename:
625
629
626 $ hg up 2 -q
630 $ hg up 2 -q
627 $ hg graft -r 4 --base 3 --hidden
631 $ hg graft -r 4 --base 3 --hidden
628 grafting 4:af28412ec03c "added d, modified b" (tip) (no-changeset !)
632 grafting 4:af28412ec03c "added d, modified b" (tip) (no-changeset !)
629 grafting 4:6325ca0b7a1c "added d, modified b" (tip) (changeset !)
633 grafting 4:6325ca0b7a1c "added d, modified b" (tip) (changeset !)
630 merging b1 and b to b1
634 merging b1 and b to b1
631
635
632 $ hg l -l1 -p
636 $ hg l -l1 -p
633 @ 5 added d, modified b
637 @ 5 added d, modified b
634 | b1
638 | b1
635 ~ diff -r 5a4825cc2926 -r 94a2f1a0e8e2 b1 (no-changeset !)
639 ~ diff -r 5a4825cc2926 -r 94a2f1a0e8e2 b1 (no-changeset !)
636 ~ diff -r 0a0ed3b3251c -r d544fb655520 b1 (changeset !)
640 ~ diff -r 0a0ed3b3251c -r d544fb655520 b1 (changeset !)
637 --- a/b1 Thu Jan 01 00:00:00 1970 +0000
641 --- a/b1 Thu Jan 01 00:00:00 1970 +0000
638 +++ b/b1 Thu Jan 01 00:00:00 1970 +0000
642 +++ b/b1 Thu Jan 01 00:00:00 1970 +0000
639 @@ -1,1 +1,2 @@
643 @@ -1,1 +1,2 @@
640 b
644 b
641 +baba
645 +baba
642
646
643 Test to make sure that fullcopytracing algorithm doesn't fail when neither of the
647 Test to make sure that fullcopytracing algorithm doesn't fail when neither of the
644 merging csets is a descendant of the base.
648 merging csets is a descendant of the base.
645 -------------------------------------------------------------------------------------------------
649 -------------------------------------------------------------------------------------------------
646
650
647 $ newrepo
651 $ newrepo
648 $ echo a > a
652 $ echo a > a
649 $ hg add a
653 $ hg add a
650 $ hg ci -m "added a"
654 $ hg ci -m "added a"
651 $ echo b > b
655 $ echo b > b
652 $ hg add b
656 $ hg add b
653 $ hg ci -m "added b"
657 $ hg ci -m "added b"
654
658
655 $ echo foobar > willconflict
659 $ echo foobar > willconflict
656 $ hg add willconflict
660 $ hg add willconflict
657 $ hg ci -m "added willconflict"
661 $ hg ci -m "added willconflict"
658 $ echo c > c
662 $ echo c > c
659 $ hg add c
663 $ hg add c
660 $ hg ci -m "added c"
664 $ hg ci -m "added c"
661
665
662 $ hg l
666 $ hg l
663 @ 3 added c
667 @ 3 added c
664 | c
668 | c
665 o 2 added willconflict
669 o 2 added willconflict
666 | willconflict
670 | willconflict
667 o 1 added b
671 o 1 added b
668 | b
672 | b
669 o 0 added a
673 o 0 added a
670 a
674 a
671
675
672 $ hg up ".^^"
676 $ hg up ".^^"
673 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
677 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
674 $ echo d > d
678 $ echo d > d
675 $ hg add d
679 $ hg add d
676 $ hg ci -m "added d"
680 $ hg ci -m "added d"
677 created new head
681 created new head
678
682
679 $ echo barfoo > willconflict
683 $ echo barfoo > willconflict
680 $ hg add willconflict
684 $ hg add willconflict
681 $ hg ci --amend -m "added willconflict and d"
685 $ hg ci --amend -m "added willconflict and d"
682
686
683 $ hg l
687 $ hg l
684 @ 5 added willconflict and d
688 @ 5 added willconflict and d
685 | d willconflict
689 | d willconflict
686 | o 3 added c
690 | o 3 added c
687 | | c
691 | | c
688 | o 2 added willconflict
692 | o 2 added willconflict
689 |/ willconflict
693 |/ willconflict
690 o 1 added b
694 o 1 added b
691 | b
695 | b
692 o 0 added a
696 o 0 added a
693 a
697 a
694
698
695 $ hg rebase -r . -d 2 -t :other
699 $ hg rebase -r . -d 2 -t :other
696 rebasing 5:5018b1509e94 tip "added willconflict and d" (no-changeset !)
700 rebasing 5:5018b1509e94 tip "added willconflict and d" (no-changeset !)
697 rebasing 5:af8d273bf580 tip "added willconflict and d" (changeset !)
701 rebasing 5:af8d273bf580 tip "added willconflict and d" (changeset !)
698
702
699 $ hg up 3 -q
703 $ hg up 3 -q
700 $ hg l --hidden
704 $ hg l --hidden
701 o 6 added willconflict and d
705 o 6 added willconflict and d
702 | d willconflict
706 | d willconflict
703 | x 5 added willconflict and d
707 | x 5 added willconflict and d
704 | | d willconflict
708 | | d willconflict
705 | | x 4 added d
709 | | x 4 added d
706 | |/ d
710 | |/ d
707 +---@ 3 added c
711 +---@ 3 added c
708 | | c
712 | | c
709 o | 2 added willconflict
713 o | 2 added willconflict
710 |/ willconflict
714 |/ willconflict
711 o 1 added b
715 o 1 added b
712 | b
716 | b
713 o 0 added a
717 o 0 added a
714 a
718 a
715
719
716 Now if we trigger a merge between revision 3 and 6 using base revision 4,
720 Now if we trigger a merge between revision 3 and 6 using base revision 4,
717 neither of the merging csets will be a descendant of the base revision:
721 neither of the merging csets will be a descendant of the base revision:
718
722
719 $ hg graft -r 6 --base 4 --hidden -t :other
723 $ hg graft -r 6 --base 4 --hidden -t :other
720 grafting 6:99802e4f1e46 "added willconflict and d" (tip) (no-changeset !)
724 grafting 6:99802e4f1e46 "added willconflict and d" (tip) (no-changeset !)
721 grafting 6:b19f0df72728 "added willconflict and d" (tip) (changeset !)
725 grafting 6:b19f0df72728 "added willconflict and d" (tip) (changeset !)
@@ -1,374 +1,385 b''
1 $ mkdir part1
1 $ mkdir part1
2 $ cd part1
2 $ cd part1
3
3
4 $ hg init
4 $ hg init
5 $ echo a > a
5 $ echo a > a
6 $ hg add a
6 $ hg add a
7 $ hg commit -m "1"
7 $ hg commit -m "1"
8 $ hg status
8 $ hg status
9 $ hg copy a b
9 $ hg copy a b
10 $ hg --config ui.portablefilenames=abort copy a con.xml
10 $ hg --config ui.portablefilenames=abort copy a con.xml
11 abort: filename contains 'con', which is reserved on Windows: con.xml
11 abort: filename contains 'con', which is reserved on Windows: con.xml
12 [10]
12 [10]
13 $ hg status
13 $ hg status
14 A b
14 A b
15 $ hg sum
15 $ hg sum
16 parent: 0:c19d34741b0a tip
16 parent: 0:c19d34741b0a tip
17 1
17 1
18 branch: default
18 branch: default
19 commit: 1 copied
19 commit: 1 copied
20 update: (current)
20 update: (current)
21 phases: 1 draft
21 phases: 1 draft
22 $ hg --debug commit -m "2"
22 $ hg --debug commit -m "2"
23 committing files:
23 committing files:
24 b
24 b
25 b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
25 b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
26 committing manifest
26 committing manifest
27 committing changelog
27 committing changelog
28 updating the branch cache
28 updating the branch cache
29 committed changeset 1:93580a2c28a50a56f63526fb305067e6fbf739c4
29 committed changeset 1:93580a2c28a50a56f63526fb305067e6fbf739c4
30
30
31 we should see two history entries
31 we should see two history entries
32
32
33 $ hg history -v
33 $ hg history -v
34 changeset: 1:93580a2c28a5
34 changeset: 1:93580a2c28a5
35 tag: tip
35 tag: tip
36 user: test
36 user: test
37 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
38 files: b
38 files: b
39 description:
39 description:
40 2
40 2
41
41
42
42
43 changeset: 0:c19d34741b0a
43 changeset: 0:c19d34741b0a
44 user: test
44 user: test
45 date: Thu Jan 01 00:00:00 1970 +0000
45 date: Thu Jan 01 00:00:00 1970 +0000
46 files: a
46 files: a
47 description:
47 description:
48 1
48 1
49
49
50
50
51
51
52 we should see one log entry for a
52 we should see one log entry for a
53
53
54 $ hg log a
54 $ hg log a
55 changeset: 0:c19d34741b0a
55 changeset: 0:c19d34741b0a
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
57 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: 1
58 summary: 1
59
59
60
60
61 this should show a revision linked to changeset 0
61 this should show a revision linked to changeset 0
62
62
63 $ hg debugindex a
63 $ hg debugindex a
64 rev linkrev nodeid p1 p2
64 rev linkrev nodeid p1 p2
65 0 0 b789fdd96dc2 000000000000 000000000000
65 0 0 b789fdd96dc2 000000000000 000000000000
66
66
67 we should see one log entry for b
67 we should see one log entry for b
68
68
69 $ hg log b
69 $ hg log b
70 changeset: 1:93580a2c28a5
70 changeset: 1:93580a2c28a5
71 tag: tip
71 tag: tip
72 user: test
72 user: test
73 date: Thu Jan 01 00:00:00 1970 +0000
73 date: Thu Jan 01 00:00:00 1970 +0000
74 summary: 2
74 summary: 2
75
75
76
76
77 this should show a revision linked to changeset 1
77 this should show a revision linked to changeset 1
78
78
79 $ hg debugindex b
79 $ hg debugindex b
80 rev linkrev nodeid p1 p2
80 rev linkrev nodeid p1 p2
81 0 1 37d9b5d994ea 000000000000 000000000000
81 0 1 37d9b5d994ea 000000000000 000000000000
82
82
83 this should show the rename information in the metadata
83 this should show the rename information in the metadata
84
84
85 $ hg debugdata b 0 | head -3 | tail -2
85 $ hg debugdata b 0 | head -3 | tail -2
86 copy: a
86 copy: a
87 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
87 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
88
88
89 #if reporevlogstore
89 #if reporevlogstore
90 $ md5sum.py .hg/store/data/b.i
90 $ md5sum.py .hg/store/data/b.i
91 44913824c8f5890ae218f9829535922e .hg/store/data/b.i
91 44913824c8f5890ae218f9829535922e .hg/store/data/b.i
92 #endif
92 #endif
93 $ hg cat b > bsum
93 $ hg cat b > bsum
94 $ md5sum.py bsum
94 $ md5sum.py bsum
95 60b725f10c9c85c70d97880dfe8191b3 bsum
95 60b725f10c9c85c70d97880dfe8191b3 bsum
96 $ hg cat a > asum
96 $ hg cat a > asum
97 $ md5sum.py asum
97 $ md5sum.py asum
98 60b725f10c9c85c70d97880dfe8191b3 asum
98 60b725f10c9c85c70d97880dfe8191b3 asum
99 $ hg verify
99 $ hg verify
100 checking changesets
100 checking changesets
101 checking manifests
101 checking manifests
102 crosschecking files in changesets and manifests
102 crosschecking files in changesets and manifests
103 checking files
103 checking files
104 checked 2 changesets with 2 changes to 2 files
104 checked 2 changesets with 2 changes to 2 files
105
105
106 $ cd ..
106 $ cd ..
107
107
108
108
109 $ mkdir part2
109 $ mkdir part2
110 $ cd part2
110 $ cd part2
111
111
112 $ hg init
112 $ hg init
113 $ echo foo > foo
113 $ echo foo > foo
114 should fail - foo is not managed
114 should fail - foo is not managed
115 $ hg mv foo bar
115 $ hg mv foo bar
116 foo: not copying - file is not managed
116 foo: not copying - file is not managed
117 abort: no files to copy
117 abort: no files to copy
118 [10]
118 [10]
119 $ hg st -A
119 $ hg st -A
120 ? foo
120 ? foo
121 respects ui.relative-paths
121 respects ui.relative-paths
122 $ mkdir dir
122 $ mkdir dir
123 $ cd dir
123 $ cd dir
124 $ hg mv ../foo ../bar
124 $ hg mv ../foo ../bar
125 ../foo: not copying - file is not managed
125 ../foo: not copying - file is not managed
126 abort: no files to copy
126 abort: no files to copy
127 [10]
127 [10]
128 $ hg mv ../foo ../bar --config ui.relative-paths=yes
128 $ hg mv ../foo ../bar --config ui.relative-paths=yes
129 ../foo: not copying - file is not managed
129 ../foo: not copying - file is not managed
130 abort: no files to copy
130 abort: no files to copy
131 [10]
131 [10]
132 $ hg mv ../foo ../bar --config ui.relative-paths=no
132 $ hg mv ../foo ../bar --config ui.relative-paths=no
133 foo: not copying - file is not managed
133 foo: not copying - file is not managed
134 abort: no files to copy
134 abort: no files to copy
135 [10]
135 [10]
136 $ cd ..
136 $ cd ..
137 $ rmdir dir
137 $ rmdir dir
138 $ hg add foo
138 $ hg add foo
139 dry-run; print a warning that this is not a real copy; foo is added
139 dry-run; print a warning that this is not a real copy; foo is added
140 $ hg mv --dry-run foo bar
140 $ hg mv --dry-run foo bar
141 foo has not been committed yet, so no copy data will be stored for bar.
141 foo has not been committed yet, so no copy data will be stored for bar.
142 $ hg st -A
142 $ hg st -A
143 A foo
143 A foo
144 should print a warning that this is not a real copy; bar is added
144 should print a warning that this is not a real copy; bar is added
145 $ hg mv foo bar
145 $ hg mv foo bar
146 foo has not been committed yet, so no copy data will be stored for bar.
146 foo has not been committed yet, so no copy data will be stored for bar.
147 $ hg st -A
147 $ hg st -A
148 A bar
148 A bar
149 should print a warning that this is not a real copy; foo is added
149 should print a warning that this is not a real copy; foo is added
150 $ hg cp bar foo
150 $ hg cp bar foo
151 bar has not been committed yet, so no copy data will be stored for foo.
151 bar has not been committed yet, so no copy data will be stored for foo.
152 $ hg rm -f bar
152 $ hg rm -f bar
153 $ rm bar
153 $ rm bar
154 $ hg st -A
154 $ hg st -A
155 A foo
155 A foo
156 $ hg commit -m1
156 $ hg commit -m1
157
157
158 moving a missing file
158 moving a missing file
159 $ rm foo
159 $ rm foo
160 $ hg mv foo foo3
160 $ hg mv foo foo3
161 foo: deleted in working directory
161 foo: deleted in working directory
162 foo3 does not exist!
162 foo3 does not exist!
163 $ hg up -qC .
163 $ hg up -qC .
164
164
165 copy --after to a nonexistent target filename
165 copy --after to a nonexistent target filename
166 $ hg cp -A foo dummy
166 $ hg cp -A foo dummy
167 foo: not recording copy - dummy does not exist
167 foo: not recording copy - dummy does not exist
168 [1]
168 [1]
169
169
170 dry-run; should show that foo is clean
170 dry-run; should show that foo is clean
171 $ hg copy --dry-run foo bar
171 $ hg copy --dry-run foo bar
172 $ hg st -A
172 $ hg st -A
173 C foo
173 C foo
174 should show copy
174 should show copy
175 $ hg copy foo bar
175 $ hg copy foo bar
176 $ hg st -C
176 $ hg st -C
177 A bar
177 A bar
178 foo
178 foo
179
179
180 shouldn't show copy
180 shouldn't show copy
181 $ hg commit -m2
181 $ hg commit -m2
182 $ hg st -C
182 $ hg st -C
183
183
184 should match
184 should match
185 $ hg debugindex foo
185 $ hg debugindex foo
186 rev linkrev nodeid p1 p2
186 rev linkrev nodeid p1 p2
187 0 0 2ed2a3912a0b 000000000000 000000000000
187 0 0 2ed2a3912a0b 000000000000 000000000000
188 $ hg debugrename bar
188 $ hg debugrename bar
189 bar renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
189 bar renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
190
190
191 $ echo bleah > foo
191 $ echo bleah > foo
192 $ echo quux > bar
192 $ echo quux > bar
193 $ hg commit -m3
193 $ hg commit -m3
194
194
195 should not be renamed
195 should not be renamed
196 $ hg debugrename bar
196 $ hg debugrename bar
197 bar not renamed
197 bar not renamed
198
198
199 $ hg copy -f foo bar
199 $ hg copy -f foo bar
200 should show copy
200 should show copy
201 $ hg st -C
201 $ hg st -C
202 M bar
202 M bar
203 foo
203 foo
204
204
205 XXX: filtering lfilesrepo.status() in 3.3-rc causes the copy source to not be
205 XXX: filtering lfilesrepo.status() in 3.3-rc causes the copy source to not be
206 displayed.
206 displayed.
207 $ hg st -C --config extensions.largefiles=
207 $ hg st -C --config extensions.largefiles=
208 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
208 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
209 M bar
209 M bar
210 foo
210 foo
211
211
212 $ hg commit -m3
212 $ hg commit -m3
213
213
214 should show no parents for tip
214 should show no parents for tip
215 $ hg debugindex bar
215 $ hg debugindex bar
216 rev linkrev nodeid p1 p2
216 rev linkrev nodeid p1 p2
217 0 1 7711d36246cc 000000000000 000000000000
217 0 1 7711d36246cc 000000000000 000000000000
218 1 2 bdf70a2b8d03 7711d36246cc 000000000000
218 1 2 bdf70a2b8d03 7711d36246cc 000000000000
219 2 3 b2558327ea8d 000000000000 000000000000
219 2 3 b2558327ea8d 000000000000 000000000000
220 should match
220 should match
221 $ hg debugindex foo
221 $ hg debugindex foo
222 rev linkrev nodeid p1 p2
222 rev linkrev nodeid p1 p2
223 0 0 2ed2a3912a0b 000000000000 000000000000
223 0 0 2ed2a3912a0b 000000000000 000000000000
224 1 2 dd12c926cf16 2ed2a3912a0b 000000000000
224 1 2 dd12c926cf16 2ed2a3912a0b 000000000000
225 $ hg debugrename bar
225 $ hg debugrename bar
226 bar renamed from foo:dd12c926cf165e3eb4cf87b084955cb617221c17
226 bar renamed from foo:dd12c926cf165e3eb4cf87b084955cb617221c17
227
227
228 should show no copies
228 should show no copies
229 $ hg st -C
229 $ hg st -C
230
230
231 note: since filelog based copy tracing only trace copy for new file, the copy information here is not displayed.
232
233 $ hg status --copies --change .
234 M bar
235
236 They are a devel option to walk all file and fine this information anyway.
237
238 $ hg status --copies --change . --config devel.copy-tracing.trace-all-files=yes
239 M bar
240 foo
241
231 copy --after on an added file
242 copy --after on an added file
232 $ cp bar baz
243 $ cp bar baz
233 $ hg add baz
244 $ hg add baz
234 $ hg cp -A bar baz
245 $ hg cp -A bar baz
235 $ hg st -C
246 $ hg st -C
236 A baz
247 A baz
237 bar
248 bar
238
249
239 foo was clean:
250 foo was clean:
240 $ hg st -AC foo
251 $ hg st -AC foo
241 C foo
252 C foo
242 Trying to copy on top of an existing file fails,
253 Trying to copy on top of an existing file fails,
243 $ hg copy -A bar foo
254 $ hg copy -A bar foo
244 foo: not overwriting - file already committed
255 foo: not overwriting - file already committed
245 ('hg copy --after --force' to replace the file by recording a copy)
256 ('hg copy --after --force' to replace the file by recording a copy)
246 [1]
257 [1]
247 same error without the --after, so the user doesn't have to go through
258 same error without the --after, so the user doesn't have to go through
248 two hints:
259 two hints:
249 $ hg copy bar foo
260 $ hg copy bar foo
250 foo: not overwriting - file already committed
261 foo: not overwriting - file already committed
251 ('hg copy --force' to replace the file by recording a copy)
262 ('hg copy --force' to replace the file by recording a copy)
252 [1]
263 [1]
253 but it's considered modified after a copy --after --force
264 but it's considered modified after a copy --after --force
254 $ hg copy -Af bar foo
265 $ hg copy -Af bar foo
255 $ hg st -AC foo
266 $ hg st -AC foo
256 M foo
267 M foo
257 bar
268 bar
258 The hint for a file that exists but is not in file history doesn't
269 The hint for a file that exists but is not in file history doesn't
259 mention --force:
270 mention --force:
260 $ touch xyzzy
271 $ touch xyzzy
261 $ hg cp bar xyzzy
272 $ hg cp bar xyzzy
262 xyzzy: not overwriting - file exists
273 xyzzy: not overwriting - file exists
263 ('hg copy --after' to record the copy)
274 ('hg copy --after' to record the copy)
264 [1]
275 [1]
265 $ hg co -qC .
276 $ hg co -qC .
266 $ rm baz xyzzy
277 $ rm baz xyzzy
267
278
268
279
269 Test unmarking copy of a single file
280 Test unmarking copy of a single file
270
281
271 # Set up by creating a copy
282 # Set up by creating a copy
272 $ hg cp bar baz
283 $ hg cp bar baz
273 # Test uncopying a non-existent file
284 # Test uncopying a non-existent file
274 $ hg copy --forget non-existent
285 $ hg copy --forget non-existent
275 non-existent: $ENOENT$
286 non-existent: $ENOENT$
276 # Test uncopying an tracked but unrelated file
287 # Test uncopying an tracked but unrelated file
277 $ hg copy --forget foo
288 $ hg copy --forget foo
278 foo: not unmarking as copy - file is not marked as copied
289 foo: not unmarking as copy - file is not marked as copied
279 # Test uncopying a copy source
290 # Test uncopying a copy source
280 $ hg copy --forget bar
291 $ hg copy --forget bar
281 bar: not unmarking as copy - file is not marked as copied
292 bar: not unmarking as copy - file is not marked as copied
282 # baz should still be marked as a copy
293 # baz should still be marked as a copy
283 $ hg st -C
294 $ hg st -C
284 A baz
295 A baz
285 bar
296 bar
286 # Test the normal case
297 # Test the normal case
287 $ hg copy --forget baz
298 $ hg copy --forget baz
288 $ hg st -C
299 $ hg st -C
289 A baz
300 A baz
290 # Test uncopy with matching an non-matching patterns
301 # Test uncopy with matching an non-matching patterns
291 $ hg cp bar baz --after
302 $ hg cp bar baz --after
292 $ hg copy --forget bar baz
303 $ hg copy --forget bar baz
293 bar: not unmarking as copy - file is not marked as copied
304 bar: not unmarking as copy - file is not marked as copied
294 $ hg st -C
305 $ hg st -C
295 A baz
306 A baz
296 # Test uncopy with no exact matches
307 # Test uncopy with no exact matches
297 $ hg cp bar baz --after
308 $ hg cp bar baz --after
298 $ hg copy --forget .
309 $ hg copy --forget .
299 $ hg st -C
310 $ hg st -C
300 A baz
311 A baz
301 $ hg forget baz
312 $ hg forget baz
302 $ rm baz
313 $ rm baz
303
314
304 Test unmarking copy of a directory
315 Test unmarking copy of a directory
305
316
306 $ mkdir dir
317 $ mkdir dir
307 $ echo foo > dir/foo
318 $ echo foo > dir/foo
308 $ echo bar > dir/bar
319 $ echo bar > dir/bar
309 $ hg add dir
320 $ hg add dir
310 adding dir/bar
321 adding dir/bar
311 adding dir/foo
322 adding dir/foo
312 $ hg ci -m 'add dir/'
323 $ hg ci -m 'add dir/'
313 $ hg cp dir dir2
324 $ hg cp dir dir2
314 copying dir/bar to dir2/bar
325 copying dir/bar to dir2/bar
315 copying dir/foo to dir2/foo
326 copying dir/foo to dir2/foo
316 $ touch dir2/untracked
327 $ touch dir2/untracked
317 $ hg copy --forget dir2
328 $ hg copy --forget dir2
318 $ hg st -C
329 $ hg st -C
319 A dir2/bar
330 A dir2/bar
320 A dir2/foo
331 A dir2/foo
321 ? dir2/untracked
332 ? dir2/untracked
322 # Clean up for next test
333 # Clean up for next test
323 $ hg forget dir2
334 $ hg forget dir2
324 removing dir2/bar
335 removing dir2/bar
325 removing dir2/foo
336 removing dir2/foo
326 $ rm -r dir2
337 $ rm -r dir2
327
338
328 Test uncopy on committed copies
339 Test uncopy on committed copies
329
340
330 # Commit some copies
341 # Commit some copies
331 $ hg cp bar baz
342 $ hg cp bar baz
332 $ hg cp bar qux
343 $ hg cp bar qux
333 $ hg ci -m copies
344 $ hg ci -m copies
334 $ hg st -C --change .
345 $ hg st -C --change .
335 A baz
346 A baz
336 bar
347 bar
337 A qux
348 A qux
338 bar
349 bar
339 $ base=$(hg log -r '.^' -T '{rev}')
350 $ base=$(hg log -r '.^' -T '{rev}')
340 $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
351 $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
341 @ 5:a612dc2edfda copies
352 @ 5:a612dc2edfda copies
342 |
353 |
343 o 4:4800b1f1f38e add dir/
354 o 4:4800b1f1f38e add dir/
344 |
355 |
345 ~
356 ~
346 # Add a dirty change on top to show that it's unaffected
357 # Add a dirty change on top to show that it's unaffected
347 $ echo dirty >> baz
358 $ echo dirty >> baz
348 $ hg st
359 $ hg st
349 M baz
360 M baz
350 $ cat baz
361 $ cat baz
351 bleah
362 bleah
352 dirty
363 dirty
353 $ hg copy --forget --at-rev . baz
364 $ hg copy --forget --at-rev . baz
354 saved backup bundle to $TESTTMP/part2/.hg/strip-backup/a612dc2edfda-e36b4448-uncopy.hg
365 saved backup bundle to $TESTTMP/part2/.hg/strip-backup/a612dc2edfda-e36b4448-uncopy.hg
355 # The unwanted copy is no longer recorded, but the unrelated one is
366 # The unwanted copy is no longer recorded, but the unrelated one is
356 $ hg st -C --change .
367 $ hg st -C --change .
357 A baz
368 A baz
358 A qux
369 A qux
359 bar
370 bar
360 # The old commit is gone and we have updated to the new commit
371 # The old commit is gone and we have updated to the new commit
361 $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
372 $ hg log -G -T '{rev}:{node|short} {desc}\n' -r $base:
362 @ 5:c45090e5effe copies
373 @ 5:c45090e5effe copies
363 |
374 |
364 o 4:4800b1f1f38e add dir/
375 o 4:4800b1f1f38e add dir/
365 |
376 |
366 ~
377 ~
367 # Working copy still has the uncommitted change
378 # Working copy still has the uncommitted change
368 $ hg st
379 $ hg st
369 M baz
380 M baz
370 $ cat baz
381 $ cat baz
371 bleah
382 bleah
372 dirty
383 dirty
373
384
374 $ cd ..
385 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now