##// END OF EJS Templates
rebase: add boolean config item rebase.store-source...
C. Masloch -
r50343:cfff73ca default
parent child Browse files
Show More
@@ -1,2284 +1,2286 b''
1 # rebase.py - rebasing feature for mercurial
1 # rebase.py - rebasing feature for mercurial
2 #
2 #
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''command to move sets of revisions to a different ancestor
8 '''command to move sets of revisions to a different ancestor
9
9
10 This extension lets you rebase changesets in an existing Mercurial
10 This extension lets you rebase changesets in an existing Mercurial
11 repository.
11 repository.
12
12
13 For more information:
13 For more information:
14 https://mercurial-scm.org/wiki/RebaseExtension
14 https://mercurial-scm.org/wiki/RebaseExtension
15 '''
15 '''
16
16
17
17
18 import os
18 import os
19
19
20 from mercurial.i18n import _
20 from mercurial.i18n import _
21 from mercurial.node import (
21 from mercurial.node import (
22 nullrev,
22 nullrev,
23 short,
23 short,
24 wdirrev,
24 wdirrev,
25 )
25 )
26 from mercurial.pycompat import open
26 from mercurial.pycompat import open
27 from mercurial import (
27 from mercurial import (
28 bookmarks,
28 bookmarks,
29 cmdutil,
29 cmdutil,
30 commands,
30 commands,
31 copies,
31 copies,
32 destutil,
32 destutil,
33 dirstateguard,
33 dirstateguard,
34 error,
34 error,
35 extensions,
35 extensions,
36 logcmdutil,
36 logcmdutil,
37 merge as mergemod,
37 merge as mergemod,
38 mergestate as mergestatemod,
38 mergestate as mergestatemod,
39 mergeutil,
39 mergeutil,
40 obsolete,
40 obsolete,
41 obsutil,
41 obsutil,
42 patch,
42 patch,
43 phases,
43 phases,
44 pycompat,
44 pycompat,
45 registrar,
45 registrar,
46 repair,
46 repair,
47 revset,
47 revset,
48 revsetlang,
48 revsetlang,
49 rewriteutil,
49 rewriteutil,
50 scmutil,
50 scmutil,
51 smartset,
51 smartset,
52 state as statemod,
52 state as statemod,
53 util,
53 util,
54 )
54 )
55
55
56 # The following constants are used throughout the rebase module. The ordering of
56 # The following constants are used throughout the rebase module. The ordering of
57 # their values must be maintained.
57 # their values must be maintained.
58
58
59 # Indicates that a revision needs to be rebased
59 # Indicates that a revision needs to be rebased
60 revtodo = -1
60 revtodo = -1
61 revtodostr = b'-1'
61 revtodostr = b'-1'
62
62
63 # legacy revstates no longer needed in current code
63 # legacy revstates no longer needed in current code
64 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
64 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
65 legacystates = {b'-2', b'-3', b'-4', b'-5'}
65 legacystates = {b'-2', b'-3', b'-4', b'-5'}
66
66
67 cmdtable = {}
67 cmdtable = {}
68 command = registrar.command(cmdtable)
68 command = registrar.command(cmdtable)
69
69
70 configtable = {}
70 configtable = {}
71 configitem = registrar.configitem(configtable)
71 configitem = registrar.configitem(configtable)
72 configitem(
72 configitem(
73 b'devel',
73 b'devel',
74 b'rebase.force-in-memory-merge',
74 b'rebase.force-in-memory-merge',
75 default=False,
75 default=False,
76 )
76 )
77 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
77 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
78 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
78 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
79 # be specifying the version(s) of Mercurial they are tested with, or
79 # be specifying the version(s) of Mercurial they are tested with, or
80 # leave the attribute unspecified.
80 # leave the attribute unspecified.
81 testedwith = b'ships-with-hg-core'
81 testedwith = b'ships-with-hg-core'
82
82
83
83
84 def _nothingtorebase():
84 def _nothingtorebase():
85 return 1
85 return 1
86
86
87
87
88 def _savegraft(ctx, extra):
88 def _savegraft(ctx, extra):
89 s = ctx.extra().get(b'source', None)
89 s = ctx.extra().get(b'source', None)
90 if s is not None:
90 if s is not None:
91 extra[b'source'] = s
91 extra[b'source'] = s
92 s = ctx.extra().get(b'intermediate-source', None)
92 s = ctx.extra().get(b'intermediate-source', None)
93 if s is not None:
93 if s is not None:
94 extra[b'intermediate-source'] = s
94 extra[b'intermediate-source'] = s
95
95
96
96
97 def _savebranch(ctx, extra):
97 def _savebranch(ctx, extra):
98 extra[b'branch'] = ctx.branch()
98 extra[b'branch'] = ctx.branch()
99
99
100
100
101 def _destrebase(repo, sourceset, destspace=None):
101 def _destrebase(repo, sourceset, destspace=None):
102 """small wrapper around destmerge to pass the right extra args
102 """small wrapper around destmerge to pass the right extra args
103
103
104 Please wrap destutil.destmerge instead."""
104 Please wrap destutil.destmerge instead."""
105 return destutil.destmerge(
105 return destutil.destmerge(
106 repo,
106 repo,
107 action=b'rebase',
107 action=b'rebase',
108 sourceset=sourceset,
108 sourceset=sourceset,
109 onheadcheck=False,
109 onheadcheck=False,
110 destspace=destspace,
110 destspace=destspace,
111 )
111 )
112
112
113
113
114 revsetpredicate = registrar.revsetpredicate()
114 revsetpredicate = registrar.revsetpredicate()
115
115
116
116
117 @revsetpredicate(b'_destrebase')
117 @revsetpredicate(b'_destrebase')
118 def _revsetdestrebase(repo, subset, x):
118 def _revsetdestrebase(repo, subset, x):
119 # ``_rebasedefaultdest()``
119 # ``_rebasedefaultdest()``
120
120
121 # default destination for rebase.
121 # default destination for rebase.
122 # # XXX: Currently private because I expect the signature to change.
122 # # XXX: Currently private because I expect the signature to change.
123 # # XXX: - bailing out in case of ambiguity vs returning all data.
123 # # XXX: - bailing out in case of ambiguity vs returning all data.
124 # i18n: "_rebasedefaultdest" is a keyword
124 # i18n: "_rebasedefaultdest" is a keyword
125 sourceset = None
125 sourceset = None
126 if x is not None:
126 if x is not None:
127 sourceset = revset.getset(repo, smartset.fullreposet(repo), x)
127 sourceset = revset.getset(repo, smartset.fullreposet(repo), x)
128 return subset & smartset.baseset([_destrebase(repo, sourceset)])
128 return subset & smartset.baseset([_destrebase(repo, sourceset)])
129
129
130
130
131 @revsetpredicate(b'_destautoorphanrebase')
131 @revsetpredicate(b'_destautoorphanrebase')
132 def _revsetdestautoorphanrebase(repo, subset, x):
132 def _revsetdestautoorphanrebase(repo, subset, x):
133 # ``_destautoorphanrebase()``
133 # ``_destautoorphanrebase()``
134
134
135 # automatic rebase destination for a single orphan revision.
135 # automatic rebase destination for a single orphan revision.
136 unfi = repo.unfiltered()
136 unfi = repo.unfiltered()
137 obsoleted = unfi.revs(b'obsolete()')
137 obsoleted = unfi.revs(b'obsolete()')
138
138
139 src = revset.getset(repo, subset, x).first()
139 src = revset.getset(repo, subset, x).first()
140
140
141 # Empty src or already obsoleted - Do not return a destination
141 # Empty src or already obsoleted - Do not return a destination
142 if not src or src in obsoleted:
142 if not src or src in obsoleted:
143 return smartset.baseset()
143 return smartset.baseset()
144 dests = destutil.orphanpossibledestination(repo, src)
144 dests = destutil.orphanpossibledestination(repo, src)
145 if len(dests) > 1:
145 if len(dests) > 1:
146 raise error.StateError(
146 raise error.StateError(
147 _(b"ambiguous automatic rebase: %r could end up on any of %r")
147 _(b"ambiguous automatic rebase: %r could end up on any of %r")
148 % (src, dests)
148 % (src, dests)
149 )
149 )
150 # We have zero or one destination, so we can just return here.
150 # We have zero or one destination, so we can just return here.
151 return smartset.baseset(dests)
151 return smartset.baseset(dests)
152
152
153
153
154 def _ctxdesc(ctx):
154 def _ctxdesc(ctx):
155 """short description for a context"""
155 """short description for a context"""
156 return cmdutil.format_changeset_summary(
156 return cmdutil.format_changeset_summary(
157 ctx.repo().ui, ctx, command=b'rebase'
157 ctx.repo().ui, ctx, command=b'rebase'
158 )
158 )
159
159
160
160
161 class rebaseruntime:
161 class rebaseruntime:
162 """This class is a container for rebase runtime state"""
162 """This class is a container for rebase runtime state"""
163
163
164 def __init__(self, repo, ui, inmemory=False, dryrun=False, opts=None):
164 def __init__(self, repo, ui, inmemory=False, dryrun=False, opts=None):
165 if opts is None:
165 if opts is None:
166 opts = {}
166 opts = {}
167
167
168 # prepared: whether we have rebasestate prepared or not. Currently it
168 # prepared: whether we have rebasestate prepared or not. Currently it
169 # decides whether "self.repo" is unfiltered or not.
169 # decides whether "self.repo" is unfiltered or not.
170 # The rebasestate has explicit hash to hash instructions not depending
170 # The rebasestate has explicit hash to hash instructions not depending
171 # on visibility. If rebasestate exists (in-memory or on-disk), use
171 # on visibility. If rebasestate exists (in-memory or on-disk), use
172 # unfiltered repo to avoid visibility issues.
172 # unfiltered repo to avoid visibility issues.
173 # Before knowing rebasestate (i.e. when starting a new rebase (not
173 # Before knowing rebasestate (i.e. when starting a new rebase (not
174 # --continue or --abort)), the original repo should be used so
174 # --continue or --abort)), the original repo should be used so
175 # visibility-dependent revsets are correct.
175 # visibility-dependent revsets are correct.
176 self.prepared = False
176 self.prepared = False
177 self.resume = False
177 self.resume = False
178 self._repo = repo
178 self._repo = repo
179
179
180 self.ui = ui
180 self.ui = ui
181 self.opts = opts
181 self.opts = opts
182 self.originalwd = None
182 self.originalwd = None
183 self.external = nullrev
183 self.external = nullrev
184 # Mapping between the old revision id and either what is the new rebased
184 # Mapping between the old revision id and either what is the new rebased
185 # revision or what needs to be done with the old revision. The state
185 # revision or what needs to be done with the old revision. The state
186 # dict will be what contains most of the rebase progress state.
186 # dict will be what contains most of the rebase progress state.
187 self.state = {}
187 self.state = {}
188 self.activebookmark = None
188 self.activebookmark = None
189 self.destmap = {}
189 self.destmap = {}
190 self.skipped = set()
190 self.skipped = set()
191
191
192 self.collapsef = opts.get('collapse', False)
192 self.collapsef = opts.get('collapse', False)
193 self.collapsemsg = cmdutil.logmessage(ui, pycompat.byteskwargs(opts))
193 self.collapsemsg = cmdutil.logmessage(ui, pycompat.byteskwargs(opts))
194 self.date = opts.get('date', None)
194 self.date = opts.get('date', None)
195
195
196 e = opts.get('extrafn') # internal, used by e.g. hgsubversion
196 e = opts.get('extrafn') # internal, used by e.g. hgsubversion
197 self.extrafns = [_savegraft]
197 self.extrafns = [_savegraft]
198 if e:
198 if e:
199 self.extrafns = [e]
199 self.extrafns = [e]
200
200
201 self.backupf = ui.configbool(b'rewrite', b'backup-bundle')
201 self.backupf = ui.configbool(b'rewrite', b'backup-bundle')
202 self.keepf = opts.get('keep', False)
202 self.keepf = opts.get('keep', False)
203 self.keepbranchesf = opts.get('keepbranches', False)
203 self.keepbranchesf = opts.get('keepbranches', False)
204 self.skipemptysuccessorf = rewriteutil.skip_empty_successor(
204 self.skipemptysuccessorf = rewriteutil.skip_empty_successor(
205 repo.ui, b'rebase'
205 repo.ui, b'rebase'
206 )
206 )
207 self.obsolete_with_successor_in_destination = {}
207 self.obsolete_with_successor_in_destination = {}
208 self.obsolete_with_successor_in_rebase_set = set()
208 self.obsolete_with_successor_in_rebase_set = set()
209 self.inmemory = inmemory
209 self.inmemory = inmemory
210 self.dryrun = dryrun
210 self.dryrun = dryrun
211 self.stateobj = statemod.cmdstate(repo, b'rebasestate')
211 self.stateobj = statemod.cmdstate(repo, b'rebasestate')
212
212
213 @property
213 @property
214 def repo(self):
214 def repo(self):
215 if self.prepared:
215 if self.prepared:
216 return self._repo.unfiltered()
216 return self._repo.unfiltered()
217 else:
217 else:
218 return self._repo
218 return self._repo
219
219
220 def storestatus(self, tr=None):
220 def storestatus(self, tr=None):
221 """Store the current status to allow recovery"""
221 """Store the current status to allow recovery"""
222 if tr:
222 if tr:
223 tr.addfilegenerator(
223 tr.addfilegenerator(
224 b'rebasestate',
224 b'rebasestate',
225 (b'rebasestate',),
225 (b'rebasestate',),
226 self._writestatus,
226 self._writestatus,
227 location=b'plain',
227 location=b'plain',
228 )
228 )
229 else:
229 else:
230 with self.repo.vfs(b"rebasestate", b"w") as f:
230 with self.repo.vfs(b"rebasestate", b"w") as f:
231 self._writestatus(f)
231 self._writestatus(f)
232
232
233 def _writestatus(self, f):
233 def _writestatus(self, f):
234 repo = self.repo
234 repo = self.repo
235 assert repo.filtername is None
235 assert repo.filtername is None
236 f.write(repo[self.originalwd].hex() + b'\n')
236 f.write(repo[self.originalwd].hex() + b'\n')
237 # was "dest". we now write dest per src root below.
237 # was "dest". we now write dest per src root below.
238 f.write(b'\n')
238 f.write(b'\n')
239 f.write(repo[self.external].hex() + b'\n')
239 f.write(repo[self.external].hex() + b'\n')
240 f.write(b'%d\n' % int(self.collapsef))
240 f.write(b'%d\n' % int(self.collapsef))
241 f.write(b'%d\n' % int(self.keepf))
241 f.write(b'%d\n' % int(self.keepf))
242 f.write(b'%d\n' % int(self.keepbranchesf))
242 f.write(b'%d\n' % int(self.keepbranchesf))
243 f.write(b'%s\n' % (self.activebookmark or b''))
243 f.write(b'%s\n' % (self.activebookmark or b''))
244 destmap = self.destmap
244 destmap = self.destmap
245 for d, v in self.state.items():
245 for d, v in self.state.items():
246 oldrev = repo[d].hex()
246 oldrev = repo[d].hex()
247 if v >= 0:
247 if v >= 0:
248 newrev = repo[v].hex()
248 newrev = repo[v].hex()
249 else:
249 else:
250 newrev = b"%d" % v
250 newrev = b"%d" % v
251 destnode = repo[destmap[d]].hex()
251 destnode = repo[destmap[d]].hex()
252 f.write(b"%s:%s:%s\n" % (oldrev, newrev, destnode))
252 f.write(b"%s:%s:%s\n" % (oldrev, newrev, destnode))
253 repo.ui.debug(b'rebase status stored\n')
253 repo.ui.debug(b'rebase status stored\n')
254
254
255 def restorestatus(self):
255 def restorestatus(self):
256 """Restore a previously stored status"""
256 """Restore a previously stored status"""
257 if not self.stateobj.exists():
257 if not self.stateobj.exists():
258 cmdutil.wrongtooltocontinue(self.repo, _(b'rebase'))
258 cmdutil.wrongtooltocontinue(self.repo, _(b'rebase'))
259
259
260 data = self._read()
260 data = self._read()
261 self.repo.ui.debug(b'rebase status resumed\n')
261 self.repo.ui.debug(b'rebase status resumed\n')
262
262
263 self.originalwd = data[b'originalwd']
263 self.originalwd = data[b'originalwd']
264 self.destmap = data[b'destmap']
264 self.destmap = data[b'destmap']
265 self.state = data[b'state']
265 self.state = data[b'state']
266 self.skipped = data[b'skipped']
266 self.skipped = data[b'skipped']
267 self.collapsef = data[b'collapse']
267 self.collapsef = data[b'collapse']
268 self.keepf = data[b'keep']
268 self.keepf = data[b'keep']
269 self.keepbranchesf = data[b'keepbranches']
269 self.keepbranchesf = data[b'keepbranches']
270 self.external = data[b'external']
270 self.external = data[b'external']
271 self.activebookmark = data[b'activebookmark']
271 self.activebookmark = data[b'activebookmark']
272
272
273 def _read(self):
273 def _read(self):
274 self.prepared = True
274 self.prepared = True
275 repo = self.repo
275 repo = self.repo
276 assert repo.filtername is None
276 assert repo.filtername is None
277 data = {
277 data = {
278 b'keepbranches': None,
278 b'keepbranches': None,
279 b'collapse': None,
279 b'collapse': None,
280 b'activebookmark': None,
280 b'activebookmark': None,
281 b'external': nullrev,
281 b'external': nullrev,
282 b'keep': None,
282 b'keep': None,
283 b'originalwd': None,
283 b'originalwd': None,
284 }
284 }
285 legacydest = None
285 legacydest = None
286 state = {}
286 state = {}
287 destmap = {}
287 destmap = {}
288
288
289 if True:
289 if True:
290 f = repo.vfs(b"rebasestate")
290 f = repo.vfs(b"rebasestate")
291 for i, l in enumerate(f.read().splitlines()):
291 for i, l in enumerate(f.read().splitlines()):
292 if i == 0:
292 if i == 0:
293 data[b'originalwd'] = repo[l].rev()
293 data[b'originalwd'] = repo[l].rev()
294 elif i == 1:
294 elif i == 1:
295 # this line should be empty in newer version. but legacy
295 # this line should be empty in newer version. but legacy
296 # clients may still use it
296 # clients may still use it
297 if l:
297 if l:
298 legacydest = repo[l].rev()
298 legacydest = repo[l].rev()
299 elif i == 2:
299 elif i == 2:
300 data[b'external'] = repo[l].rev()
300 data[b'external'] = repo[l].rev()
301 elif i == 3:
301 elif i == 3:
302 data[b'collapse'] = bool(int(l))
302 data[b'collapse'] = bool(int(l))
303 elif i == 4:
303 elif i == 4:
304 data[b'keep'] = bool(int(l))
304 data[b'keep'] = bool(int(l))
305 elif i == 5:
305 elif i == 5:
306 data[b'keepbranches'] = bool(int(l))
306 data[b'keepbranches'] = bool(int(l))
307 elif i == 6 and not (len(l) == 81 and b':' in l):
307 elif i == 6 and not (len(l) == 81 and b':' in l):
308 # line 6 is a recent addition, so for backwards
308 # line 6 is a recent addition, so for backwards
309 # compatibility check that the line doesn't look like the
309 # compatibility check that the line doesn't look like the
310 # oldrev:newrev lines
310 # oldrev:newrev lines
311 data[b'activebookmark'] = l
311 data[b'activebookmark'] = l
312 else:
312 else:
313 args = l.split(b':')
313 args = l.split(b':')
314 oldrev = repo[args[0]].rev()
314 oldrev = repo[args[0]].rev()
315 newrev = args[1]
315 newrev = args[1]
316 if newrev in legacystates:
316 if newrev in legacystates:
317 continue
317 continue
318 if len(args) > 2:
318 if len(args) > 2:
319 destrev = repo[args[2]].rev()
319 destrev = repo[args[2]].rev()
320 else:
320 else:
321 destrev = legacydest
321 destrev = legacydest
322 destmap[oldrev] = destrev
322 destmap[oldrev] = destrev
323 if newrev == revtodostr:
323 if newrev == revtodostr:
324 state[oldrev] = revtodo
324 state[oldrev] = revtodo
325 # Legacy compat special case
325 # Legacy compat special case
326 else:
326 else:
327 state[oldrev] = repo[newrev].rev()
327 state[oldrev] = repo[newrev].rev()
328
328
329 if data[b'keepbranches'] is None:
329 if data[b'keepbranches'] is None:
330 raise error.Abort(_(b'.hg/rebasestate is incomplete'))
330 raise error.Abort(_(b'.hg/rebasestate is incomplete'))
331
331
332 data[b'destmap'] = destmap
332 data[b'destmap'] = destmap
333 data[b'state'] = state
333 data[b'state'] = state
334 skipped = set()
334 skipped = set()
335 # recompute the set of skipped revs
335 # recompute the set of skipped revs
336 if not data[b'collapse']:
336 if not data[b'collapse']:
337 seen = set(destmap.values())
337 seen = set(destmap.values())
338 for old, new in sorted(state.items()):
338 for old, new in sorted(state.items()):
339 if new != revtodo and new in seen:
339 if new != revtodo and new in seen:
340 skipped.add(old)
340 skipped.add(old)
341 seen.add(new)
341 seen.add(new)
342 data[b'skipped'] = skipped
342 data[b'skipped'] = skipped
343 repo.ui.debug(
343 repo.ui.debug(
344 b'computed skipped revs: %s\n'
344 b'computed skipped revs: %s\n'
345 % (b' '.join(b'%d' % r for r in sorted(skipped)) or b'')
345 % (b' '.join(b'%d' % r for r in sorted(skipped)) or b'')
346 )
346 )
347
347
348 return data
348 return data
349
349
350 def _handleskippingobsolete(self):
350 def _handleskippingobsolete(self):
351 """Compute structures necessary for skipping obsolete revisions"""
351 """Compute structures necessary for skipping obsolete revisions"""
352 if self.keepf:
352 if self.keepf:
353 return
353 return
354 if not self.ui.configbool(b'experimental', b'rebaseskipobsolete'):
354 if not self.ui.configbool(b'experimental', b'rebaseskipobsolete'):
355 return
355 return
356 obsoleteset = {r for r in self.state if self.repo[r].obsolete()}
356 obsoleteset = {r for r in self.state if self.repo[r].obsolete()}
357 (
357 (
358 self.obsolete_with_successor_in_destination,
358 self.obsolete_with_successor_in_destination,
359 self.obsolete_with_successor_in_rebase_set,
359 self.obsolete_with_successor_in_rebase_set,
360 ) = _compute_obsolete_sets(self.repo, obsoleteset, self.destmap)
360 ) = _compute_obsolete_sets(self.repo, obsoleteset, self.destmap)
361 skippedset = set(self.obsolete_with_successor_in_destination)
361 skippedset = set(self.obsolete_with_successor_in_destination)
362 skippedset.update(self.obsolete_with_successor_in_rebase_set)
362 skippedset.update(self.obsolete_with_successor_in_rebase_set)
363 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
363 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
364 if obsolete.isenabled(self.repo, obsolete.allowdivergenceopt):
364 if obsolete.isenabled(self.repo, obsolete.allowdivergenceopt):
365 self.obsolete_with_successor_in_rebase_set = set()
365 self.obsolete_with_successor_in_rebase_set = set()
366 else:
366 else:
367 for rev in self.repo.revs(
367 for rev in self.repo.revs(
368 b'descendants(%ld) and not %ld',
368 b'descendants(%ld) and not %ld',
369 self.obsolete_with_successor_in_rebase_set,
369 self.obsolete_with_successor_in_rebase_set,
370 self.obsolete_with_successor_in_rebase_set,
370 self.obsolete_with_successor_in_rebase_set,
371 ):
371 ):
372 self.state.pop(rev, None)
372 self.state.pop(rev, None)
373 self.destmap.pop(rev, None)
373 self.destmap.pop(rev, None)
374
374
375 def _prepareabortorcontinue(
375 def _prepareabortorcontinue(
376 self, isabort, backup=True, suppwarns=False, dryrun=False, confirm=False
376 self, isabort, backup=True, suppwarns=False, dryrun=False, confirm=False
377 ):
377 ):
378 self.resume = True
378 self.resume = True
379 try:
379 try:
380 self.restorestatus()
380 self.restorestatus()
381 # Calculate self.obsolete_* sets
381 # Calculate self.obsolete_* sets
382 self._handleskippingobsolete()
382 self._handleskippingobsolete()
383 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
383 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
384 except error.RepoLookupError:
384 except error.RepoLookupError:
385 if isabort:
385 if isabort:
386 clearstatus(self.repo)
386 clearstatus(self.repo)
387 clearcollapsemsg(self.repo)
387 clearcollapsemsg(self.repo)
388 self.repo.ui.warn(
388 self.repo.ui.warn(
389 _(
389 _(
390 b'rebase aborted (no revision is removed,'
390 b'rebase aborted (no revision is removed,'
391 b' only broken state is cleared)\n'
391 b' only broken state is cleared)\n'
392 )
392 )
393 )
393 )
394 return 0
394 return 0
395 else:
395 else:
396 msg = _(b'cannot continue inconsistent rebase')
396 msg = _(b'cannot continue inconsistent rebase')
397 hint = _(b'use "hg rebase --abort" to clear broken state')
397 hint = _(b'use "hg rebase --abort" to clear broken state')
398 raise error.Abort(msg, hint=hint)
398 raise error.Abort(msg, hint=hint)
399
399
400 if isabort:
400 if isabort:
401 backup = backup and self.backupf
401 backup = backup and self.backupf
402 return self._abort(
402 return self._abort(
403 backup=backup,
403 backup=backup,
404 suppwarns=suppwarns,
404 suppwarns=suppwarns,
405 dryrun=dryrun,
405 dryrun=dryrun,
406 confirm=confirm,
406 confirm=confirm,
407 )
407 )
408
408
409 def _preparenewrebase(self, destmap):
409 def _preparenewrebase(self, destmap):
410 if not destmap:
410 if not destmap:
411 return _nothingtorebase()
411 return _nothingtorebase()
412
412
413 result = buildstate(self.repo, destmap, self.collapsef)
413 result = buildstate(self.repo, destmap, self.collapsef)
414
414
415 if not result:
415 if not result:
416 # Empty state built, nothing to rebase
416 # Empty state built, nothing to rebase
417 self.ui.status(_(b'nothing to rebase\n'))
417 self.ui.status(_(b'nothing to rebase\n'))
418 return _nothingtorebase()
418 return _nothingtorebase()
419
419
420 (self.originalwd, self.destmap, self.state) = result
420 (self.originalwd, self.destmap, self.state) = result
421 if self.collapsef:
421 if self.collapsef:
422 dests = set(self.destmap.values())
422 dests = set(self.destmap.values())
423 if len(dests) != 1:
423 if len(dests) != 1:
424 raise error.InputError(
424 raise error.InputError(
425 _(b'--collapse does not work with multiple destinations')
425 _(b'--collapse does not work with multiple destinations')
426 )
426 )
427 destrev = next(iter(dests))
427 destrev = next(iter(dests))
428 destancestors = self.repo.changelog.ancestors(
428 destancestors = self.repo.changelog.ancestors(
429 [destrev], inclusive=True
429 [destrev], inclusive=True
430 )
430 )
431 self.external = externalparent(self.repo, self.state, destancestors)
431 self.external = externalparent(self.repo, self.state, destancestors)
432
432
433 for destrev in sorted(set(destmap.values())):
433 for destrev in sorted(set(destmap.values())):
434 dest = self.repo[destrev]
434 dest = self.repo[destrev]
435 if dest.closesbranch() and not self.keepbranchesf:
435 if dest.closesbranch() and not self.keepbranchesf:
436 self.ui.status(_(b'reopening closed branch head %s\n') % dest)
436 self.ui.status(_(b'reopening closed branch head %s\n') % dest)
437
437
438 # Calculate self.obsolete_* sets
438 # Calculate self.obsolete_* sets
439 self._handleskippingobsolete()
439 self._handleskippingobsolete()
440
440
441 if not self.keepf:
441 if not self.keepf:
442 rebaseset = set(destmap.keys())
442 rebaseset = set(destmap.keys())
443 rebaseset -= set(self.obsolete_with_successor_in_destination)
443 rebaseset -= set(self.obsolete_with_successor_in_destination)
444 rebaseset -= self.obsolete_with_successor_in_rebase_set
444 rebaseset -= self.obsolete_with_successor_in_rebase_set
445 # We have our own divergence-checking in the rebase extension
445 # We have our own divergence-checking in the rebase extension
446 overrides = {}
446 overrides = {}
447 if obsolete.isenabled(self.repo, obsolete.createmarkersopt):
447 if obsolete.isenabled(self.repo, obsolete.createmarkersopt):
448 overrides = {
448 overrides = {
449 (b'experimental', b'evolution.allowdivergence'): b'true'
449 (b'experimental', b'evolution.allowdivergence'): b'true'
450 }
450 }
451 try:
451 try:
452 with self.ui.configoverride(overrides):
452 with self.ui.configoverride(overrides):
453 rewriteutil.precheck(self.repo, rebaseset, action=b'rebase')
453 rewriteutil.precheck(self.repo, rebaseset, action=b'rebase')
454 except error.Abort as e:
454 except error.Abort as e:
455 if e.hint is None:
455 if e.hint is None:
456 e.hint = _(b'use --keep to keep original changesets')
456 e.hint = _(b'use --keep to keep original changesets')
457 raise e
457 raise e
458
458
459 self.prepared = True
459 self.prepared = True
460
460
461 def _assignworkingcopy(self):
461 def _assignworkingcopy(self):
462 if self.inmemory:
462 if self.inmemory:
463 from mercurial.context import overlayworkingctx
463 from mercurial.context import overlayworkingctx
464
464
465 self.wctx = overlayworkingctx(self.repo)
465 self.wctx = overlayworkingctx(self.repo)
466 self.repo.ui.debug(b"rebasing in memory\n")
466 self.repo.ui.debug(b"rebasing in memory\n")
467 else:
467 else:
468 self.wctx = self.repo[None]
468 self.wctx = self.repo[None]
469 self.repo.ui.debug(b"rebasing on disk\n")
469 self.repo.ui.debug(b"rebasing on disk\n")
470 self.repo.ui.log(
470 self.repo.ui.log(
471 b"rebase",
471 b"rebase",
472 b"using in-memory rebase: %r\n",
472 b"using in-memory rebase: %r\n",
473 self.inmemory,
473 self.inmemory,
474 rebase_imm_used=self.inmemory,
474 rebase_imm_used=self.inmemory,
475 )
475 )
476
476
477 def _performrebase(self, tr):
477 def _performrebase(self, tr):
478 self._assignworkingcopy()
478 self._assignworkingcopy()
479 repo, ui = self.repo, self.ui
479 repo, ui = self.repo, self.ui
480 if self.keepbranchesf:
480 if self.keepbranchesf:
481 # insert _savebranch at the start of extrafns so if
481 # insert _savebranch at the start of extrafns so if
482 # there's a user-provided extrafn it can clobber branch if
482 # there's a user-provided extrafn it can clobber branch if
483 # desired
483 # desired
484 self.extrafns.insert(0, _savebranch)
484 self.extrafns.insert(0, _savebranch)
485 if self.collapsef:
485 if self.collapsef:
486 branches = set()
486 branches = set()
487 for rev in self.state:
487 for rev in self.state:
488 branches.add(repo[rev].branch())
488 branches.add(repo[rev].branch())
489 if len(branches) > 1:
489 if len(branches) > 1:
490 raise error.InputError(
490 raise error.InputError(
491 _(b'cannot collapse multiple named branches')
491 _(b'cannot collapse multiple named branches')
492 )
492 )
493
493
494 # Keep track of the active bookmarks in order to reset them later
494 # Keep track of the active bookmarks in order to reset them later
495 self.activebookmark = self.activebookmark or repo._activebookmark
495 self.activebookmark = self.activebookmark or repo._activebookmark
496 if self.activebookmark:
496 if self.activebookmark:
497 bookmarks.deactivate(repo)
497 bookmarks.deactivate(repo)
498
498
499 # Store the state before we begin so users can run 'hg rebase --abort'
499 # Store the state before we begin so users can run 'hg rebase --abort'
500 # if we fail before the transaction closes.
500 # if we fail before the transaction closes.
501 self.storestatus()
501 self.storestatus()
502 if tr:
502 if tr:
503 # When using single transaction, store state when transaction
503 # When using single transaction, store state when transaction
504 # commits.
504 # commits.
505 self.storestatus(tr)
505 self.storestatus(tr)
506
506
507 cands = [k for k, v in self.state.items() if v == revtodo]
507 cands = [k for k, v in self.state.items() if v == revtodo]
508 p = repo.ui.makeprogress(
508 p = repo.ui.makeprogress(
509 _(b"rebasing"), unit=_(b'changesets'), total=len(cands)
509 _(b"rebasing"), unit=_(b'changesets'), total=len(cands)
510 )
510 )
511
511
512 def progress(ctx):
512 def progress(ctx):
513 p.increment(item=(b"%d:%s" % (ctx.rev(), ctx)))
513 p.increment(item=(b"%d:%s" % (ctx.rev(), ctx)))
514
514
515 for subset in sortsource(self.destmap):
515 for subset in sortsource(self.destmap):
516 sortedrevs = self.repo.revs(b'sort(%ld, -topo)', subset)
516 sortedrevs = self.repo.revs(b'sort(%ld, -topo)', subset)
517 for rev in sortedrevs:
517 for rev in sortedrevs:
518 self._rebasenode(tr, rev, progress)
518 self._rebasenode(tr, rev, progress)
519 p.complete()
519 p.complete()
520 ui.note(_(b'rebase merging completed\n'))
520 ui.note(_(b'rebase merging completed\n'))
521
521
522 def _concludenode(self, rev, editor, commitmsg=None):
522 def _concludenode(self, rev, editor, commitmsg=None):
523 """Commit the wd changes with parents p1 and p2.
523 """Commit the wd changes with parents p1 and p2.
524
524
525 Reuse commit info from rev but also store useful information in extra.
525 Reuse commit info from rev but also store useful information in extra.
526 Return node of committed revision."""
526 Return node of committed revision."""
527 repo = self.repo
527 repo = self.repo
528 ctx = repo[rev]
528 ctx = repo[rev]
529 if commitmsg is None:
529 if commitmsg is None:
530 commitmsg = ctx.description()
530 commitmsg = ctx.description()
531
531
532 # Skip replacement if collapsing, as that degenerates to p1 for all
532 # Skip replacement if collapsing, as that degenerates to p1 for all
533 # nodes.
533 # nodes.
534 if not self.collapsef:
534 if not self.collapsef:
535 cl = repo.changelog
535 cl = repo.changelog
536 commitmsg = rewriteutil.update_hash_refs(
536 commitmsg = rewriteutil.update_hash_refs(
537 repo,
537 repo,
538 commitmsg,
538 commitmsg,
539 {
539 {
540 cl.node(oldrev): [cl.node(newrev)]
540 cl.node(oldrev): [cl.node(newrev)]
541 for oldrev, newrev in self.state.items()
541 for oldrev, newrev in self.state.items()
542 if newrev != revtodo
542 if newrev != revtodo
543 },
543 },
544 )
544 )
545
545
546 date = self.date
546 date = self.date
547 if date is None:
547 if date is None:
548 date = ctx.date()
548 date = ctx.date()
549 extra = {b'rebase_source': ctx.hex()}
549 extra = {}
550 if repo.ui.configbool(b'rebase', b'store-source'):
551 extra = {b'rebase_source': ctx.hex()}
550 for c in self.extrafns:
552 for c in self.extrafns:
551 c(ctx, extra)
553 c(ctx, extra)
552 destphase = max(ctx.phase(), phases.draft)
554 destphase = max(ctx.phase(), phases.draft)
553 overrides = {
555 overrides = {
554 (b'phases', b'new-commit'): destphase,
556 (b'phases', b'new-commit'): destphase,
555 (b'ui', b'allowemptycommit'): not self.skipemptysuccessorf,
557 (b'ui', b'allowemptycommit'): not self.skipemptysuccessorf,
556 }
558 }
557 with repo.ui.configoverride(overrides, b'rebase'):
559 with repo.ui.configoverride(overrides, b'rebase'):
558 if self.inmemory:
560 if self.inmemory:
559 newnode = commitmemorynode(
561 newnode = commitmemorynode(
560 repo,
562 repo,
561 wctx=self.wctx,
563 wctx=self.wctx,
562 extra=extra,
564 extra=extra,
563 commitmsg=commitmsg,
565 commitmsg=commitmsg,
564 editor=editor,
566 editor=editor,
565 user=ctx.user(),
567 user=ctx.user(),
566 date=date,
568 date=date,
567 )
569 )
568 else:
570 else:
569 newnode = commitnode(
571 newnode = commitnode(
570 repo,
572 repo,
571 extra=extra,
573 extra=extra,
572 commitmsg=commitmsg,
574 commitmsg=commitmsg,
573 editor=editor,
575 editor=editor,
574 user=ctx.user(),
576 user=ctx.user(),
575 date=date,
577 date=date,
576 )
578 )
577
579
578 return newnode
580 return newnode
579
581
580 def _rebasenode(self, tr, rev, progressfn):
582 def _rebasenode(self, tr, rev, progressfn):
581 repo, ui, opts = self.repo, self.ui, self.opts
583 repo, ui, opts = self.repo, self.ui, self.opts
582 ctx = repo[rev]
584 ctx = repo[rev]
583 desc = _ctxdesc(ctx)
585 desc = _ctxdesc(ctx)
584 if self.state[rev] == rev:
586 if self.state[rev] == rev:
585 ui.status(_(b'already rebased %s\n') % desc)
587 ui.status(_(b'already rebased %s\n') % desc)
586 elif rev in self.obsolete_with_successor_in_rebase_set:
588 elif rev in self.obsolete_with_successor_in_rebase_set:
587 msg = (
589 msg = (
588 _(
590 _(
589 b'note: not rebasing %s and its descendants as '
591 b'note: not rebasing %s and its descendants as '
590 b'this would cause divergence\n'
592 b'this would cause divergence\n'
591 )
593 )
592 % desc
594 % desc
593 )
595 )
594 repo.ui.status(msg)
596 repo.ui.status(msg)
595 self.skipped.add(rev)
597 self.skipped.add(rev)
596 elif rev in self.obsolete_with_successor_in_destination:
598 elif rev in self.obsolete_with_successor_in_destination:
597 succ = self.obsolete_with_successor_in_destination[rev]
599 succ = self.obsolete_with_successor_in_destination[rev]
598 if succ is None:
600 if succ is None:
599 msg = _(b'note: not rebasing %s, it has no successor\n') % desc
601 msg = _(b'note: not rebasing %s, it has no successor\n') % desc
600 else:
602 else:
601 succdesc = _ctxdesc(repo[succ])
603 succdesc = _ctxdesc(repo[succ])
602 msg = _(
604 msg = _(
603 b'note: not rebasing %s, already in destination as %s\n'
605 b'note: not rebasing %s, already in destination as %s\n'
604 ) % (desc, succdesc)
606 ) % (desc, succdesc)
605 repo.ui.status(msg)
607 repo.ui.status(msg)
606 # Make clearrebased aware state[rev] is not a true successor
608 # Make clearrebased aware state[rev] is not a true successor
607 self.skipped.add(rev)
609 self.skipped.add(rev)
608 # Record rev as moved to its desired destination in self.state.
610 # Record rev as moved to its desired destination in self.state.
609 # This helps bookmark and working parent movement.
611 # This helps bookmark and working parent movement.
610 dest = max(
612 dest = max(
611 adjustdest(repo, rev, self.destmap, self.state, self.skipped)
613 adjustdest(repo, rev, self.destmap, self.state, self.skipped)
612 )
614 )
613 self.state[rev] = dest
615 self.state[rev] = dest
614 elif self.state[rev] == revtodo:
616 elif self.state[rev] == revtodo:
615 ui.status(_(b'rebasing %s\n') % desc)
617 ui.status(_(b'rebasing %s\n') % desc)
616 progressfn(ctx)
618 progressfn(ctx)
617 p1, p2, base = defineparents(
619 p1, p2, base = defineparents(
618 repo,
620 repo,
619 rev,
621 rev,
620 self.destmap,
622 self.destmap,
621 self.state,
623 self.state,
622 self.skipped,
624 self.skipped,
623 self.obsolete_with_successor_in_destination,
625 self.obsolete_with_successor_in_destination,
624 )
626 )
625 if self.resume and self.wctx.p1().rev() == p1:
627 if self.resume and self.wctx.p1().rev() == p1:
626 repo.ui.debug(b'resuming interrupted rebase\n')
628 repo.ui.debug(b'resuming interrupted rebase\n')
627 self.resume = False
629 self.resume = False
628 else:
630 else:
629 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
631 overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')}
630 with ui.configoverride(overrides, b'rebase'):
632 with ui.configoverride(overrides, b'rebase'):
631 try:
633 try:
632 rebasenode(
634 rebasenode(
633 repo,
635 repo,
634 rev,
636 rev,
635 p1,
637 p1,
636 p2,
638 p2,
637 base,
639 base,
638 self.collapsef,
640 self.collapsef,
639 wctx=self.wctx,
641 wctx=self.wctx,
640 )
642 )
641 except error.InMemoryMergeConflictsError:
643 except error.InMemoryMergeConflictsError:
642 if self.dryrun:
644 if self.dryrun:
643 raise error.ConflictResolutionRequired(b'rebase')
645 raise error.ConflictResolutionRequired(b'rebase')
644 if self.collapsef:
646 if self.collapsef:
645 # TODO: Make the overlayworkingctx reflected
647 # TODO: Make the overlayworkingctx reflected
646 # in the working copy here instead of re-raising
648 # in the working copy here instead of re-raising
647 # so the entire rebase operation is retried.
649 # so the entire rebase operation is retried.
648 raise
650 raise
649 ui.status(
651 ui.status(
650 _(
652 _(
651 b"hit merge conflicts; rebasing that "
653 b"hit merge conflicts; rebasing that "
652 b"commit again in the working copy\n"
654 b"commit again in the working copy\n"
653 )
655 )
654 )
656 )
655 try:
657 try:
656 cmdutil.bailifchanged(repo)
658 cmdutil.bailifchanged(repo)
657 except error.Abort:
659 except error.Abort:
658 clearstatus(repo)
660 clearstatus(repo)
659 clearcollapsemsg(repo)
661 clearcollapsemsg(repo)
660 raise
662 raise
661 self.inmemory = False
663 self.inmemory = False
662 self._assignworkingcopy()
664 self._assignworkingcopy()
663 mergemod.update(repo[p1], wc=self.wctx)
665 mergemod.update(repo[p1], wc=self.wctx)
664 rebasenode(
666 rebasenode(
665 repo,
667 repo,
666 rev,
668 rev,
667 p1,
669 p1,
668 p2,
670 p2,
669 base,
671 base,
670 self.collapsef,
672 self.collapsef,
671 wctx=self.wctx,
673 wctx=self.wctx,
672 )
674 )
673 if not self.collapsef:
675 if not self.collapsef:
674 merging = p2 != nullrev
676 merging = p2 != nullrev
675 editform = cmdutil.mergeeditform(merging, b'rebase')
677 editform = cmdutil.mergeeditform(merging, b'rebase')
676 editor = cmdutil.getcommiteditor(editform=editform, **opts)
678 editor = cmdutil.getcommiteditor(editform=editform, **opts)
677 # We need to set parents again here just in case we're continuing
679 # We need to set parents again here just in case we're continuing
678 # a rebase started with an old hg version (before 9c9cfecd4600),
680 # a rebase started with an old hg version (before 9c9cfecd4600),
679 # because those old versions would have left us with two dirstate
681 # because those old versions would have left us with two dirstate
680 # parents, and we don't want to create a merge commit here (unless
682 # parents, and we don't want to create a merge commit here (unless
681 # we're rebasing a merge commit).
683 # we're rebasing a merge commit).
682 self.wctx.setparents(repo[p1].node(), repo[p2].node())
684 self.wctx.setparents(repo[p1].node(), repo[p2].node())
683 newnode = self._concludenode(rev, editor)
685 newnode = self._concludenode(rev, editor)
684 else:
686 else:
685 # Skip commit if we are collapsing
687 # Skip commit if we are collapsing
686 newnode = None
688 newnode = None
687 # Update the state
689 # Update the state
688 if newnode is not None:
690 if newnode is not None:
689 self.state[rev] = repo[newnode].rev()
691 self.state[rev] = repo[newnode].rev()
690 ui.debug(b'rebased as %s\n' % short(newnode))
692 ui.debug(b'rebased as %s\n' % short(newnode))
691 if repo[newnode].isempty():
693 if repo[newnode].isempty():
692 ui.warn(
694 ui.warn(
693 _(
695 _(
694 b'note: created empty successor for %s, its '
696 b'note: created empty successor for %s, its '
695 b'destination already has all its changes\n'
697 b'destination already has all its changes\n'
696 )
698 )
697 % desc
699 % desc
698 )
700 )
699 else:
701 else:
700 if not self.collapsef:
702 if not self.collapsef:
701 ui.warn(
703 ui.warn(
702 _(
704 _(
703 b'note: not rebasing %s, its destination already '
705 b'note: not rebasing %s, its destination already '
704 b'has all its changes\n'
706 b'has all its changes\n'
705 )
707 )
706 % desc
708 % desc
707 )
709 )
708 self.skipped.add(rev)
710 self.skipped.add(rev)
709 self.state[rev] = p1
711 self.state[rev] = p1
710 ui.debug(b'next revision set to %d\n' % p1)
712 ui.debug(b'next revision set to %d\n' % p1)
711 else:
713 else:
712 ui.status(
714 ui.status(
713 _(b'already rebased %s as %s\n') % (desc, repo[self.state[rev]])
715 _(b'already rebased %s as %s\n') % (desc, repo[self.state[rev]])
714 )
716 )
715 if not tr:
717 if not tr:
716 # When not using single transaction, store state after each
718 # When not using single transaction, store state after each
717 # commit is completely done. On InterventionRequired, we thus
719 # commit is completely done. On InterventionRequired, we thus
718 # won't store the status. Instead, we'll hit the "len(parents) == 2"
720 # won't store the status. Instead, we'll hit the "len(parents) == 2"
719 # case and realize that the commit was in progress.
721 # case and realize that the commit was in progress.
720 self.storestatus()
722 self.storestatus()
721
723
722 def _finishrebase(self):
724 def _finishrebase(self):
723 repo, ui, opts = self.repo, self.ui, self.opts
725 repo, ui, opts = self.repo, self.ui, self.opts
724 fm = ui.formatter(b'rebase', pycompat.byteskwargs(opts))
726 fm = ui.formatter(b'rebase', pycompat.byteskwargs(opts))
725 fm.startitem()
727 fm.startitem()
726 if self.collapsef:
728 if self.collapsef:
727 p1, p2, _base = defineparents(
729 p1, p2, _base = defineparents(
728 repo,
730 repo,
729 min(self.state),
731 min(self.state),
730 self.destmap,
732 self.destmap,
731 self.state,
733 self.state,
732 self.skipped,
734 self.skipped,
733 self.obsolete_with_successor_in_destination,
735 self.obsolete_with_successor_in_destination,
734 )
736 )
735 editopt = opts.get('edit')
737 editopt = opts.get('edit')
736 editform = b'rebase.collapse'
738 editform = b'rebase.collapse'
737 if self.collapsemsg:
739 if self.collapsemsg:
738 commitmsg = self.collapsemsg
740 commitmsg = self.collapsemsg
739 else:
741 else:
740 commitmsg = b'Collapsed revision'
742 commitmsg = b'Collapsed revision'
741 for rebased in sorted(self.state):
743 for rebased in sorted(self.state):
742 if rebased not in self.skipped:
744 if rebased not in self.skipped:
743 commitmsg += b'\n* %s' % repo[rebased].description()
745 commitmsg += b'\n* %s' % repo[rebased].description()
744 editopt = True
746 editopt = True
745 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
747 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
746 revtoreuse = max(self.state)
748 revtoreuse = max(self.state)
747
749
748 self.wctx.setparents(repo[p1].node(), repo[self.external].node())
750 self.wctx.setparents(repo[p1].node(), repo[self.external].node())
749 newnode = self._concludenode(
751 newnode = self._concludenode(
750 revtoreuse, editor, commitmsg=commitmsg
752 revtoreuse, editor, commitmsg=commitmsg
751 )
753 )
752
754
753 if newnode is not None:
755 if newnode is not None:
754 newrev = repo[newnode].rev()
756 newrev = repo[newnode].rev()
755 for oldrev in self.state:
757 for oldrev in self.state:
756 self.state[oldrev] = newrev
758 self.state[oldrev] = newrev
757
759
758 if b'qtip' in repo.tags():
760 if b'qtip' in repo.tags():
759 updatemq(repo, self.state, self.skipped, **opts)
761 updatemq(repo, self.state, self.skipped, **opts)
760
762
761 # restore original working directory
763 # restore original working directory
762 # (we do this before stripping)
764 # (we do this before stripping)
763 newwd = self.state.get(self.originalwd, self.originalwd)
765 newwd = self.state.get(self.originalwd, self.originalwd)
764 if newwd < 0:
766 if newwd < 0:
765 # original directory is a parent of rebase set root or ignored
767 # original directory is a parent of rebase set root or ignored
766 newwd = self.originalwd
768 newwd = self.originalwd
767 if newwd not in [c.rev() for c in repo[None].parents()]:
769 if newwd not in [c.rev() for c in repo[None].parents()]:
768 ui.note(_(b"update back to initial working directory parent\n"))
770 ui.note(_(b"update back to initial working directory parent\n"))
769 mergemod.update(repo[newwd])
771 mergemod.update(repo[newwd])
770
772
771 collapsedas = None
773 collapsedas = None
772 if self.collapsef and not self.keepf:
774 if self.collapsef and not self.keepf:
773 collapsedas = newnode
775 collapsedas = newnode
774 clearrebased(
776 clearrebased(
775 ui,
777 ui,
776 repo,
778 repo,
777 self.destmap,
779 self.destmap,
778 self.state,
780 self.state,
779 self.skipped,
781 self.skipped,
780 collapsedas,
782 collapsedas,
781 self.keepf,
783 self.keepf,
782 fm=fm,
784 fm=fm,
783 backup=self.backupf,
785 backup=self.backupf,
784 )
786 )
785
787
786 clearstatus(repo)
788 clearstatus(repo)
787 clearcollapsemsg(repo)
789 clearcollapsemsg(repo)
788
790
789 ui.note(_(b"rebase completed\n"))
791 ui.note(_(b"rebase completed\n"))
790 util.unlinkpath(repo.sjoin(b'undo'), ignoremissing=True)
792 util.unlinkpath(repo.sjoin(b'undo'), ignoremissing=True)
791 if self.skipped:
793 if self.skipped:
792 skippedlen = len(self.skipped)
794 skippedlen = len(self.skipped)
793 ui.note(_(b"%d revisions have been skipped\n") % skippedlen)
795 ui.note(_(b"%d revisions have been skipped\n") % skippedlen)
794 fm.end()
796 fm.end()
795
797
796 if (
798 if (
797 self.activebookmark
799 self.activebookmark
798 and self.activebookmark in repo._bookmarks
800 and self.activebookmark in repo._bookmarks
799 and repo[b'.'].node() == repo._bookmarks[self.activebookmark]
801 and repo[b'.'].node() == repo._bookmarks[self.activebookmark]
800 ):
802 ):
801 bookmarks.activate(repo, self.activebookmark)
803 bookmarks.activate(repo, self.activebookmark)
802
804
803 def _abort(self, backup=True, suppwarns=False, dryrun=False, confirm=False):
805 def _abort(self, backup=True, suppwarns=False, dryrun=False, confirm=False):
804 '''Restore the repository to its original state.'''
806 '''Restore the repository to its original state.'''
805
807
806 repo = self.repo
808 repo = self.repo
807 try:
809 try:
808 # If the first commits in the rebased set get skipped during the
810 # If the first commits in the rebased set get skipped during the
809 # rebase, their values within the state mapping will be the dest
811 # rebase, their values within the state mapping will be the dest
810 # rev id. The rebased list must must not contain the dest rev
812 # rev id. The rebased list must must not contain the dest rev
811 # (issue4896)
813 # (issue4896)
812 rebased = [
814 rebased = [
813 s
815 s
814 for r, s in self.state.items()
816 for r, s in self.state.items()
815 if s >= 0 and s != r and s != self.destmap[r]
817 if s >= 0 and s != r and s != self.destmap[r]
816 ]
818 ]
817 immutable = [d for d in rebased if not repo[d].mutable()]
819 immutable = [d for d in rebased if not repo[d].mutable()]
818 cleanup = True
820 cleanup = True
819 if immutable:
821 if immutable:
820 repo.ui.warn(
822 repo.ui.warn(
821 _(b"warning: can't clean up public changesets %s\n")
823 _(b"warning: can't clean up public changesets %s\n")
822 % b', '.join(bytes(repo[r]) for r in immutable),
824 % b', '.join(bytes(repo[r]) for r in immutable),
823 hint=_(b"see 'hg help phases' for details"),
825 hint=_(b"see 'hg help phases' for details"),
824 )
826 )
825 cleanup = False
827 cleanup = False
826
828
827 descendants = set()
829 descendants = set()
828 if rebased:
830 if rebased:
829 descendants = set(repo.changelog.descendants(rebased))
831 descendants = set(repo.changelog.descendants(rebased))
830 if descendants - set(rebased):
832 if descendants - set(rebased):
831 repo.ui.warn(
833 repo.ui.warn(
832 _(
834 _(
833 b"warning: new changesets detected on "
835 b"warning: new changesets detected on "
834 b"destination branch, can't strip\n"
836 b"destination branch, can't strip\n"
835 )
837 )
836 )
838 )
837 cleanup = False
839 cleanup = False
838
840
839 if cleanup:
841 if cleanup:
840 if rebased:
842 if rebased:
841 strippoints = [
843 strippoints = [
842 c.node() for c in repo.set(b'roots(%ld)', rebased)
844 c.node() for c in repo.set(b'roots(%ld)', rebased)
843 ]
845 ]
844
846
845 updateifonnodes = set(rebased)
847 updateifonnodes = set(rebased)
846 updateifonnodes.update(self.destmap.values())
848 updateifonnodes.update(self.destmap.values())
847
849
848 if not dryrun and not confirm:
850 if not dryrun and not confirm:
849 updateifonnodes.add(self.originalwd)
851 updateifonnodes.add(self.originalwd)
850
852
851 shouldupdate = repo[b'.'].rev() in updateifonnodes
853 shouldupdate = repo[b'.'].rev() in updateifonnodes
852
854
853 # Update away from the rebase if necessary
855 # Update away from the rebase if necessary
854 if shouldupdate:
856 if shouldupdate:
855 mergemod.clean_update(repo[self.originalwd])
857 mergemod.clean_update(repo[self.originalwd])
856
858
857 # Strip from the first rebased revision
859 # Strip from the first rebased revision
858 if rebased:
860 if rebased:
859 repair.strip(repo.ui, repo, strippoints, backup=backup)
861 repair.strip(repo.ui, repo, strippoints, backup=backup)
860
862
861 if self.activebookmark and self.activebookmark in repo._bookmarks:
863 if self.activebookmark and self.activebookmark in repo._bookmarks:
862 bookmarks.activate(repo, self.activebookmark)
864 bookmarks.activate(repo, self.activebookmark)
863
865
864 finally:
866 finally:
865 clearstatus(repo)
867 clearstatus(repo)
866 clearcollapsemsg(repo)
868 clearcollapsemsg(repo)
867 if not suppwarns:
869 if not suppwarns:
868 repo.ui.warn(_(b'rebase aborted\n'))
870 repo.ui.warn(_(b'rebase aborted\n'))
869 return 0
871 return 0
870
872
871
873
872 @command(
874 @command(
873 b'rebase',
875 b'rebase',
874 [
876 [
875 (
877 (
876 b's',
878 b's',
877 b'source',
879 b'source',
878 [],
880 [],
879 _(b'rebase the specified changesets and their descendants'),
881 _(b'rebase the specified changesets and their descendants'),
880 _(b'REV'),
882 _(b'REV'),
881 ),
883 ),
882 (
884 (
883 b'b',
885 b'b',
884 b'base',
886 b'base',
885 [],
887 [],
886 _(b'rebase everything from branching point of specified changeset'),
888 _(b'rebase everything from branching point of specified changeset'),
887 _(b'REV'),
889 _(b'REV'),
888 ),
890 ),
889 (b'r', b'rev', [], _(b'rebase these revisions'), _(b'REV')),
891 (b'r', b'rev', [], _(b'rebase these revisions'), _(b'REV')),
890 (
892 (
891 b'd',
893 b'd',
892 b'dest',
894 b'dest',
893 b'',
895 b'',
894 _(b'rebase onto the specified changeset'),
896 _(b'rebase onto the specified changeset'),
895 _(b'REV'),
897 _(b'REV'),
896 ),
898 ),
897 (b'', b'collapse', False, _(b'collapse the rebased changesets')),
899 (b'', b'collapse', False, _(b'collapse the rebased changesets')),
898 (
900 (
899 b'm',
901 b'm',
900 b'message',
902 b'message',
901 b'',
903 b'',
902 _(b'use text as collapse commit message'),
904 _(b'use text as collapse commit message'),
903 _(b'TEXT'),
905 _(b'TEXT'),
904 ),
906 ),
905 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
907 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
906 (
908 (
907 b'l',
909 b'l',
908 b'logfile',
910 b'logfile',
909 b'',
911 b'',
910 _(b'read collapse commit message from file'),
912 _(b'read collapse commit message from file'),
911 _(b'FILE'),
913 _(b'FILE'),
912 ),
914 ),
913 (b'k', b'keep', False, _(b'keep original changesets')),
915 (b'k', b'keep', False, _(b'keep original changesets')),
914 (b'', b'keepbranches', False, _(b'keep original branch names')),
916 (b'', b'keepbranches', False, _(b'keep original branch names')),
915 (b'D', b'detach', False, _(b'(DEPRECATED)')),
917 (b'D', b'detach', False, _(b'(DEPRECATED)')),
916 (b'i', b'interactive', False, _(b'(DEPRECATED)')),
918 (b'i', b'interactive', False, _(b'(DEPRECATED)')),
917 (b't', b'tool', b'', _(b'specify merge tool')),
919 (b't', b'tool', b'', _(b'specify merge tool')),
918 (b'', b'stop', False, _(b'stop interrupted rebase')),
920 (b'', b'stop', False, _(b'stop interrupted rebase')),
919 (b'c', b'continue', False, _(b'continue an interrupted rebase')),
921 (b'c', b'continue', False, _(b'continue an interrupted rebase')),
920 (b'a', b'abort', False, _(b'abort an interrupted rebase')),
922 (b'a', b'abort', False, _(b'abort an interrupted rebase')),
921 (
923 (
922 b'',
924 b'',
923 b'auto-orphans',
925 b'auto-orphans',
924 b'',
926 b'',
925 _(
927 _(
926 b'automatically rebase orphan revisions '
928 b'automatically rebase orphan revisions '
927 b'in the specified revset (EXPERIMENTAL)'
929 b'in the specified revset (EXPERIMENTAL)'
928 ),
930 ),
929 ),
931 ),
930 ]
932 ]
931 + cmdutil.dryrunopts
933 + cmdutil.dryrunopts
932 + cmdutil.formatteropts
934 + cmdutil.formatteropts
933 + cmdutil.confirmopts,
935 + cmdutil.confirmopts,
934 _(b'[[-s REV]... | [-b REV]... | [-r REV]...] [-d REV] [OPTION]...'),
936 _(b'[[-s REV]... | [-b REV]... | [-r REV]...] [-d REV] [OPTION]...'),
935 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
937 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
936 )
938 )
937 def rebase(ui, repo, **opts):
939 def rebase(ui, repo, **opts):
938 """move changeset (and descendants) to a different branch
940 """move changeset (and descendants) to a different branch
939
941
940 Rebase uses repeated merging to graft changesets from one part of
942 Rebase uses repeated merging to graft changesets from one part of
941 history (the source) onto another (the destination). This can be
943 history (the source) onto another (the destination). This can be
942 useful for linearizing *local* changes relative to a master
944 useful for linearizing *local* changes relative to a master
943 development tree.
945 development tree.
944
946
945 Published commits cannot be rebased (see :hg:`help phases`).
947 Published commits cannot be rebased (see :hg:`help phases`).
946 To copy commits, see :hg:`help graft`.
948 To copy commits, see :hg:`help graft`.
947
949
948 If you don't specify a destination changeset (``-d/--dest``), rebase
950 If you don't specify a destination changeset (``-d/--dest``), rebase
949 will use the same logic as :hg:`merge` to pick a destination. if
951 will use the same logic as :hg:`merge` to pick a destination. if
950 the current branch contains exactly one other head, the other head
952 the current branch contains exactly one other head, the other head
951 is merged with by default. Otherwise, an explicit revision with
953 is merged with by default. Otherwise, an explicit revision with
952 which to merge with must be provided. (destination changeset is not
954 which to merge with must be provided. (destination changeset is not
953 modified by rebasing, but new changesets are added as its
955 modified by rebasing, but new changesets are added as its
954 descendants.)
956 descendants.)
955
957
956 Here are the ways to select changesets:
958 Here are the ways to select changesets:
957
959
958 1. Explicitly select them using ``--rev``.
960 1. Explicitly select them using ``--rev``.
959
961
960 2. Use ``--source`` to select a root changeset and include all of its
962 2. Use ``--source`` to select a root changeset and include all of its
961 descendants.
963 descendants.
962
964
963 3. Use ``--base`` to select a changeset; rebase will find ancestors
965 3. Use ``--base`` to select a changeset; rebase will find ancestors
964 and their descendants which are not also ancestors of the destination.
966 and their descendants which are not also ancestors of the destination.
965
967
966 4. If you do not specify any of ``--rev``, ``--source``, or ``--base``,
968 4. If you do not specify any of ``--rev``, ``--source``, or ``--base``,
967 rebase will use ``--base .`` as above.
969 rebase will use ``--base .`` as above.
968
970
969 If ``--source`` or ``--rev`` is used, special names ``SRC`` and ``ALLSRC``
971 If ``--source`` or ``--rev`` is used, special names ``SRC`` and ``ALLSRC``
970 can be used in ``--dest``. Destination would be calculated per source
972 can be used in ``--dest``. Destination would be calculated per source
971 revision with ``SRC`` substituted by that single source revision and
973 revision with ``SRC`` substituted by that single source revision and
972 ``ALLSRC`` substituted by all source revisions.
974 ``ALLSRC`` substituted by all source revisions.
973
975
974 Rebase will destroy original changesets unless you use ``--keep``.
976 Rebase will destroy original changesets unless you use ``--keep``.
975 It will also move your bookmarks (even if you do).
977 It will also move your bookmarks (even if you do).
976
978
977 Some changesets may be dropped if they do not contribute changes
979 Some changesets may be dropped if they do not contribute changes
978 (e.g. merges from the destination branch).
980 (e.g. merges from the destination branch).
979
981
980 Unlike ``merge``, rebase will do nothing if you are at the branch tip of
982 Unlike ``merge``, rebase will do nothing if you are at the branch tip of
981 a named branch with two heads. You will need to explicitly specify source
983 a named branch with two heads. You will need to explicitly specify source
982 and/or destination.
984 and/or destination.
983
985
984 If you need to use a tool to automate merge/conflict decisions, you
986 If you need to use a tool to automate merge/conflict decisions, you
985 can specify one with ``--tool``, see :hg:`help merge-tools`.
987 can specify one with ``--tool``, see :hg:`help merge-tools`.
986 As a caveat: the tool will not be used to mediate when a file was
988 As a caveat: the tool will not be used to mediate when a file was
987 deleted, there is no hook presently available for this.
989 deleted, there is no hook presently available for this.
988
990
989 If a rebase is interrupted to manually resolve a conflict, it can be
991 If a rebase is interrupted to manually resolve a conflict, it can be
990 continued with --continue/-c, aborted with --abort/-a, or stopped with
992 continued with --continue/-c, aborted with --abort/-a, or stopped with
991 --stop.
993 --stop.
992
994
993 .. container:: verbose
995 .. container:: verbose
994
996
995 Examples:
997 Examples:
996
998
997 - move "local changes" (current commit back to branching point)
999 - move "local changes" (current commit back to branching point)
998 to the current branch tip after a pull::
1000 to the current branch tip after a pull::
999
1001
1000 hg rebase
1002 hg rebase
1001
1003
1002 - move a single changeset to the stable branch::
1004 - move a single changeset to the stable branch::
1003
1005
1004 hg rebase -r 5f493448 -d stable
1006 hg rebase -r 5f493448 -d stable
1005
1007
1006 - splice a commit and all its descendants onto another part of history::
1008 - splice a commit and all its descendants onto another part of history::
1007
1009
1008 hg rebase --source c0c3 --dest 4cf9
1010 hg rebase --source c0c3 --dest 4cf9
1009
1011
1010 - rebase everything on a branch marked by a bookmark onto the
1012 - rebase everything on a branch marked by a bookmark onto the
1011 default branch::
1013 default branch::
1012
1014
1013 hg rebase --base myfeature --dest default
1015 hg rebase --base myfeature --dest default
1014
1016
1015 - collapse a sequence of changes into a single commit::
1017 - collapse a sequence of changes into a single commit::
1016
1018
1017 hg rebase --collapse -r 1520:1525 -d .
1019 hg rebase --collapse -r 1520:1525 -d .
1018
1020
1019 - move a named branch while preserving its name::
1021 - move a named branch while preserving its name::
1020
1022
1021 hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
1023 hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
1022
1024
1023 - stabilize orphaned changesets so history looks linear::
1025 - stabilize orphaned changesets so history looks linear::
1024
1026
1025 hg rebase -r 'orphan()-obsolete()'\
1027 hg rebase -r 'orphan()-obsolete()'\
1026 -d 'first(max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::) +\
1028 -d 'first(max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::) +\
1027 max(::((roots(ALLSRC) & ::SRC)^)-obsolete()))'
1029 max(::((roots(ALLSRC) & ::SRC)^)-obsolete()))'
1028
1030
1029 Configuration Options:
1031 Configuration Options:
1030
1032
1031 You can make rebase require a destination if you set the following config
1033 You can make rebase require a destination if you set the following config
1032 option::
1034 option::
1033
1035
1034 [commands]
1036 [commands]
1035 rebase.requiredest = True
1037 rebase.requiredest = True
1036
1038
1037 By default, rebase will close the transaction after each commit. For
1039 By default, rebase will close the transaction after each commit. For
1038 performance purposes, you can configure rebase to use a single transaction
1040 performance purposes, you can configure rebase to use a single transaction
1039 across the entire rebase. WARNING: This setting introduces a significant
1041 across the entire rebase. WARNING: This setting introduces a significant
1040 risk of losing the work you've done in a rebase if the rebase aborts
1042 risk of losing the work you've done in a rebase if the rebase aborts
1041 unexpectedly::
1043 unexpectedly::
1042
1044
1043 [rebase]
1045 [rebase]
1044 singletransaction = True
1046 singletransaction = True
1045
1047
1046 By default, rebase writes to the working copy, but you can configure it to
1048 By default, rebase writes to the working copy, but you can configure it to
1047 run in-memory for better performance. When the rebase is not moving the
1049 run in-memory for better performance. When the rebase is not moving the
1048 parent(s) of the working copy (AKA the "currently checked out changesets"),
1050 parent(s) of the working copy (AKA the "currently checked out changesets"),
1049 this may also allow it to run even if the working copy is dirty::
1051 this may also allow it to run even if the working copy is dirty::
1050
1052
1051 [rebase]
1053 [rebase]
1052 experimental.inmemory = True
1054 experimental.inmemory = True
1053
1055
1054 Return Values:
1056 Return Values:
1055
1057
1056 Returns 0 on success, 1 if nothing to rebase or there are
1058 Returns 0 on success, 1 if nothing to rebase or there are
1057 unresolved conflicts.
1059 unresolved conflicts.
1058
1060
1059 """
1061 """
1060 inmemory = ui.configbool(b'rebase', b'experimental.inmemory')
1062 inmemory = ui.configbool(b'rebase', b'experimental.inmemory')
1061 action = cmdutil.check_at_most_one_arg(opts, 'abort', 'stop', 'continue')
1063 action = cmdutil.check_at_most_one_arg(opts, 'abort', 'stop', 'continue')
1062 if action:
1064 if action:
1063 cmdutil.check_incompatible_arguments(
1065 cmdutil.check_incompatible_arguments(
1064 opts, action, ['confirm', 'dry_run']
1066 opts, action, ['confirm', 'dry_run']
1065 )
1067 )
1066 cmdutil.check_incompatible_arguments(
1068 cmdutil.check_incompatible_arguments(
1067 opts, action, ['rev', 'source', 'base', 'dest']
1069 opts, action, ['rev', 'source', 'base', 'dest']
1068 )
1070 )
1069 cmdutil.check_at_most_one_arg(opts, 'confirm', 'dry_run')
1071 cmdutil.check_at_most_one_arg(opts, 'confirm', 'dry_run')
1070 cmdutil.check_at_most_one_arg(opts, 'rev', 'source', 'base')
1072 cmdutil.check_at_most_one_arg(opts, 'rev', 'source', 'base')
1071
1073
1072 if action or repo.currenttransaction() is not None:
1074 if action or repo.currenttransaction() is not None:
1073 # in-memory rebase is not compatible with resuming rebases.
1075 # in-memory rebase is not compatible with resuming rebases.
1074 # (Or if it is run within a transaction, since the restart logic can
1076 # (Or if it is run within a transaction, since the restart logic can
1075 # fail the entire transaction.)
1077 # fail the entire transaction.)
1076 inmemory = False
1078 inmemory = False
1077
1079
1078 if opts.get('auto_orphans'):
1080 if opts.get('auto_orphans'):
1079 disallowed_opts = set(opts) - {'auto_orphans'}
1081 disallowed_opts = set(opts) - {'auto_orphans'}
1080 cmdutil.check_incompatible_arguments(
1082 cmdutil.check_incompatible_arguments(
1081 opts, 'auto_orphans', disallowed_opts
1083 opts, 'auto_orphans', disallowed_opts
1082 )
1084 )
1083
1085
1084 userrevs = list(repo.revs(opts.get('auto_orphans')))
1086 userrevs = list(repo.revs(opts.get('auto_orphans')))
1085 opts['rev'] = [revsetlang.formatspec(b'%ld and orphan()', userrevs)]
1087 opts['rev'] = [revsetlang.formatspec(b'%ld and orphan()', userrevs)]
1086 opts['dest'] = b'_destautoorphanrebase(SRC)'
1088 opts['dest'] = b'_destautoorphanrebase(SRC)'
1087
1089
1088 if opts.get('dry_run') or opts.get('confirm'):
1090 if opts.get('dry_run') or opts.get('confirm'):
1089 return _dryrunrebase(ui, repo, action, opts)
1091 return _dryrunrebase(ui, repo, action, opts)
1090 elif action == 'stop':
1092 elif action == 'stop':
1091 rbsrt = rebaseruntime(repo, ui)
1093 rbsrt = rebaseruntime(repo, ui)
1092 with repo.wlock(), repo.lock():
1094 with repo.wlock(), repo.lock():
1093 rbsrt.restorestatus()
1095 rbsrt.restorestatus()
1094 if rbsrt.collapsef:
1096 if rbsrt.collapsef:
1095 raise error.StateError(_(b"cannot stop in --collapse session"))
1097 raise error.StateError(_(b"cannot stop in --collapse session"))
1096 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1098 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1097 if not (rbsrt.keepf or allowunstable):
1099 if not (rbsrt.keepf or allowunstable):
1098 raise error.StateError(
1100 raise error.StateError(
1099 _(
1101 _(
1100 b"cannot remove original changesets with"
1102 b"cannot remove original changesets with"
1101 b" unrebased descendants"
1103 b" unrebased descendants"
1102 ),
1104 ),
1103 hint=_(
1105 hint=_(
1104 b'either enable obsmarkers to allow unstable '
1106 b'either enable obsmarkers to allow unstable '
1105 b'revisions or use --keep to keep original '
1107 b'revisions or use --keep to keep original '
1106 b'changesets'
1108 b'changesets'
1107 ),
1109 ),
1108 )
1110 )
1109 # update to the current working revision
1111 # update to the current working revision
1110 # to clear interrupted merge
1112 # to clear interrupted merge
1111 mergemod.clean_update(repo[rbsrt.originalwd])
1113 mergemod.clean_update(repo[rbsrt.originalwd])
1112 rbsrt._finishrebase()
1114 rbsrt._finishrebase()
1113 return 0
1115 return 0
1114 elif inmemory:
1116 elif inmemory:
1115 try:
1117 try:
1116 # in-memory merge doesn't support conflicts, so if we hit any, abort
1118 # in-memory merge doesn't support conflicts, so if we hit any, abort
1117 # and re-run as an on-disk merge.
1119 # and re-run as an on-disk merge.
1118 overrides = {(b'rebase', b'singletransaction'): True}
1120 overrides = {(b'rebase', b'singletransaction'): True}
1119 with ui.configoverride(overrides, b'rebase'):
1121 with ui.configoverride(overrides, b'rebase'):
1120 return _dorebase(ui, repo, action, opts, inmemory=inmemory)
1122 return _dorebase(ui, repo, action, opts, inmemory=inmemory)
1121 except error.InMemoryMergeConflictsError:
1123 except error.InMemoryMergeConflictsError:
1122 if ui.configbool(b'devel', b'rebase.force-in-memory-merge'):
1124 if ui.configbool(b'devel', b'rebase.force-in-memory-merge'):
1123 raise
1125 raise
1124 ui.warn(
1126 ui.warn(
1125 _(
1127 _(
1126 b'hit merge conflicts; re-running rebase without in-memory'
1128 b'hit merge conflicts; re-running rebase without in-memory'
1127 b' merge\n'
1129 b' merge\n'
1128 )
1130 )
1129 )
1131 )
1130 clearstatus(repo)
1132 clearstatus(repo)
1131 clearcollapsemsg(repo)
1133 clearcollapsemsg(repo)
1132 return _dorebase(ui, repo, action, opts, inmemory=False)
1134 return _dorebase(ui, repo, action, opts, inmemory=False)
1133 else:
1135 else:
1134 return _dorebase(ui, repo, action, opts)
1136 return _dorebase(ui, repo, action, opts)
1135
1137
1136
1138
1137 def _dryrunrebase(ui, repo, action, opts):
1139 def _dryrunrebase(ui, repo, action, opts):
1138 rbsrt = rebaseruntime(repo, ui, inmemory=True, dryrun=True, opts=opts)
1140 rbsrt = rebaseruntime(repo, ui, inmemory=True, dryrun=True, opts=opts)
1139 confirm = opts.get('confirm')
1141 confirm = opts.get('confirm')
1140 if confirm:
1142 if confirm:
1141 ui.status(_(b'starting in-memory rebase\n'))
1143 ui.status(_(b'starting in-memory rebase\n'))
1142 else:
1144 else:
1143 ui.status(
1145 ui.status(
1144 _(b'starting dry-run rebase; repository will not be changed\n')
1146 _(b'starting dry-run rebase; repository will not be changed\n')
1145 )
1147 )
1146 with repo.wlock(), repo.lock():
1148 with repo.wlock(), repo.lock():
1147 needsabort = True
1149 needsabort = True
1148 try:
1150 try:
1149 overrides = {(b'rebase', b'singletransaction'): True}
1151 overrides = {(b'rebase', b'singletransaction'): True}
1150 with ui.configoverride(overrides, b'rebase'):
1152 with ui.configoverride(overrides, b'rebase'):
1151 res = _origrebase(
1153 res = _origrebase(
1152 ui,
1154 ui,
1153 repo,
1155 repo,
1154 action,
1156 action,
1155 opts,
1157 opts,
1156 rbsrt,
1158 rbsrt,
1157 )
1159 )
1158 if res == _nothingtorebase():
1160 if res == _nothingtorebase():
1159 needsabort = False
1161 needsabort = False
1160 return res
1162 return res
1161 except error.ConflictResolutionRequired:
1163 except error.ConflictResolutionRequired:
1162 ui.status(_(b'hit a merge conflict\n'))
1164 ui.status(_(b'hit a merge conflict\n'))
1163 return 1
1165 return 1
1164 except error.Abort:
1166 except error.Abort:
1165 needsabort = False
1167 needsabort = False
1166 raise
1168 raise
1167 else:
1169 else:
1168 if confirm:
1170 if confirm:
1169 ui.status(_(b'rebase completed successfully\n'))
1171 ui.status(_(b'rebase completed successfully\n'))
1170 if not ui.promptchoice(_(b'apply changes (yn)?$$ &Yes $$ &No')):
1172 if not ui.promptchoice(_(b'apply changes (yn)?$$ &Yes $$ &No')):
1171 # finish unfinished rebase
1173 # finish unfinished rebase
1172 rbsrt._finishrebase()
1174 rbsrt._finishrebase()
1173 else:
1175 else:
1174 rbsrt._prepareabortorcontinue(
1176 rbsrt._prepareabortorcontinue(
1175 isabort=True,
1177 isabort=True,
1176 backup=False,
1178 backup=False,
1177 suppwarns=True,
1179 suppwarns=True,
1178 confirm=confirm,
1180 confirm=confirm,
1179 )
1181 )
1180 needsabort = False
1182 needsabort = False
1181 else:
1183 else:
1182 ui.status(
1184 ui.status(
1183 _(
1185 _(
1184 b'dry-run rebase completed successfully; run without'
1186 b'dry-run rebase completed successfully; run without'
1185 b' -n/--dry-run to perform this rebase\n'
1187 b' -n/--dry-run to perform this rebase\n'
1186 )
1188 )
1187 )
1189 )
1188 return 0
1190 return 0
1189 finally:
1191 finally:
1190 if needsabort:
1192 if needsabort:
1191 # no need to store backup in case of dryrun
1193 # no need to store backup in case of dryrun
1192 rbsrt._prepareabortorcontinue(
1194 rbsrt._prepareabortorcontinue(
1193 isabort=True,
1195 isabort=True,
1194 backup=False,
1196 backup=False,
1195 suppwarns=True,
1197 suppwarns=True,
1196 dryrun=opts.get('dry_run'),
1198 dryrun=opts.get('dry_run'),
1197 )
1199 )
1198
1200
1199
1201
1200 def _dorebase(ui, repo, action, opts, inmemory=False):
1202 def _dorebase(ui, repo, action, opts, inmemory=False):
1201 rbsrt = rebaseruntime(repo, ui, inmemory, opts=opts)
1203 rbsrt = rebaseruntime(repo, ui, inmemory, opts=opts)
1202 return _origrebase(ui, repo, action, opts, rbsrt)
1204 return _origrebase(ui, repo, action, opts, rbsrt)
1203
1205
1204
1206
1205 def _origrebase(ui, repo, action, opts, rbsrt):
1207 def _origrebase(ui, repo, action, opts, rbsrt):
1206 assert action != 'stop'
1208 assert action != 'stop'
1207 with repo.wlock(), repo.lock():
1209 with repo.wlock(), repo.lock():
1208 if opts.get('interactive'):
1210 if opts.get('interactive'):
1209 try:
1211 try:
1210 if extensions.find(b'histedit'):
1212 if extensions.find(b'histedit'):
1211 enablehistedit = b''
1213 enablehistedit = b''
1212 except KeyError:
1214 except KeyError:
1213 enablehistedit = b" --config extensions.histedit="
1215 enablehistedit = b" --config extensions.histedit="
1214 help = b"hg%s help -e histedit" % enablehistedit
1216 help = b"hg%s help -e histedit" % enablehistedit
1215 msg = (
1217 msg = (
1216 _(
1218 _(
1217 b"interactive history editing is supported by the "
1219 b"interactive history editing is supported by the "
1218 b"'histedit' extension (see \"%s\")"
1220 b"'histedit' extension (see \"%s\")"
1219 )
1221 )
1220 % help
1222 % help
1221 )
1223 )
1222 raise error.InputError(msg)
1224 raise error.InputError(msg)
1223
1225
1224 if rbsrt.collapsemsg and not rbsrt.collapsef:
1226 if rbsrt.collapsemsg and not rbsrt.collapsef:
1225 raise error.InputError(
1227 raise error.InputError(
1226 _(b'message can only be specified with collapse')
1228 _(b'message can only be specified with collapse')
1227 )
1229 )
1228
1230
1229 if action:
1231 if action:
1230 if rbsrt.collapsef:
1232 if rbsrt.collapsef:
1231 raise error.InputError(
1233 raise error.InputError(
1232 _(b'cannot use collapse with continue or abort')
1234 _(b'cannot use collapse with continue or abort')
1233 )
1235 )
1234 if action == 'abort' and opts.get('tool', False):
1236 if action == 'abort' and opts.get('tool', False):
1235 ui.warn(_(b'tool option will be ignored\n'))
1237 ui.warn(_(b'tool option will be ignored\n'))
1236 if action == 'continue':
1238 if action == 'continue':
1237 ms = mergestatemod.mergestate.read(repo)
1239 ms = mergestatemod.mergestate.read(repo)
1238 mergeutil.checkunresolved(ms)
1240 mergeutil.checkunresolved(ms)
1239
1241
1240 retcode = rbsrt._prepareabortorcontinue(isabort=(action == 'abort'))
1242 retcode = rbsrt._prepareabortorcontinue(isabort=(action == 'abort'))
1241 if retcode is not None:
1243 if retcode is not None:
1242 return retcode
1244 return retcode
1243 else:
1245 else:
1244 # search default destination in this space
1246 # search default destination in this space
1245 # used in the 'hg pull --rebase' case, see issue 5214.
1247 # used in the 'hg pull --rebase' case, see issue 5214.
1246 destspace = opts.get('_destspace')
1248 destspace = opts.get('_destspace')
1247 destmap = _definedestmap(
1249 destmap = _definedestmap(
1248 ui,
1250 ui,
1249 repo,
1251 repo,
1250 rbsrt.inmemory,
1252 rbsrt.inmemory,
1251 opts.get('dest', None),
1253 opts.get('dest', None),
1252 opts.get('source', []),
1254 opts.get('source', []),
1253 opts.get('base', []),
1255 opts.get('base', []),
1254 opts.get('rev', []),
1256 opts.get('rev', []),
1255 destspace=destspace,
1257 destspace=destspace,
1256 )
1258 )
1257 retcode = rbsrt._preparenewrebase(destmap)
1259 retcode = rbsrt._preparenewrebase(destmap)
1258 if retcode is not None:
1260 if retcode is not None:
1259 return retcode
1261 return retcode
1260 storecollapsemsg(repo, rbsrt.collapsemsg)
1262 storecollapsemsg(repo, rbsrt.collapsemsg)
1261
1263
1262 tr = None
1264 tr = None
1263
1265
1264 singletr = ui.configbool(b'rebase', b'singletransaction')
1266 singletr = ui.configbool(b'rebase', b'singletransaction')
1265 if singletr:
1267 if singletr:
1266 tr = repo.transaction(b'rebase')
1268 tr = repo.transaction(b'rebase')
1267
1269
1268 # If `rebase.singletransaction` is enabled, wrap the entire operation in
1270 # If `rebase.singletransaction` is enabled, wrap the entire operation in
1269 # one transaction here. Otherwise, transactions are obtained when
1271 # one transaction here. Otherwise, transactions are obtained when
1270 # committing each node, which is slower but allows partial success.
1272 # committing each node, which is slower but allows partial success.
1271 with util.acceptintervention(tr):
1273 with util.acceptintervention(tr):
1272 # Same logic for the dirstate guard, except we don't create one when
1274 # Same logic for the dirstate guard, except we don't create one when
1273 # rebasing in-memory (it's not needed).
1275 # rebasing in-memory (it's not needed).
1274 dsguard = None
1276 dsguard = None
1275 if singletr and not rbsrt.inmemory:
1277 if singletr and not rbsrt.inmemory:
1276 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1278 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1277 with util.acceptintervention(dsguard):
1279 with util.acceptintervention(dsguard):
1278 rbsrt._performrebase(tr)
1280 rbsrt._performrebase(tr)
1279 if not rbsrt.dryrun:
1281 if not rbsrt.dryrun:
1280 rbsrt._finishrebase()
1282 rbsrt._finishrebase()
1281
1283
1282
1284
1283 def _definedestmap(ui, repo, inmemory, destf, srcf, basef, revf, destspace):
1285 def _definedestmap(ui, repo, inmemory, destf, srcf, basef, revf, destspace):
1284 """use revisions argument to define destmap {srcrev: destrev}"""
1286 """use revisions argument to define destmap {srcrev: destrev}"""
1285 if revf is None:
1287 if revf is None:
1286 revf = []
1288 revf = []
1287
1289
1288 # destspace is here to work around issues with `hg pull --rebase` see
1290 # destspace is here to work around issues with `hg pull --rebase` see
1289 # issue5214 for details
1291 # issue5214 for details
1290
1292
1291 cmdutil.checkunfinished(repo)
1293 cmdutil.checkunfinished(repo)
1292 if not inmemory:
1294 if not inmemory:
1293 cmdutil.bailifchanged(repo)
1295 cmdutil.bailifchanged(repo)
1294
1296
1295 if ui.configbool(b'commands', b'rebase.requiredest') and not destf:
1297 if ui.configbool(b'commands', b'rebase.requiredest') and not destf:
1296 raise error.InputError(
1298 raise error.InputError(
1297 _(b'you must specify a destination'),
1299 _(b'you must specify a destination'),
1298 hint=_(b'use: hg rebase -d REV'),
1300 hint=_(b'use: hg rebase -d REV'),
1299 )
1301 )
1300
1302
1301 dest = None
1303 dest = None
1302
1304
1303 if revf:
1305 if revf:
1304 rebaseset = logcmdutil.revrange(repo, revf)
1306 rebaseset = logcmdutil.revrange(repo, revf)
1305 if not rebaseset:
1307 if not rebaseset:
1306 ui.status(_(b'empty "rev" revision set - nothing to rebase\n'))
1308 ui.status(_(b'empty "rev" revision set - nothing to rebase\n'))
1307 return None
1309 return None
1308 elif srcf:
1310 elif srcf:
1309 src = logcmdutil.revrange(repo, srcf)
1311 src = logcmdutil.revrange(repo, srcf)
1310 if not src:
1312 if not src:
1311 ui.status(_(b'empty "source" revision set - nothing to rebase\n'))
1313 ui.status(_(b'empty "source" revision set - nothing to rebase\n'))
1312 return None
1314 return None
1313 # `+ (%ld)` to work around `wdir()::` being empty
1315 # `+ (%ld)` to work around `wdir()::` being empty
1314 rebaseset = repo.revs(b'(%ld):: + (%ld)', src, src)
1316 rebaseset = repo.revs(b'(%ld):: + (%ld)', src, src)
1315 else:
1317 else:
1316 base = logcmdutil.revrange(repo, basef or [b'.'])
1318 base = logcmdutil.revrange(repo, basef or [b'.'])
1317 if not base:
1319 if not base:
1318 ui.status(
1320 ui.status(
1319 _(b'empty "base" revision set - ' b"can't compute rebase set\n")
1321 _(b'empty "base" revision set - ' b"can't compute rebase set\n")
1320 )
1322 )
1321 return None
1323 return None
1322 if destf:
1324 if destf:
1323 # --base does not support multiple destinations
1325 # --base does not support multiple destinations
1324 dest = logcmdutil.revsingle(repo, destf)
1326 dest = logcmdutil.revsingle(repo, destf)
1325 else:
1327 else:
1326 dest = repo[_destrebase(repo, base, destspace=destspace)]
1328 dest = repo[_destrebase(repo, base, destspace=destspace)]
1327 destf = bytes(dest)
1329 destf = bytes(dest)
1328
1330
1329 roots = [] # selected children of branching points
1331 roots = [] # selected children of branching points
1330 bpbase = {} # {branchingpoint: [origbase]}
1332 bpbase = {} # {branchingpoint: [origbase]}
1331 for b in base: # group bases by branching points
1333 for b in base: # group bases by branching points
1332 bp = repo.revs(b'ancestor(%d, %d)', b, dest.rev()).first()
1334 bp = repo.revs(b'ancestor(%d, %d)', b, dest.rev()).first()
1333 bpbase[bp] = bpbase.get(bp, []) + [b]
1335 bpbase[bp] = bpbase.get(bp, []) + [b]
1334 if None in bpbase:
1336 if None in bpbase:
1335 # emulate the old behavior, showing "nothing to rebase" (a better
1337 # emulate the old behavior, showing "nothing to rebase" (a better
1336 # behavior may be abort with "cannot find branching point" error)
1338 # behavior may be abort with "cannot find branching point" error)
1337 bpbase.clear()
1339 bpbase.clear()
1338 for bp, bs in bpbase.items(): # calculate roots
1340 for bp, bs in bpbase.items(): # calculate roots
1339 roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
1341 roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
1340
1342
1341 rebaseset = repo.revs(b'%ld::', roots)
1343 rebaseset = repo.revs(b'%ld::', roots)
1342
1344
1343 if not rebaseset:
1345 if not rebaseset:
1344 # transform to list because smartsets are not comparable to
1346 # transform to list because smartsets are not comparable to
1345 # lists. This should be improved to honor laziness of
1347 # lists. This should be improved to honor laziness of
1346 # smartset.
1348 # smartset.
1347 if list(base) == [dest.rev()]:
1349 if list(base) == [dest.rev()]:
1348 if basef:
1350 if basef:
1349 ui.status(
1351 ui.status(
1350 _(
1352 _(
1351 b'nothing to rebase - %s is both "base"'
1353 b'nothing to rebase - %s is both "base"'
1352 b' and destination\n'
1354 b' and destination\n'
1353 )
1355 )
1354 % dest
1356 % dest
1355 )
1357 )
1356 else:
1358 else:
1357 ui.status(
1359 ui.status(
1358 _(
1360 _(
1359 b'nothing to rebase - working directory '
1361 b'nothing to rebase - working directory '
1360 b'parent is also destination\n'
1362 b'parent is also destination\n'
1361 )
1363 )
1362 )
1364 )
1363 elif not repo.revs(b'%ld - ::%d', base, dest.rev()):
1365 elif not repo.revs(b'%ld - ::%d', base, dest.rev()):
1364 if basef:
1366 if basef:
1365 ui.status(
1367 ui.status(
1366 _(
1368 _(
1367 b'nothing to rebase - "base" %s is '
1369 b'nothing to rebase - "base" %s is '
1368 b'already an ancestor of destination '
1370 b'already an ancestor of destination '
1369 b'%s\n'
1371 b'%s\n'
1370 )
1372 )
1371 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1373 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1372 )
1374 )
1373 else:
1375 else:
1374 ui.status(
1376 ui.status(
1375 _(
1377 _(
1376 b'nothing to rebase - working '
1378 b'nothing to rebase - working '
1377 b'directory parent is already an '
1379 b'directory parent is already an '
1378 b'ancestor of destination %s\n'
1380 b'ancestor of destination %s\n'
1379 )
1381 )
1380 % dest
1382 % dest
1381 )
1383 )
1382 else: # can it happen?
1384 else: # can it happen?
1383 ui.status(
1385 ui.status(
1384 _(b'nothing to rebase from %s to %s\n')
1386 _(b'nothing to rebase from %s to %s\n')
1385 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1387 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1386 )
1388 )
1387 return None
1389 return None
1388
1390
1389 if wdirrev in rebaseset:
1391 if wdirrev in rebaseset:
1390 raise error.InputError(_(b'cannot rebase the working copy'))
1392 raise error.InputError(_(b'cannot rebase the working copy'))
1391 rebasingwcp = repo[b'.'].rev() in rebaseset
1393 rebasingwcp = repo[b'.'].rev() in rebaseset
1392 ui.log(
1394 ui.log(
1393 b"rebase",
1395 b"rebase",
1394 b"rebasing working copy parent: %r\n",
1396 b"rebasing working copy parent: %r\n",
1395 rebasingwcp,
1397 rebasingwcp,
1396 rebase_rebasing_wcp=rebasingwcp,
1398 rebase_rebasing_wcp=rebasingwcp,
1397 )
1399 )
1398 if inmemory and rebasingwcp:
1400 if inmemory and rebasingwcp:
1399 # Check these since we did not before.
1401 # Check these since we did not before.
1400 cmdutil.checkunfinished(repo)
1402 cmdutil.checkunfinished(repo)
1401 cmdutil.bailifchanged(repo)
1403 cmdutil.bailifchanged(repo)
1402
1404
1403 if not destf:
1405 if not destf:
1404 dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
1406 dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
1405 destf = bytes(dest)
1407 destf = bytes(dest)
1406
1408
1407 allsrc = revsetlang.formatspec(b'%ld', rebaseset)
1409 allsrc = revsetlang.formatspec(b'%ld', rebaseset)
1408 alias = {b'ALLSRC': allsrc}
1410 alias = {b'ALLSRC': allsrc}
1409
1411
1410 if dest is None:
1412 if dest is None:
1411 try:
1413 try:
1412 # fast path: try to resolve dest without SRC alias
1414 # fast path: try to resolve dest without SRC alias
1413 dest = scmutil.revsingle(repo, destf, localalias=alias)
1415 dest = scmutil.revsingle(repo, destf, localalias=alias)
1414 except error.RepoLookupError:
1416 except error.RepoLookupError:
1415 # multi-dest path: resolve dest for each SRC separately
1417 # multi-dest path: resolve dest for each SRC separately
1416 destmap = {}
1418 destmap = {}
1417 for r in rebaseset:
1419 for r in rebaseset:
1418 alias[b'SRC'] = revsetlang.formatspec(b'%d', r)
1420 alias[b'SRC'] = revsetlang.formatspec(b'%d', r)
1419 # use repo.anyrevs instead of scmutil.revsingle because we
1421 # use repo.anyrevs instead of scmutil.revsingle because we
1420 # don't want to abort if destset is empty.
1422 # don't want to abort if destset is empty.
1421 destset = repo.anyrevs([destf], user=True, localalias=alias)
1423 destset = repo.anyrevs([destf], user=True, localalias=alias)
1422 size = len(destset)
1424 size = len(destset)
1423 if size == 1:
1425 if size == 1:
1424 destmap[r] = destset.first()
1426 destmap[r] = destset.first()
1425 elif size == 0:
1427 elif size == 0:
1426 ui.note(_(b'skipping %s - empty destination\n') % repo[r])
1428 ui.note(_(b'skipping %s - empty destination\n') % repo[r])
1427 else:
1429 else:
1428 raise error.InputError(
1430 raise error.InputError(
1429 _(b'rebase destination for %s is not unique') % repo[r]
1431 _(b'rebase destination for %s is not unique') % repo[r]
1430 )
1432 )
1431
1433
1432 if dest is not None:
1434 if dest is not None:
1433 # single-dest case: assign dest to each rev in rebaseset
1435 # single-dest case: assign dest to each rev in rebaseset
1434 destrev = dest.rev()
1436 destrev = dest.rev()
1435 destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
1437 destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
1436
1438
1437 if not destmap:
1439 if not destmap:
1438 ui.status(_(b'nothing to rebase - empty destination\n'))
1440 ui.status(_(b'nothing to rebase - empty destination\n'))
1439 return None
1441 return None
1440
1442
1441 return destmap
1443 return destmap
1442
1444
1443
1445
1444 def externalparent(repo, state, destancestors):
1446 def externalparent(repo, state, destancestors):
1445 """Return the revision that should be used as the second parent
1447 """Return the revision that should be used as the second parent
1446 when the revisions in state is collapsed on top of destancestors.
1448 when the revisions in state is collapsed on top of destancestors.
1447 Abort if there is more than one parent.
1449 Abort if there is more than one parent.
1448 """
1450 """
1449 parents = set()
1451 parents = set()
1450 source = min(state)
1452 source = min(state)
1451 for rev in state:
1453 for rev in state:
1452 if rev == source:
1454 if rev == source:
1453 continue
1455 continue
1454 for p in repo[rev].parents():
1456 for p in repo[rev].parents():
1455 if p.rev() not in state and p.rev() not in destancestors:
1457 if p.rev() not in state and p.rev() not in destancestors:
1456 parents.add(p.rev())
1458 parents.add(p.rev())
1457 if not parents:
1459 if not parents:
1458 return nullrev
1460 return nullrev
1459 if len(parents) == 1:
1461 if len(parents) == 1:
1460 return parents.pop()
1462 return parents.pop()
1461 raise error.StateError(
1463 raise error.StateError(
1462 _(
1464 _(
1463 b'unable to collapse on top of %d, there is more '
1465 b'unable to collapse on top of %d, there is more '
1464 b'than one external parent: %s'
1466 b'than one external parent: %s'
1465 )
1467 )
1466 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents)))
1468 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents)))
1467 )
1469 )
1468
1470
1469
1471
1470 def commitmemorynode(repo, wctx, editor, extra, user, date, commitmsg):
1472 def commitmemorynode(repo, wctx, editor, extra, user, date, commitmsg):
1471 """Commit the memory changes with parents p1 and p2.
1473 """Commit the memory changes with parents p1 and p2.
1472 Return node of committed revision."""
1474 Return node of committed revision."""
1473 # By convention, ``extra['branch']`` (set by extrafn) clobbers
1475 # By convention, ``extra['branch']`` (set by extrafn) clobbers
1474 # ``branch`` (used when passing ``--keepbranches``).
1476 # ``branch`` (used when passing ``--keepbranches``).
1475 branch = None
1477 branch = None
1476 if b'branch' in extra:
1478 if b'branch' in extra:
1477 branch = extra[b'branch']
1479 branch = extra[b'branch']
1478
1480
1479 # FIXME: We call _compact() because it's required to correctly detect
1481 # FIXME: We call _compact() because it's required to correctly detect
1480 # changed files. This was added to fix a regression shortly before the 5.5
1482 # changed files. This was added to fix a regression shortly before the 5.5
1481 # release. A proper fix will be done in the default branch.
1483 # release. A proper fix will be done in the default branch.
1482 wctx._compact()
1484 wctx._compact()
1483 memctx = wctx.tomemctx(
1485 memctx = wctx.tomemctx(
1484 commitmsg,
1486 commitmsg,
1485 date=date,
1487 date=date,
1486 extra=extra,
1488 extra=extra,
1487 user=user,
1489 user=user,
1488 branch=branch,
1490 branch=branch,
1489 editor=editor,
1491 editor=editor,
1490 )
1492 )
1491 if memctx.isempty() and not repo.ui.configbool(b'ui', b'allowemptycommit'):
1493 if memctx.isempty() and not repo.ui.configbool(b'ui', b'allowemptycommit'):
1492 return None
1494 return None
1493 commitres = repo.commitctx(memctx)
1495 commitres = repo.commitctx(memctx)
1494 wctx.clean() # Might be reused
1496 wctx.clean() # Might be reused
1495 return commitres
1497 return commitres
1496
1498
1497
1499
1498 def commitnode(repo, editor, extra, user, date, commitmsg):
1500 def commitnode(repo, editor, extra, user, date, commitmsg):
1499 """Commit the wd changes with parents p1 and p2.
1501 """Commit the wd changes with parents p1 and p2.
1500 Return node of committed revision."""
1502 Return node of committed revision."""
1501 dsguard = util.nullcontextmanager()
1503 dsguard = util.nullcontextmanager()
1502 if not repo.ui.configbool(b'rebase', b'singletransaction'):
1504 if not repo.ui.configbool(b'rebase', b'singletransaction'):
1503 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1505 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1504 with dsguard:
1506 with dsguard:
1505 # Commit might fail if unresolved files exist
1507 # Commit might fail if unresolved files exist
1506 newnode = repo.commit(
1508 newnode = repo.commit(
1507 text=commitmsg, user=user, date=date, extra=extra, editor=editor
1509 text=commitmsg, user=user, date=date, extra=extra, editor=editor
1508 )
1510 )
1509
1511
1510 repo.dirstate.setbranch(repo[newnode].branch())
1512 repo.dirstate.setbranch(repo[newnode].branch())
1511 return newnode
1513 return newnode
1512
1514
1513
1515
1514 def rebasenode(repo, rev, p1, p2, base, collapse, wctx):
1516 def rebasenode(repo, rev, p1, p2, base, collapse, wctx):
1515 """Rebase a single revision rev on top of p1 using base as merge ancestor"""
1517 """Rebase a single revision rev on top of p1 using base as merge ancestor"""
1516 # Merge phase
1518 # Merge phase
1517 # Update to destination and merge it with local
1519 # Update to destination and merge it with local
1518 p1ctx = repo[p1]
1520 p1ctx = repo[p1]
1519 if wctx.isinmemory():
1521 if wctx.isinmemory():
1520 wctx.setbase(p1ctx)
1522 wctx.setbase(p1ctx)
1521 else:
1523 else:
1522 if repo[b'.'].rev() != p1:
1524 if repo[b'.'].rev() != p1:
1523 repo.ui.debug(b" update to %d:%s\n" % (p1, p1ctx))
1525 repo.ui.debug(b" update to %d:%s\n" % (p1, p1ctx))
1524 mergemod.clean_update(p1ctx)
1526 mergemod.clean_update(p1ctx)
1525 else:
1527 else:
1526 repo.ui.debug(b" already in destination\n")
1528 repo.ui.debug(b" already in destination\n")
1527 # This is, alas, necessary to invalidate workingctx's manifest cache,
1529 # This is, alas, necessary to invalidate workingctx's manifest cache,
1528 # as well as other data we litter on it in other places.
1530 # as well as other data we litter on it in other places.
1529 wctx = repo[None]
1531 wctx = repo[None]
1530 repo.dirstate.write(repo.currenttransaction())
1532 repo.dirstate.write(repo.currenttransaction())
1531 ctx = repo[rev]
1533 ctx = repo[rev]
1532 repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
1534 repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
1533 if base is not None:
1535 if base is not None:
1534 repo.ui.debug(b" detach base %d:%s\n" % (base, repo[base]))
1536 repo.ui.debug(b" detach base %d:%s\n" % (base, repo[base]))
1535
1537
1536 # See explanation in merge.graft()
1538 # See explanation in merge.graft()
1537 mergeancestor = repo.changelog.isancestor(p1ctx.node(), ctx.node())
1539 mergeancestor = repo.changelog.isancestor(p1ctx.node(), ctx.node())
1538 stats = mergemod._update(
1540 stats = mergemod._update(
1539 repo,
1541 repo,
1540 rev,
1542 rev,
1541 branchmerge=True,
1543 branchmerge=True,
1542 force=True,
1544 force=True,
1543 ancestor=base,
1545 ancestor=base,
1544 mergeancestor=mergeancestor,
1546 mergeancestor=mergeancestor,
1545 labels=[b'dest', b'source', b'parent of source'],
1547 labels=[b'dest', b'source', b'parent of source'],
1546 wc=wctx,
1548 wc=wctx,
1547 )
1549 )
1548 wctx.setparents(p1ctx.node(), repo[p2].node())
1550 wctx.setparents(p1ctx.node(), repo[p2].node())
1549 if collapse:
1551 if collapse:
1550 copies.graftcopies(wctx, ctx, p1ctx)
1552 copies.graftcopies(wctx, ctx, p1ctx)
1551 else:
1553 else:
1552 # If we're not using --collapse, we need to
1554 # If we're not using --collapse, we need to
1553 # duplicate copies between the revision we're
1555 # duplicate copies between the revision we're
1554 # rebasing and its first parent.
1556 # rebasing and its first parent.
1555 copies.graftcopies(wctx, ctx, ctx.p1())
1557 copies.graftcopies(wctx, ctx, ctx.p1())
1556
1558
1557 if stats.unresolvedcount > 0:
1559 if stats.unresolvedcount > 0:
1558 if wctx.isinmemory():
1560 if wctx.isinmemory():
1559 raise error.InMemoryMergeConflictsError()
1561 raise error.InMemoryMergeConflictsError()
1560 else:
1562 else:
1561 raise error.ConflictResolutionRequired(b'rebase')
1563 raise error.ConflictResolutionRequired(b'rebase')
1562
1564
1563
1565
1564 def adjustdest(repo, rev, destmap, state, skipped):
1566 def adjustdest(repo, rev, destmap, state, skipped):
1565 r"""adjust rebase destination given the current rebase state
1567 r"""adjust rebase destination given the current rebase state
1566
1568
1567 rev is what is being rebased. Return a list of two revs, which are the
1569 rev is what is being rebased. Return a list of two revs, which are the
1568 adjusted destinations for rev's p1 and p2, respectively. If a parent is
1570 adjusted destinations for rev's p1 and p2, respectively. If a parent is
1569 nullrev, return dest without adjustment for it.
1571 nullrev, return dest without adjustment for it.
1570
1572
1571 For example, when doing rebasing B+E to F, C to G, rebase will first move B
1573 For example, when doing rebasing B+E to F, C to G, rebase will first move B
1572 to B1, and E's destination will be adjusted from F to B1.
1574 to B1, and E's destination will be adjusted from F to B1.
1573
1575
1574 B1 <- written during rebasing B
1576 B1 <- written during rebasing B
1575 |
1577 |
1576 F <- original destination of B, E
1578 F <- original destination of B, E
1577 |
1579 |
1578 | E <- rev, which is being rebased
1580 | E <- rev, which is being rebased
1579 | |
1581 | |
1580 | D <- prev, one parent of rev being checked
1582 | D <- prev, one parent of rev being checked
1581 | |
1583 | |
1582 | x <- skipped, ex. no successor or successor in (::dest)
1584 | x <- skipped, ex. no successor or successor in (::dest)
1583 | |
1585 | |
1584 | C <- rebased as C', different destination
1586 | C <- rebased as C', different destination
1585 | |
1587 | |
1586 | B <- rebased as B1 C'
1588 | B <- rebased as B1 C'
1587 |/ |
1589 |/ |
1588 A G <- destination of C, different
1590 A G <- destination of C, different
1589
1591
1590 Another example about merge changeset, rebase -r C+G+H -d K, rebase will
1592 Another example about merge changeset, rebase -r C+G+H -d K, rebase will
1591 first move C to C1, G to G1, and when it's checking H, the adjusted
1593 first move C to C1, G to G1, and when it's checking H, the adjusted
1592 destinations will be [C1, G1].
1594 destinations will be [C1, G1].
1593
1595
1594 H C1 G1
1596 H C1 G1
1595 /| | /
1597 /| | /
1596 F G |/
1598 F G |/
1597 K | | -> K
1599 K | | -> K
1598 | C D |
1600 | C D |
1599 | |/ |
1601 | |/ |
1600 | B | ...
1602 | B | ...
1601 |/ |/
1603 |/ |/
1602 A A
1604 A A
1603
1605
1604 Besides, adjust dest according to existing rebase information. For example,
1606 Besides, adjust dest according to existing rebase information. For example,
1605
1607
1606 B C D B needs to be rebased on top of C, C needs to be rebased on top
1608 B C D B needs to be rebased on top of C, C needs to be rebased on top
1607 \|/ of D. We will rebase C first.
1609 \|/ of D. We will rebase C first.
1608 A
1610 A
1609
1611
1610 C' After rebasing C, when considering B's destination, use C'
1612 C' After rebasing C, when considering B's destination, use C'
1611 | instead of the original C.
1613 | instead of the original C.
1612 B D
1614 B D
1613 \ /
1615 \ /
1614 A
1616 A
1615 """
1617 """
1616 # pick already rebased revs with same dest from state as interesting source
1618 # pick already rebased revs with same dest from state as interesting source
1617 dest = destmap[rev]
1619 dest = destmap[rev]
1618 source = [
1620 source = [
1619 s
1621 s
1620 for s, d in state.items()
1622 for s, d in state.items()
1621 if d > 0 and destmap[s] == dest and s not in skipped
1623 if d > 0 and destmap[s] == dest and s not in skipped
1622 ]
1624 ]
1623
1625
1624 result = []
1626 result = []
1625 for prev in repo.changelog.parentrevs(rev):
1627 for prev in repo.changelog.parentrevs(rev):
1626 adjusted = dest
1628 adjusted = dest
1627 if prev != nullrev:
1629 if prev != nullrev:
1628 candidate = repo.revs(b'max(%ld and (::%d))', source, prev).first()
1630 candidate = repo.revs(b'max(%ld and (::%d))', source, prev).first()
1629 if candidate is not None:
1631 if candidate is not None:
1630 adjusted = state[candidate]
1632 adjusted = state[candidate]
1631 if adjusted == dest and dest in state:
1633 if adjusted == dest and dest in state:
1632 adjusted = state[dest]
1634 adjusted = state[dest]
1633 if adjusted == revtodo:
1635 if adjusted == revtodo:
1634 # sortsource should produce an order that makes this impossible
1636 # sortsource should produce an order that makes this impossible
1635 raise error.ProgrammingError(
1637 raise error.ProgrammingError(
1636 b'rev %d should be rebased already at this time' % dest
1638 b'rev %d should be rebased already at this time' % dest
1637 )
1639 )
1638 result.append(adjusted)
1640 result.append(adjusted)
1639 return result
1641 return result
1640
1642
1641
1643
1642 def _checkobsrebase(repo, ui, rebaseobsrevs, rebaseobsskipped):
1644 def _checkobsrebase(repo, ui, rebaseobsrevs, rebaseobsskipped):
1643 """
1645 """
1644 Abort if rebase will create divergence or rebase is noop because of markers
1646 Abort if rebase will create divergence or rebase is noop because of markers
1645
1647
1646 `rebaseobsrevs`: set of obsolete revision in source
1648 `rebaseobsrevs`: set of obsolete revision in source
1647 `rebaseobsskipped`: set of revisions from source skipped because they have
1649 `rebaseobsskipped`: set of revisions from source skipped because they have
1648 successors in destination or no non-obsolete successor.
1650 successors in destination or no non-obsolete successor.
1649 """
1651 """
1650 # Obsolete node with successors not in dest leads to divergence
1652 # Obsolete node with successors not in dest leads to divergence
1651 divergenceok = obsolete.isenabled(repo, obsolete.allowdivergenceopt)
1653 divergenceok = obsolete.isenabled(repo, obsolete.allowdivergenceopt)
1652 divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
1654 divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
1653
1655
1654 if divergencebasecandidates and not divergenceok:
1656 if divergencebasecandidates and not divergenceok:
1655 divhashes = (bytes(repo[r]) for r in divergencebasecandidates)
1657 divhashes = (bytes(repo[r]) for r in divergencebasecandidates)
1656 msg = _(b"this rebase will cause divergences from: %s")
1658 msg = _(b"this rebase will cause divergences from: %s")
1657 h = _(
1659 h = _(
1658 b"to force the rebase please set "
1660 b"to force the rebase please set "
1659 b"experimental.evolution.allowdivergence=True"
1661 b"experimental.evolution.allowdivergence=True"
1660 )
1662 )
1661 raise error.StateError(msg % (b",".join(divhashes),), hint=h)
1663 raise error.StateError(msg % (b",".join(divhashes),), hint=h)
1662
1664
1663
1665
1664 def successorrevs(unfi, rev):
1666 def successorrevs(unfi, rev):
1665 """yield revision numbers for successors of rev"""
1667 """yield revision numbers for successors of rev"""
1666 assert unfi.filtername is None
1668 assert unfi.filtername is None
1667 get_rev = unfi.changelog.index.get_rev
1669 get_rev = unfi.changelog.index.get_rev
1668 for s in obsutil.allsuccessors(unfi.obsstore, [unfi[rev].node()]):
1670 for s in obsutil.allsuccessors(unfi.obsstore, [unfi[rev].node()]):
1669 r = get_rev(s)
1671 r = get_rev(s)
1670 if r is not None:
1672 if r is not None:
1671 yield r
1673 yield r
1672
1674
1673
1675
1674 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1676 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1675 """Return new parents and optionally a merge base for rev being rebased
1677 """Return new parents and optionally a merge base for rev being rebased
1676
1678
1677 The destination specified by "dest" cannot always be used directly because
1679 The destination specified by "dest" cannot always be used directly because
1678 previously rebase result could affect destination. For example,
1680 previously rebase result could affect destination. For example,
1679
1681
1680 D E rebase -r C+D+E -d B
1682 D E rebase -r C+D+E -d B
1681 |/ C will be rebased to C'
1683 |/ C will be rebased to C'
1682 B C D's new destination will be C' instead of B
1684 B C D's new destination will be C' instead of B
1683 |/ E's new destination will be C' instead of B
1685 |/ E's new destination will be C' instead of B
1684 A
1686 A
1685
1687
1686 The new parents of a merge is slightly more complicated. See the comment
1688 The new parents of a merge is slightly more complicated. See the comment
1687 block below.
1689 block below.
1688 """
1690 """
1689 # use unfiltered changelog since successorrevs may return filtered nodes
1691 # use unfiltered changelog since successorrevs may return filtered nodes
1690 assert repo.filtername is None
1692 assert repo.filtername is None
1691 cl = repo.changelog
1693 cl = repo.changelog
1692 isancestor = cl.isancestorrev
1694 isancestor = cl.isancestorrev
1693
1695
1694 dest = destmap[rev]
1696 dest = destmap[rev]
1695 oldps = repo.changelog.parentrevs(rev) # old parents
1697 oldps = repo.changelog.parentrevs(rev) # old parents
1696 newps = [nullrev, nullrev] # new parents
1698 newps = [nullrev, nullrev] # new parents
1697 dests = adjustdest(repo, rev, destmap, state, skipped)
1699 dests = adjustdest(repo, rev, destmap, state, skipped)
1698 bases = list(oldps) # merge base candidates, initially just old parents
1700 bases = list(oldps) # merge base candidates, initially just old parents
1699
1701
1700 if all(r == nullrev for r in oldps[1:]):
1702 if all(r == nullrev for r in oldps[1:]):
1701 # For non-merge changeset, just move p to adjusted dest as requested.
1703 # For non-merge changeset, just move p to adjusted dest as requested.
1702 newps[0] = dests[0]
1704 newps[0] = dests[0]
1703 else:
1705 else:
1704 # For merge changeset, if we move p to dests[i] unconditionally, both
1706 # For merge changeset, if we move p to dests[i] unconditionally, both
1705 # parents may change and the end result looks like "the merge loses a
1707 # parents may change and the end result looks like "the merge loses a
1706 # parent", which is a surprise. This is a limit because "--dest" only
1708 # parent", which is a surprise. This is a limit because "--dest" only
1707 # accepts one dest per src.
1709 # accepts one dest per src.
1708 #
1710 #
1709 # Therefore, only move p with reasonable conditions (in this order):
1711 # Therefore, only move p with reasonable conditions (in this order):
1710 # 1. use dest, if dest is a descendent of (p or one of p's successors)
1712 # 1. use dest, if dest is a descendent of (p or one of p's successors)
1711 # 2. use p's rebased result, if p is rebased (state[p] > 0)
1713 # 2. use p's rebased result, if p is rebased (state[p] > 0)
1712 #
1714 #
1713 # Comparing with adjustdest, the logic here does some additional work:
1715 # Comparing with adjustdest, the logic here does some additional work:
1714 # 1. decide which parents will not be moved towards dest
1716 # 1. decide which parents will not be moved towards dest
1715 # 2. if the above decision is "no", should a parent still be moved
1717 # 2. if the above decision is "no", should a parent still be moved
1716 # because it was rebased?
1718 # because it was rebased?
1717 #
1719 #
1718 # For example:
1720 # For example:
1719 #
1721 #
1720 # C # "rebase -r C -d D" is an error since none of the parents
1722 # C # "rebase -r C -d D" is an error since none of the parents
1721 # /| # can be moved. "rebase -r B+C -d D" will move C's parent
1723 # /| # can be moved. "rebase -r B+C -d D" will move C's parent
1722 # A B D # B (using rule "2."), since B will be rebased.
1724 # A B D # B (using rule "2."), since B will be rebased.
1723 #
1725 #
1724 # The loop tries to be not rely on the fact that a Mercurial node has
1726 # The loop tries to be not rely on the fact that a Mercurial node has
1725 # at most 2 parents.
1727 # at most 2 parents.
1726 for i, p in enumerate(oldps):
1728 for i, p in enumerate(oldps):
1727 np = p # new parent
1729 np = p # new parent
1728 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)):
1730 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)):
1729 np = dests[i]
1731 np = dests[i]
1730 elif p in state and state[p] > 0:
1732 elif p in state and state[p] > 0:
1731 np = state[p]
1733 np = state[p]
1732
1734
1733 # If one parent becomes an ancestor of the other, drop the ancestor
1735 # If one parent becomes an ancestor of the other, drop the ancestor
1734 for j, x in enumerate(newps[:i]):
1736 for j, x in enumerate(newps[:i]):
1735 if x == nullrev:
1737 if x == nullrev:
1736 continue
1738 continue
1737 if isancestor(np, x): # CASE-1
1739 if isancestor(np, x): # CASE-1
1738 np = nullrev
1740 np = nullrev
1739 elif isancestor(x, np): # CASE-2
1741 elif isancestor(x, np): # CASE-2
1740 newps[j] = np
1742 newps[j] = np
1741 np = nullrev
1743 np = nullrev
1742 # New parents forming an ancestor relationship does not
1744 # New parents forming an ancestor relationship does not
1743 # mean the old parents have a similar relationship. Do not
1745 # mean the old parents have a similar relationship. Do not
1744 # set bases[x] to nullrev.
1746 # set bases[x] to nullrev.
1745 bases[j], bases[i] = bases[i], bases[j]
1747 bases[j], bases[i] = bases[i], bases[j]
1746
1748
1747 newps[i] = np
1749 newps[i] = np
1748
1750
1749 # "rebasenode" updates to new p1, and the old p1 will be used as merge
1751 # "rebasenode" updates to new p1, and the old p1 will be used as merge
1750 # base. If only p2 changes, merging using unchanged p1 as merge base is
1752 # base. If only p2 changes, merging using unchanged p1 as merge base is
1751 # suboptimal. Therefore swap parents to make the merge sane.
1753 # suboptimal. Therefore swap parents to make the merge sane.
1752 if newps[1] != nullrev and oldps[0] == newps[0]:
1754 if newps[1] != nullrev and oldps[0] == newps[0]:
1753 assert len(newps) == 2 and len(oldps) == 2
1755 assert len(newps) == 2 and len(oldps) == 2
1754 newps.reverse()
1756 newps.reverse()
1755 bases.reverse()
1757 bases.reverse()
1756
1758
1757 # No parent change might be an error because we fail to make rev a
1759 # No parent change might be an error because we fail to make rev a
1758 # descendent of requested dest. This can happen, for example:
1760 # descendent of requested dest. This can happen, for example:
1759 #
1761 #
1760 # C # rebase -r C -d D
1762 # C # rebase -r C -d D
1761 # /| # None of A and B will be changed to D and rebase fails.
1763 # /| # None of A and B will be changed to D and rebase fails.
1762 # A B D
1764 # A B D
1763 if set(newps) == set(oldps) and dest not in newps:
1765 if set(newps) == set(oldps) and dest not in newps:
1764 raise error.InputError(
1766 raise error.InputError(
1765 _(
1767 _(
1766 b'cannot rebase %d:%s without '
1768 b'cannot rebase %d:%s without '
1767 b'moving at least one of its parents'
1769 b'moving at least one of its parents'
1768 )
1770 )
1769 % (rev, repo[rev])
1771 % (rev, repo[rev])
1770 )
1772 )
1771
1773
1772 # Source should not be ancestor of dest. The check here guarantees it's
1774 # Source should not be ancestor of dest. The check here guarantees it's
1773 # impossible. With multi-dest, the initial check does not cover complex
1775 # impossible. With multi-dest, the initial check does not cover complex
1774 # cases since we don't have abstractions to dry-run rebase cheaply.
1776 # cases since we don't have abstractions to dry-run rebase cheaply.
1775 if any(p != nullrev and isancestor(rev, p) for p in newps):
1777 if any(p != nullrev and isancestor(rev, p) for p in newps):
1776 raise error.InputError(_(b'source is ancestor of destination'))
1778 raise error.InputError(_(b'source is ancestor of destination'))
1777
1779
1778 # Check if the merge will contain unwanted changes. That may happen if
1780 # Check if the merge will contain unwanted changes. That may happen if
1779 # there are multiple special (non-changelog ancestor) merge bases, which
1781 # there are multiple special (non-changelog ancestor) merge bases, which
1780 # cannot be handled well by the 3-way merge algorithm. For example:
1782 # cannot be handled well by the 3-way merge algorithm. For example:
1781 #
1783 #
1782 # F
1784 # F
1783 # /|
1785 # /|
1784 # D E # "rebase -r D+E+F -d Z", when rebasing F, if "D" was chosen
1786 # D E # "rebase -r D+E+F -d Z", when rebasing F, if "D" was chosen
1785 # | | # as merge base, the difference between D and F will include
1787 # | | # as merge base, the difference between D and F will include
1786 # B C # C, so the rebased F will contain C surprisingly. If "E" was
1788 # B C # C, so the rebased F will contain C surprisingly. If "E" was
1787 # |/ # chosen, the rebased F will contain B.
1789 # |/ # chosen, the rebased F will contain B.
1788 # A Z
1790 # A Z
1789 #
1791 #
1790 # But our merge base candidates (D and E in above case) could still be
1792 # But our merge base candidates (D and E in above case) could still be
1791 # better than the default (ancestor(F, Z) == null). Therefore still
1793 # better than the default (ancestor(F, Z) == null). Therefore still
1792 # pick one (so choose p1 above).
1794 # pick one (so choose p1 above).
1793 if sum(1 for b in set(bases) if b != nullrev and b not in newps) > 1:
1795 if sum(1 for b in set(bases) if b != nullrev and b not in newps) > 1:
1794 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i]
1796 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i]
1795 for i, base in enumerate(bases):
1797 for i, base in enumerate(bases):
1796 if base == nullrev or base in newps:
1798 if base == nullrev or base in newps:
1797 continue
1799 continue
1798 # Revisions in the side (not chosen as merge base) branch that
1800 # Revisions in the side (not chosen as merge base) branch that
1799 # might contain "surprising" contents
1801 # might contain "surprising" contents
1800 other_bases = set(bases) - {base}
1802 other_bases = set(bases) - {base}
1801 siderevs = list(
1803 siderevs = list(
1802 repo.revs(b'(%ld %% (%d+%d))', other_bases, base, dest)
1804 repo.revs(b'(%ld %% (%d+%d))', other_bases, base, dest)
1803 )
1805 )
1804
1806
1805 # If those revisions are covered by rebaseset, the result is good.
1807 # If those revisions are covered by rebaseset, the result is good.
1806 # A merge in rebaseset would be considered to cover its ancestors.
1808 # A merge in rebaseset would be considered to cover its ancestors.
1807 if siderevs:
1809 if siderevs:
1808 rebaseset = [
1810 rebaseset = [
1809 r for r, d in state.items() if d > 0 and r not in obsskipped
1811 r for r, d in state.items() if d > 0 and r not in obsskipped
1810 ]
1812 ]
1811 merges = [
1813 merges = [
1812 r for r in rebaseset if cl.parentrevs(r)[1] != nullrev
1814 r for r in rebaseset if cl.parentrevs(r)[1] != nullrev
1813 ]
1815 ]
1814 unwanted[i] = list(
1816 unwanted[i] = list(
1815 repo.revs(
1817 repo.revs(
1816 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset
1818 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset
1817 )
1819 )
1818 )
1820 )
1819
1821
1820 if any(revs is not None for revs in unwanted):
1822 if any(revs is not None for revs in unwanted):
1821 # Choose a merge base that has a minimal number of unwanted revs.
1823 # Choose a merge base that has a minimal number of unwanted revs.
1822 l, i = min(
1824 l, i = min(
1823 (len(revs), i)
1825 (len(revs), i)
1824 for i, revs in enumerate(unwanted)
1826 for i, revs in enumerate(unwanted)
1825 if revs is not None
1827 if revs is not None
1826 )
1828 )
1827
1829
1828 # The merge will include unwanted revisions. Abort now. Revisit this if
1830 # The merge will include unwanted revisions. Abort now. Revisit this if
1829 # we have a more advanced merge algorithm that handles multiple bases.
1831 # we have a more advanced merge algorithm that handles multiple bases.
1830 if l > 0:
1832 if l > 0:
1831 unwanteddesc = _(b' or ').join(
1833 unwanteddesc = _(b' or ').join(
1832 (
1834 (
1833 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs)
1835 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs)
1834 for revs in unwanted
1836 for revs in unwanted
1835 if revs is not None
1837 if revs is not None
1836 )
1838 )
1837 )
1839 )
1838 raise error.InputError(
1840 raise error.InputError(
1839 _(b'rebasing %d:%s will include unwanted changes from %s')
1841 _(b'rebasing %d:%s will include unwanted changes from %s')
1840 % (rev, repo[rev], unwanteddesc)
1842 % (rev, repo[rev], unwanteddesc)
1841 )
1843 )
1842
1844
1843 # newps[0] should match merge base if possible. Currently, if newps[i]
1845 # newps[0] should match merge base if possible. Currently, if newps[i]
1844 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is
1846 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is
1845 # the other's ancestor. In that case, it's fine to not swap newps here.
1847 # the other's ancestor. In that case, it's fine to not swap newps here.
1846 # (see CASE-1 and CASE-2 above)
1848 # (see CASE-1 and CASE-2 above)
1847 if i != 0:
1849 if i != 0:
1848 if newps[i] != nullrev:
1850 if newps[i] != nullrev:
1849 newps[0], newps[i] = newps[i], newps[0]
1851 newps[0], newps[i] = newps[i], newps[0]
1850 bases[0], bases[i] = bases[i], bases[0]
1852 bases[0], bases[i] = bases[i], bases[0]
1851
1853
1852 # "rebasenode" updates to new p1, use the corresponding merge base.
1854 # "rebasenode" updates to new p1, use the corresponding merge base.
1853 base = bases[0]
1855 base = bases[0]
1854
1856
1855 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps))
1857 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps))
1856
1858
1857 return newps[0], newps[1], base
1859 return newps[0], newps[1], base
1858
1860
1859
1861
1860 def isagitpatch(repo, patchname):
1862 def isagitpatch(repo, patchname):
1861 """Return true if the given patch is in git format"""
1863 """Return true if the given patch is in git format"""
1862 mqpatch = os.path.join(repo.mq.path, patchname)
1864 mqpatch = os.path.join(repo.mq.path, patchname)
1863 for line in patch.linereader(open(mqpatch, b'rb')):
1865 for line in patch.linereader(open(mqpatch, b'rb')):
1864 if line.startswith(b'diff --git'):
1866 if line.startswith(b'diff --git'):
1865 return True
1867 return True
1866 return False
1868 return False
1867
1869
1868
1870
1869 def updatemq(repo, state, skipped, **opts):
1871 def updatemq(repo, state, skipped, **opts):
1870 """Update rebased mq patches - finalize and then import them"""
1872 """Update rebased mq patches - finalize and then import them"""
1871 mqrebase = {}
1873 mqrebase = {}
1872 mq = repo.mq
1874 mq = repo.mq
1873 original_series = mq.fullseries[:]
1875 original_series = mq.fullseries[:]
1874 skippedpatches = set()
1876 skippedpatches = set()
1875
1877
1876 for p in mq.applied:
1878 for p in mq.applied:
1877 rev = repo[p.node].rev()
1879 rev = repo[p.node].rev()
1878 if rev in state:
1880 if rev in state:
1879 repo.ui.debug(
1881 repo.ui.debug(
1880 b'revision %d is an mq patch (%s), finalize it.\n'
1882 b'revision %d is an mq patch (%s), finalize it.\n'
1881 % (rev, p.name)
1883 % (rev, p.name)
1882 )
1884 )
1883 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
1885 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
1884 else:
1886 else:
1885 # Applied but not rebased, not sure this should happen
1887 # Applied but not rebased, not sure this should happen
1886 skippedpatches.add(p.name)
1888 skippedpatches.add(p.name)
1887
1889
1888 if mqrebase:
1890 if mqrebase:
1889 mq.finish(repo, mqrebase.keys())
1891 mq.finish(repo, mqrebase.keys())
1890
1892
1891 # We must start import from the newest revision
1893 # We must start import from the newest revision
1892 for rev in sorted(mqrebase, reverse=True):
1894 for rev in sorted(mqrebase, reverse=True):
1893 if rev not in skipped:
1895 if rev not in skipped:
1894 name, isgit = mqrebase[rev]
1896 name, isgit = mqrebase[rev]
1895 repo.ui.note(
1897 repo.ui.note(
1896 _(b'updating mq patch %s to %d:%s\n')
1898 _(b'updating mq patch %s to %d:%s\n')
1897 % (name, state[rev], repo[state[rev]])
1899 % (name, state[rev], repo[state[rev]])
1898 )
1900 )
1899 mq.qimport(
1901 mq.qimport(
1900 repo,
1902 repo,
1901 (),
1903 (),
1902 patchname=name,
1904 patchname=name,
1903 git=isgit,
1905 git=isgit,
1904 rev=[b"%d" % state[rev]],
1906 rev=[b"%d" % state[rev]],
1905 )
1907 )
1906 else:
1908 else:
1907 # Rebased and skipped
1909 # Rebased and skipped
1908 skippedpatches.add(mqrebase[rev][0])
1910 skippedpatches.add(mqrebase[rev][0])
1909
1911
1910 # Patches were either applied and rebased and imported in
1912 # Patches were either applied and rebased and imported in
1911 # order, applied and removed or unapplied. Discard the removed
1913 # order, applied and removed or unapplied. Discard the removed
1912 # ones while preserving the original series order and guards.
1914 # ones while preserving the original series order and guards.
1913 newseries = [
1915 newseries = [
1914 s
1916 s
1915 for s in original_series
1917 for s in original_series
1916 if mq.guard_re.split(s, 1)[0] not in skippedpatches
1918 if mq.guard_re.split(s, 1)[0] not in skippedpatches
1917 ]
1919 ]
1918 mq.fullseries[:] = newseries
1920 mq.fullseries[:] = newseries
1919 mq.seriesdirty = True
1921 mq.seriesdirty = True
1920 mq.savedirty()
1922 mq.savedirty()
1921
1923
1922
1924
1923 def storecollapsemsg(repo, collapsemsg):
1925 def storecollapsemsg(repo, collapsemsg):
1924 """Store the collapse message to allow recovery"""
1926 """Store the collapse message to allow recovery"""
1925 collapsemsg = collapsemsg or b''
1927 collapsemsg = collapsemsg or b''
1926 f = repo.vfs(b"last-message.txt", b"w")
1928 f = repo.vfs(b"last-message.txt", b"w")
1927 f.write(b"%s\n" % collapsemsg)
1929 f.write(b"%s\n" % collapsemsg)
1928 f.close()
1930 f.close()
1929
1931
1930
1932
1931 def clearcollapsemsg(repo):
1933 def clearcollapsemsg(repo):
1932 """Remove collapse message file"""
1934 """Remove collapse message file"""
1933 repo.vfs.unlinkpath(b"last-message.txt", ignoremissing=True)
1935 repo.vfs.unlinkpath(b"last-message.txt", ignoremissing=True)
1934
1936
1935
1937
1936 def restorecollapsemsg(repo, isabort):
1938 def restorecollapsemsg(repo, isabort):
1937 """Restore previously stored collapse message"""
1939 """Restore previously stored collapse message"""
1938 try:
1940 try:
1939 f = repo.vfs(b"last-message.txt")
1941 f = repo.vfs(b"last-message.txt")
1940 collapsemsg = f.readline().strip()
1942 collapsemsg = f.readline().strip()
1941 f.close()
1943 f.close()
1942 except FileNotFoundError:
1944 except FileNotFoundError:
1943 if isabort:
1945 if isabort:
1944 # Oh well, just abort like normal
1946 # Oh well, just abort like normal
1945 collapsemsg = b''
1947 collapsemsg = b''
1946 else:
1948 else:
1947 raise error.Abort(_(b'missing .hg/last-message.txt for rebase'))
1949 raise error.Abort(_(b'missing .hg/last-message.txt for rebase'))
1948 return collapsemsg
1950 return collapsemsg
1949
1951
1950
1952
1951 def clearstatus(repo):
1953 def clearstatus(repo):
1952 """Remove the status files"""
1954 """Remove the status files"""
1953 # Make sure the active transaction won't write the state file
1955 # Make sure the active transaction won't write the state file
1954 tr = repo.currenttransaction()
1956 tr = repo.currenttransaction()
1955 if tr:
1957 if tr:
1956 tr.removefilegenerator(b'rebasestate')
1958 tr.removefilegenerator(b'rebasestate')
1957 repo.vfs.unlinkpath(b"rebasestate", ignoremissing=True)
1959 repo.vfs.unlinkpath(b"rebasestate", ignoremissing=True)
1958
1960
1959
1961
1960 def sortsource(destmap):
1962 def sortsource(destmap):
1961 """yield source revisions in an order that we only rebase things once
1963 """yield source revisions in an order that we only rebase things once
1962
1964
1963 If source and destination overlaps, we should filter out revisions
1965 If source and destination overlaps, we should filter out revisions
1964 depending on other revisions which hasn't been rebased yet.
1966 depending on other revisions which hasn't been rebased yet.
1965
1967
1966 Yield a sorted list of revisions each time.
1968 Yield a sorted list of revisions each time.
1967
1969
1968 For example, when rebasing A to B, B to C. This function yields [B], then
1970 For example, when rebasing A to B, B to C. This function yields [B], then
1969 [A], indicating B needs to be rebased first.
1971 [A], indicating B needs to be rebased first.
1970
1972
1971 Raise if there is a cycle so the rebase is impossible.
1973 Raise if there is a cycle so the rebase is impossible.
1972 """
1974 """
1973 srcset = set(destmap)
1975 srcset = set(destmap)
1974 while srcset:
1976 while srcset:
1975 srclist = sorted(srcset)
1977 srclist = sorted(srcset)
1976 result = []
1978 result = []
1977 for r in srclist:
1979 for r in srclist:
1978 if destmap[r] not in srcset:
1980 if destmap[r] not in srcset:
1979 result.append(r)
1981 result.append(r)
1980 if not result:
1982 if not result:
1981 raise error.InputError(_(b'source and destination form a cycle'))
1983 raise error.InputError(_(b'source and destination form a cycle'))
1982 srcset -= set(result)
1984 srcset -= set(result)
1983 yield result
1985 yield result
1984
1986
1985
1987
1986 def buildstate(repo, destmap, collapse):
1988 def buildstate(repo, destmap, collapse):
1987 """Define which revisions are going to be rebased and where
1989 """Define which revisions are going to be rebased and where
1988
1990
1989 repo: repo
1991 repo: repo
1990 destmap: {srcrev: destrev}
1992 destmap: {srcrev: destrev}
1991 """
1993 """
1992 rebaseset = destmap.keys()
1994 rebaseset = destmap.keys()
1993 originalwd = repo[b'.'].rev()
1995 originalwd = repo[b'.'].rev()
1994
1996
1995 # This check isn't strictly necessary, since mq detects commits over an
1997 # This check isn't strictly necessary, since mq detects commits over an
1996 # applied patch. But it prevents messing up the working directory when
1998 # applied patch. But it prevents messing up the working directory when
1997 # a partially completed rebase is blocked by mq.
1999 # a partially completed rebase is blocked by mq.
1998 if b'qtip' in repo.tags():
2000 if b'qtip' in repo.tags():
1999 mqapplied = {repo[s.node].rev() for s in repo.mq.applied}
2001 mqapplied = {repo[s.node].rev() for s in repo.mq.applied}
2000 if set(destmap.values()) & mqapplied:
2002 if set(destmap.values()) & mqapplied:
2001 raise error.StateError(_(b'cannot rebase onto an applied mq patch'))
2003 raise error.StateError(_(b'cannot rebase onto an applied mq patch'))
2002
2004
2003 # Get "cycle" error early by exhausting the generator.
2005 # Get "cycle" error early by exhausting the generator.
2004 sortedsrc = list(sortsource(destmap)) # a list of sorted revs
2006 sortedsrc = list(sortsource(destmap)) # a list of sorted revs
2005 if not sortedsrc:
2007 if not sortedsrc:
2006 raise error.InputError(_(b'no matching revisions'))
2008 raise error.InputError(_(b'no matching revisions'))
2007
2009
2008 # Only check the first batch of revisions to rebase not depending on other
2010 # Only check the first batch of revisions to rebase not depending on other
2009 # rebaseset. This means "source is ancestor of destination" for the second
2011 # rebaseset. This means "source is ancestor of destination" for the second
2010 # (and following) batches of revisions are not checked here. We rely on
2012 # (and following) batches of revisions are not checked here. We rely on
2011 # "defineparents" to do that check.
2013 # "defineparents" to do that check.
2012 roots = list(repo.set(b'roots(%ld)', sortedsrc[0]))
2014 roots = list(repo.set(b'roots(%ld)', sortedsrc[0]))
2013 if not roots:
2015 if not roots:
2014 raise error.InputError(_(b'no matching revisions'))
2016 raise error.InputError(_(b'no matching revisions'))
2015
2017
2016 def revof(r):
2018 def revof(r):
2017 return r.rev()
2019 return r.rev()
2018
2020
2019 roots = sorted(roots, key=revof)
2021 roots = sorted(roots, key=revof)
2020 state = dict.fromkeys(rebaseset, revtodo)
2022 state = dict.fromkeys(rebaseset, revtodo)
2021 emptyrebase = len(sortedsrc) == 1
2023 emptyrebase = len(sortedsrc) == 1
2022 for root in roots:
2024 for root in roots:
2023 dest = repo[destmap[root.rev()]]
2025 dest = repo[destmap[root.rev()]]
2024 commonbase = root.ancestor(dest)
2026 commonbase = root.ancestor(dest)
2025 if commonbase == root:
2027 if commonbase == root:
2026 raise error.InputError(_(b'source is ancestor of destination'))
2028 raise error.InputError(_(b'source is ancestor of destination'))
2027 if commonbase == dest:
2029 if commonbase == dest:
2028 wctx = repo[None]
2030 wctx = repo[None]
2029 if dest == wctx.p1():
2031 if dest == wctx.p1():
2030 # when rebasing to '.', it will use the current wd branch name
2032 # when rebasing to '.', it will use the current wd branch name
2031 samebranch = root.branch() == wctx.branch()
2033 samebranch = root.branch() == wctx.branch()
2032 else:
2034 else:
2033 samebranch = root.branch() == dest.branch()
2035 samebranch = root.branch() == dest.branch()
2034 if not collapse and samebranch and dest in root.parents():
2036 if not collapse and samebranch and dest in root.parents():
2035 # mark the revision as done by setting its new revision
2037 # mark the revision as done by setting its new revision
2036 # equal to its old (current) revisions
2038 # equal to its old (current) revisions
2037 state[root.rev()] = root.rev()
2039 state[root.rev()] = root.rev()
2038 repo.ui.debug(b'source is a child of destination\n')
2040 repo.ui.debug(b'source is a child of destination\n')
2039 continue
2041 continue
2040
2042
2041 emptyrebase = False
2043 emptyrebase = False
2042 repo.ui.debug(b'rebase onto %s starting from %s\n' % (dest, root))
2044 repo.ui.debug(b'rebase onto %s starting from %s\n' % (dest, root))
2043 if emptyrebase:
2045 if emptyrebase:
2044 return None
2046 return None
2045 for rev in sorted(state):
2047 for rev in sorted(state):
2046 parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
2048 parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
2047 # if all parents of this revision are done, then so is this revision
2049 # if all parents of this revision are done, then so is this revision
2048 if parents and all((state.get(p) == p for p in parents)):
2050 if parents and all((state.get(p) == p for p in parents)):
2049 state[rev] = rev
2051 state[rev] = rev
2050 return originalwd, destmap, state
2052 return originalwd, destmap, state
2051
2053
2052
2054
2053 def clearrebased(
2055 def clearrebased(
2054 ui,
2056 ui,
2055 repo,
2057 repo,
2056 destmap,
2058 destmap,
2057 state,
2059 state,
2058 skipped,
2060 skipped,
2059 collapsedas=None,
2061 collapsedas=None,
2060 keepf=False,
2062 keepf=False,
2061 fm=None,
2063 fm=None,
2062 backup=True,
2064 backup=True,
2063 ):
2065 ):
2064 """dispose of rebased revision at the end of the rebase
2066 """dispose of rebased revision at the end of the rebase
2065
2067
2066 If `collapsedas` is not None, the rebase was a collapse whose result if the
2068 If `collapsedas` is not None, the rebase was a collapse whose result if the
2067 `collapsedas` node.
2069 `collapsedas` node.
2068
2070
2069 If `keepf` is not True, the rebase has --keep set and no nodes should be
2071 If `keepf` is not True, the rebase has --keep set and no nodes should be
2070 removed (but bookmarks still need to be moved).
2072 removed (but bookmarks still need to be moved).
2071
2073
2072 If `backup` is False, no backup will be stored when stripping rebased
2074 If `backup` is False, no backup will be stored when stripping rebased
2073 revisions.
2075 revisions.
2074 """
2076 """
2075 tonode = repo.changelog.node
2077 tonode = repo.changelog.node
2076 replacements = {}
2078 replacements = {}
2077 moves = {}
2079 moves = {}
2078 stripcleanup = not obsolete.isenabled(repo, obsolete.createmarkersopt)
2080 stripcleanup = not obsolete.isenabled(repo, obsolete.createmarkersopt)
2079
2081
2080 collapsednodes = []
2082 collapsednodes = []
2081 for rev, newrev in sorted(state.items()):
2083 for rev, newrev in sorted(state.items()):
2082 if newrev >= 0 and newrev != rev:
2084 if newrev >= 0 and newrev != rev:
2083 oldnode = tonode(rev)
2085 oldnode = tonode(rev)
2084 newnode = collapsedas or tonode(newrev)
2086 newnode = collapsedas or tonode(newrev)
2085 moves[oldnode] = newnode
2087 moves[oldnode] = newnode
2086 succs = None
2088 succs = None
2087 if rev in skipped:
2089 if rev in skipped:
2088 if stripcleanup or not repo[rev].obsolete():
2090 if stripcleanup or not repo[rev].obsolete():
2089 succs = ()
2091 succs = ()
2090 elif collapsedas:
2092 elif collapsedas:
2091 collapsednodes.append(oldnode)
2093 collapsednodes.append(oldnode)
2092 else:
2094 else:
2093 succs = (newnode,)
2095 succs = (newnode,)
2094 if succs is not None:
2096 if succs is not None:
2095 replacements[(oldnode,)] = succs
2097 replacements[(oldnode,)] = succs
2096 if collapsednodes:
2098 if collapsednodes:
2097 replacements[tuple(collapsednodes)] = (collapsedas,)
2099 replacements[tuple(collapsednodes)] = (collapsedas,)
2098 if fm:
2100 if fm:
2099 hf = fm.hexfunc
2101 hf = fm.hexfunc
2100 fl = fm.formatlist
2102 fl = fm.formatlist
2101 fd = fm.formatdict
2103 fd = fm.formatdict
2102 changes = {}
2104 changes = {}
2103 for oldns, newn in replacements.items():
2105 for oldns, newn in replacements.items():
2104 for oldn in oldns:
2106 for oldn in oldns:
2105 changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
2107 changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
2106 nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
2108 nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
2107 fm.data(nodechanges=nodechanges)
2109 fm.data(nodechanges=nodechanges)
2108 if keepf:
2110 if keepf:
2109 replacements = {}
2111 replacements = {}
2110 scmutil.cleanupnodes(repo, replacements, b'rebase', moves, backup=backup)
2112 scmutil.cleanupnodes(repo, replacements, b'rebase', moves, backup=backup)
2111
2113
2112
2114
2113 def pullrebase(orig, ui, repo, *args, **opts):
2115 def pullrebase(orig, ui, repo, *args, **opts):
2114 """Call rebase after pull if the latter has been invoked with --rebase"""
2116 """Call rebase after pull if the latter has been invoked with --rebase"""
2115 if opts.get('rebase'):
2117 if opts.get('rebase'):
2116 if ui.configbool(b'commands', b'rebase.requiredest'):
2118 if ui.configbool(b'commands', b'rebase.requiredest'):
2117 msg = _(b'rebase destination required by configuration')
2119 msg = _(b'rebase destination required by configuration')
2118 hint = _(b'use hg pull followed by hg rebase -d DEST')
2120 hint = _(b'use hg pull followed by hg rebase -d DEST')
2119 raise error.InputError(msg, hint=hint)
2121 raise error.InputError(msg, hint=hint)
2120
2122
2121 with repo.wlock(), repo.lock():
2123 with repo.wlock(), repo.lock():
2122 if opts.get('update'):
2124 if opts.get('update'):
2123 del opts['update']
2125 del opts['update']
2124 ui.debug(
2126 ui.debug(
2125 b'--update and --rebase are not compatible, ignoring '
2127 b'--update and --rebase are not compatible, ignoring '
2126 b'the update flag\n'
2128 b'the update flag\n'
2127 )
2129 )
2128
2130
2129 cmdutil.checkunfinished(repo, skipmerge=True)
2131 cmdutil.checkunfinished(repo, skipmerge=True)
2130 cmdutil.bailifchanged(
2132 cmdutil.bailifchanged(
2131 repo,
2133 repo,
2132 hint=_(
2134 hint=_(
2133 b'cannot pull with rebase: '
2135 b'cannot pull with rebase: '
2134 b'please commit or shelve your changes first'
2136 b'please commit or shelve your changes first'
2135 ),
2137 ),
2136 )
2138 )
2137
2139
2138 revsprepull = len(repo)
2140 revsprepull = len(repo)
2139 origpostincoming = commands.postincoming
2141 origpostincoming = commands.postincoming
2140
2142
2141 def _dummy(*args, **kwargs):
2143 def _dummy(*args, **kwargs):
2142 pass
2144 pass
2143
2145
2144 commands.postincoming = _dummy
2146 commands.postincoming = _dummy
2145 try:
2147 try:
2146 ret = orig(ui, repo, *args, **opts)
2148 ret = orig(ui, repo, *args, **opts)
2147 finally:
2149 finally:
2148 commands.postincoming = origpostincoming
2150 commands.postincoming = origpostincoming
2149 revspostpull = len(repo)
2151 revspostpull = len(repo)
2150 if revspostpull > revsprepull:
2152 if revspostpull > revsprepull:
2151 # --rev option from pull conflict with rebase own --rev
2153 # --rev option from pull conflict with rebase own --rev
2152 # dropping it
2154 # dropping it
2153 if 'rev' in opts:
2155 if 'rev' in opts:
2154 del opts['rev']
2156 del opts['rev']
2155 # positional argument from pull conflicts with rebase's own
2157 # positional argument from pull conflicts with rebase's own
2156 # --source.
2158 # --source.
2157 if 'source' in opts:
2159 if 'source' in opts:
2158 del opts['source']
2160 del opts['source']
2159 # revsprepull is the len of the repo, not revnum of tip.
2161 # revsprepull is the len of the repo, not revnum of tip.
2160 destspace = list(repo.changelog.revs(start=revsprepull))
2162 destspace = list(repo.changelog.revs(start=revsprepull))
2161 opts['_destspace'] = destspace
2163 opts['_destspace'] = destspace
2162 try:
2164 try:
2163 rebase(ui, repo, **opts)
2165 rebase(ui, repo, **opts)
2164 except error.NoMergeDestAbort:
2166 except error.NoMergeDestAbort:
2165 # we can maybe update instead
2167 # we can maybe update instead
2166 rev, _a, _b = destutil.destupdate(repo)
2168 rev, _a, _b = destutil.destupdate(repo)
2167 if rev == repo[b'.'].rev():
2169 if rev == repo[b'.'].rev():
2168 ui.status(_(b'nothing to rebase\n'))
2170 ui.status(_(b'nothing to rebase\n'))
2169 else:
2171 else:
2170 ui.status(_(b'nothing to rebase - updating instead\n'))
2172 ui.status(_(b'nothing to rebase - updating instead\n'))
2171 # not passing argument to get the bare update behavior
2173 # not passing argument to get the bare update behavior
2172 # with warning and trumpets
2174 # with warning and trumpets
2173 commands.update(ui, repo)
2175 commands.update(ui, repo)
2174 else:
2176 else:
2175 if opts.get('tool'):
2177 if opts.get('tool'):
2176 raise error.InputError(_(b'--tool can only be used with --rebase'))
2178 raise error.InputError(_(b'--tool can only be used with --rebase'))
2177 ret = orig(ui, repo, *args, **opts)
2179 ret = orig(ui, repo, *args, **opts)
2178
2180
2179 return ret
2181 return ret
2180
2182
2181
2183
2182 def _compute_obsolete_sets(repo, rebaseobsrevs, destmap):
2184 def _compute_obsolete_sets(repo, rebaseobsrevs, destmap):
2183 """Figure out what to do about about obsolete revisions
2185 """Figure out what to do about about obsolete revisions
2184
2186
2185 `obsolete_with_successor_in_destination` is a mapping mapping obsolete => successor for all
2187 `obsolete_with_successor_in_destination` is a mapping mapping obsolete => successor for all
2186 obsolete nodes to be rebased given in `rebaseobsrevs`.
2188 obsolete nodes to be rebased given in `rebaseobsrevs`.
2187
2189
2188 `obsolete_with_successor_in_rebase_set` is a set with obsolete revisions,
2190 `obsolete_with_successor_in_rebase_set` is a set with obsolete revisions,
2189 without a successor in destination, that would cause divergence.
2191 without a successor in destination, that would cause divergence.
2190 """
2192 """
2191 obsolete_with_successor_in_destination = {}
2193 obsolete_with_successor_in_destination = {}
2192 obsolete_with_successor_in_rebase_set = set()
2194 obsolete_with_successor_in_rebase_set = set()
2193
2195
2194 cl = repo.changelog
2196 cl = repo.changelog
2195 get_rev = cl.index.get_rev
2197 get_rev = cl.index.get_rev
2196 extinctrevs = set(repo.revs(b'extinct()'))
2198 extinctrevs = set(repo.revs(b'extinct()'))
2197 for srcrev in rebaseobsrevs:
2199 for srcrev in rebaseobsrevs:
2198 srcnode = cl.node(srcrev)
2200 srcnode = cl.node(srcrev)
2199 # XXX: more advanced APIs are required to handle split correctly
2201 # XXX: more advanced APIs are required to handle split correctly
2200 successors = set(obsutil.allsuccessors(repo.obsstore, [srcnode]))
2202 successors = set(obsutil.allsuccessors(repo.obsstore, [srcnode]))
2201 # obsutil.allsuccessors includes node itself
2203 # obsutil.allsuccessors includes node itself
2202 successors.remove(srcnode)
2204 successors.remove(srcnode)
2203 succrevs = {get_rev(s) for s in successors}
2205 succrevs = {get_rev(s) for s in successors}
2204 succrevs.discard(None)
2206 succrevs.discard(None)
2205 if not successors or succrevs.issubset(extinctrevs):
2207 if not successors or succrevs.issubset(extinctrevs):
2206 # no successor, or all successors are extinct
2208 # no successor, or all successors are extinct
2207 obsolete_with_successor_in_destination[srcrev] = None
2209 obsolete_with_successor_in_destination[srcrev] = None
2208 else:
2210 else:
2209 dstrev = destmap[srcrev]
2211 dstrev = destmap[srcrev]
2210 for succrev in succrevs:
2212 for succrev in succrevs:
2211 if cl.isancestorrev(succrev, dstrev):
2213 if cl.isancestorrev(succrev, dstrev):
2212 obsolete_with_successor_in_destination[srcrev] = succrev
2214 obsolete_with_successor_in_destination[srcrev] = succrev
2213 break
2215 break
2214 else:
2216 else:
2215 # If 'srcrev' has a successor in rebase set but none in
2217 # If 'srcrev' has a successor in rebase set but none in
2216 # destination (which would be catched above), we shall skip it
2218 # destination (which would be catched above), we shall skip it
2217 # and its descendants to avoid divergence.
2219 # and its descendants to avoid divergence.
2218 if srcrev in extinctrevs or any(s in destmap for s in succrevs):
2220 if srcrev in extinctrevs or any(s in destmap for s in succrevs):
2219 obsolete_with_successor_in_rebase_set.add(srcrev)
2221 obsolete_with_successor_in_rebase_set.add(srcrev)
2220
2222
2221 return (
2223 return (
2222 obsolete_with_successor_in_destination,
2224 obsolete_with_successor_in_destination,
2223 obsolete_with_successor_in_rebase_set,
2225 obsolete_with_successor_in_rebase_set,
2224 )
2226 )
2225
2227
2226
2228
2227 def abortrebase(ui, repo):
2229 def abortrebase(ui, repo):
2228 with repo.wlock(), repo.lock():
2230 with repo.wlock(), repo.lock():
2229 rbsrt = rebaseruntime(repo, ui)
2231 rbsrt = rebaseruntime(repo, ui)
2230 rbsrt._prepareabortorcontinue(isabort=True)
2232 rbsrt._prepareabortorcontinue(isabort=True)
2231
2233
2232
2234
2233 def continuerebase(ui, repo):
2235 def continuerebase(ui, repo):
2234 with repo.wlock(), repo.lock():
2236 with repo.wlock(), repo.lock():
2235 rbsrt = rebaseruntime(repo, ui)
2237 rbsrt = rebaseruntime(repo, ui)
2236 ms = mergestatemod.mergestate.read(repo)
2238 ms = mergestatemod.mergestate.read(repo)
2237 mergeutil.checkunresolved(ms)
2239 mergeutil.checkunresolved(ms)
2238 retcode = rbsrt._prepareabortorcontinue(isabort=False)
2240 retcode = rbsrt._prepareabortorcontinue(isabort=False)
2239 if retcode is not None:
2241 if retcode is not None:
2240 return retcode
2242 return retcode
2241 rbsrt._performrebase(None)
2243 rbsrt._performrebase(None)
2242 rbsrt._finishrebase()
2244 rbsrt._finishrebase()
2243
2245
2244
2246
2245 def summaryhook(ui, repo):
2247 def summaryhook(ui, repo):
2246 if not repo.vfs.exists(b'rebasestate'):
2248 if not repo.vfs.exists(b'rebasestate'):
2247 return
2249 return
2248 try:
2250 try:
2249 rbsrt = rebaseruntime(repo, ui, {})
2251 rbsrt = rebaseruntime(repo, ui, {})
2250 rbsrt.restorestatus()
2252 rbsrt.restorestatus()
2251 state = rbsrt.state
2253 state = rbsrt.state
2252 except error.RepoLookupError:
2254 except error.RepoLookupError:
2253 # i18n: column positioning for "hg summary"
2255 # i18n: column positioning for "hg summary"
2254 msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
2256 msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
2255 ui.write(msg)
2257 ui.write(msg)
2256 return
2258 return
2257 numrebased = len([i for i in state.values() if i >= 0])
2259 numrebased = len([i for i in state.values() if i >= 0])
2258 # i18n: column positioning for "hg summary"
2260 # i18n: column positioning for "hg summary"
2259 ui.write(
2261 ui.write(
2260 _(b'rebase: %s, %s (rebase --continue)\n')
2262 _(b'rebase: %s, %s (rebase --continue)\n')
2261 % (
2263 % (
2262 ui.label(_(b'%d rebased'), b'rebase.rebased') % numrebased,
2264 ui.label(_(b'%d rebased'), b'rebase.rebased') % numrebased,
2263 ui.label(_(b'%d remaining'), b'rebase.remaining')
2265 ui.label(_(b'%d remaining'), b'rebase.remaining')
2264 % (len(state) - numrebased),
2266 % (len(state) - numrebased),
2265 )
2267 )
2266 )
2268 )
2267
2269
2268
2270
2269 def uisetup(ui):
2271 def uisetup(ui):
2270 # Replace pull with a decorator to provide --rebase option
2272 # Replace pull with a decorator to provide --rebase option
2271 entry = extensions.wrapcommand(commands.table, b'pull', pullrebase)
2273 entry = extensions.wrapcommand(commands.table, b'pull', pullrebase)
2272 entry[1].append(
2274 entry[1].append(
2273 (b'', b'rebase', None, _(b"rebase working directory to branch head"))
2275 (b'', b'rebase', None, _(b"rebase working directory to branch head"))
2274 )
2276 )
2275 entry[1].append((b't', b'tool', b'', _(b"specify merge tool for rebase")))
2277 entry[1].append((b't', b'tool', b'', _(b"specify merge tool for rebase")))
2276 cmdutil.summaryhooks.add(b'rebase', summaryhook)
2278 cmdutil.summaryhooks.add(b'rebase', summaryhook)
2277 statemod.addunfinished(
2279 statemod.addunfinished(
2278 b'rebase',
2280 b'rebase',
2279 fname=b'rebasestate',
2281 fname=b'rebasestate',
2280 stopflag=True,
2282 stopflag=True,
2281 continueflag=True,
2283 continueflag=True,
2282 abortfunc=abortrebase,
2284 abortfunc=abortrebase,
2283 continuefunc=continuerebase,
2285 continuefunc=continuerebase,
2284 )
2286 )
@@ -1,2843 +1,2857 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import functools
9 import functools
10 import re
10 import re
11
11
12 from . import (
12 from . import (
13 encoding,
13 encoding,
14 error,
14 error,
15 )
15 )
16
16
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = b"extension '%s' overwrite config item '%s.%s'"
25 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config=b'warn-config')
27 ui.develwarn(msg, config=b'warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31
31
32 class configitem:
32 class configitem:
33 """represent a known config item
33 """represent a known config item
34
34
35 :section: the official config section where to find this item,
35 :section: the official config section where to find this item,
36 :name: the official name within the section,
36 :name: the official name within the section,
37 :default: default value for this item,
37 :default: default value for this item,
38 :alias: optional list of tuples as alternatives,
38 :alias: optional list of tuples as alternatives,
39 :generic: this is a generic definition, match name using regular expression.
39 :generic: this is a generic definition, match name using regular expression.
40 """
40 """
41
41
42 def __init__(
42 def __init__(
43 self,
43 self,
44 section,
44 section,
45 name,
45 name,
46 default=None,
46 default=None,
47 alias=(),
47 alias=(),
48 generic=False,
48 generic=False,
49 priority=0,
49 priority=0,
50 experimental=False,
50 experimental=False,
51 ):
51 ):
52 self.section = section
52 self.section = section
53 self.name = name
53 self.name = name
54 self.default = default
54 self.default = default
55 self.alias = list(alias)
55 self.alias = list(alias)
56 self.generic = generic
56 self.generic = generic
57 self.priority = priority
57 self.priority = priority
58 self.experimental = experimental
58 self.experimental = experimental
59 self._re = None
59 self._re = None
60 if generic:
60 if generic:
61 self._re = re.compile(self.name)
61 self._re = re.compile(self.name)
62
62
63
63
64 class itemregister(dict):
64 class itemregister(dict):
65 """A specialized dictionary that can handle wild-card selection"""
65 """A specialized dictionary that can handle wild-card selection"""
66
66
67 def __init__(self):
67 def __init__(self):
68 super(itemregister, self).__init__()
68 super(itemregister, self).__init__()
69 self._generics = set()
69 self._generics = set()
70
70
71 def update(self, other):
71 def update(self, other):
72 super(itemregister, self).update(other)
72 super(itemregister, self).update(other)
73 self._generics.update(other._generics)
73 self._generics.update(other._generics)
74
74
75 def __setitem__(self, key, item):
75 def __setitem__(self, key, item):
76 super(itemregister, self).__setitem__(key, item)
76 super(itemregister, self).__setitem__(key, item)
77 if item.generic:
77 if item.generic:
78 self._generics.add(item)
78 self._generics.add(item)
79
79
80 def get(self, key):
80 def get(self, key):
81 baseitem = super(itemregister, self).get(key)
81 baseitem = super(itemregister, self).get(key)
82 if baseitem is not None and not baseitem.generic:
82 if baseitem is not None and not baseitem.generic:
83 return baseitem
83 return baseitem
84
84
85 # search for a matching generic item
85 # search for a matching generic item
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 for item in generics:
87 for item in generics:
88 # we use 'match' instead of 'search' to make the matching simpler
88 # we use 'match' instead of 'search' to make the matching simpler
89 # for people unfamiliar with regular expression. Having the match
89 # for people unfamiliar with regular expression. Having the match
90 # rooted to the start of the string will produce less surprising
90 # rooted to the start of the string will produce less surprising
91 # result for user writing simple regex for sub-attribute.
91 # result for user writing simple regex for sub-attribute.
92 #
92 #
93 # For example using "color\..*" match produces an unsurprising
93 # For example using "color\..*" match produces an unsurprising
94 # result, while using search could suddenly match apparently
94 # result, while using search could suddenly match apparently
95 # unrelated configuration that happens to contains "color."
95 # unrelated configuration that happens to contains "color."
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # some match to avoid the need to prefix most pattern with "^".
97 # some match to avoid the need to prefix most pattern with "^".
98 # The "^" seems more error prone.
98 # The "^" seems more error prone.
99 if item._re.match(key):
99 if item._re.match(key):
100 return item
100 return item
101
101
102 return None
102 return None
103
103
104
104
105 coreitems = {}
105 coreitems = {}
106
106
107
107
108 def _register(configtable, *args, **kwargs):
108 def _register(configtable, *args, **kwargs):
109 item = configitem(*args, **kwargs)
109 item = configitem(*args, **kwargs)
110 section = configtable.setdefault(item.section, itemregister())
110 section = configtable.setdefault(item.section, itemregister())
111 if item.name in section:
111 if item.name in section:
112 msg = b"duplicated config item registration for '%s.%s'"
112 msg = b"duplicated config item registration for '%s.%s'"
113 raise error.ProgrammingError(msg % (item.section, item.name))
113 raise error.ProgrammingError(msg % (item.section, item.name))
114 section[item.name] = item
114 section[item.name] = item
115
115
116
116
117 # special value for case where the default is derived from other values
117 # special value for case where the default is derived from other values
118 dynamicdefault = object()
118 dynamicdefault = object()
119
119
120 # Registering actual config items
120 # Registering actual config items
121
121
122
122
123 def getitemregister(configtable):
123 def getitemregister(configtable):
124 f = functools.partial(_register, configtable)
124 f = functools.partial(_register, configtable)
125 # export pseudo enum as configitem.*
125 # export pseudo enum as configitem.*
126 f.dynamicdefault = dynamicdefault
126 f.dynamicdefault = dynamicdefault
127 return f
127 return f
128
128
129
129
130 coreconfigitem = getitemregister(coreitems)
130 coreconfigitem = getitemregister(coreitems)
131
131
132
132
133 def _registerdiffopts(section, configprefix=b''):
133 def _registerdiffopts(section, configprefix=b''):
134 coreconfigitem(
134 coreconfigitem(
135 section,
135 section,
136 configprefix + b'nodates',
136 configprefix + b'nodates',
137 default=False,
137 default=False,
138 )
138 )
139 coreconfigitem(
139 coreconfigitem(
140 section,
140 section,
141 configprefix + b'showfunc',
141 configprefix + b'showfunc',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(
144 coreconfigitem(
145 section,
145 section,
146 configprefix + b'unified',
146 configprefix + b'unified',
147 default=None,
147 default=None,
148 )
148 )
149 coreconfigitem(
149 coreconfigitem(
150 section,
150 section,
151 configprefix + b'git',
151 configprefix + b'git',
152 default=False,
152 default=False,
153 )
153 )
154 coreconfigitem(
154 coreconfigitem(
155 section,
155 section,
156 configprefix + b'ignorews',
156 configprefix + b'ignorews',
157 default=False,
157 default=False,
158 )
158 )
159 coreconfigitem(
159 coreconfigitem(
160 section,
160 section,
161 configprefix + b'ignorewsamount',
161 configprefix + b'ignorewsamount',
162 default=False,
162 default=False,
163 )
163 )
164 coreconfigitem(
164 coreconfigitem(
165 section,
165 section,
166 configprefix + b'ignoreblanklines',
166 configprefix + b'ignoreblanklines',
167 default=False,
167 default=False,
168 )
168 )
169 coreconfigitem(
169 coreconfigitem(
170 section,
170 section,
171 configprefix + b'ignorewseol',
171 configprefix + b'ignorewseol',
172 default=False,
172 default=False,
173 )
173 )
174 coreconfigitem(
174 coreconfigitem(
175 section,
175 section,
176 configprefix + b'nobinary',
176 configprefix + b'nobinary',
177 default=False,
177 default=False,
178 )
178 )
179 coreconfigitem(
179 coreconfigitem(
180 section,
180 section,
181 configprefix + b'noprefix',
181 configprefix + b'noprefix',
182 default=False,
182 default=False,
183 )
183 )
184 coreconfigitem(
184 coreconfigitem(
185 section,
185 section,
186 configprefix + b'word-diff',
186 configprefix + b'word-diff',
187 default=False,
187 default=False,
188 )
188 )
189
189
190
190
191 coreconfigitem(
191 coreconfigitem(
192 b'alias',
192 b'alias',
193 b'.*',
193 b'.*',
194 default=dynamicdefault,
194 default=dynamicdefault,
195 generic=True,
195 generic=True,
196 )
196 )
197 coreconfigitem(
197 coreconfigitem(
198 b'auth',
198 b'auth',
199 b'cookiefile',
199 b'cookiefile',
200 default=None,
200 default=None,
201 )
201 )
202 _registerdiffopts(section=b'annotate')
202 _registerdiffopts(section=b'annotate')
203 # bookmarks.pushing: internal hack for discovery
203 # bookmarks.pushing: internal hack for discovery
204 coreconfigitem(
204 coreconfigitem(
205 b'bookmarks',
205 b'bookmarks',
206 b'pushing',
206 b'pushing',
207 default=list,
207 default=list,
208 )
208 )
209 # bundle.mainreporoot: internal hack for bundlerepo
209 # bundle.mainreporoot: internal hack for bundlerepo
210 coreconfigitem(
210 coreconfigitem(
211 b'bundle',
211 b'bundle',
212 b'mainreporoot',
212 b'mainreporoot',
213 default=b'',
213 default=b'',
214 )
214 )
215 coreconfigitem(
215 coreconfigitem(
216 b'censor',
216 b'censor',
217 b'policy',
217 b'policy',
218 default=b'abort',
218 default=b'abort',
219 experimental=True,
219 experimental=True,
220 )
220 )
221 coreconfigitem(
221 coreconfigitem(
222 b'chgserver',
222 b'chgserver',
223 b'idletimeout',
223 b'idletimeout',
224 default=3600,
224 default=3600,
225 )
225 )
226 coreconfigitem(
226 coreconfigitem(
227 b'chgserver',
227 b'chgserver',
228 b'skiphash',
228 b'skiphash',
229 default=False,
229 default=False,
230 )
230 )
231 coreconfigitem(
231 coreconfigitem(
232 b'cmdserver',
232 b'cmdserver',
233 b'log',
233 b'log',
234 default=None,
234 default=None,
235 )
235 )
236 coreconfigitem(
236 coreconfigitem(
237 b'cmdserver',
237 b'cmdserver',
238 b'max-log-files',
238 b'max-log-files',
239 default=7,
239 default=7,
240 )
240 )
241 coreconfigitem(
241 coreconfigitem(
242 b'cmdserver',
242 b'cmdserver',
243 b'max-log-size',
243 b'max-log-size',
244 default=b'1 MB',
244 default=b'1 MB',
245 )
245 )
246 coreconfigitem(
246 coreconfigitem(
247 b'cmdserver',
247 b'cmdserver',
248 b'max-repo-cache',
248 b'max-repo-cache',
249 default=0,
249 default=0,
250 experimental=True,
250 experimental=True,
251 )
251 )
252 coreconfigitem(
252 coreconfigitem(
253 b'cmdserver',
253 b'cmdserver',
254 b'message-encodings',
254 b'message-encodings',
255 default=list,
255 default=list,
256 )
256 )
257 coreconfigitem(
257 coreconfigitem(
258 b'cmdserver',
258 b'cmdserver',
259 b'track-log',
259 b'track-log',
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 )
261 )
262 coreconfigitem(
262 coreconfigitem(
263 b'cmdserver',
263 b'cmdserver',
264 b'shutdown-on-interrupt',
264 b'shutdown-on-interrupt',
265 default=True,
265 default=True,
266 )
266 )
267 coreconfigitem(
267 coreconfigitem(
268 b'color',
268 b'color',
269 b'.*',
269 b'.*',
270 default=None,
270 default=None,
271 generic=True,
271 generic=True,
272 )
272 )
273 coreconfigitem(
273 coreconfigitem(
274 b'color',
274 b'color',
275 b'mode',
275 b'mode',
276 default=b'auto',
276 default=b'auto',
277 )
277 )
278 coreconfigitem(
278 coreconfigitem(
279 b'color',
279 b'color',
280 b'pagermode',
280 b'pagermode',
281 default=dynamicdefault,
281 default=dynamicdefault,
282 )
282 )
283 coreconfigitem(
283 coreconfigitem(
284 b'command-templates',
284 b'command-templates',
285 b'graphnode',
285 b'graphnode',
286 default=None,
286 default=None,
287 alias=[(b'ui', b'graphnodetemplate')],
287 alias=[(b'ui', b'graphnodetemplate')],
288 )
288 )
289 coreconfigitem(
289 coreconfigitem(
290 b'command-templates',
290 b'command-templates',
291 b'log',
291 b'log',
292 default=None,
292 default=None,
293 alias=[(b'ui', b'logtemplate')],
293 alias=[(b'ui', b'logtemplate')],
294 )
294 )
295 coreconfigitem(
295 coreconfigitem(
296 b'command-templates',
296 b'command-templates',
297 b'mergemarker',
297 b'mergemarker',
298 default=(
298 default=(
299 b'{node|short} '
299 b'{node|short} '
300 b'{ifeq(tags, "tip", "", '
300 b'{ifeq(tags, "tip", "", '
301 b'ifeq(tags, "", "", "{tags} "))}'
301 b'ifeq(tags, "", "", "{tags} "))}'
302 b'{if(bookmarks, "{bookmarks} ")}'
302 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'- {author|user}: {desc|firstline}'
304 b'- {author|user}: {desc|firstline}'
305 ),
305 ),
306 alias=[(b'ui', b'mergemarkertemplate')],
306 alias=[(b'ui', b'mergemarkertemplate')],
307 )
307 )
308 coreconfigitem(
308 coreconfigitem(
309 b'command-templates',
309 b'command-templates',
310 b'pre-merge-tool-output',
310 b'pre-merge-tool-output',
311 default=None,
311 default=None,
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 )
313 )
314 coreconfigitem(
314 coreconfigitem(
315 b'command-templates',
315 b'command-templates',
316 b'oneline-summary',
316 b'oneline-summary',
317 default=None,
317 default=None,
318 )
318 )
319 coreconfigitem(
319 coreconfigitem(
320 b'command-templates',
320 b'command-templates',
321 b'oneline-summary.*',
321 b'oneline-summary.*',
322 default=dynamicdefault,
322 default=dynamicdefault,
323 generic=True,
323 generic=True,
324 )
324 )
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 coreconfigitem(
326 coreconfigitem(
327 b'commands',
327 b'commands',
328 b'commit.post-status',
328 b'commit.post-status',
329 default=False,
329 default=False,
330 )
330 )
331 coreconfigitem(
331 coreconfigitem(
332 b'commands',
332 b'commands',
333 b'grep.all-files',
333 b'grep.all-files',
334 default=False,
334 default=False,
335 experimental=True,
335 experimental=True,
336 )
336 )
337 coreconfigitem(
337 coreconfigitem(
338 b'commands',
338 b'commands',
339 b'merge.require-rev',
339 b'merge.require-rev',
340 default=False,
340 default=False,
341 )
341 )
342 coreconfigitem(
342 coreconfigitem(
343 b'commands',
343 b'commands',
344 b'push.require-revs',
344 b'push.require-revs',
345 default=False,
345 default=False,
346 )
346 )
347 coreconfigitem(
347 coreconfigitem(
348 b'commands',
348 b'commands',
349 b'resolve.confirm',
349 b'resolve.confirm',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem(
352 coreconfigitem(
353 b'commands',
353 b'commands',
354 b'resolve.explicit-re-merge',
354 b'resolve.explicit-re-merge',
355 default=False,
355 default=False,
356 )
356 )
357 coreconfigitem(
357 coreconfigitem(
358 b'commands',
358 b'commands',
359 b'resolve.mark-check',
359 b'resolve.mark-check',
360 default=b'none',
360 default=b'none',
361 )
361 )
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 coreconfigitem(
363 coreconfigitem(
364 b'commands',
364 b'commands',
365 b'show.aliasprefix',
365 b'show.aliasprefix',
366 default=list,
366 default=list,
367 )
367 )
368 coreconfigitem(
368 coreconfigitem(
369 b'commands',
369 b'commands',
370 b'status.relative',
370 b'status.relative',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem(
373 coreconfigitem(
374 b'commands',
374 b'commands',
375 b'status.skipstates',
375 b'status.skipstates',
376 default=[],
376 default=[],
377 experimental=True,
377 experimental=True,
378 )
378 )
379 coreconfigitem(
379 coreconfigitem(
380 b'commands',
380 b'commands',
381 b'status.terse',
381 b'status.terse',
382 default=b'',
382 default=b'',
383 )
383 )
384 coreconfigitem(
384 coreconfigitem(
385 b'commands',
385 b'commands',
386 b'status.verbose',
386 b'status.verbose',
387 default=False,
387 default=False,
388 )
388 )
389 coreconfigitem(
389 coreconfigitem(
390 b'commands',
390 b'commands',
391 b'update.check',
391 b'update.check',
392 default=None,
392 default=None,
393 )
393 )
394 coreconfigitem(
394 coreconfigitem(
395 b'commands',
395 b'commands',
396 b'update.requiredest',
396 b'update.requiredest',
397 default=False,
397 default=False,
398 )
398 )
399 coreconfigitem(
399 coreconfigitem(
400 b'committemplate',
400 b'committemplate',
401 b'.*',
401 b'.*',
402 default=None,
402 default=None,
403 generic=True,
403 generic=True,
404 )
404 )
405 coreconfigitem(
405 coreconfigitem(
406 b'convert',
406 b'convert',
407 b'bzr.saverev',
407 b'bzr.saverev',
408 default=True,
408 default=True,
409 )
409 )
410 coreconfigitem(
410 coreconfigitem(
411 b'convert',
411 b'convert',
412 b'cvsps.cache',
412 b'cvsps.cache',
413 default=True,
413 default=True,
414 )
414 )
415 coreconfigitem(
415 coreconfigitem(
416 b'convert',
416 b'convert',
417 b'cvsps.fuzz',
417 b'cvsps.fuzz',
418 default=60,
418 default=60,
419 )
419 )
420 coreconfigitem(
420 coreconfigitem(
421 b'convert',
421 b'convert',
422 b'cvsps.logencoding',
422 b'cvsps.logencoding',
423 default=None,
423 default=None,
424 )
424 )
425 coreconfigitem(
425 coreconfigitem(
426 b'convert',
426 b'convert',
427 b'cvsps.mergefrom',
427 b'cvsps.mergefrom',
428 default=None,
428 default=None,
429 )
429 )
430 coreconfigitem(
430 coreconfigitem(
431 b'convert',
431 b'convert',
432 b'cvsps.mergeto',
432 b'cvsps.mergeto',
433 default=None,
433 default=None,
434 )
434 )
435 coreconfigitem(
435 coreconfigitem(
436 b'convert',
436 b'convert',
437 b'git.committeractions',
437 b'git.committeractions',
438 default=lambda: [b'messagedifferent'],
438 default=lambda: [b'messagedifferent'],
439 )
439 )
440 coreconfigitem(
440 coreconfigitem(
441 b'convert',
441 b'convert',
442 b'git.extrakeys',
442 b'git.extrakeys',
443 default=list,
443 default=list,
444 )
444 )
445 coreconfigitem(
445 coreconfigitem(
446 b'convert',
446 b'convert',
447 b'git.findcopiesharder',
447 b'git.findcopiesharder',
448 default=False,
448 default=False,
449 )
449 )
450 coreconfigitem(
450 coreconfigitem(
451 b'convert',
451 b'convert',
452 b'git.remoteprefix',
452 b'git.remoteprefix',
453 default=b'remote',
453 default=b'remote',
454 )
454 )
455 coreconfigitem(
455 coreconfigitem(
456 b'convert',
456 b'convert',
457 b'git.renamelimit',
457 b'git.renamelimit',
458 default=400,
458 default=400,
459 )
459 )
460 coreconfigitem(
460 coreconfigitem(
461 b'convert',
461 b'convert',
462 b'git.saverev',
462 b'git.saverev',
463 default=True,
463 default=True,
464 )
464 )
465 coreconfigitem(
465 coreconfigitem(
466 b'convert',
466 b'convert',
467 b'git.similarity',
467 b'git.similarity',
468 default=50,
468 default=50,
469 )
469 )
470 coreconfigitem(
470 coreconfigitem(
471 b'convert',
471 b'convert',
472 b'git.skipsubmodules',
472 b'git.skipsubmodules',
473 default=False,
473 default=False,
474 )
474 )
475 coreconfigitem(
475 coreconfigitem(
476 b'convert',
476 b'convert',
477 b'hg.clonebranches',
477 b'hg.clonebranches',
478 default=False,
478 default=False,
479 )
479 )
480 coreconfigitem(
480 coreconfigitem(
481 b'convert',
481 b'convert',
482 b'hg.ignoreerrors',
482 b'hg.ignoreerrors',
483 default=False,
483 default=False,
484 )
484 )
485 coreconfigitem(
485 coreconfigitem(
486 b'convert',
486 b'convert',
487 b'hg.preserve-hash',
487 b'hg.preserve-hash',
488 default=False,
488 default=False,
489 )
489 )
490 coreconfigitem(
490 coreconfigitem(
491 b'convert',
491 b'convert',
492 b'hg.revs',
492 b'hg.revs',
493 default=None,
493 default=None,
494 )
494 )
495 coreconfigitem(
495 coreconfigitem(
496 b'convert',
496 b'convert',
497 b'hg.saverev',
497 b'hg.saverev',
498 default=False,
498 default=False,
499 )
499 )
500 coreconfigitem(
500 coreconfigitem(
501 b'convert',
501 b'convert',
502 b'hg.sourcename',
502 b'hg.sourcename',
503 default=None,
503 default=None,
504 )
504 )
505 coreconfigitem(
505 coreconfigitem(
506 b'convert',
506 b'convert',
507 b'hg.startrev',
507 b'hg.startrev',
508 default=None,
508 default=None,
509 )
509 )
510 coreconfigitem(
510 coreconfigitem(
511 b'convert',
511 b'convert',
512 b'hg.tagsbranch',
512 b'hg.tagsbranch',
513 default=b'default',
513 default=b'default',
514 )
514 )
515 coreconfigitem(
515 coreconfigitem(
516 b'convert',
516 b'convert',
517 b'hg.usebranchnames',
517 b'hg.usebranchnames',
518 default=True,
518 default=True,
519 )
519 )
520 coreconfigitem(
520 coreconfigitem(
521 b'convert',
521 b'convert',
522 b'ignoreancestorcheck',
522 b'ignoreancestorcheck',
523 default=False,
523 default=False,
524 experimental=True,
524 experimental=True,
525 )
525 )
526 coreconfigitem(
526 coreconfigitem(
527 b'convert',
527 b'convert',
528 b'localtimezone',
528 b'localtimezone',
529 default=False,
529 default=False,
530 )
530 )
531 coreconfigitem(
531 coreconfigitem(
532 b'convert',
532 b'convert',
533 b'p4.encoding',
533 b'p4.encoding',
534 default=dynamicdefault,
534 default=dynamicdefault,
535 )
535 )
536 coreconfigitem(
536 coreconfigitem(
537 b'convert',
537 b'convert',
538 b'p4.startrev',
538 b'p4.startrev',
539 default=0,
539 default=0,
540 )
540 )
541 coreconfigitem(
541 coreconfigitem(
542 b'convert',
542 b'convert',
543 b'skiptags',
543 b'skiptags',
544 default=False,
544 default=False,
545 )
545 )
546 coreconfigitem(
546 coreconfigitem(
547 b'convert',
547 b'convert',
548 b'svn.debugsvnlog',
548 b'svn.debugsvnlog',
549 default=True,
549 default=True,
550 )
550 )
551 coreconfigitem(
551 coreconfigitem(
552 b'convert',
552 b'convert',
553 b'svn.trunk',
553 b'svn.trunk',
554 default=None,
554 default=None,
555 )
555 )
556 coreconfigitem(
556 coreconfigitem(
557 b'convert',
557 b'convert',
558 b'svn.tags',
558 b'svn.tags',
559 default=None,
559 default=None,
560 )
560 )
561 coreconfigitem(
561 coreconfigitem(
562 b'convert',
562 b'convert',
563 b'svn.branches',
563 b'svn.branches',
564 default=None,
564 default=None,
565 )
565 )
566 coreconfigitem(
566 coreconfigitem(
567 b'convert',
567 b'convert',
568 b'svn.startrev',
568 b'svn.startrev',
569 default=0,
569 default=0,
570 )
570 )
571 coreconfigitem(
571 coreconfigitem(
572 b'convert',
572 b'convert',
573 b'svn.dangerous-set-commit-dates',
573 b'svn.dangerous-set-commit-dates',
574 default=False,
574 default=False,
575 )
575 )
576 coreconfigitem(
576 coreconfigitem(
577 b'debug',
577 b'debug',
578 b'dirstate.delaywrite',
578 b'dirstate.delaywrite',
579 default=0,
579 default=0,
580 )
580 )
581 coreconfigitem(
581 coreconfigitem(
582 b'debug',
582 b'debug',
583 b'revlog.verifyposition.changelog',
583 b'revlog.verifyposition.changelog',
584 default=b'',
584 default=b'',
585 )
585 )
586 coreconfigitem(
586 coreconfigitem(
587 b'debug',
587 b'debug',
588 b'revlog.debug-delta',
588 b'revlog.debug-delta',
589 default=False,
589 default=False,
590 )
590 )
591 coreconfigitem(
591 coreconfigitem(
592 b'defaults',
592 b'defaults',
593 b'.*',
593 b'.*',
594 default=None,
594 default=None,
595 generic=True,
595 generic=True,
596 )
596 )
597 coreconfigitem(
597 coreconfigitem(
598 b'devel',
598 b'devel',
599 b'all-warnings',
599 b'all-warnings',
600 default=False,
600 default=False,
601 )
601 )
602 coreconfigitem(
602 coreconfigitem(
603 b'devel',
603 b'devel',
604 b'bundle2.debug',
604 b'bundle2.debug',
605 default=False,
605 default=False,
606 )
606 )
607 coreconfigitem(
607 coreconfigitem(
608 b'devel',
608 b'devel',
609 b'bundle.delta',
609 b'bundle.delta',
610 default=b'',
610 default=b'',
611 )
611 )
612 coreconfigitem(
612 coreconfigitem(
613 b'devel',
613 b'devel',
614 b'cache-vfs',
614 b'cache-vfs',
615 default=None,
615 default=None,
616 )
616 )
617 coreconfigitem(
617 coreconfigitem(
618 b'devel',
618 b'devel',
619 b'check-locks',
619 b'check-locks',
620 default=False,
620 default=False,
621 )
621 )
622 coreconfigitem(
622 coreconfigitem(
623 b'devel',
623 b'devel',
624 b'check-relroot',
624 b'check-relroot',
625 default=False,
625 default=False,
626 )
626 )
627 # Track copy information for all file, not just "added" one (very slow)
627 # Track copy information for all file, not just "added" one (very slow)
628 coreconfigitem(
628 coreconfigitem(
629 b'devel',
629 b'devel',
630 b'copy-tracing.trace-all-files',
630 b'copy-tracing.trace-all-files',
631 default=False,
631 default=False,
632 )
632 )
633 coreconfigitem(
633 coreconfigitem(
634 b'devel',
634 b'devel',
635 b'default-date',
635 b'default-date',
636 default=None,
636 default=None,
637 )
637 )
638 coreconfigitem(
638 coreconfigitem(
639 b'devel',
639 b'devel',
640 b'deprec-warn',
640 b'deprec-warn',
641 default=False,
641 default=False,
642 )
642 )
643 coreconfigitem(
643 coreconfigitem(
644 b'devel',
644 b'devel',
645 b'disableloaddefaultcerts',
645 b'disableloaddefaultcerts',
646 default=False,
646 default=False,
647 )
647 )
648 coreconfigitem(
648 coreconfigitem(
649 b'devel',
649 b'devel',
650 b'warn-empty-changegroup',
650 b'warn-empty-changegroup',
651 default=False,
651 default=False,
652 )
652 )
653 coreconfigitem(
653 coreconfigitem(
654 b'devel',
654 b'devel',
655 b'legacy.exchange',
655 b'legacy.exchange',
656 default=list,
656 default=list,
657 )
657 )
658 # When True, revlogs use a special reference version of the nodemap, that is not
658 # When True, revlogs use a special reference version of the nodemap, that is not
659 # performant but is "known" to behave properly.
659 # performant but is "known" to behave properly.
660 coreconfigitem(
660 coreconfigitem(
661 b'devel',
661 b'devel',
662 b'persistent-nodemap',
662 b'persistent-nodemap',
663 default=False,
663 default=False,
664 )
664 )
665 coreconfigitem(
665 coreconfigitem(
666 b'devel',
666 b'devel',
667 b'servercafile',
667 b'servercafile',
668 default=b'',
668 default=b'',
669 )
669 )
670 coreconfigitem(
670 coreconfigitem(
671 b'devel',
671 b'devel',
672 b'serverexactprotocol',
672 b'serverexactprotocol',
673 default=b'',
673 default=b'',
674 )
674 )
675 coreconfigitem(
675 coreconfigitem(
676 b'devel',
676 b'devel',
677 b'serverrequirecert',
677 b'serverrequirecert',
678 default=False,
678 default=False,
679 )
679 )
680 coreconfigitem(
680 coreconfigitem(
681 b'devel',
681 b'devel',
682 b'strip-obsmarkers',
682 b'strip-obsmarkers',
683 default=True,
683 default=True,
684 )
684 )
685 coreconfigitem(
685 coreconfigitem(
686 b'devel',
686 b'devel',
687 b'warn-config',
687 b'warn-config',
688 default=None,
688 default=None,
689 )
689 )
690 coreconfigitem(
690 coreconfigitem(
691 b'devel',
691 b'devel',
692 b'warn-config-default',
692 b'warn-config-default',
693 default=None,
693 default=None,
694 )
694 )
695 coreconfigitem(
695 coreconfigitem(
696 b'devel',
696 b'devel',
697 b'user.obsmarker',
697 b'user.obsmarker',
698 default=None,
698 default=None,
699 )
699 )
700 coreconfigitem(
700 coreconfigitem(
701 b'devel',
701 b'devel',
702 b'warn-config-unknown',
702 b'warn-config-unknown',
703 default=None,
703 default=None,
704 )
704 )
705 coreconfigitem(
705 coreconfigitem(
706 b'devel',
706 b'devel',
707 b'debug.copies',
707 b'debug.copies',
708 default=False,
708 default=False,
709 )
709 )
710 coreconfigitem(
710 coreconfigitem(
711 b'devel',
711 b'devel',
712 b'copy-tracing.multi-thread',
712 b'copy-tracing.multi-thread',
713 default=True,
713 default=True,
714 )
714 )
715 coreconfigitem(
715 coreconfigitem(
716 b'devel',
716 b'devel',
717 b'debug.extensions',
717 b'debug.extensions',
718 default=False,
718 default=False,
719 )
719 )
720 coreconfigitem(
720 coreconfigitem(
721 b'devel',
721 b'devel',
722 b'debug.repo-filters',
722 b'debug.repo-filters',
723 default=False,
723 default=False,
724 )
724 )
725 coreconfigitem(
725 coreconfigitem(
726 b'devel',
726 b'devel',
727 b'debug.peer-request',
727 b'debug.peer-request',
728 default=False,
728 default=False,
729 )
729 )
730 # If discovery.exchange-heads is False, the discovery will not start with
730 # If discovery.exchange-heads is False, the discovery will not start with
731 # remote head fetching and local head querying.
731 # remote head fetching and local head querying.
732 coreconfigitem(
732 coreconfigitem(
733 b'devel',
733 b'devel',
734 b'discovery.exchange-heads',
734 b'discovery.exchange-heads',
735 default=True,
735 default=True,
736 )
736 )
737 # If discovery.grow-sample is False, the sample size used in set discovery will
737 # If discovery.grow-sample is False, the sample size used in set discovery will
738 # not be increased through the process
738 # not be increased through the process
739 coreconfigitem(
739 coreconfigitem(
740 b'devel',
740 b'devel',
741 b'discovery.grow-sample',
741 b'discovery.grow-sample',
742 default=True,
742 default=True,
743 )
743 )
744 # When discovery.grow-sample.dynamic is True, the default, the sample size is
744 # When discovery.grow-sample.dynamic is True, the default, the sample size is
745 # adapted to the shape of the undecided set (it is set to the max of:
745 # adapted to the shape of the undecided set (it is set to the max of:
746 # <target-size>, len(roots(undecided)), len(heads(undecided)
746 # <target-size>, len(roots(undecided)), len(heads(undecided)
747 coreconfigitem(
747 coreconfigitem(
748 b'devel',
748 b'devel',
749 b'discovery.grow-sample.dynamic',
749 b'discovery.grow-sample.dynamic',
750 default=True,
750 default=True,
751 )
751 )
752 # discovery.grow-sample.rate control the rate at which the sample grow
752 # discovery.grow-sample.rate control the rate at which the sample grow
753 coreconfigitem(
753 coreconfigitem(
754 b'devel',
754 b'devel',
755 b'discovery.grow-sample.rate',
755 b'discovery.grow-sample.rate',
756 default=1.05,
756 default=1.05,
757 )
757 )
758 # If discovery.randomize is False, random sampling during discovery are
758 # If discovery.randomize is False, random sampling during discovery are
759 # deterministic. It is meant for integration tests.
759 # deterministic. It is meant for integration tests.
760 coreconfigitem(
760 coreconfigitem(
761 b'devel',
761 b'devel',
762 b'discovery.randomize',
762 b'discovery.randomize',
763 default=True,
763 default=True,
764 )
764 )
765 # Control the initial size of the discovery sample
765 # Control the initial size of the discovery sample
766 coreconfigitem(
766 coreconfigitem(
767 b'devel',
767 b'devel',
768 b'discovery.sample-size',
768 b'discovery.sample-size',
769 default=200,
769 default=200,
770 )
770 )
771 # Control the initial size of the discovery for initial change
771 # Control the initial size of the discovery for initial change
772 coreconfigitem(
772 coreconfigitem(
773 b'devel',
773 b'devel',
774 b'discovery.sample-size.initial',
774 b'discovery.sample-size.initial',
775 default=100,
775 default=100,
776 )
776 )
777 _registerdiffopts(section=b'diff')
777 _registerdiffopts(section=b'diff')
778 coreconfigitem(
778 coreconfigitem(
779 b'diff',
779 b'diff',
780 b'merge',
780 b'merge',
781 default=False,
781 default=False,
782 experimental=True,
782 experimental=True,
783 )
783 )
784 coreconfigitem(
784 coreconfigitem(
785 b'email',
785 b'email',
786 b'bcc',
786 b'bcc',
787 default=None,
787 default=None,
788 )
788 )
789 coreconfigitem(
789 coreconfigitem(
790 b'email',
790 b'email',
791 b'cc',
791 b'cc',
792 default=None,
792 default=None,
793 )
793 )
794 coreconfigitem(
794 coreconfigitem(
795 b'email',
795 b'email',
796 b'charsets',
796 b'charsets',
797 default=list,
797 default=list,
798 )
798 )
799 coreconfigitem(
799 coreconfigitem(
800 b'email',
800 b'email',
801 b'from',
801 b'from',
802 default=None,
802 default=None,
803 )
803 )
804 coreconfigitem(
804 coreconfigitem(
805 b'email',
805 b'email',
806 b'method',
806 b'method',
807 default=b'smtp',
807 default=b'smtp',
808 )
808 )
809 coreconfigitem(
809 coreconfigitem(
810 b'email',
810 b'email',
811 b'reply-to',
811 b'reply-to',
812 default=None,
812 default=None,
813 )
813 )
814 coreconfigitem(
814 coreconfigitem(
815 b'email',
815 b'email',
816 b'to',
816 b'to',
817 default=None,
817 default=None,
818 )
818 )
819 coreconfigitem(
819 coreconfigitem(
820 b'experimental',
820 b'experimental',
821 b'archivemetatemplate',
821 b'archivemetatemplate',
822 default=dynamicdefault,
822 default=dynamicdefault,
823 )
823 )
824 coreconfigitem(
824 coreconfigitem(
825 b'experimental',
825 b'experimental',
826 b'auto-publish',
826 b'auto-publish',
827 default=b'publish',
827 default=b'publish',
828 )
828 )
829 coreconfigitem(
829 coreconfigitem(
830 b'experimental',
830 b'experimental',
831 b'bundle-phases',
831 b'bundle-phases',
832 default=False,
832 default=False,
833 )
833 )
834 coreconfigitem(
834 coreconfigitem(
835 b'experimental',
835 b'experimental',
836 b'bundle2-advertise',
836 b'bundle2-advertise',
837 default=True,
837 default=True,
838 )
838 )
839 coreconfigitem(
839 coreconfigitem(
840 b'experimental',
840 b'experimental',
841 b'bundle2-output-capture',
841 b'bundle2-output-capture',
842 default=False,
842 default=False,
843 )
843 )
844 coreconfigitem(
844 coreconfigitem(
845 b'experimental',
845 b'experimental',
846 b'bundle2.pushback',
846 b'bundle2.pushback',
847 default=False,
847 default=False,
848 )
848 )
849 coreconfigitem(
849 coreconfigitem(
850 b'experimental',
850 b'experimental',
851 b'bundle2lazylocking',
851 b'bundle2lazylocking',
852 default=False,
852 default=False,
853 )
853 )
854 coreconfigitem(
854 coreconfigitem(
855 b'experimental',
855 b'experimental',
856 b'bundlecomplevel',
856 b'bundlecomplevel',
857 default=None,
857 default=None,
858 )
858 )
859 coreconfigitem(
859 coreconfigitem(
860 b'experimental',
860 b'experimental',
861 b'bundlecomplevel.bzip2',
861 b'bundlecomplevel.bzip2',
862 default=None,
862 default=None,
863 )
863 )
864 coreconfigitem(
864 coreconfigitem(
865 b'experimental',
865 b'experimental',
866 b'bundlecomplevel.gzip',
866 b'bundlecomplevel.gzip',
867 default=None,
867 default=None,
868 )
868 )
869 coreconfigitem(
869 coreconfigitem(
870 b'experimental',
870 b'experimental',
871 b'bundlecomplevel.none',
871 b'bundlecomplevel.none',
872 default=None,
872 default=None,
873 )
873 )
874 coreconfigitem(
874 coreconfigitem(
875 b'experimental',
875 b'experimental',
876 b'bundlecomplevel.zstd',
876 b'bundlecomplevel.zstd',
877 default=None,
877 default=None,
878 )
878 )
879 coreconfigitem(
879 coreconfigitem(
880 b'experimental',
880 b'experimental',
881 b'bundlecompthreads',
881 b'bundlecompthreads',
882 default=None,
882 default=None,
883 )
883 )
884 coreconfigitem(
884 coreconfigitem(
885 b'experimental',
885 b'experimental',
886 b'bundlecompthreads.bzip2',
886 b'bundlecompthreads.bzip2',
887 default=None,
887 default=None,
888 )
888 )
889 coreconfigitem(
889 coreconfigitem(
890 b'experimental',
890 b'experimental',
891 b'bundlecompthreads.gzip',
891 b'bundlecompthreads.gzip',
892 default=None,
892 default=None,
893 )
893 )
894 coreconfigitem(
894 coreconfigitem(
895 b'experimental',
895 b'experimental',
896 b'bundlecompthreads.none',
896 b'bundlecompthreads.none',
897 default=None,
897 default=None,
898 )
898 )
899 coreconfigitem(
899 coreconfigitem(
900 b'experimental',
900 b'experimental',
901 b'bundlecompthreads.zstd',
901 b'bundlecompthreads.zstd',
902 default=None,
902 default=None,
903 )
903 )
904 coreconfigitem(
904 coreconfigitem(
905 b'experimental',
905 b'experimental',
906 b'changegroup3',
906 b'changegroup3',
907 default=False,
907 default=False,
908 )
908 )
909 coreconfigitem(
909 coreconfigitem(
910 b'experimental',
910 b'experimental',
911 b'changegroup4',
911 b'changegroup4',
912 default=False,
912 default=False,
913 )
913 )
914 coreconfigitem(
914 coreconfigitem(
915 b'experimental',
915 b'experimental',
916 b'cleanup-as-archived',
916 b'cleanup-as-archived',
917 default=False,
917 default=False,
918 )
918 )
919 coreconfigitem(
919 coreconfigitem(
920 b'experimental',
920 b'experimental',
921 b'clientcompressionengines',
921 b'clientcompressionengines',
922 default=list,
922 default=list,
923 )
923 )
924 coreconfigitem(
924 coreconfigitem(
925 b'experimental',
925 b'experimental',
926 b'copytrace',
926 b'copytrace',
927 default=b'on',
927 default=b'on',
928 )
928 )
929 coreconfigitem(
929 coreconfigitem(
930 b'experimental',
930 b'experimental',
931 b'copytrace.movecandidateslimit',
931 b'copytrace.movecandidateslimit',
932 default=100,
932 default=100,
933 )
933 )
934 coreconfigitem(
934 coreconfigitem(
935 b'experimental',
935 b'experimental',
936 b'copytrace.sourcecommitlimit',
936 b'copytrace.sourcecommitlimit',
937 default=100,
937 default=100,
938 )
938 )
939 coreconfigitem(
939 coreconfigitem(
940 b'experimental',
940 b'experimental',
941 b'copies.read-from',
941 b'copies.read-from',
942 default=b"filelog-only",
942 default=b"filelog-only",
943 )
943 )
944 coreconfigitem(
944 coreconfigitem(
945 b'experimental',
945 b'experimental',
946 b'copies.write-to',
946 b'copies.write-to',
947 default=b'filelog-only',
947 default=b'filelog-only',
948 )
948 )
949 coreconfigitem(
949 coreconfigitem(
950 b'experimental',
950 b'experimental',
951 b'crecordtest',
951 b'crecordtest',
952 default=None,
952 default=None,
953 )
953 )
954 coreconfigitem(
954 coreconfigitem(
955 b'experimental',
955 b'experimental',
956 b'directaccess',
956 b'directaccess',
957 default=False,
957 default=False,
958 )
958 )
959 coreconfigitem(
959 coreconfigitem(
960 b'experimental',
960 b'experimental',
961 b'directaccess.revnums',
961 b'directaccess.revnums',
962 default=False,
962 default=False,
963 )
963 )
964 coreconfigitem(
964 coreconfigitem(
965 b'experimental',
965 b'experimental',
966 b'editortmpinhg',
966 b'editortmpinhg',
967 default=False,
967 default=False,
968 )
968 )
969 coreconfigitem(
969 coreconfigitem(
970 b'experimental',
970 b'experimental',
971 b'evolution',
971 b'evolution',
972 default=list,
972 default=list,
973 )
973 )
974 coreconfigitem(
974 coreconfigitem(
975 b'experimental',
975 b'experimental',
976 b'evolution.allowdivergence',
976 b'evolution.allowdivergence',
977 default=False,
977 default=False,
978 alias=[(b'experimental', b'allowdivergence')],
978 alias=[(b'experimental', b'allowdivergence')],
979 )
979 )
980 coreconfigitem(
980 coreconfigitem(
981 b'experimental',
981 b'experimental',
982 b'evolution.allowunstable',
982 b'evolution.allowunstable',
983 default=None,
983 default=None,
984 )
984 )
985 coreconfigitem(
985 coreconfigitem(
986 b'experimental',
986 b'experimental',
987 b'evolution.createmarkers',
987 b'evolution.createmarkers',
988 default=None,
988 default=None,
989 )
989 )
990 coreconfigitem(
990 coreconfigitem(
991 b'experimental',
991 b'experimental',
992 b'evolution.effect-flags',
992 b'evolution.effect-flags',
993 default=True,
993 default=True,
994 alias=[(b'experimental', b'effect-flags')],
994 alias=[(b'experimental', b'effect-flags')],
995 )
995 )
996 coreconfigitem(
996 coreconfigitem(
997 b'experimental',
997 b'experimental',
998 b'evolution.exchange',
998 b'evolution.exchange',
999 default=None,
999 default=None,
1000 )
1000 )
1001 coreconfigitem(
1001 coreconfigitem(
1002 b'experimental',
1002 b'experimental',
1003 b'evolution.bundle-obsmarker',
1003 b'evolution.bundle-obsmarker',
1004 default=False,
1004 default=False,
1005 )
1005 )
1006 coreconfigitem(
1006 coreconfigitem(
1007 b'experimental',
1007 b'experimental',
1008 b'evolution.bundle-obsmarker:mandatory',
1008 b'evolution.bundle-obsmarker:mandatory',
1009 default=True,
1009 default=True,
1010 )
1010 )
1011 coreconfigitem(
1011 coreconfigitem(
1012 b'experimental',
1012 b'experimental',
1013 b'log.topo',
1013 b'log.topo',
1014 default=False,
1014 default=False,
1015 )
1015 )
1016 coreconfigitem(
1016 coreconfigitem(
1017 b'experimental',
1017 b'experimental',
1018 b'evolution.report-instabilities',
1018 b'evolution.report-instabilities',
1019 default=True,
1019 default=True,
1020 )
1020 )
1021 coreconfigitem(
1021 coreconfigitem(
1022 b'experimental',
1022 b'experimental',
1023 b'evolution.track-operation',
1023 b'evolution.track-operation',
1024 default=True,
1024 default=True,
1025 )
1025 )
1026 # repo-level config to exclude a revset visibility
1026 # repo-level config to exclude a revset visibility
1027 #
1027 #
1028 # The target use case is to use `share` to expose different subset of the same
1028 # The target use case is to use `share` to expose different subset of the same
1029 # repository, especially server side. See also `server.view`.
1029 # repository, especially server side. See also `server.view`.
1030 coreconfigitem(
1030 coreconfigitem(
1031 b'experimental',
1031 b'experimental',
1032 b'extra-filter-revs',
1032 b'extra-filter-revs',
1033 default=None,
1033 default=None,
1034 )
1034 )
1035 coreconfigitem(
1035 coreconfigitem(
1036 b'experimental',
1036 b'experimental',
1037 b'maxdeltachainspan',
1037 b'maxdeltachainspan',
1038 default=-1,
1038 default=-1,
1039 )
1039 )
1040 # tracks files which were undeleted (merge might delete them but we explicitly
1040 # tracks files which were undeleted (merge might delete them but we explicitly
1041 # kept/undeleted them) and creates new filenodes for them
1041 # kept/undeleted them) and creates new filenodes for them
1042 coreconfigitem(
1042 coreconfigitem(
1043 b'experimental',
1043 b'experimental',
1044 b'merge-track-salvaged',
1044 b'merge-track-salvaged',
1045 default=False,
1045 default=False,
1046 )
1046 )
1047 coreconfigitem(
1047 coreconfigitem(
1048 b'experimental',
1048 b'experimental',
1049 b'mmapindexthreshold',
1049 b'mmapindexthreshold',
1050 default=None,
1050 default=None,
1051 )
1051 )
1052 coreconfigitem(
1052 coreconfigitem(
1053 b'experimental',
1053 b'experimental',
1054 b'narrow',
1054 b'narrow',
1055 default=False,
1055 default=False,
1056 )
1056 )
1057 coreconfigitem(
1057 coreconfigitem(
1058 b'experimental',
1058 b'experimental',
1059 b'nonnormalparanoidcheck',
1059 b'nonnormalparanoidcheck',
1060 default=False,
1060 default=False,
1061 )
1061 )
1062 coreconfigitem(
1062 coreconfigitem(
1063 b'experimental',
1063 b'experimental',
1064 b'exportableenviron',
1064 b'exportableenviron',
1065 default=list,
1065 default=list,
1066 )
1066 )
1067 coreconfigitem(
1067 coreconfigitem(
1068 b'experimental',
1068 b'experimental',
1069 b'extendedheader.index',
1069 b'extendedheader.index',
1070 default=None,
1070 default=None,
1071 )
1071 )
1072 coreconfigitem(
1072 coreconfigitem(
1073 b'experimental',
1073 b'experimental',
1074 b'extendedheader.similarity',
1074 b'extendedheader.similarity',
1075 default=False,
1075 default=False,
1076 )
1076 )
1077 coreconfigitem(
1077 coreconfigitem(
1078 b'experimental',
1078 b'experimental',
1079 b'graphshorten',
1079 b'graphshorten',
1080 default=False,
1080 default=False,
1081 )
1081 )
1082 coreconfigitem(
1082 coreconfigitem(
1083 b'experimental',
1083 b'experimental',
1084 b'graphstyle.parent',
1084 b'graphstyle.parent',
1085 default=dynamicdefault,
1085 default=dynamicdefault,
1086 )
1086 )
1087 coreconfigitem(
1087 coreconfigitem(
1088 b'experimental',
1088 b'experimental',
1089 b'graphstyle.missing',
1089 b'graphstyle.missing',
1090 default=dynamicdefault,
1090 default=dynamicdefault,
1091 )
1091 )
1092 coreconfigitem(
1092 coreconfigitem(
1093 b'experimental',
1093 b'experimental',
1094 b'graphstyle.grandparent',
1094 b'graphstyle.grandparent',
1095 default=dynamicdefault,
1095 default=dynamicdefault,
1096 )
1096 )
1097 coreconfigitem(
1097 coreconfigitem(
1098 b'experimental',
1098 b'experimental',
1099 b'hook-track-tags',
1099 b'hook-track-tags',
1100 default=False,
1100 default=False,
1101 )
1101 )
1102 coreconfigitem(
1102 coreconfigitem(
1103 b'experimental',
1103 b'experimental',
1104 b'httppostargs',
1104 b'httppostargs',
1105 default=False,
1105 default=False,
1106 )
1106 )
1107 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1107 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1108 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1108 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1109
1109
1110 coreconfigitem(
1110 coreconfigitem(
1111 b'experimental',
1111 b'experimental',
1112 b'obsmarkers-exchange-debug',
1112 b'obsmarkers-exchange-debug',
1113 default=False,
1113 default=False,
1114 )
1114 )
1115 coreconfigitem(
1115 coreconfigitem(
1116 b'experimental',
1116 b'experimental',
1117 b'remotenames',
1117 b'remotenames',
1118 default=False,
1118 default=False,
1119 )
1119 )
1120 coreconfigitem(
1120 coreconfigitem(
1121 b'experimental',
1121 b'experimental',
1122 b'removeemptydirs',
1122 b'removeemptydirs',
1123 default=True,
1123 default=True,
1124 )
1124 )
1125 coreconfigitem(
1125 coreconfigitem(
1126 b'experimental',
1126 b'experimental',
1127 b'revert.interactive.select-to-keep',
1127 b'revert.interactive.select-to-keep',
1128 default=False,
1128 default=False,
1129 )
1129 )
1130 coreconfigitem(
1130 coreconfigitem(
1131 b'experimental',
1131 b'experimental',
1132 b'revisions.prefixhexnode',
1132 b'revisions.prefixhexnode',
1133 default=False,
1133 default=False,
1134 )
1134 )
1135 # "out of experimental" todo list.
1135 # "out of experimental" todo list.
1136 #
1136 #
1137 # * include management of a persistent nodemap in the main docket
1137 # * include management of a persistent nodemap in the main docket
1138 # * enforce a "no-truncate" policy for mmap safety
1138 # * enforce a "no-truncate" policy for mmap safety
1139 # - for censoring operation
1139 # - for censoring operation
1140 # - for stripping operation
1140 # - for stripping operation
1141 # - for rollback operation
1141 # - for rollback operation
1142 # * proper streaming (race free) of the docket file
1142 # * proper streaming (race free) of the docket file
1143 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1143 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1144 # * Exchange-wise, we will also need to do something more efficient than
1144 # * Exchange-wise, we will also need to do something more efficient than
1145 # keeping references to the affected revlogs, especially memory-wise when
1145 # keeping references to the affected revlogs, especially memory-wise when
1146 # rewriting sidedata.
1146 # rewriting sidedata.
1147 # * introduce a proper solution to reduce the number of filelog related files.
1147 # * introduce a proper solution to reduce the number of filelog related files.
1148 # * use caching for reading sidedata (similar to what we do for data).
1148 # * use caching for reading sidedata (similar to what we do for data).
1149 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1149 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1150 # * Improvement to consider
1150 # * Improvement to consider
1151 # - avoid compression header in chunk using the default compression?
1151 # - avoid compression header in chunk using the default compression?
1152 # - forbid "inline" compression mode entirely?
1152 # - forbid "inline" compression mode entirely?
1153 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1153 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1154 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1154 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1155 # - keep track of chain base or size (probably not that useful anymore)
1155 # - keep track of chain base or size (probably not that useful anymore)
1156 coreconfigitem(
1156 coreconfigitem(
1157 b'experimental',
1157 b'experimental',
1158 b'revlogv2',
1158 b'revlogv2',
1159 default=None,
1159 default=None,
1160 )
1160 )
1161 coreconfigitem(
1161 coreconfigitem(
1162 b'experimental',
1162 b'experimental',
1163 b'revisions.disambiguatewithin',
1163 b'revisions.disambiguatewithin',
1164 default=None,
1164 default=None,
1165 )
1165 )
1166 coreconfigitem(
1166 coreconfigitem(
1167 b'experimental',
1167 b'experimental',
1168 b'rust.index',
1168 b'rust.index',
1169 default=False,
1169 default=False,
1170 )
1170 )
1171 coreconfigitem(
1171 coreconfigitem(
1172 b'experimental',
1172 b'experimental',
1173 b'server.filesdata.recommended-batch-size',
1173 b'server.filesdata.recommended-batch-size',
1174 default=50000,
1174 default=50000,
1175 )
1175 )
1176 coreconfigitem(
1176 coreconfigitem(
1177 b'experimental',
1177 b'experimental',
1178 b'server.manifestdata.recommended-batch-size',
1178 b'server.manifestdata.recommended-batch-size',
1179 default=100000,
1179 default=100000,
1180 )
1180 )
1181 coreconfigitem(
1181 coreconfigitem(
1182 b'experimental',
1182 b'experimental',
1183 b'server.stream-narrow-clones',
1183 b'server.stream-narrow-clones',
1184 default=False,
1184 default=False,
1185 )
1185 )
1186 coreconfigitem(
1186 coreconfigitem(
1187 b'experimental',
1187 b'experimental',
1188 b'single-head-per-branch',
1188 b'single-head-per-branch',
1189 default=False,
1189 default=False,
1190 )
1190 )
1191 coreconfigitem(
1191 coreconfigitem(
1192 b'experimental',
1192 b'experimental',
1193 b'single-head-per-branch:account-closed-heads',
1193 b'single-head-per-branch:account-closed-heads',
1194 default=False,
1194 default=False,
1195 )
1195 )
1196 coreconfigitem(
1196 coreconfigitem(
1197 b'experimental',
1197 b'experimental',
1198 b'single-head-per-branch:public-changes-only',
1198 b'single-head-per-branch:public-changes-only',
1199 default=False,
1199 default=False,
1200 )
1200 )
1201 coreconfigitem(
1201 coreconfigitem(
1202 b'experimental',
1202 b'experimental',
1203 b'sparse-read',
1203 b'sparse-read',
1204 default=False,
1204 default=False,
1205 )
1205 )
1206 coreconfigitem(
1206 coreconfigitem(
1207 b'experimental',
1207 b'experimental',
1208 b'sparse-read.density-threshold',
1208 b'sparse-read.density-threshold',
1209 default=0.50,
1209 default=0.50,
1210 )
1210 )
1211 coreconfigitem(
1211 coreconfigitem(
1212 b'experimental',
1212 b'experimental',
1213 b'sparse-read.min-gap-size',
1213 b'sparse-read.min-gap-size',
1214 default=b'65K',
1214 default=b'65K',
1215 )
1215 )
1216 coreconfigitem(
1216 coreconfigitem(
1217 b'experimental',
1217 b'experimental',
1218 b'treemanifest',
1218 b'treemanifest',
1219 default=False,
1219 default=False,
1220 )
1220 )
1221 coreconfigitem(
1221 coreconfigitem(
1222 b'experimental',
1222 b'experimental',
1223 b'update.atomic-file',
1223 b'update.atomic-file',
1224 default=False,
1224 default=False,
1225 )
1225 )
1226 coreconfigitem(
1226 coreconfigitem(
1227 b'experimental',
1227 b'experimental',
1228 b'web.full-garbage-collection-rate',
1228 b'web.full-garbage-collection-rate',
1229 default=1, # still forcing a full collection on each request
1229 default=1, # still forcing a full collection on each request
1230 )
1230 )
1231 coreconfigitem(
1231 coreconfigitem(
1232 b'experimental',
1232 b'experimental',
1233 b'worker.wdir-get-thread-safe',
1233 b'worker.wdir-get-thread-safe',
1234 default=False,
1234 default=False,
1235 )
1235 )
1236 coreconfigitem(
1236 coreconfigitem(
1237 b'experimental',
1237 b'experimental',
1238 b'worker.repository-upgrade',
1238 b'worker.repository-upgrade',
1239 default=False,
1239 default=False,
1240 )
1240 )
1241 coreconfigitem(
1241 coreconfigitem(
1242 b'experimental',
1242 b'experimental',
1243 b'xdiff',
1243 b'xdiff',
1244 default=False,
1244 default=False,
1245 )
1245 )
1246 coreconfigitem(
1246 coreconfigitem(
1247 b'extensions',
1247 b'extensions',
1248 b'[^:]*',
1248 b'[^:]*',
1249 default=None,
1249 default=None,
1250 generic=True,
1250 generic=True,
1251 )
1251 )
1252 coreconfigitem(
1252 coreconfigitem(
1253 b'extensions',
1253 b'extensions',
1254 b'[^:]*:required',
1254 b'[^:]*:required',
1255 default=False,
1255 default=False,
1256 generic=True,
1256 generic=True,
1257 )
1257 )
1258 coreconfigitem(
1258 coreconfigitem(
1259 b'extdata',
1259 b'extdata',
1260 b'.*',
1260 b'.*',
1261 default=None,
1261 default=None,
1262 generic=True,
1262 generic=True,
1263 )
1263 )
1264 coreconfigitem(
1264 coreconfigitem(
1265 b'format',
1265 b'format',
1266 b'bookmarks-in-store',
1266 b'bookmarks-in-store',
1267 default=False,
1267 default=False,
1268 )
1268 )
1269 coreconfigitem(
1269 coreconfigitem(
1270 b'format',
1270 b'format',
1271 b'chunkcachesize',
1271 b'chunkcachesize',
1272 default=None,
1272 default=None,
1273 experimental=True,
1273 experimental=True,
1274 )
1274 )
1275 coreconfigitem(
1275 coreconfigitem(
1276 # Enable this dirstate format *when creating a new repository*.
1276 # Enable this dirstate format *when creating a new repository*.
1277 # Which format to use for existing repos is controlled by .hg/requires
1277 # Which format to use for existing repos is controlled by .hg/requires
1278 b'format',
1278 b'format',
1279 b'use-dirstate-v2',
1279 b'use-dirstate-v2',
1280 default=False,
1280 default=False,
1281 experimental=True,
1281 experimental=True,
1282 alias=[(b'format', b'exp-rc-dirstate-v2')],
1282 alias=[(b'format', b'exp-rc-dirstate-v2')],
1283 )
1283 )
1284 coreconfigitem(
1284 coreconfigitem(
1285 b'format',
1285 b'format',
1286 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1286 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1287 default=False,
1287 default=False,
1288 experimental=True,
1288 experimental=True,
1289 )
1289 )
1290 coreconfigitem(
1290 coreconfigitem(
1291 b'format',
1291 b'format',
1292 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1292 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1293 default=False,
1293 default=False,
1294 experimental=True,
1294 experimental=True,
1295 )
1295 )
1296 coreconfigitem(
1296 coreconfigitem(
1297 b'format',
1297 b'format',
1298 b'use-dirstate-tracked-hint',
1298 b'use-dirstate-tracked-hint',
1299 default=False,
1299 default=False,
1300 experimental=True,
1300 experimental=True,
1301 )
1301 )
1302 coreconfigitem(
1302 coreconfigitem(
1303 b'format',
1303 b'format',
1304 b'use-dirstate-tracked-hint.version',
1304 b'use-dirstate-tracked-hint.version',
1305 default=1,
1305 default=1,
1306 experimental=True,
1306 experimental=True,
1307 )
1307 )
1308 coreconfigitem(
1308 coreconfigitem(
1309 b'format',
1309 b'format',
1310 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1310 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1311 default=False,
1311 default=False,
1312 experimental=True,
1312 experimental=True,
1313 )
1313 )
1314 coreconfigitem(
1314 coreconfigitem(
1315 b'format',
1315 b'format',
1316 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1316 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1317 default=False,
1317 default=False,
1318 experimental=True,
1318 experimental=True,
1319 )
1319 )
1320 coreconfigitem(
1320 coreconfigitem(
1321 b'format',
1321 b'format',
1322 b'dotencode',
1322 b'dotencode',
1323 default=True,
1323 default=True,
1324 )
1324 )
1325 coreconfigitem(
1325 coreconfigitem(
1326 b'format',
1326 b'format',
1327 b'generaldelta',
1327 b'generaldelta',
1328 default=False,
1328 default=False,
1329 experimental=True,
1329 experimental=True,
1330 )
1330 )
1331 coreconfigitem(
1331 coreconfigitem(
1332 b'format',
1332 b'format',
1333 b'manifestcachesize',
1333 b'manifestcachesize',
1334 default=None,
1334 default=None,
1335 experimental=True,
1335 experimental=True,
1336 )
1336 )
1337 coreconfigitem(
1337 coreconfigitem(
1338 b'format',
1338 b'format',
1339 b'maxchainlen',
1339 b'maxchainlen',
1340 default=dynamicdefault,
1340 default=dynamicdefault,
1341 experimental=True,
1341 experimental=True,
1342 )
1342 )
1343 coreconfigitem(
1343 coreconfigitem(
1344 b'format',
1344 b'format',
1345 b'obsstore-version',
1345 b'obsstore-version',
1346 default=None,
1346 default=None,
1347 )
1347 )
1348 coreconfigitem(
1348 coreconfigitem(
1349 b'format',
1349 b'format',
1350 b'sparse-revlog',
1350 b'sparse-revlog',
1351 default=True,
1351 default=True,
1352 )
1352 )
1353 coreconfigitem(
1353 coreconfigitem(
1354 b'format',
1354 b'format',
1355 b'revlog-compression',
1355 b'revlog-compression',
1356 default=lambda: [b'zstd', b'zlib'],
1356 default=lambda: [b'zstd', b'zlib'],
1357 alias=[(b'experimental', b'format.compression')],
1357 alias=[(b'experimental', b'format.compression')],
1358 )
1358 )
1359 # Experimental TODOs:
1359 # Experimental TODOs:
1360 #
1360 #
1361 # * Same as for revlogv2 (but for the reduction of the number of files)
1361 # * Same as for revlogv2 (but for the reduction of the number of files)
1362 # * Actually computing the rank of changesets
1362 # * Actually computing the rank of changesets
1363 # * Improvement to investigate
1363 # * Improvement to investigate
1364 # - storing .hgtags fnode
1364 # - storing .hgtags fnode
1365 # - storing branch related identifier
1365 # - storing branch related identifier
1366
1366
1367 coreconfigitem(
1367 coreconfigitem(
1368 b'format',
1368 b'format',
1369 b'exp-use-changelog-v2',
1369 b'exp-use-changelog-v2',
1370 default=None,
1370 default=None,
1371 experimental=True,
1371 experimental=True,
1372 )
1372 )
1373 coreconfigitem(
1373 coreconfigitem(
1374 b'format',
1374 b'format',
1375 b'usefncache',
1375 b'usefncache',
1376 default=True,
1376 default=True,
1377 )
1377 )
1378 coreconfigitem(
1378 coreconfigitem(
1379 b'format',
1379 b'format',
1380 b'usegeneraldelta',
1380 b'usegeneraldelta',
1381 default=True,
1381 default=True,
1382 )
1382 )
1383 coreconfigitem(
1383 coreconfigitem(
1384 b'format',
1384 b'format',
1385 b'usestore',
1385 b'usestore',
1386 default=True,
1386 default=True,
1387 )
1387 )
1388
1388
1389
1389
1390 def _persistent_nodemap_default():
1390 def _persistent_nodemap_default():
1391 """compute `use-persistent-nodemap` default value
1391 """compute `use-persistent-nodemap` default value
1392
1392
1393 The feature is disabled unless a fast implementation is available.
1393 The feature is disabled unless a fast implementation is available.
1394 """
1394 """
1395 from . import policy
1395 from . import policy
1396
1396
1397 return policy.importrust('revlog') is not None
1397 return policy.importrust('revlog') is not None
1398
1398
1399
1399
1400 coreconfigitem(
1400 coreconfigitem(
1401 b'format',
1401 b'format',
1402 b'use-persistent-nodemap',
1402 b'use-persistent-nodemap',
1403 default=_persistent_nodemap_default,
1403 default=_persistent_nodemap_default,
1404 )
1404 )
1405 coreconfigitem(
1405 coreconfigitem(
1406 b'format',
1406 b'format',
1407 b'exp-use-copies-side-data-changeset',
1407 b'exp-use-copies-side-data-changeset',
1408 default=False,
1408 default=False,
1409 experimental=True,
1409 experimental=True,
1410 )
1410 )
1411 coreconfigitem(
1411 coreconfigitem(
1412 b'format',
1412 b'format',
1413 b'use-share-safe',
1413 b'use-share-safe',
1414 default=True,
1414 default=True,
1415 )
1415 )
1416 coreconfigitem(
1416 coreconfigitem(
1417 b'format',
1417 b'format',
1418 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1418 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1419 default=False,
1419 default=False,
1420 experimental=True,
1420 experimental=True,
1421 )
1421 )
1422 coreconfigitem(
1422 coreconfigitem(
1423 b'format',
1423 b'format',
1424 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1424 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1425 default=False,
1425 default=False,
1426 experimental=True,
1426 experimental=True,
1427 )
1427 )
1428 coreconfigitem(
1428 coreconfigitem(
1429 b'format',
1429 b'format',
1430 b'internal-phase',
1430 b'internal-phase',
1431 default=False,
1431 default=False,
1432 experimental=True,
1432 experimental=True,
1433 )
1433 )
1434 coreconfigitem(
1434 coreconfigitem(
1435 b'shelve',
1435 b'shelve',
1436 b'store',
1436 b'store',
1437 default='internal',
1437 default='internal',
1438 experimental=True,
1438 experimental=True,
1439 )
1439 )
1440 coreconfigitem(
1440 coreconfigitem(
1441 b'fsmonitor',
1441 b'fsmonitor',
1442 b'warn_when_unused',
1442 b'warn_when_unused',
1443 default=True,
1443 default=True,
1444 )
1444 )
1445 coreconfigitem(
1445 coreconfigitem(
1446 b'fsmonitor',
1446 b'fsmonitor',
1447 b'warn_update_file_count',
1447 b'warn_update_file_count',
1448 default=50000,
1448 default=50000,
1449 )
1449 )
1450 coreconfigitem(
1450 coreconfigitem(
1451 b'fsmonitor',
1451 b'fsmonitor',
1452 b'warn_update_file_count_rust',
1452 b'warn_update_file_count_rust',
1453 default=400000,
1453 default=400000,
1454 )
1454 )
1455 coreconfigitem(
1455 coreconfigitem(
1456 b'help',
1456 b'help',
1457 br'hidden-command\..*',
1457 br'hidden-command\..*',
1458 default=False,
1458 default=False,
1459 generic=True,
1459 generic=True,
1460 )
1460 )
1461 coreconfigitem(
1461 coreconfigitem(
1462 b'help',
1462 b'help',
1463 br'hidden-topic\..*',
1463 br'hidden-topic\..*',
1464 default=False,
1464 default=False,
1465 generic=True,
1465 generic=True,
1466 )
1466 )
1467 coreconfigitem(
1467 coreconfigitem(
1468 b'hooks',
1468 b'hooks',
1469 b'[^:]*',
1469 b'[^:]*',
1470 default=dynamicdefault,
1470 default=dynamicdefault,
1471 generic=True,
1471 generic=True,
1472 )
1472 )
1473 coreconfigitem(
1473 coreconfigitem(
1474 b'hooks',
1474 b'hooks',
1475 b'.*:run-with-plain',
1475 b'.*:run-with-plain',
1476 default=True,
1476 default=True,
1477 generic=True,
1477 generic=True,
1478 )
1478 )
1479 coreconfigitem(
1479 coreconfigitem(
1480 b'hgweb-paths',
1480 b'hgweb-paths',
1481 b'.*',
1481 b'.*',
1482 default=list,
1482 default=list,
1483 generic=True,
1483 generic=True,
1484 )
1484 )
1485 coreconfigitem(
1485 coreconfigitem(
1486 b'hostfingerprints',
1486 b'hostfingerprints',
1487 b'.*',
1487 b'.*',
1488 default=list,
1488 default=list,
1489 generic=True,
1489 generic=True,
1490 )
1490 )
1491 coreconfigitem(
1491 coreconfigitem(
1492 b'hostsecurity',
1492 b'hostsecurity',
1493 b'ciphers',
1493 b'ciphers',
1494 default=None,
1494 default=None,
1495 )
1495 )
1496 coreconfigitem(
1496 coreconfigitem(
1497 b'hostsecurity',
1497 b'hostsecurity',
1498 b'minimumprotocol',
1498 b'minimumprotocol',
1499 default=dynamicdefault,
1499 default=dynamicdefault,
1500 )
1500 )
1501 coreconfigitem(
1501 coreconfigitem(
1502 b'hostsecurity',
1502 b'hostsecurity',
1503 b'.*:minimumprotocol$',
1503 b'.*:minimumprotocol$',
1504 default=dynamicdefault,
1504 default=dynamicdefault,
1505 generic=True,
1505 generic=True,
1506 )
1506 )
1507 coreconfigitem(
1507 coreconfigitem(
1508 b'hostsecurity',
1508 b'hostsecurity',
1509 b'.*:ciphers$',
1509 b'.*:ciphers$',
1510 default=dynamicdefault,
1510 default=dynamicdefault,
1511 generic=True,
1511 generic=True,
1512 )
1512 )
1513 coreconfigitem(
1513 coreconfigitem(
1514 b'hostsecurity',
1514 b'hostsecurity',
1515 b'.*:fingerprints$',
1515 b'.*:fingerprints$',
1516 default=list,
1516 default=list,
1517 generic=True,
1517 generic=True,
1518 )
1518 )
1519 coreconfigitem(
1519 coreconfigitem(
1520 b'hostsecurity',
1520 b'hostsecurity',
1521 b'.*:verifycertsfile$',
1521 b'.*:verifycertsfile$',
1522 default=None,
1522 default=None,
1523 generic=True,
1523 generic=True,
1524 )
1524 )
1525
1525
1526 coreconfigitem(
1526 coreconfigitem(
1527 b'http_proxy',
1527 b'http_proxy',
1528 b'always',
1528 b'always',
1529 default=False,
1529 default=False,
1530 )
1530 )
1531 coreconfigitem(
1531 coreconfigitem(
1532 b'http_proxy',
1532 b'http_proxy',
1533 b'host',
1533 b'host',
1534 default=None,
1534 default=None,
1535 )
1535 )
1536 coreconfigitem(
1536 coreconfigitem(
1537 b'http_proxy',
1537 b'http_proxy',
1538 b'no',
1538 b'no',
1539 default=list,
1539 default=list,
1540 )
1540 )
1541 coreconfigitem(
1541 coreconfigitem(
1542 b'http_proxy',
1542 b'http_proxy',
1543 b'passwd',
1543 b'passwd',
1544 default=None,
1544 default=None,
1545 )
1545 )
1546 coreconfigitem(
1546 coreconfigitem(
1547 b'http_proxy',
1547 b'http_proxy',
1548 b'user',
1548 b'user',
1549 default=None,
1549 default=None,
1550 )
1550 )
1551
1551
1552 coreconfigitem(
1552 coreconfigitem(
1553 b'http',
1553 b'http',
1554 b'timeout',
1554 b'timeout',
1555 default=None,
1555 default=None,
1556 )
1556 )
1557
1557
1558 coreconfigitem(
1558 coreconfigitem(
1559 b'logtoprocess',
1559 b'logtoprocess',
1560 b'commandexception',
1560 b'commandexception',
1561 default=None,
1561 default=None,
1562 )
1562 )
1563 coreconfigitem(
1563 coreconfigitem(
1564 b'logtoprocess',
1564 b'logtoprocess',
1565 b'commandfinish',
1565 b'commandfinish',
1566 default=None,
1566 default=None,
1567 )
1567 )
1568 coreconfigitem(
1568 coreconfigitem(
1569 b'logtoprocess',
1569 b'logtoprocess',
1570 b'command',
1570 b'command',
1571 default=None,
1571 default=None,
1572 )
1572 )
1573 coreconfigitem(
1573 coreconfigitem(
1574 b'logtoprocess',
1574 b'logtoprocess',
1575 b'develwarn',
1575 b'develwarn',
1576 default=None,
1576 default=None,
1577 )
1577 )
1578 coreconfigitem(
1578 coreconfigitem(
1579 b'logtoprocess',
1579 b'logtoprocess',
1580 b'uiblocked',
1580 b'uiblocked',
1581 default=None,
1581 default=None,
1582 )
1582 )
1583 coreconfigitem(
1583 coreconfigitem(
1584 b'merge',
1584 b'merge',
1585 b'checkunknown',
1585 b'checkunknown',
1586 default=b'abort',
1586 default=b'abort',
1587 )
1587 )
1588 coreconfigitem(
1588 coreconfigitem(
1589 b'merge',
1589 b'merge',
1590 b'checkignored',
1590 b'checkignored',
1591 default=b'abort',
1591 default=b'abort',
1592 )
1592 )
1593 coreconfigitem(
1593 coreconfigitem(
1594 b'experimental',
1594 b'experimental',
1595 b'merge.checkpathconflicts',
1595 b'merge.checkpathconflicts',
1596 default=False,
1596 default=False,
1597 )
1597 )
1598 coreconfigitem(
1598 coreconfigitem(
1599 b'merge',
1599 b'merge',
1600 b'followcopies',
1600 b'followcopies',
1601 default=True,
1601 default=True,
1602 )
1602 )
1603 coreconfigitem(
1603 coreconfigitem(
1604 b'merge',
1604 b'merge',
1605 b'on-failure',
1605 b'on-failure',
1606 default=b'continue',
1606 default=b'continue',
1607 )
1607 )
1608 coreconfigitem(
1608 coreconfigitem(
1609 b'merge',
1609 b'merge',
1610 b'preferancestor',
1610 b'preferancestor',
1611 default=lambda: [b'*'],
1611 default=lambda: [b'*'],
1612 experimental=True,
1612 experimental=True,
1613 )
1613 )
1614 coreconfigitem(
1614 coreconfigitem(
1615 b'merge',
1615 b'merge',
1616 b'strict-capability-check',
1616 b'strict-capability-check',
1617 default=False,
1617 default=False,
1618 )
1618 )
1619 coreconfigitem(
1619 coreconfigitem(
1620 b'merge',
1620 b'merge',
1621 b'disable-partial-tools',
1621 b'disable-partial-tools',
1622 default=False,
1622 default=False,
1623 experimental=True,
1623 experimental=True,
1624 )
1624 )
1625 coreconfigitem(
1625 coreconfigitem(
1626 b'partial-merge-tools',
1626 b'partial-merge-tools',
1627 b'.*',
1627 b'.*',
1628 default=None,
1628 default=None,
1629 generic=True,
1629 generic=True,
1630 experimental=True,
1630 experimental=True,
1631 )
1631 )
1632 coreconfigitem(
1632 coreconfigitem(
1633 b'partial-merge-tools',
1633 b'partial-merge-tools',
1634 br'.*\.patterns',
1634 br'.*\.patterns',
1635 default=dynamicdefault,
1635 default=dynamicdefault,
1636 generic=True,
1636 generic=True,
1637 priority=-1,
1637 priority=-1,
1638 experimental=True,
1638 experimental=True,
1639 )
1639 )
1640 coreconfigitem(
1640 coreconfigitem(
1641 b'partial-merge-tools',
1641 b'partial-merge-tools',
1642 br'.*\.executable$',
1642 br'.*\.executable$',
1643 default=dynamicdefault,
1643 default=dynamicdefault,
1644 generic=True,
1644 generic=True,
1645 priority=-1,
1645 priority=-1,
1646 experimental=True,
1646 experimental=True,
1647 )
1647 )
1648 coreconfigitem(
1648 coreconfigitem(
1649 b'partial-merge-tools',
1649 b'partial-merge-tools',
1650 br'.*\.order',
1650 br'.*\.order',
1651 default=0,
1651 default=0,
1652 generic=True,
1652 generic=True,
1653 priority=-1,
1653 priority=-1,
1654 experimental=True,
1654 experimental=True,
1655 )
1655 )
1656 coreconfigitem(
1656 coreconfigitem(
1657 b'partial-merge-tools',
1657 b'partial-merge-tools',
1658 br'.*\.args',
1658 br'.*\.args',
1659 default=b"$local $base $other",
1659 default=b"$local $base $other",
1660 generic=True,
1660 generic=True,
1661 priority=-1,
1661 priority=-1,
1662 experimental=True,
1662 experimental=True,
1663 )
1663 )
1664 coreconfigitem(
1664 coreconfigitem(
1665 b'partial-merge-tools',
1665 b'partial-merge-tools',
1666 br'.*\.disable',
1666 br'.*\.disable',
1667 default=False,
1667 default=False,
1668 generic=True,
1668 generic=True,
1669 priority=-1,
1669 priority=-1,
1670 experimental=True,
1670 experimental=True,
1671 )
1671 )
1672 coreconfigitem(
1672 coreconfigitem(
1673 b'merge-tools',
1673 b'merge-tools',
1674 b'.*',
1674 b'.*',
1675 default=None,
1675 default=None,
1676 generic=True,
1676 generic=True,
1677 )
1677 )
1678 coreconfigitem(
1678 coreconfigitem(
1679 b'merge-tools',
1679 b'merge-tools',
1680 br'.*\.args$',
1680 br'.*\.args$',
1681 default=b"$local $base $other",
1681 default=b"$local $base $other",
1682 generic=True,
1682 generic=True,
1683 priority=-1,
1683 priority=-1,
1684 )
1684 )
1685 coreconfigitem(
1685 coreconfigitem(
1686 b'merge-tools',
1686 b'merge-tools',
1687 br'.*\.binary$',
1687 br'.*\.binary$',
1688 default=False,
1688 default=False,
1689 generic=True,
1689 generic=True,
1690 priority=-1,
1690 priority=-1,
1691 )
1691 )
1692 coreconfigitem(
1692 coreconfigitem(
1693 b'merge-tools',
1693 b'merge-tools',
1694 br'.*\.check$',
1694 br'.*\.check$',
1695 default=list,
1695 default=list,
1696 generic=True,
1696 generic=True,
1697 priority=-1,
1697 priority=-1,
1698 )
1698 )
1699 coreconfigitem(
1699 coreconfigitem(
1700 b'merge-tools',
1700 b'merge-tools',
1701 br'.*\.checkchanged$',
1701 br'.*\.checkchanged$',
1702 default=False,
1702 default=False,
1703 generic=True,
1703 generic=True,
1704 priority=-1,
1704 priority=-1,
1705 )
1705 )
1706 coreconfigitem(
1706 coreconfigitem(
1707 b'merge-tools',
1707 b'merge-tools',
1708 br'.*\.executable$',
1708 br'.*\.executable$',
1709 default=dynamicdefault,
1709 default=dynamicdefault,
1710 generic=True,
1710 generic=True,
1711 priority=-1,
1711 priority=-1,
1712 )
1712 )
1713 coreconfigitem(
1713 coreconfigitem(
1714 b'merge-tools',
1714 b'merge-tools',
1715 br'.*\.fixeol$',
1715 br'.*\.fixeol$',
1716 default=False,
1716 default=False,
1717 generic=True,
1717 generic=True,
1718 priority=-1,
1718 priority=-1,
1719 )
1719 )
1720 coreconfigitem(
1720 coreconfigitem(
1721 b'merge-tools',
1721 b'merge-tools',
1722 br'.*\.gui$',
1722 br'.*\.gui$',
1723 default=False,
1723 default=False,
1724 generic=True,
1724 generic=True,
1725 priority=-1,
1725 priority=-1,
1726 )
1726 )
1727 coreconfigitem(
1727 coreconfigitem(
1728 b'merge-tools',
1728 b'merge-tools',
1729 br'.*\.mergemarkers$',
1729 br'.*\.mergemarkers$',
1730 default=b'basic',
1730 default=b'basic',
1731 generic=True,
1731 generic=True,
1732 priority=-1,
1732 priority=-1,
1733 )
1733 )
1734 coreconfigitem(
1734 coreconfigitem(
1735 b'merge-tools',
1735 b'merge-tools',
1736 br'.*\.mergemarkertemplate$',
1736 br'.*\.mergemarkertemplate$',
1737 default=dynamicdefault, # take from command-templates.mergemarker
1737 default=dynamicdefault, # take from command-templates.mergemarker
1738 generic=True,
1738 generic=True,
1739 priority=-1,
1739 priority=-1,
1740 )
1740 )
1741 coreconfigitem(
1741 coreconfigitem(
1742 b'merge-tools',
1742 b'merge-tools',
1743 br'.*\.priority$',
1743 br'.*\.priority$',
1744 default=0,
1744 default=0,
1745 generic=True,
1745 generic=True,
1746 priority=-1,
1746 priority=-1,
1747 )
1747 )
1748 coreconfigitem(
1748 coreconfigitem(
1749 b'merge-tools',
1749 b'merge-tools',
1750 br'.*\.premerge$',
1750 br'.*\.premerge$',
1751 default=dynamicdefault,
1751 default=dynamicdefault,
1752 generic=True,
1752 generic=True,
1753 priority=-1,
1753 priority=-1,
1754 )
1754 )
1755 coreconfigitem(
1755 coreconfigitem(
1756 b'merge-tools',
1756 b'merge-tools',
1757 br'.*\.symlink$',
1757 br'.*\.symlink$',
1758 default=False,
1758 default=False,
1759 generic=True,
1759 generic=True,
1760 priority=-1,
1760 priority=-1,
1761 )
1761 )
1762 coreconfigitem(
1762 coreconfigitem(
1763 b'pager',
1763 b'pager',
1764 b'attend-.*',
1764 b'attend-.*',
1765 default=dynamicdefault,
1765 default=dynamicdefault,
1766 generic=True,
1766 generic=True,
1767 )
1767 )
1768 coreconfigitem(
1768 coreconfigitem(
1769 b'pager',
1769 b'pager',
1770 b'ignore',
1770 b'ignore',
1771 default=list,
1771 default=list,
1772 )
1772 )
1773 coreconfigitem(
1773 coreconfigitem(
1774 b'pager',
1774 b'pager',
1775 b'pager',
1775 b'pager',
1776 default=dynamicdefault,
1776 default=dynamicdefault,
1777 )
1777 )
1778 coreconfigitem(
1778 coreconfigitem(
1779 b'patch',
1779 b'patch',
1780 b'eol',
1780 b'eol',
1781 default=b'strict',
1781 default=b'strict',
1782 )
1782 )
1783 coreconfigitem(
1783 coreconfigitem(
1784 b'patch',
1784 b'patch',
1785 b'fuzz',
1785 b'fuzz',
1786 default=2,
1786 default=2,
1787 )
1787 )
1788 coreconfigitem(
1788 coreconfigitem(
1789 b'paths',
1789 b'paths',
1790 b'default',
1790 b'default',
1791 default=None,
1791 default=None,
1792 )
1792 )
1793 coreconfigitem(
1793 coreconfigitem(
1794 b'paths',
1794 b'paths',
1795 b'default-push',
1795 b'default-push',
1796 default=None,
1796 default=None,
1797 )
1797 )
1798 coreconfigitem(
1798 coreconfigitem(
1799 b'paths',
1799 b'paths',
1800 b'.*',
1800 b'.*',
1801 default=None,
1801 default=None,
1802 generic=True,
1802 generic=True,
1803 )
1803 )
1804 coreconfigitem(
1804 coreconfigitem(
1805 b'paths',
1805 b'paths',
1806 b'.*:bookmarks.mode',
1806 b'.*:bookmarks.mode',
1807 default='default',
1807 default='default',
1808 generic=True,
1808 generic=True,
1809 )
1809 )
1810 coreconfigitem(
1810 coreconfigitem(
1811 b'paths',
1811 b'paths',
1812 b'.*:multi-urls',
1812 b'.*:multi-urls',
1813 default=False,
1813 default=False,
1814 generic=True,
1814 generic=True,
1815 )
1815 )
1816 coreconfigitem(
1816 coreconfigitem(
1817 b'paths',
1817 b'paths',
1818 b'.*:pushrev',
1818 b'.*:pushrev',
1819 default=None,
1819 default=None,
1820 generic=True,
1820 generic=True,
1821 )
1821 )
1822 coreconfigitem(
1822 coreconfigitem(
1823 b'paths',
1823 b'paths',
1824 b'.*:pushurl',
1824 b'.*:pushurl',
1825 default=None,
1825 default=None,
1826 generic=True,
1826 generic=True,
1827 )
1827 )
1828 coreconfigitem(
1828 coreconfigitem(
1829 b'phases',
1829 b'phases',
1830 b'checksubrepos',
1830 b'checksubrepos',
1831 default=b'follow',
1831 default=b'follow',
1832 )
1832 )
1833 coreconfigitem(
1833 coreconfigitem(
1834 b'phases',
1834 b'phases',
1835 b'new-commit',
1835 b'new-commit',
1836 default=b'draft',
1836 default=b'draft',
1837 )
1837 )
1838 coreconfigitem(
1838 coreconfigitem(
1839 b'phases',
1839 b'phases',
1840 b'publish',
1840 b'publish',
1841 default=True,
1841 default=True,
1842 )
1842 )
1843 coreconfigitem(
1843 coreconfigitem(
1844 b'profiling',
1844 b'profiling',
1845 b'enabled',
1845 b'enabled',
1846 default=False,
1846 default=False,
1847 )
1847 )
1848 coreconfigitem(
1848 coreconfigitem(
1849 b'profiling',
1849 b'profiling',
1850 b'format',
1850 b'format',
1851 default=b'text',
1851 default=b'text',
1852 )
1852 )
1853 coreconfigitem(
1853 coreconfigitem(
1854 b'profiling',
1854 b'profiling',
1855 b'freq',
1855 b'freq',
1856 default=1000,
1856 default=1000,
1857 )
1857 )
1858 coreconfigitem(
1858 coreconfigitem(
1859 b'profiling',
1859 b'profiling',
1860 b'limit',
1860 b'limit',
1861 default=30,
1861 default=30,
1862 )
1862 )
1863 coreconfigitem(
1863 coreconfigitem(
1864 b'profiling',
1864 b'profiling',
1865 b'nested',
1865 b'nested',
1866 default=0,
1866 default=0,
1867 )
1867 )
1868 coreconfigitem(
1868 coreconfigitem(
1869 b'profiling',
1869 b'profiling',
1870 b'output',
1870 b'output',
1871 default=None,
1871 default=None,
1872 )
1872 )
1873 coreconfigitem(
1873 coreconfigitem(
1874 b'profiling',
1874 b'profiling',
1875 b'showmax',
1875 b'showmax',
1876 default=0.999,
1876 default=0.999,
1877 )
1877 )
1878 coreconfigitem(
1878 coreconfigitem(
1879 b'profiling',
1879 b'profiling',
1880 b'showmin',
1880 b'showmin',
1881 default=dynamicdefault,
1881 default=dynamicdefault,
1882 )
1882 )
1883 coreconfigitem(
1883 coreconfigitem(
1884 b'profiling',
1884 b'profiling',
1885 b'showtime',
1885 b'showtime',
1886 default=True,
1886 default=True,
1887 )
1887 )
1888 coreconfigitem(
1888 coreconfigitem(
1889 b'profiling',
1889 b'profiling',
1890 b'sort',
1890 b'sort',
1891 default=b'inlinetime',
1891 default=b'inlinetime',
1892 )
1892 )
1893 coreconfigitem(
1893 coreconfigitem(
1894 b'profiling',
1894 b'profiling',
1895 b'statformat',
1895 b'statformat',
1896 default=b'hotpath',
1896 default=b'hotpath',
1897 )
1897 )
1898 coreconfigitem(
1898 coreconfigitem(
1899 b'profiling',
1899 b'profiling',
1900 b'time-track',
1900 b'time-track',
1901 default=dynamicdefault,
1901 default=dynamicdefault,
1902 )
1902 )
1903 coreconfigitem(
1903 coreconfigitem(
1904 b'profiling',
1904 b'profiling',
1905 b'type',
1905 b'type',
1906 default=b'stat',
1906 default=b'stat',
1907 )
1907 )
1908 coreconfigitem(
1908 coreconfigitem(
1909 b'progress',
1909 b'progress',
1910 b'assume-tty',
1910 b'assume-tty',
1911 default=False,
1911 default=False,
1912 )
1912 )
1913 coreconfigitem(
1913 coreconfigitem(
1914 b'progress',
1914 b'progress',
1915 b'changedelay',
1915 b'changedelay',
1916 default=1,
1916 default=1,
1917 )
1917 )
1918 coreconfigitem(
1918 coreconfigitem(
1919 b'progress',
1919 b'progress',
1920 b'clear-complete',
1920 b'clear-complete',
1921 default=True,
1921 default=True,
1922 )
1922 )
1923 coreconfigitem(
1923 coreconfigitem(
1924 b'progress',
1924 b'progress',
1925 b'debug',
1925 b'debug',
1926 default=False,
1926 default=False,
1927 )
1927 )
1928 coreconfigitem(
1928 coreconfigitem(
1929 b'progress',
1929 b'progress',
1930 b'delay',
1930 b'delay',
1931 default=3,
1931 default=3,
1932 )
1932 )
1933 coreconfigitem(
1933 coreconfigitem(
1934 b'progress',
1934 b'progress',
1935 b'disable',
1935 b'disable',
1936 default=False,
1936 default=False,
1937 )
1937 )
1938 coreconfigitem(
1938 coreconfigitem(
1939 b'progress',
1939 b'progress',
1940 b'estimateinterval',
1940 b'estimateinterval',
1941 default=60.0,
1941 default=60.0,
1942 )
1942 )
1943 coreconfigitem(
1943 coreconfigitem(
1944 b'progress',
1944 b'progress',
1945 b'format',
1945 b'format',
1946 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1946 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
1947 )
1947 )
1948 coreconfigitem(
1948 coreconfigitem(
1949 b'progress',
1949 b'progress',
1950 b'refresh',
1950 b'refresh',
1951 default=0.1,
1951 default=0.1,
1952 )
1952 )
1953 coreconfigitem(
1953 coreconfigitem(
1954 b'progress',
1954 b'progress',
1955 b'width',
1955 b'width',
1956 default=dynamicdefault,
1956 default=dynamicdefault,
1957 )
1957 )
1958 coreconfigitem(
1958 coreconfigitem(
1959 b'pull',
1959 b'pull',
1960 b'confirm',
1960 b'confirm',
1961 default=False,
1961 default=False,
1962 )
1962 )
1963 coreconfigitem(
1963 coreconfigitem(
1964 b'push',
1964 b'push',
1965 b'pushvars.server',
1965 b'pushvars.server',
1966 default=False,
1966 default=False,
1967 )
1967 )
1968 coreconfigitem(
1968 coreconfigitem(
1969 b'rewrite',
1969 b'rewrite',
1970 b'backup-bundle',
1970 b'backup-bundle',
1971 default=True,
1971 default=True,
1972 alias=[(b'ui', b'history-editing-backup')],
1972 alias=[(b'ui', b'history-editing-backup')],
1973 )
1973 )
1974 coreconfigitem(
1974 coreconfigitem(
1975 b'rewrite',
1975 b'rewrite',
1976 b'update-timestamp',
1976 b'update-timestamp',
1977 default=False,
1977 default=False,
1978 )
1978 )
1979 coreconfigitem(
1979 coreconfigitem(
1980 b'rewrite',
1980 b'rewrite',
1981 b'empty-successor',
1981 b'empty-successor',
1982 default=b'skip',
1982 default=b'skip',
1983 experimental=True,
1983 experimental=True,
1984 )
1984 )
1985 # experimental as long as format.use-dirstate-v2 is.
1985 # experimental as long as format.use-dirstate-v2 is.
1986 coreconfigitem(
1986 coreconfigitem(
1987 b'storage',
1987 b'storage',
1988 b'dirstate-v2.slow-path',
1988 b'dirstate-v2.slow-path',
1989 default=b"abort",
1989 default=b"abort",
1990 experimental=True,
1990 experimental=True,
1991 )
1991 )
1992 coreconfigitem(
1992 coreconfigitem(
1993 b'storage',
1993 b'storage',
1994 b'new-repo-backend',
1994 b'new-repo-backend',
1995 default=b'revlogv1',
1995 default=b'revlogv1',
1996 experimental=True,
1996 experimental=True,
1997 )
1997 )
1998 coreconfigitem(
1998 coreconfigitem(
1999 b'storage',
1999 b'storage',
2000 b'revlog.optimize-delta-parent-choice',
2000 b'revlog.optimize-delta-parent-choice',
2001 default=True,
2001 default=True,
2002 alias=[(b'format', b'aggressivemergedeltas')],
2002 alias=[(b'format', b'aggressivemergedeltas')],
2003 )
2003 )
2004 coreconfigitem(
2004 coreconfigitem(
2005 b'storage',
2005 b'storage',
2006 b'revlog.issue6528.fix-incoming',
2006 b'revlog.issue6528.fix-incoming',
2007 default=True,
2007 default=True,
2008 )
2008 )
2009 # experimental as long as rust is experimental (or a C version is implemented)
2009 # experimental as long as rust is experimental (or a C version is implemented)
2010 coreconfigitem(
2010 coreconfigitem(
2011 b'storage',
2011 b'storage',
2012 b'revlog.persistent-nodemap.mmap',
2012 b'revlog.persistent-nodemap.mmap',
2013 default=True,
2013 default=True,
2014 )
2014 )
2015 # experimental as long as format.use-persistent-nodemap is.
2015 # experimental as long as format.use-persistent-nodemap is.
2016 coreconfigitem(
2016 coreconfigitem(
2017 b'storage',
2017 b'storage',
2018 b'revlog.persistent-nodemap.slow-path',
2018 b'revlog.persistent-nodemap.slow-path',
2019 default=b"abort",
2019 default=b"abort",
2020 )
2020 )
2021
2021
2022 coreconfigitem(
2022 coreconfigitem(
2023 b'storage',
2023 b'storage',
2024 b'revlog.reuse-external-delta',
2024 b'revlog.reuse-external-delta',
2025 default=True,
2025 default=True,
2026 )
2026 )
2027 coreconfigitem(
2027 coreconfigitem(
2028 b'storage',
2028 b'storage',
2029 b'revlog.reuse-external-delta-parent',
2029 b'revlog.reuse-external-delta-parent',
2030 default=None,
2030 default=None,
2031 )
2031 )
2032 coreconfigitem(
2032 coreconfigitem(
2033 b'storage',
2033 b'storage',
2034 b'revlog.zlib.level',
2034 b'revlog.zlib.level',
2035 default=None,
2035 default=None,
2036 )
2036 )
2037 coreconfigitem(
2037 coreconfigitem(
2038 b'storage',
2038 b'storage',
2039 b'revlog.zstd.level',
2039 b'revlog.zstd.level',
2040 default=None,
2040 default=None,
2041 )
2041 )
2042 coreconfigitem(
2042 coreconfigitem(
2043 b'server',
2043 b'server',
2044 b'bookmarks-pushkey-compat',
2044 b'bookmarks-pushkey-compat',
2045 default=True,
2045 default=True,
2046 )
2046 )
2047 coreconfigitem(
2047 coreconfigitem(
2048 b'server',
2048 b'server',
2049 b'bundle1',
2049 b'bundle1',
2050 default=True,
2050 default=True,
2051 )
2051 )
2052 coreconfigitem(
2052 coreconfigitem(
2053 b'server',
2053 b'server',
2054 b'bundle1gd',
2054 b'bundle1gd',
2055 default=None,
2055 default=None,
2056 )
2056 )
2057 coreconfigitem(
2057 coreconfigitem(
2058 b'server',
2058 b'server',
2059 b'bundle1.pull',
2059 b'bundle1.pull',
2060 default=None,
2060 default=None,
2061 )
2061 )
2062 coreconfigitem(
2062 coreconfigitem(
2063 b'server',
2063 b'server',
2064 b'bundle1gd.pull',
2064 b'bundle1gd.pull',
2065 default=None,
2065 default=None,
2066 )
2066 )
2067 coreconfigitem(
2067 coreconfigitem(
2068 b'server',
2068 b'server',
2069 b'bundle1.push',
2069 b'bundle1.push',
2070 default=None,
2070 default=None,
2071 )
2071 )
2072 coreconfigitem(
2072 coreconfigitem(
2073 b'server',
2073 b'server',
2074 b'bundle1gd.push',
2074 b'bundle1gd.push',
2075 default=None,
2075 default=None,
2076 )
2076 )
2077 coreconfigitem(
2077 coreconfigitem(
2078 b'server',
2078 b'server',
2079 b'bundle2.stream',
2079 b'bundle2.stream',
2080 default=True,
2080 default=True,
2081 alias=[(b'experimental', b'bundle2.stream')],
2081 alias=[(b'experimental', b'bundle2.stream')],
2082 )
2082 )
2083 coreconfigitem(
2083 coreconfigitem(
2084 b'server',
2084 b'server',
2085 b'compressionengines',
2085 b'compressionengines',
2086 default=list,
2086 default=list,
2087 )
2087 )
2088 coreconfigitem(
2088 coreconfigitem(
2089 b'server',
2089 b'server',
2090 b'concurrent-push-mode',
2090 b'concurrent-push-mode',
2091 default=b'check-related',
2091 default=b'check-related',
2092 )
2092 )
2093 coreconfigitem(
2093 coreconfigitem(
2094 b'server',
2094 b'server',
2095 b'disablefullbundle',
2095 b'disablefullbundle',
2096 default=False,
2096 default=False,
2097 )
2097 )
2098 coreconfigitem(
2098 coreconfigitem(
2099 b'server',
2099 b'server',
2100 b'maxhttpheaderlen',
2100 b'maxhttpheaderlen',
2101 default=1024,
2101 default=1024,
2102 )
2102 )
2103 coreconfigitem(
2103 coreconfigitem(
2104 b'server',
2104 b'server',
2105 b'pullbundle',
2105 b'pullbundle',
2106 default=False,
2106 default=False,
2107 )
2107 )
2108 coreconfigitem(
2108 coreconfigitem(
2109 b'server',
2109 b'server',
2110 b'preferuncompressed',
2110 b'preferuncompressed',
2111 default=False,
2111 default=False,
2112 )
2112 )
2113 coreconfigitem(
2113 coreconfigitem(
2114 b'server',
2114 b'server',
2115 b'streamunbundle',
2115 b'streamunbundle',
2116 default=False,
2116 default=False,
2117 )
2117 )
2118 coreconfigitem(
2118 coreconfigitem(
2119 b'server',
2119 b'server',
2120 b'uncompressed',
2120 b'uncompressed',
2121 default=True,
2121 default=True,
2122 )
2122 )
2123 coreconfigitem(
2123 coreconfigitem(
2124 b'server',
2124 b'server',
2125 b'uncompressedallowsecret',
2125 b'uncompressedallowsecret',
2126 default=False,
2126 default=False,
2127 )
2127 )
2128 coreconfigitem(
2128 coreconfigitem(
2129 b'server',
2129 b'server',
2130 b'view',
2130 b'view',
2131 default=b'served',
2131 default=b'served',
2132 )
2132 )
2133 coreconfigitem(
2133 coreconfigitem(
2134 b'server',
2134 b'server',
2135 b'validate',
2135 b'validate',
2136 default=False,
2136 default=False,
2137 )
2137 )
2138 coreconfigitem(
2138 coreconfigitem(
2139 b'server',
2139 b'server',
2140 b'zliblevel',
2140 b'zliblevel',
2141 default=-1,
2141 default=-1,
2142 )
2142 )
2143 coreconfigitem(
2143 coreconfigitem(
2144 b'server',
2144 b'server',
2145 b'zstdlevel',
2145 b'zstdlevel',
2146 default=3,
2146 default=3,
2147 )
2147 )
2148 coreconfigitem(
2148 coreconfigitem(
2149 b'share',
2149 b'share',
2150 b'pool',
2150 b'pool',
2151 default=None,
2151 default=None,
2152 )
2152 )
2153 coreconfigitem(
2153 coreconfigitem(
2154 b'share',
2154 b'share',
2155 b'poolnaming',
2155 b'poolnaming',
2156 default=b'identity',
2156 default=b'identity',
2157 )
2157 )
2158 coreconfigitem(
2158 coreconfigitem(
2159 b'share',
2159 b'share',
2160 b'safe-mismatch.source-not-safe',
2160 b'safe-mismatch.source-not-safe',
2161 default=b'abort',
2161 default=b'abort',
2162 )
2162 )
2163 coreconfigitem(
2163 coreconfigitem(
2164 b'share',
2164 b'share',
2165 b'safe-mismatch.source-safe',
2165 b'safe-mismatch.source-safe',
2166 default=b'abort',
2166 default=b'abort',
2167 )
2167 )
2168 coreconfigitem(
2168 coreconfigitem(
2169 b'share',
2169 b'share',
2170 b'safe-mismatch.source-not-safe.warn',
2170 b'safe-mismatch.source-not-safe.warn',
2171 default=True,
2171 default=True,
2172 )
2172 )
2173 coreconfigitem(
2173 coreconfigitem(
2174 b'share',
2174 b'share',
2175 b'safe-mismatch.source-safe.warn',
2175 b'safe-mismatch.source-safe.warn',
2176 default=True,
2176 default=True,
2177 )
2177 )
2178 coreconfigitem(
2178 coreconfigitem(
2179 b'share',
2179 b'share',
2180 b'safe-mismatch.source-not-safe:verbose-upgrade',
2180 b'safe-mismatch.source-not-safe:verbose-upgrade',
2181 default=True,
2181 default=True,
2182 )
2182 )
2183 coreconfigitem(
2183 coreconfigitem(
2184 b'share',
2184 b'share',
2185 b'safe-mismatch.source-safe:verbose-upgrade',
2185 b'safe-mismatch.source-safe:verbose-upgrade',
2186 default=True,
2186 default=True,
2187 )
2187 )
2188 coreconfigitem(
2188 coreconfigitem(
2189 b'shelve',
2189 b'shelve',
2190 b'maxbackups',
2190 b'maxbackups',
2191 default=10,
2191 default=10,
2192 )
2192 )
2193 coreconfigitem(
2193 coreconfigitem(
2194 b'smtp',
2194 b'smtp',
2195 b'host',
2195 b'host',
2196 default=None,
2196 default=None,
2197 )
2197 )
2198 coreconfigitem(
2198 coreconfigitem(
2199 b'smtp',
2199 b'smtp',
2200 b'local_hostname',
2200 b'local_hostname',
2201 default=None,
2201 default=None,
2202 )
2202 )
2203 coreconfigitem(
2203 coreconfigitem(
2204 b'smtp',
2204 b'smtp',
2205 b'password',
2205 b'password',
2206 default=None,
2206 default=None,
2207 )
2207 )
2208 coreconfigitem(
2208 coreconfigitem(
2209 b'smtp',
2209 b'smtp',
2210 b'port',
2210 b'port',
2211 default=dynamicdefault,
2211 default=dynamicdefault,
2212 )
2212 )
2213 coreconfigitem(
2213 coreconfigitem(
2214 b'smtp',
2214 b'smtp',
2215 b'tls',
2215 b'tls',
2216 default=b'none',
2216 default=b'none',
2217 )
2217 )
2218 coreconfigitem(
2218 coreconfigitem(
2219 b'smtp',
2219 b'smtp',
2220 b'username',
2220 b'username',
2221 default=None,
2221 default=None,
2222 )
2222 )
2223 coreconfigitem(
2223 coreconfigitem(
2224 b'sparse',
2224 b'sparse',
2225 b'missingwarning',
2225 b'missingwarning',
2226 default=True,
2226 default=True,
2227 experimental=True,
2227 experimental=True,
2228 )
2228 )
2229 coreconfigitem(
2229 coreconfigitem(
2230 b'subrepos',
2230 b'subrepos',
2231 b'allowed',
2231 b'allowed',
2232 default=dynamicdefault, # to make backporting simpler
2232 default=dynamicdefault, # to make backporting simpler
2233 )
2233 )
2234 coreconfigitem(
2234 coreconfigitem(
2235 b'subrepos',
2235 b'subrepos',
2236 b'hg:allowed',
2236 b'hg:allowed',
2237 default=dynamicdefault,
2237 default=dynamicdefault,
2238 )
2238 )
2239 coreconfigitem(
2239 coreconfigitem(
2240 b'subrepos',
2240 b'subrepos',
2241 b'git:allowed',
2241 b'git:allowed',
2242 default=dynamicdefault,
2242 default=dynamicdefault,
2243 )
2243 )
2244 coreconfigitem(
2244 coreconfigitem(
2245 b'subrepos',
2245 b'subrepos',
2246 b'svn:allowed',
2246 b'svn:allowed',
2247 default=dynamicdefault,
2247 default=dynamicdefault,
2248 )
2248 )
2249 coreconfigitem(
2249 coreconfigitem(
2250 b'templates',
2250 b'templates',
2251 b'.*',
2251 b'.*',
2252 default=None,
2252 default=None,
2253 generic=True,
2253 generic=True,
2254 )
2254 )
2255 coreconfigitem(
2255 coreconfigitem(
2256 b'templateconfig',
2256 b'templateconfig',
2257 b'.*',
2257 b'.*',
2258 default=dynamicdefault,
2258 default=dynamicdefault,
2259 generic=True,
2259 generic=True,
2260 )
2260 )
2261 coreconfigitem(
2261 coreconfigitem(
2262 b'trusted',
2262 b'trusted',
2263 b'groups',
2263 b'groups',
2264 default=list,
2264 default=list,
2265 )
2265 )
2266 coreconfigitem(
2266 coreconfigitem(
2267 b'trusted',
2267 b'trusted',
2268 b'users',
2268 b'users',
2269 default=list,
2269 default=list,
2270 )
2270 )
2271 coreconfigitem(
2271 coreconfigitem(
2272 b'ui',
2272 b'ui',
2273 b'_usedassubrepo',
2273 b'_usedassubrepo',
2274 default=False,
2274 default=False,
2275 )
2275 )
2276 coreconfigitem(
2276 coreconfigitem(
2277 b'ui',
2277 b'ui',
2278 b'allowemptycommit',
2278 b'allowemptycommit',
2279 default=False,
2279 default=False,
2280 )
2280 )
2281 coreconfigitem(
2281 coreconfigitem(
2282 b'ui',
2282 b'ui',
2283 b'archivemeta',
2283 b'archivemeta',
2284 default=True,
2284 default=True,
2285 )
2285 )
2286 coreconfigitem(
2286 coreconfigitem(
2287 b'ui',
2287 b'ui',
2288 b'askusername',
2288 b'askusername',
2289 default=False,
2289 default=False,
2290 )
2290 )
2291 coreconfigitem(
2291 coreconfigitem(
2292 b'ui',
2292 b'ui',
2293 b'available-memory',
2293 b'available-memory',
2294 default=None,
2294 default=None,
2295 )
2295 )
2296
2296
2297 coreconfigitem(
2297 coreconfigitem(
2298 b'ui',
2298 b'ui',
2299 b'clonebundlefallback',
2299 b'clonebundlefallback',
2300 default=False,
2300 default=False,
2301 )
2301 )
2302 coreconfigitem(
2302 coreconfigitem(
2303 b'ui',
2303 b'ui',
2304 b'clonebundleprefers',
2304 b'clonebundleprefers',
2305 default=list,
2305 default=list,
2306 )
2306 )
2307 coreconfigitem(
2307 coreconfigitem(
2308 b'ui',
2308 b'ui',
2309 b'clonebundles',
2309 b'clonebundles',
2310 default=True,
2310 default=True,
2311 )
2311 )
2312 coreconfigitem(
2312 coreconfigitem(
2313 b'ui',
2313 b'ui',
2314 b'color',
2314 b'color',
2315 default=b'auto',
2315 default=b'auto',
2316 )
2316 )
2317 coreconfigitem(
2317 coreconfigitem(
2318 b'ui',
2318 b'ui',
2319 b'commitsubrepos',
2319 b'commitsubrepos',
2320 default=False,
2320 default=False,
2321 )
2321 )
2322 coreconfigitem(
2322 coreconfigitem(
2323 b'ui',
2323 b'ui',
2324 b'debug',
2324 b'debug',
2325 default=False,
2325 default=False,
2326 )
2326 )
2327 coreconfigitem(
2327 coreconfigitem(
2328 b'ui',
2328 b'ui',
2329 b'debugger',
2329 b'debugger',
2330 default=None,
2330 default=None,
2331 )
2331 )
2332 coreconfigitem(
2332 coreconfigitem(
2333 b'ui',
2333 b'ui',
2334 b'editor',
2334 b'editor',
2335 default=dynamicdefault,
2335 default=dynamicdefault,
2336 )
2336 )
2337 coreconfigitem(
2337 coreconfigitem(
2338 b'ui',
2338 b'ui',
2339 b'detailed-exit-code',
2339 b'detailed-exit-code',
2340 default=False,
2340 default=False,
2341 experimental=True,
2341 experimental=True,
2342 )
2342 )
2343 coreconfigitem(
2343 coreconfigitem(
2344 b'ui',
2344 b'ui',
2345 b'fallbackencoding',
2345 b'fallbackencoding',
2346 default=None,
2346 default=None,
2347 )
2347 )
2348 coreconfigitem(
2348 coreconfigitem(
2349 b'ui',
2349 b'ui',
2350 b'forcecwd',
2350 b'forcecwd',
2351 default=None,
2351 default=None,
2352 )
2352 )
2353 coreconfigitem(
2353 coreconfigitem(
2354 b'ui',
2354 b'ui',
2355 b'forcemerge',
2355 b'forcemerge',
2356 default=None,
2356 default=None,
2357 )
2357 )
2358 coreconfigitem(
2358 coreconfigitem(
2359 b'ui',
2359 b'ui',
2360 b'formatdebug',
2360 b'formatdebug',
2361 default=False,
2361 default=False,
2362 )
2362 )
2363 coreconfigitem(
2363 coreconfigitem(
2364 b'ui',
2364 b'ui',
2365 b'formatjson',
2365 b'formatjson',
2366 default=False,
2366 default=False,
2367 )
2367 )
2368 coreconfigitem(
2368 coreconfigitem(
2369 b'ui',
2369 b'ui',
2370 b'formatted',
2370 b'formatted',
2371 default=None,
2371 default=None,
2372 )
2372 )
2373 coreconfigitem(
2373 coreconfigitem(
2374 b'ui',
2374 b'ui',
2375 b'interactive',
2375 b'interactive',
2376 default=None,
2376 default=None,
2377 )
2377 )
2378 coreconfigitem(
2378 coreconfigitem(
2379 b'ui',
2379 b'ui',
2380 b'interface',
2380 b'interface',
2381 default=None,
2381 default=None,
2382 )
2382 )
2383 coreconfigitem(
2383 coreconfigitem(
2384 b'ui',
2384 b'ui',
2385 b'interface.chunkselector',
2385 b'interface.chunkselector',
2386 default=None,
2386 default=None,
2387 )
2387 )
2388 coreconfigitem(
2388 coreconfigitem(
2389 b'ui',
2389 b'ui',
2390 b'large-file-limit',
2390 b'large-file-limit',
2391 default=10 * (2 ** 20),
2391 default=10 * (2 ** 20),
2392 )
2392 )
2393 coreconfigitem(
2393 coreconfigitem(
2394 b'ui',
2394 b'ui',
2395 b'logblockedtimes',
2395 b'logblockedtimes',
2396 default=False,
2396 default=False,
2397 )
2397 )
2398 coreconfigitem(
2398 coreconfigitem(
2399 b'ui',
2399 b'ui',
2400 b'merge',
2400 b'merge',
2401 default=None,
2401 default=None,
2402 )
2402 )
2403 coreconfigitem(
2403 coreconfigitem(
2404 b'ui',
2404 b'ui',
2405 b'mergemarkers',
2405 b'mergemarkers',
2406 default=b'basic',
2406 default=b'basic',
2407 )
2407 )
2408 coreconfigitem(
2408 coreconfigitem(
2409 b'ui',
2409 b'ui',
2410 b'message-output',
2410 b'message-output',
2411 default=b'stdio',
2411 default=b'stdio',
2412 )
2412 )
2413 coreconfigitem(
2413 coreconfigitem(
2414 b'ui',
2414 b'ui',
2415 b'nontty',
2415 b'nontty',
2416 default=False,
2416 default=False,
2417 )
2417 )
2418 coreconfigitem(
2418 coreconfigitem(
2419 b'ui',
2419 b'ui',
2420 b'origbackuppath',
2420 b'origbackuppath',
2421 default=None,
2421 default=None,
2422 )
2422 )
2423 coreconfigitem(
2423 coreconfigitem(
2424 b'ui',
2424 b'ui',
2425 b'paginate',
2425 b'paginate',
2426 default=True,
2426 default=True,
2427 )
2427 )
2428 coreconfigitem(
2428 coreconfigitem(
2429 b'ui',
2429 b'ui',
2430 b'patch',
2430 b'patch',
2431 default=None,
2431 default=None,
2432 )
2432 )
2433 coreconfigitem(
2433 coreconfigitem(
2434 b'ui',
2434 b'ui',
2435 b'portablefilenames',
2435 b'portablefilenames',
2436 default=b'warn',
2436 default=b'warn',
2437 )
2437 )
2438 coreconfigitem(
2438 coreconfigitem(
2439 b'ui',
2439 b'ui',
2440 b'promptecho',
2440 b'promptecho',
2441 default=False,
2441 default=False,
2442 )
2442 )
2443 coreconfigitem(
2443 coreconfigitem(
2444 b'ui',
2444 b'ui',
2445 b'quiet',
2445 b'quiet',
2446 default=False,
2446 default=False,
2447 )
2447 )
2448 coreconfigitem(
2448 coreconfigitem(
2449 b'ui',
2449 b'ui',
2450 b'quietbookmarkmove',
2450 b'quietbookmarkmove',
2451 default=False,
2451 default=False,
2452 )
2452 )
2453 coreconfigitem(
2453 coreconfigitem(
2454 b'ui',
2454 b'ui',
2455 b'relative-paths',
2455 b'relative-paths',
2456 default=b'legacy',
2456 default=b'legacy',
2457 )
2457 )
2458 coreconfigitem(
2458 coreconfigitem(
2459 b'ui',
2459 b'ui',
2460 b'remotecmd',
2460 b'remotecmd',
2461 default=b'hg',
2461 default=b'hg',
2462 )
2462 )
2463 coreconfigitem(
2463 coreconfigitem(
2464 b'ui',
2464 b'ui',
2465 b'report_untrusted',
2465 b'report_untrusted',
2466 default=True,
2466 default=True,
2467 )
2467 )
2468 coreconfigitem(
2468 coreconfigitem(
2469 b'ui',
2469 b'ui',
2470 b'rollback',
2470 b'rollback',
2471 default=True,
2471 default=True,
2472 )
2472 )
2473 coreconfigitem(
2473 coreconfigitem(
2474 b'ui',
2474 b'ui',
2475 b'signal-safe-lock',
2475 b'signal-safe-lock',
2476 default=True,
2476 default=True,
2477 )
2477 )
2478 coreconfigitem(
2478 coreconfigitem(
2479 b'ui',
2479 b'ui',
2480 b'slash',
2480 b'slash',
2481 default=False,
2481 default=False,
2482 )
2482 )
2483 coreconfigitem(
2483 coreconfigitem(
2484 b'ui',
2484 b'ui',
2485 b'ssh',
2485 b'ssh',
2486 default=b'ssh',
2486 default=b'ssh',
2487 )
2487 )
2488 coreconfigitem(
2488 coreconfigitem(
2489 b'ui',
2489 b'ui',
2490 b'ssherrorhint',
2490 b'ssherrorhint',
2491 default=None,
2491 default=None,
2492 )
2492 )
2493 coreconfigitem(
2493 coreconfigitem(
2494 b'ui',
2494 b'ui',
2495 b'statuscopies',
2495 b'statuscopies',
2496 default=False,
2496 default=False,
2497 )
2497 )
2498 coreconfigitem(
2498 coreconfigitem(
2499 b'ui',
2499 b'ui',
2500 b'strict',
2500 b'strict',
2501 default=False,
2501 default=False,
2502 )
2502 )
2503 coreconfigitem(
2503 coreconfigitem(
2504 b'ui',
2504 b'ui',
2505 b'style',
2505 b'style',
2506 default=b'',
2506 default=b'',
2507 )
2507 )
2508 coreconfigitem(
2508 coreconfigitem(
2509 b'ui',
2509 b'ui',
2510 b'supportcontact',
2510 b'supportcontact',
2511 default=None,
2511 default=None,
2512 )
2512 )
2513 coreconfigitem(
2513 coreconfigitem(
2514 b'ui',
2514 b'ui',
2515 b'textwidth',
2515 b'textwidth',
2516 default=78,
2516 default=78,
2517 )
2517 )
2518 coreconfigitem(
2518 coreconfigitem(
2519 b'ui',
2519 b'ui',
2520 b'timeout',
2520 b'timeout',
2521 default=b'600',
2521 default=b'600',
2522 )
2522 )
2523 coreconfigitem(
2523 coreconfigitem(
2524 b'ui',
2524 b'ui',
2525 b'timeout.warn',
2525 b'timeout.warn',
2526 default=0,
2526 default=0,
2527 )
2527 )
2528 coreconfigitem(
2528 coreconfigitem(
2529 b'ui',
2529 b'ui',
2530 b'timestamp-output',
2530 b'timestamp-output',
2531 default=False,
2531 default=False,
2532 )
2532 )
2533 coreconfigitem(
2533 coreconfigitem(
2534 b'ui',
2534 b'ui',
2535 b'traceback',
2535 b'traceback',
2536 default=False,
2536 default=False,
2537 )
2537 )
2538 coreconfigitem(
2538 coreconfigitem(
2539 b'ui',
2539 b'ui',
2540 b'tweakdefaults',
2540 b'tweakdefaults',
2541 default=False,
2541 default=False,
2542 )
2542 )
2543 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2543 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2544 coreconfigitem(
2544 coreconfigitem(
2545 b'ui',
2545 b'ui',
2546 b'verbose',
2546 b'verbose',
2547 default=False,
2547 default=False,
2548 )
2548 )
2549 coreconfigitem(
2549 coreconfigitem(
2550 b'verify',
2550 b'verify',
2551 b'skipflags',
2551 b'skipflags',
2552 default=None,
2552 default=None,
2553 )
2553 )
2554 coreconfigitem(
2554 coreconfigitem(
2555 b'web',
2555 b'web',
2556 b'allowbz2',
2556 b'allowbz2',
2557 default=False,
2557 default=False,
2558 )
2558 )
2559 coreconfigitem(
2559 coreconfigitem(
2560 b'web',
2560 b'web',
2561 b'allowgz',
2561 b'allowgz',
2562 default=False,
2562 default=False,
2563 )
2563 )
2564 coreconfigitem(
2564 coreconfigitem(
2565 b'web',
2565 b'web',
2566 b'allow-pull',
2566 b'allow-pull',
2567 alias=[(b'web', b'allowpull')],
2567 alias=[(b'web', b'allowpull')],
2568 default=True,
2568 default=True,
2569 )
2569 )
2570 coreconfigitem(
2570 coreconfigitem(
2571 b'web',
2571 b'web',
2572 b'allow-push',
2572 b'allow-push',
2573 alias=[(b'web', b'allow_push')],
2573 alias=[(b'web', b'allow_push')],
2574 default=list,
2574 default=list,
2575 )
2575 )
2576 coreconfigitem(
2576 coreconfigitem(
2577 b'web',
2577 b'web',
2578 b'allowzip',
2578 b'allowzip',
2579 default=False,
2579 default=False,
2580 )
2580 )
2581 coreconfigitem(
2581 coreconfigitem(
2582 b'web',
2582 b'web',
2583 b'archivesubrepos',
2583 b'archivesubrepos',
2584 default=False,
2584 default=False,
2585 )
2585 )
2586 coreconfigitem(
2586 coreconfigitem(
2587 b'web',
2587 b'web',
2588 b'cache',
2588 b'cache',
2589 default=True,
2589 default=True,
2590 )
2590 )
2591 coreconfigitem(
2591 coreconfigitem(
2592 b'web',
2592 b'web',
2593 b'comparisoncontext',
2593 b'comparisoncontext',
2594 default=5,
2594 default=5,
2595 )
2595 )
2596 coreconfigitem(
2596 coreconfigitem(
2597 b'web',
2597 b'web',
2598 b'contact',
2598 b'contact',
2599 default=None,
2599 default=None,
2600 )
2600 )
2601 coreconfigitem(
2601 coreconfigitem(
2602 b'web',
2602 b'web',
2603 b'deny_push',
2603 b'deny_push',
2604 default=list,
2604 default=list,
2605 )
2605 )
2606 coreconfigitem(
2606 coreconfigitem(
2607 b'web',
2607 b'web',
2608 b'guessmime',
2608 b'guessmime',
2609 default=False,
2609 default=False,
2610 )
2610 )
2611 coreconfigitem(
2611 coreconfigitem(
2612 b'web',
2612 b'web',
2613 b'hidden',
2613 b'hidden',
2614 default=False,
2614 default=False,
2615 )
2615 )
2616 coreconfigitem(
2616 coreconfigitem(
2617 b'web',
2617 b'web',
2618 b'labels',
2618 b'labels',
2619 default=list,
2619 default=list,
2620 )
2620 )
2621 coreconfigitem(
2621 coreconfigitem(
2622 b'web',
2622 b'web',
2623 b'logoimg',
2623 b'logoimg',
2624 default=b'hglogo.png',
2624 default=b'hglogo.png',
2625 )
2625 )
2626 coreconfigitem(
2626 coreconfigitem(
2627 b'web',
2627 b'web',
2628 b'logourl',
2628 b'logourl',
2629 default=b'https://mercurial-scm.org/',
2629 default=b'https://mercurial-scm.org/',
2630 )
2630 )
2631 coreconfigitem(
2631 coreconfigitem(
2632 b'web',
2632 b'web',
2633 b'accesslog',
2633 b'accesslog',
2634 default=b'-',
2634 default=b'-',
2635 )
2635 )
2636 coreconfigitem(
2636 coreconfigitem(
2637 b'web',
2637 b'web',
2638 b'address',
2638 b'address',
2639 default=b'',
2639 default=b'',
2640 )
2640 )
2641 coreconfigitem(
2641 coreconfigitem(
2642 b'web',
2642 b'web',
2643 b'allow-archive',
2643 b'allow-archive',
2644 alias=[(b'web', b'allow_archive')],
2644 alias=[(b'web', b'allow_archive')],
2645 default=list,
2645 default=list,
2646 )
2646 )
2647 coreconfigitem(
2647 coreconfigitem(
2648 b'web',
2648 b'web',
2649 b'allow_read',
2649 b'allow_read',
2650 default=list,
2650 default=list,
2651 )
2651 )
2652 coreconfigitem(
2652 coreconfigitem(
2653 b'web',
2653 b'web',
2654 b'baseurl',
2654 b'baseurl',
2655 default=None,
2655 default=None,
2656 )
2656 )
2657 coreconfigitem(
2657 coreconfigitem(
2658 b'web',
2658 b'web',
2659 b'cacerts',
2659 b'cacerts',
2660 default=None,
2660 default=None,
2661 )
2661 )
2662 coreconfigitem(
2662 coreconfigitem(
2663 b'web',
2663 b'web',
2664 b'certificate',
2664 b'certificate',
2665 default=None,
2665 default=None,
2666 )
2666 )
2667 coreconfigitem(
2667 coreconfigitem(
2668 b'web',
2668 b'web',
2669 b'collapse',
2669 b'collapse',
2670 default=False,
2670 default=False,
2671 )
2671 )
2672 coreconfigitem(
2672 coreconfigitem(
2673 b'web',
2673 b'web',
2674 b'csp',
2674 b'csp',
2675 default=None,
2675 default=None,
2676 )
2676 )
2677 coreconfigitem(
2677 coreconfigitem(
2678 b'web',
2678 b'web',
2679 b'deny_read',
2679 b'deny_read',
2680 default=list,
2680 default=list,
2681 )
2681 )
2682 coreconfigitem(
2682 coreconfigitem(
2683 b'web',
2683 b'web',
2684 b'descend',
2684 b'descend',
2685 default=True,
2685 default=True,
2686 )
2686 )
2687 coreconfigitem(
2687 coreconfigitem(
2688 b'web',
2688 b'web',
2689 b'description',
2689 b'description',
2690 default=b"",
2690 default=b"",
2691 )
2691 )
2692 coreconfigitem(
2692 coreconfigitem(
2693 b'web',
2693 b'web',
2694 b'encoding',
2694 b'encoding',
2695 default=lambda: encoding.encoding,
2695 default=lambda: encoding.encoding,
2696 )
2696 )
2697 coreconfigitem(
2697 coreconfigitem(
2698 b'web',
2698 b'web',
2699 b'errorlog',
2699 b'errorlog',
2700 default=b'-',
2700 default=b'-',
2701 )
2701 )
2702 coreconfigitem(
2702 coreconfigitem(
2703 b'web',
2703 b'web',
2704 b'ipv6',
2704 b'ipv6',
2705 default=False,
2705 default=False,
2706 )
2706 )
2707 coreconfigitem(
2707 coreconfigitem(
2708 b'web',
2708 b'web',
2709 b'maxchanges',
2709 b'maxchanges',
2710 default=10,
2710 default=10,
2711 )
2711 )
2712 coreconfigitem(
2712 coreconfigitem(
2713 b'web',
2713 b'web',
2714 b'maxfiles',
2714 b'maxfiles',
2715 default=10,
2715 default=10,
2716 )
2716 )
2717 coreconfigitem(
2717 coreconfigitem(
2718 b'web',
2718 b'web',
2719 b'maxshortchanges',
2719 b'maxshortchanges',
2720 default=60,
2720 default=60,
2721 )
2721 )
2722 coreconfigitem(
2722 coreconfigitem(
2723 b'web',
2723 b'web',
2724 b'motd',
2724 b'motd',
2725 default=b'',
2725 default=b'',
2726 )
2726 )
2727 coreconfigitem(
2727 coreconfigitem(
2728 b'web',
2728 b'web',
2729 b'name',
2729 b'name',
2730 default=dynamicdefault,
2730 default=dynamicdefault,
2731 )
2731 )
2732 coreconfigitem(
2732 coreconfigitem(
2733 b'web',
2733 b'web',
2734 b'port',
2734 b'port',
2735 default=8000,
2735 default=8000,
2736 )
2736 )
2737 coreconfigitem(
2737 coreconfigitem(
2738 b'web',
2738 b'web',
2739 b'prefix',
2739 b'prefix',
2740 default=b'',
2740 default=b'',
2741 )
2741 )
2742 coreconfigitem(
2742 coreconfigitem(
2743 b'web',
2743 b'web',
2744 b'push_ssl',
2744 b'push_ssl',
2745 default=True,
2745 default=True,
2746 )
2746 )
2747 coreconfigitem(
2747 coreconfigitem(
2748 b'web',
2748 b'web',
2749 b'refreshinterval',
2749 b'refreshinterval',
2750 default=20,
2750 default=20,
2751 )
2751 )
2752 coreconfigitem(
2752 coreconfigitem(
2753 b'web',
2753 b'web',
2754 b'server-header',
2754 b'server-header',
2755 default=None,
2755 default=None,
2756 )
2756 )
2757 coreconfigitem(
2757 coreconfigitem(
2758 b'web',
2758 b'web',
2759 b'static',
2759 b'static',
2760 default=None,
2760 default=None,
2761 )
2761 )
2762 coreconfigitem(
2762 coreconfigitem(
2763 b'web',
2763 b'web',
2764 b'staticurl',
2764 b'staticurl',
2765 default=None,
2765 default=None,
2766 )
2766 )
2767 coreconfigitem(
2767 coreconfigitem(
2768 b'web',
2768 b'web',
2769 b'stripes',
2769 b'stripes',
2770 default=1,
2770 default=1,
2771 )
2771 )
2772 coreconfigitem(
2772 coreconfigitem(
2773 b'web',
2773 b'web',
2774 b'style',
2774 b'style',
2775 default=b'paper',
2775 default=b'paper',
2776 )
2776 )
2777 coreconfigitem(
2777 coreconfigitem(
2778 b'web',
2778 b'web',
2779 b'templates',
2779 b'templates',
2780 default=None,
2780 default=None,
2781 )
2781 )
2782 coreconfigitem(
2782 coreconfigitem(
2783 b'web',
2783 b'web',
2784 b'view',
2784 b'view',
2785 default=b'served',
2785 default=b'served',
2786 experimental=True,
2786 experimental=True,
2787 )
2787 )
2788 coreconfigitem(
2788 coreconfigitem(
2789 b'worker',
2789 b'worker',
2790 b'backgroundclose',
2790 b'backgroundclose',
2791 default=dynamicdefault,
2791 default=dynamicdefault,
2792 )
2792 )
2793 # Windows defaults to a limit of 512 open files. A buffer of 128
2793 # Windows defaults to a limit of 512 open files. A buffer of 128
2794 # should give us enough headway.
2794 # should give us enough headway.
2795 coreconfigitem(
2795 coreconfigitem(
2796 b'worker',
2796 b'worker',
2797 b'backgroundclosemaxqueue',
2797 b'backgroundclosemaxqueue',
2798 default=384,
2798 default=384,
2799 )
2799 )
2800 coreconfigitem(
2800 coreconfigitem(
2801 b'worker',
2801 b'worker',
2802 b'backgroundcloseminfilecount',
2802 b'backgroundcloseminfilecount',
2803 default=2048,
2803 default=2048,
2804 )
2804 )
2805 coreconfigitem(
2805 coreconfigitem(
2806 b'worker',
2806 b'worker',
2807 b'backgroundclosethreadcount',
2807 b'backgroundclosethreadcount',
2808 default=4,
2808 default=4,
2809 )
2809 )
2810 coreconfigitem(
2810 coreconfigitem(
2811 b'worker',
2811 b'worker',
2812 b'enabled',
2812 b'enabled',
2813 default=True,
2813 default=True,
2814 )
2814 )
2815 coreconfigitem(
2815 coreconfigitem(
2816 b'worker',
2816 b'worker',
2817 b'numcpus',
2817 b'numcpus',
2818 default=None,
2818 default=None,
2819 )
2819 )
2820
2820
2821 # Rebase related configuration moved to core because other extension are doing
2821 # Rebase related configuration moved to core because other extension are doing
2822 # strange things. For example, shelve import the extensions to reuse some bit
2822 # strange things. For example, shelve import the extensions to reuse some bit
2823 # without formally loading it.
2823 # without formally loading it.
2824 coreconfigitem(
2824 coreconfigitem(
2825 b'commands',
2825 b'commands',
2826 b'rebase.requiredest',
2826 b'rebase.requiredest',
2827 default=False,
2827 default=False,
2828 )
2828 )
2829 coreconfigitem(
2829 coreconfigitem(
2830 b'experimental',
2830 b'experimental',
2831 b'rebaseskipobsolete',
2831 b'rebaseskipobsolete',
2832 default=True,
2832 default=True,
2833 )
2833 )
2834 coreconfigitem(
2834 coreconfigitem(
2835 b'rebase',
2835 b'rebase',
2836 b'singletransaction',
2836 b'singletransaction',
2837 default=False,
2837 default=False,
2838 )
2838 )
2839 coreconfigitem(
2839 coreconfigitem(
2840 b'rebase',
2840 b'rebase',
2841 b'experimental.inmemory',
2841 b'experimental.inmemory',
2842 default=False,
2842 default=False,
2843 )
2843 )
2844
2845 # This setting controls creation of a rebase_source extra field
2846 # during rebase. When False, no such field is created. This is
2847 # useful eg for incrementally converting changesets and then
2848 # rebasing them onto an existing repo.
2849 # WARNING: this is an advanced setting reserved for people who know
2850 # exactly what they are doing. Misuse of this setting can easily
2851 # result in obsmarker cycles and a vivid headache.
2852 coreconfigitem(
2853 b'rebase',
2854 b'store-source',
2855 default=True,
2856 experimental=True,
2857 )
General Comments 0
You need to be logged in to leave comments. Login now