##// END OF EJS Templates
rebase: don't use rebased node as dirstate p2 (BC)...
Martin von Zweigbergk -
r45206:9c9cfecd default
parent child Browse files
Show More
@@ -1,2251 +1,2249 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 from __future__ import absolute_import
17 from __future__ import absolute_import
18
18
19 import errno
19 import errno
20 import os
20 import os
21
21
22 from mercurial.i18n import _
22 from mercurial.i18n import _
23 from mercurial.node import (
23 from mercurial.node import (
24 nullrev,
24 nullrev,
25 short,
25 short,
26 )
26 )
27 from mercurial.pycompat import open
27 from mercurial.pycompat import open
28 from mercurial import (
28 from mercurial import (
29 bookmarks,
29 bookmarks,
30 cmdutil,
30 cmdutil,
31 commands,
31 commands,
32 copies,
32 copies,
33 destutil,
33 destutil,
34 dirstateguard,
34 dirstateguard,
35 error,
35 error,
36 extensions,
36 extensions,
37 hg,
37 hg,
38 merge as mergemod,
38 merge as mergemod,
39 mergeutil,
39 mergeutil,
40 node as nodemod,
40 node as nodemod,
41 obsolete,
41 obsolete,
42 obsutil,
42 obsutil,
43 patch,
43 patch,
44 phases,
44 phases,
45 pycompat,
45 pycompat,
46 registrar,
46 registrar,
47 repair,
47 repair,
48 revset,
48 revset,
49 revsetlang,
49 revsetlang,
50 rewriteutil,
50 rewriteutil,
51 scmutil,
51 scmutil,
52 smartset,
52 smartset,
53 state as statemod,
53 state as statemod,
54 util,
54 util,
55 )
55 )
56
56
57 # The following constants are used throughout the rebase module. The ordering of
57 # The following constants are used throughout the rebase module. The ordering of
58 # their values must be maintained.
58 # their values must be maintained.
59
59
60 # Indicates that a revision needs to be rebased
60 # Indicates that a revision needs to be rebased
61 revtodo = -1
61 revtodo = -1
62 revtodostr = b'-1'
62 revtodostr = b'-1'
63
63
64 # legacy revstates no longer needed in current code
64 # legacy revstates no longer needed in current code
65 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
65 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
66 legacystates = {b'-2', b'-3', b'-4', b'-5'}
66 legacystates = {b'-2', b'-3', b'-4', b'-5'}
67
67
68 cmdtable = {}
68 cmdtable = {}
69 command = registrar.command(cmdtable)
69 command = registrar.command(cmdtable)
70 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
70 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
71 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
71 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
72 # be specifying the version(s) of Mercurial they are tested with, or
72 # be specifying the version(s) of Mercurial they are tested with, or
73 # leave the attribute unspecified.
73 # leave the attribute unspecified.
74 testedwith = b'ships-with-hg-core'
74 testedwith = b'ships-with-hg-core'
75
75
76
76
77 def _nothingtorebase():
77 def _nothingtorebase():
78 return 1
78 return 1
79
79
80
80
81 def _savegraft(ctx, extra):
81 def _savegraft(ctx, extra):
82 s = ctx.extra().get(b'source', None)
82 s = ctx.extra().get(b'source', None)
83 if s is not None:
83 if s is not None:
84 extra[b'source'] = s
84 extra[b'source'] = s
85 s = ctx.extra().get(b'intermediate-source', None)
85 s = ctx.extra().get(b'intermediate-source', None)
86 if s is not None:
86 if s is not None:
87 extra[b'intermediate-source'] = s
87 extra[b'intermediate-source'] = s
88
88
89
89
90 def _savebranch(ctx, extra):
90 def _savebranch(ctx, extra):
91 extra[b'branch'] = ctx.branch()
91 extra[b'branch'] = ctx.branch()
92
92
93
93
94 def _destrebase(repo, sourceset, destspace=None):
94 def _destrebase(repo, sourceset, destspace=None):
95 """small wrapper around destmerge to pass the right extra args
95 """small wrapper around destmerge to pass the right extra args
96
96
97 Please wrap destutil.destmerge instead."""
97 Please wrap destutil.destmerge instead."""
98 return destutil.destmerge(
98 return destutil.destmerge(
99 repo,
99 repo,
100 action=b'rebase',
100 action=b'rebase',
101 sourceset=sourceset,
101 sourceset=sourceset,
102 onheadcheck=False,
102 onheadcheck=False,
103 destspace=destspace,
103 destspace=destspace,
104 )
104 )
105
105
106
106
107 revsetpredicate = registrar.revsetpredicate()
107 revsetpredicate = registrar.revsetpredicate()
108
108
109
109
110 @revsetpredicate(b'_destrebase')
110 @revsetpredicate(b'_destrebase')
111 def _revsetdestrebase(repo, subset, x):
111 def _revsetdestrebase(repo, subset, x):
112 # ``_rebasedefaultdest()``
112 # ``_rebasedefaultdest()``
113
113
114 # default destination for rebase.
114 # default destination for rebase.
115 # # XXX: Currently private because I expect the signature to change.
115 # # XXX: Currently private because I expect the signature to change.
116 # # XXX: - bailing out in case of ambiguity vs returning all data.
116 # # XXX: - bailing out in case of ambiguity vs returning all data.
117 # i18n: "_rebasedefaultdest" is a keyword
117 # i18n: "_rebasedefaultdest" is a keyword
118 sourceset = None
118 sourceset = None
119 if x is not None:
119 if x is not None:
120 sourceset = revset.getset(repo, smartset.fullreposet(repo), x)
120 sourceset = revset.getset(repo, smartset.fullreposet(repo), x)
121 return subset & smartset.baseset([_destrebase(repo, sourceset)])
121 return subset & smartset.baseset([_destrebase(repo, sourceset)])
122
122
123
123
124 @revsetpredicate(b'_destautoorphanrebase')
124 @revsetpredicate(b'_destautoorphanrebase')
125 def _revsetdestautoorphanrebase(repo, subset, x):
125 def _revsetdestautoorphanrebase(repo, subset, x):
126 # ``_destautoorphanrebase()``
126 # ``_destautoorphanrebase()``
127
127
128 # automatic rebase destination for a single orphan revision.
128 # automatic rebase destination for a single orphan revision.
129 unfi = repo.unfiltered()
129 unfi = repo.unfiltered()
130 obsoleted = unfi.revs(b'obsolete()')
130 obsoleted = unfi.revs(b'obsolete()')
131
131
132 src = revset.getset(repo, subset, x).first()
132 src = revset.getset(repo, subset, x).first()
133
133
134 # Empty src or already obsoleted - Do not return a destination
134 # Empty src or already obsoleted - Do not return a destination
135 if not src or src in obsoleted:
135 if not src or src in obsoleted:
136 return smartset.baseset()
136 return smartset.baseset()
137 dests = destutil.orphanpossibledestination(repo, src)
137 dests = destutil.orphanpossibledestination(repo, src)
138 if len(dests) > 1:
138 if len(dests) > 1:
139 raise error.Abort(
139 raise error.Abort(
140 _(b"ambiguous automatic rebase: %r could end up on any of %r")
140 _(b"ambiguous automatic rebase: %r could end up on any of %r")
141 % (src, dests)
141 % (src, dests)
142 )
142 )
143 # We have zero or one destination, so we can just return here.
143 # We have zero or one destination, so we can just return here.
144 return smartset.baseset(dests)
144 return smartset.baseset(dests)
145
145
146
146
147 def _ctxdesc(ctx):
147 def _ctxdesc(ctx):
148 """short description for a context"""
148 """short description for a context"""
149 desc = b'%d:%s "%s"' % (
149 desc = b'%d:%s "%s"' % (
150 ctx.rev(),
150 ctx.rev(),
151 ctx,
151 ctx,
152 ctx.description().split(b'\n', 1)[0],
152 ctx.description().split(b'\n', 1)[0],
153 )
153 )
154 repo = ctx.repo()
154 repo = ctx.repo()
155 names = []
155 names = []
156 for nsname, ns in pycompat.iteritems(repo.names):
156 for nsname, ns in pycompat.iteritems(repo.names):
157 if nsname == b'branches':
157 if nsname == b'branches':
158 continue
158 continue
159 names.extend(ns.names(repo, ctx.node()))
159 names.extend(ns.names(repo, ctx.node()))
160 if names:
160 if names:
161 desc += b' (%s)' % b' '.join(names)
161 desc += b' (%s)' % b' '.join(names)
162 return desc
162 return desc
163
163
164
164
165 class rebaseruntime(object):
165 class rebaseruntime(object):
166 """This class is a container for rebase runtime state"""
166 """This class is a container for rebase runtime state"""
167
167
168 def __init__(self, repo, ui, inmemory=False, opts=None):
168 def __init__(self, repo, ui, inmemory=False, opts=None):
169 if opts is None:
169 if opts is None:
170 opts = {}
170 opts = {}
171
171
172 # prepared: whether we have rebasestate prepared or not. Currently it
172 # prepared: whether we have rebasestate prepared or not. Currently it
173 # decides whether "self.repo" is unfiltered or not.
173 # decides whether "self.repo" is unfiltered or not.
174 # The rebasestate has explicit hash to hash instructions not depending
174 # The rebasestate has explicit hash to hash instructions not depending
175 # on visibility. If rebasestate exists (in-memory or on-disk), use
175 # on visibility. If rebasestate exists (in-memory or on-disk), use
176 # unfiltered repo to avoid visibility issues.
176 # unfiltered repo to avoid visibility issues.
177 # Before knowing rebasestate (i.e. when starting a new rebase (not
177 # Before knowing rebasestate (i.e. when starting a new rebase (not
178 # --continue or --abort)), the original repo should be used so
178 # --continue or --abort)), the original repo should be used so
179 # visibility-dependent revsets are correct.
179 # visibility-dependent revsets are correct.
180 self.prepared = False
180 self.prepared = False
181 self.resume = False
181 self.resume = False
182 self._repo = repo
182 self._repo = repo
183
183
184 self.ui = ui
184 self.ui = ui
185 self.opts = opts
185 self.opts = opts
186 self.originalwd = None
186 self.originalwd = None
187 self.external = nullrev
187 self.external = nullrev
188 # Mapping between the old revision id and either what is the new rebased
188 # Mapping between the old revision id and either what is the new rebased
189 # revision or what needs to be done with the old revision. The state
189 # revision or what needs to be done with the old revision. The state
190 # dict will be what contains most of the rebase progress state.
190 # dict will be what contains most of the rebase progress state.
191 self.state = {}
191 self.state = {}
192 self.activebookmark = None
192 self.activebookmark = None
193 self.destmap = {}
193 self.destmap = {}
194 self.skipped = set()
194 self.skipped = set()
195
195
196 self.collapsef = opts.get(b'collapse', False)
196 self.collapsef = opts.get(b'collapse', False)
197 self.collapsemsg = cmdutil.logmessage(ui, opts)
197 self.collapsemsg = cmdutil.logmessage(ui, opts)
198 self.date = opts.get(b'date', None)
198 self.date = opts.get(b'date', None)
199
199
200 e = opts.get(b'extrafn') # internal, used by e.g. hgsubversion
200 e = opts.get(b'extrafn') # internal, used by e.g. hgsubversion
201 self.extrafns = [_savegraft]
201 self.extrafns = [_savegraft]
202 if e:
202 if e:
203 self.extrafns = [e]
203 self.extrafns = [e]
204
204
205 self.backupf = ui.configbool(b'rewrite', b'backup-bundle')
205 self.backupf = ui.configbool(b'rewrite', b'backup-bundle')
206 self.keepf = opts.get(b'keep', False)
206 self.keepf = opts.get(b'keep', False)
207 self.keepbranchesf = opts.get(b'keepbranches', False)
207 self.keepbranchesf = opts.get(b'keepbranches', False)
208 self.obsoletenotrebased = {}
208 self.obsoletenotrebased = {}
209 self.obsoletewithoutsuccessorindestination = set()
209 self.obsoletewithoutsuccessorindestination = set()
210 self.inmemory = inmemory
210 self.inmemory = inmemory
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 pycompat.iteritems(self.state):
245 for d, v in pycompat.iteritems(self.state):
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, obsoleterevs, destmap):
350 def _handleskippingobsolete(self, obsoleterevs, destmap):
351 """Compute structures necessary for skipping obsolete revisions
351 """Compute structures necessary for skipping obsolete revisions
352
352
353 obsoleterevs: iterable of all obsolete revisions in rebaseset
353 obsoleterevs: iterable of all obsolete revisions in rebaseset
354 destmap: {srcrev: destrev} destination revisions
354 destmap: {srcrev: destrev} destination revisions
355 """
355 """
356 self.obsoletenotrebased = {}
356 self.obsoletenotrebased = {}
357 if not self.ui.configbool(b'experimental', b'rebaseskipobsolete'):
357 if not self.ui.configbool(b'experimental', b'rebaseskipobsolete'):
358 return
358 return
359 obsoleteset = set(obsoleterevs)
359 obsoleteset = set(obsoleterevs)
360 (
360 (
361 self.obsoletenotrebased,
361 self.obsoletenotrebased,
362 self.obsoletewithoutsuccessorindestination,
362 self.obsoletewithoutsuccessorindestination,
363 obsoleteextinctsuccessors,
363 obsoleteextinctsuccessors,
364 ) = _computeobsoletenotrebased(self.repo, obsoleteset, destmap)
364 ) = _computeobsoletenotrebased(self.repo, obsoleteset, destmap)
365 skippedset = set(self.obsoletenotrebased)
365 skippedset = set(self.obsoletenotrebased)
366 skippedset.update(self.obsoletewithoutsuccessorindestination)
366 skippedset.update(self.obsoletewithoutsuccessorindestination)
367 skippedset.update(obsoleteextinctsuccessors)
367 skippedset.update(obsoleteextinctsuccessors)
368 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
368 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
369
369
370 def _prepareabortorcontinue(self, isabort, backup=True, suppwarns=False):
370 def _prepareabortorcontinue(self, isabort, backup=True, suppwarns=False):
371 self.resume = True
371 self.resume = True
372 try:
372 try:
373 self.restorestatus()
373 self.restorestatus()
374 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
374 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
375 except error.RepoLookupError:
375 except error.RepoLookupError:
376 if isabort:
376 if isabort:
377 clearstatus(self.repo)
377 clearstatus(self.repo)
378 clearcollapsemsg(self.repo)
378 clearcollapsemsg(self.repo)
379 self.repo.ui.warn(
379 self.repo.ui.warn(
380 _(
380 _(
381 b'rebase aborted (no revision is removed,'
381 b'rebase aborted (no revision is removed,'
382 b' only broken state is cleared)\n'
382 b' only broken state is cleared)\n'
383 )
383 )
384 )
384 )
385 return 0
385 return 0
386 else:
386 else:
387 msg = _(b'cannot continue inconsistent rebase')
387 msg = _(b'cannot continue inconsistent rebase')
388 hint = _(b'use "hg rebase --abort" to clear broken state')
388 hint = _(b'use "hg rebase --abort" to clear broken state')
389 raise error.Abort(msg, hint=hint)
389 raise error.Abort(msg, hint=hint)
390
390
391 if isabort:
391 if isabort:
392 backup = backup and self.backupf
392 backup = backup and self.backupf
393 return self._abort(backup=backup, suppwarns=suppwarns)
393 return self._abort(backup=backup, suppwarns=suppwarns)
394
394
395 def _preparenewrebase(self, destmap):
395 def _preparenewrebase(self, destmap):
396 if not destmap:
396 if not destmap:
397 return _nothingtorebase()
397 return _nothingtorebase()
398
398
399 rebaseset = destmap.keys()
399 rebaseset = destmap.keys()
400 if not self.keepf:
400 if not self.keepf:
401 try:
401 try:
402 rewriteutil.precheck(self.repo, rebaseset, action=b'rebase')
402 rewriteutil.precheck(self.repo, rebaseset, action=b'rebase')
403 except error.Abort as e:
403 except error.Abort as e:
404 if e.hint is None:
404 if e.hint is None:
405 e.hint = _(b'use --keep to keep original changesets')
405 e.hint = _(b'use --keep to keep original changesets')
406 raise e
406 raise e
407
407
408 result = buildstate(self.repo, destmap, self.collapsef)
408 result = buildstate(self.repo, destmap, self.collapsef)
409
409
410 if not result:
410 if not result:
411 # Empty state built, nothing to rebase
411 # Empty state built, nothing to rebase
412 self.ui.status(_(b'nothing to rebase\n'))
412 self.ui.status(_(b'nothing to rebase\n'))
413 return _nothingtorebase()
413 return _nothingtorebase()
414
414
415 (self.originalwd, self.destmap, self.state) = result
415 (self.originalwd, self.destmap, self.state) = result
416 if self.collapsef:
416 if self.collapsef:
417 dests = set(self.destmap.values())
417 dests = set(self.destmap.values())
418 if len(dests) != 1:
418 if len(dests) != 1:
419 raise error.Abort(
419 raise error.Abort(
420 _(b'--collapse does not work with multiple destinations')
420 _(b'--collapse does not work with multiple destinations')
421 )
421 )
422 destrev = next(iter(dests))
422 destrev = next(iter(dests))
423 destancestors = self.repo.changelog.ancestors(
423 destancestors = self.repo.changelog.ancestors(
424 [destrev], inclusive=True
424 [destrev], inclusive=True
425 )
425 )
426 self.external = externalparent(self.repo, self.state, destancestors)
426 self.external = externalparent(self.repo, self.state, destancestors)
427
427
428 for destrev in sorted(set(destmap.values())):
428 for destrev in sorted(set(destmap.values())):
429 dest = self.repo[destrev]
429 dest = self.repo[destrev]
430 if dest.closesbranch() and not self.keepbranchesf:
430 if dest.closesbranch() and not self.keepbranchesf:
431 self.ui.status(_(b'reopening closed branch head %s\n') % dest)
431 self.ui.status(_(b'reopening closed branch head %s\n') % dest)
432
432
433 self.prepared = True
433 self.prepared = True
434
434
435 def _assignworkingcopy(self):
435 def _assignworkingcopy(self):
436 if self.inmemory:
436 if self.inmemory:
437 from mercurial.context import overlayworkingctx
437 from mercurial.context import overlayworkingctx
438
438
439 self.wctx = overlayworkingctx(self.repo)
439 self.wctx = overlayworkingctx(self.repo)
440 self.repo.ui.debug(b"rebasing in-memory\n")
440 self.repo.ui.debug(b"rebasing in-memory\n")
441 else:
441 else:
442 self.wctx = self.repo[None]
442 self.wctx = self.repo[None]
443 self.repo.ui.debug(b"rebasing on disk\n")
443 self.repo.ui.debug(b"rebasing on disk\n")
444 self.repo.ui.log(
444 self.repo.ui.log(
445 b"rebase",
445 b"rebase",
446 b"using in-memory rebase: %r\n",
446 b"using in-memory rebase: %r\n",
447 self.inmemory,
447 self.inmemory,
448 rebase_imm_used=self.inmemory,
448 rebase_imm_used=self.inmemory,
449 )
449 )
450
450
451 def _performrebase(self, tr):
451 def _performrebase(self, tr):
452 self._assignworkingcopy()
452 self._assignworkingcopy()
453 repo, ui = self.repo, self.ui
453 repo, ui = self.repo, self.ui
454 if self.keepbranchesf:
454 if self.keepbranchesf:
455 # insert _savebranch at the start of extrafns so if
455 # insert _savebranch at the start of extrafns so if
456 # there's a user-provided extrafn it can clobber branch if
456 # there's a user-provided extrafn it can clobber branch if
457 # desired
457 # desired
458 self.extrafns.insert(0, _savebranch)
458 self.extrafns.insert(0, _savebranch)
459 if self.collapsef:
459 if self.collapsef:
460 branches = set()
460 branches = set()
461 for rev in self.state:
461 for rev in self.state:
462 branches.add(repo[rev].branch())
462 branches.add(repo[rev].branch())
463 if len(branches) > 1:
463 if len(branches) > 1:
464 raise error.Abort(
464 raise error.Abort(
465 _(b'cannot collapse multiple named branches')
465 _(b'cannot collapse multiple named branches')
466 )
466 )
467
467
468 # Calculate self.obsoletenotrebased
468 # Calculate self.obsoletenotrebased
469 obsrevs = _filterobsoleterevs(self.repo, self.state)
469 obsrevs = _filterobsoleterevs(self.repo, self.state)
470 self._handleskippingobsolete(obsrevs, self.destmap)
470 self._handleskippingobsolete(obsrevs, self.destmap)
471
471
472 # Keep track of the active bookmarks in order to reset them later
472 # Keep track of the active bookmarks in order to reset them later
473 self.activebookmark = self.activebookmark or repo._activebookmark
473 self.activebookmark = self.activebookmark or repo._activebookmark
474 if self.activebookmark:
474 if self.activebookmark:
475 bookmarks.deactivate(repo)
475 bookmarks.deactivate(repo)
476
476
477 # Store the state before we begin so users can run 'hg rebase --abort'
477 # Store the state before we begin so users can run 'hg rebase --abort'
478 # if we fail before the transaction closes.
478 # if we fail before the transaction closes.
479 self.storestatus()
479 self.storestatus()
480 if tr:
480 if tr:
481 # When using single transaction, store state when transaction
481 # When using single transaction, store state when transaction
482 # commits.
482 # commits.
483 self.storestatus(tr)
483 self.storestatus(tr)
484
484
485 cands = [k for k, v in pycompat.iteritems(self.state) if v == revtodo]
485 cands = [k for k, v in pycompat.iteritems(self.state) if v == revtodo]
486 p = repo.ui.makeprogress(
486 p = repo.ui.makeprogress(
487 _(b"rebasing"), unit=_(b'changesets'), total=len(cands)
487 _(b"rebasing"), unit=_(b'changesets'), total=len(cands)
488 )
488 )
489
489
490 def progress(ctx):
490 def progress(ctx):
491 p.increment(item=(b"%d:%s" % (ctx.rev(), ctx)))
491 p.increment(item=(b"%d:%s" % (ctx.rev(), ctx)))
492
492
493 allowdivergence = self.ui.configbool(
493 allowdivergence = self.ui.configbool(
494 b'experimental', b'evolution.allowdivergence'
494 b'experimental', b'evolution.allowdivergence'
495 )
495 )
496 for subset in sortsource(self.destmap):
496 for subset in sortsource(self.destmap):
497 sortedrevs = self.repo.revs(b'sort(%ld, -topo)', subset)
497 sortedrevs = self.repo.revs(b'sort(%ld, -topo)', subset)
498 if not allowdivergence:
498 if not allowdivergence:
499 sortedrevs -= self.repo.revs(
499 sortedrevs -= self.repo.revs(
500 b'descendants(%ld) and not %ld',
500 b'descendants(%ld) and not %ld',
501 self.obsoletewithoutsuccessorindestination,
501 self.obsoletewithoutsuccessorindestination,
502 self.obsoletewithoutsuccessorindestination,
502 self.obsoletewithoutsuccessorindestination,
503 )
503 )
504 for rev in sortedrevs:
504 for rev in sortedrevs:
505 self._rebasenode(tr, rev, allowdivergence, progress)
505 self._rebasenode(tr, rev, allowdivergence, progress)
506 p.complete()
506 p.complete()
507 ui.note(_(b'rebase merging completed\n'))
507 ui.note(_(b'rebase merging completed\n'))
508
508
509 def _concludenode(self, rev, p1, p2, editor, commitmsg=None):
509 def _concludenode(self, rev, p1, p2, editor, commitmsg=None):
510 '''Commit the wd changes with parents p1 and p2.
510 '''Commit the wd changes with parents p1 and p2.
511
511
512 Reuse commit info from rev but also store useful information in extra.
512 Reuse commit info from rev but also store useful information in extra.
513 Return node of committed revision.'''
513 Return node of committed revision.'''
514 repo = self.repo
514 repo = self.repo
515 ctx = repo[rev]
515 ctx = repo[rev]
516 if commitmsg is None:
516 if commitmsg is None:
517 commitmsg = ctx.description()
517 commitmsg = ctx.description()
518 date = self.date
518 date = self.date
519 if date is None:
519 if date is None:
520 date = ctx.date()
520 date = ctx.date()
521 extra = {b'rebase_source': ctx.hex()}
521 extra = {b'rebase_source': ctx.hex()}
522 for c in self.extrafns:
522 for c in self.extrafns:
523 c(ctx, extra)
523 c(ctx, extra)
524 keepbranch = self.keepbranchesf and repo[p1].branch() != ctx.branch()
524 keepbranch = self.keepbranchesf and repo[p1].branch() != ctx.branch()
525 destphase = max(ctx.phase(), phases.draft)
525 destphase = max(ctx.phase(), phases.draft)
526 overrides = {(b'phases', b'new-commit'): destphase}
526 overrides = {(b'phases', b'new-commit'): destphase}
527 if keepbranch:
527 if keepbranch:
528 overrides[(b'ui', b'allowemptycommit')] = True
528 overrides[(b'ui', b'allowemptycommit')] = True
529 with repo.ui.configoverride(overrides, b'rebase'):
529 with repo.ui.configoverride(overrides, b'rebase'):
530 if self.inmemory:
530 if self.inmemory:
531 newnode = commitmemorynode(
531 newnode = commitmemorynode(
532 repo,
532 repo,
533 p1,
533 p1,
534 p2,
534 p2,
535 wctx=self.wctx,
535 wctx=self.wctx,
536 extra=extra,
536 extra=extra,
537 commitmsg=commitmsg,
537 commitmsg=commitmsg,
538 editor=editor,
538 editor=editor,
539 user=ctx.user(),
539 user=ctx.user(),
540 date=date,
540 date=date,
541 )
541 )
542 mergemod.mergestate.clean(repo)
542 mergemod.mergestate.clean(repo)
543 else:
543 else:
544 newnode = commitnode(
544 newnode = commitnode(
545 repo,
545 repo,
546 p1,
546 p1,
547 p2,
547 p2,
548 extra=extra,
548 extra=extra,
549 commitmsg=commitmsg,
549 commitmsg=commitmsg,
550 editor=editor,
550 editor=editor,
551 user=ctx.user(),
551 user=ctx.user(),
552 date=date,
552 date=date,
553 )
553 )
554
554
555 if newnode is None:
555 if newnode is None:
556 # If it ended up being a no-op commit, then the normal
556 # If it ended up being a no-op commit, then the normal
557 # merge state clean-up path doesn't happen, so do it
557 # merge state clean-up path doesn't happen, so do it
558 # here. Fix issue5494
558 # here. Fix issue5494
559 mergemod.mergestate.clean(repo)
559 mergemod.mergestate.clean(repo)
560 return newnode
560 return newnode
561
561
562 def _rebasenode(self, tr, rev, allowdivergence, progressfn):
562 def _rebasenode(self, tr, rev, allowdivergence, progressfn):
563 repo, ui, opts = self.repo, self.ui, self.opts
563 repo, ui, opts = self.repo, self.ui, self.opts
564 dest = self.destmap[rev]
564 dest = self.destmap[rev]
565 ctx = repo[rev]
565 ctx = repo[rev]
566 desc = _ctxdesc(ctx)
566 desc = _ctxdesc(ctx)
567 if self.state[rev] == rev:
567 if self.state[rev] == rev:
568 ui.status(_(b'already rebased %s\n') % desc)
568 ui.status(_(b'already rebased %s\n') % desc)
569 elif (
569 elif (
570 not allowdivergence
570 not allowdivergence
571 and rev in self.obsoletewithoutsuccessorindestination
571 and rev in self.obsoletewithoutsuccessorindestination
572 ):
572 ):
573 msg = (
573 msg = (
574 _(
574 _(
575 b'note: not rebasing %s and its descendants as '
575 b'note: not rebasing %s and its descendants as '
576 b'this would cause divergence\n'
576 b'this would cause divergence\n'
577 )
577 )
578 % desc
578 % desc
579 )
579 )
580 repo.ui.status(msg)
580 repo.ui.status(msg)
581 self.skipped.add(rev)
581 self.skipped.add(rev)
582 elif rev in self.obsoletenotrebased:
582 elif rev in self.obsoletenotrebased:
583 succ = self.obsoletenotrebased[rev]
583 succ = self.obsoletenotrebased[rev]
584 if succ is None:
584 if succ is None:
585 msg = _(b'note: not rebasing %s, it has no successor\n') % desc
585 msg = _(b'note: not rebasing %s, it has no successor\n') % desc
586 else:
586 else:
587 succdesc = _ctxdesc(repo[succ])
587 succdesc = _ctxdesc(repo[succ])
588 msg = _(
588 msg = _(
589 b'note: not rebasing %s, already in destination as %s\n'
589 b'note: not rebasing %s, already in destination as %s\n'
590 ) % (desc, succdesc)
590 ) % (desc, succdesc)
591 repo.ui.status(msg)
591 repo.ui.status(msg)
592 # Make clearrebased aware state[rev] is not a true successor
592 # Make clearrebased aware state[rev] is not a true successor
593 self.skipped.add(rev)
593 self.skipped.add(rev)
594 # Record rev as moved to its desired destination in self.state.
594 # Record rev as moved to its desired destination in self.state.
595 # This helps bookmark and working parent movement.
595 # This helps bookmark and working parent movement.
596 dest = max(
596 dest = max(
597 adjustdest(repo, rev, self.destmap, self.state, self.skipped)
597 adjustdest(repo, rev, self.destmap, self.state, self.skipped)
598 )
598 )
599 self.state[rev] = dest
599 self.state[rev] = dest
600 elif self.state[rev] == revtodo:
600 elif self.state[rev] == revtodo:
601 ui.status(_(b'rebasing %s\n') % desc)
601 ui.status(_(b'rebasing %s\n') % desc)
602 progressfn(ctx)
602 progressfn(ctx)
603 p1, p2, base = defineparents(
603 p1, p2, base = defineparents(
604 repo,
604 repo,
605 rev,
605 rev,
606 self.destmap,
606 self.destmap,
607 self.state,
607 self.state,
608 self.skipped,
608 self.skipped,
609 self.obsoletenotrebased,
609 self.obsoletenotrebased,
610 )
610 )
611 if self.resume and self.wctx.p1().rev() == p1:
611 if self.resume and self.wctx.p1().rev() == p1:
612 repo.ui.debug(b'resuming interrupted rebase\n')
612 repo.ui.debug(b'resuming interrupted rebase\n')
613 self.resume = False
613 self.resume = False
614 else:
614 else:
615 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
615 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
616 with ui.configoverride(overrides, b'rebase'):
616 with ui.configoverride(overrides, b'rebase'):
617 stats = rebasenode(
617 stats = rebasenode(
618 repo,
618 repo,
619 rev,
619 rev,
620 p1,
620 p1,
621 p2,
621 base,
622 base,
622 self.collapsef,
623 self.collapsef,
623 dest,
624 dest,
624 wctx=self.wctx,
625 wctx=self.wctx,
625 )
626 )
626 if stats.unresolvedcount > 0:
627 if stats.unresolvedcount > 0:
627 if self.inmemory:
628 if self.inmemory:
628 raise error.InMemoryMergeConflictsError()
629 raise error.InMemoryMergeConflictsError()
629 else:
630 else:
630 raise error.InterventionRequired(
631 raise error.InterventionRequired(
631 _(
632 _(
632 b'unresolved conflicts (see hg '
633 b'unresolved conflicts (see hg '
633 b'resolve, then hg rebase --continue)'
634 b'resolve, then hg rebase --continue)'
634 )
635 )
635 )
636 )
636 if not self.collapsef:
637 if not self.collapsef:
637 merging = p2 != nullrev
638 merging = p2 != nullrev
638 editform = cmdutil.mergeeditform(merging, b'rebase')
639 editform = cmdutil.mergeeditform(merging, b'rebase')
639 editor = cmdutil.getcommiteditor(
640 editor = cmdutil.getcommiteditor(
640 editform=editform, **pycompat.strkwargs(opts)
641 editform=editform, **pycompat.strkwargs(opts)
641 )
642 )
642 newnode = self._concludenode(rev, p1, p2, editor)
643 newnode = self._concludenode(rev, p1, p2, editor)
643 else:
644 else:
644 # Skip commit if we are collapsing
645 # Skip commit if we are collapsing
645 if self.inmemory:
646 self.wctx.setbase(repo[p1])
647 else:
648 repo.setparents(repo[p1].node())
649 newnode = None
646 newnode = None
650 # Update the state
647 # Update the state
651 if newnode is not None:
648 if newnode is not None:
652 self.state[rev] = repo[newnode].rev()
649 self.state[rev] = repo[newnode].rev()
653 ui.debug(b'rebased as %s\n' % short(newnode))
650 ui.debug(b'rebased as %s\n' % short(newnode))
654 else:
651 else:
655 if not self.collapsef:
652 if not self.collapsef:
656 ui.warn(
653 ui.warn(
657 _(
654 _(
658 b'note: not rebasing %s, its destination already '
655 b'note: not rebasing %s, its destination already '
659 b'has all its changes\n'
656 b'has all its changes\n'
660 )
657 )
661 % desc
658 % desc
662 )
659 )
663 self.skipped.add(rev)
660 self.skipped.add(rev)
664 self.state[rev] = p1
661 self.state[rev] = p1
665 ui.debug(b'next revision set to %d\n' % p1)
662 ui.debug(b'next revision set to %d\n' % p1)
666 else:
663 else:
667 ui.status(
664 ui.status(
668 _(b'already rebased %s as %s\n') % (desc, repo[self.state[rev]])
665 _(b'already rebased %s as %s\n') % (desc, repo[self.state[rev]])
669 )
666 )
670 if not tr:
667 if not tr:
671 # When not using single transaction, store state after each
668 # When not using single transaction, store state after each
672 # commit is completely done. On InterventionRequired, we thus
669 # commit is completely done. On InterventionRequired, we thus
673 # won't store the status. Instead, we'll hit the "len(parents) == 2"
670 # won't store the status. Instead, we'll hit the "len(parents) == 2"
674 # case and realize that the commit was in progress.
671 # case and realize that the commit was in progress.
675 self.storestatus()
672 self.storestatus()
676
673
677 def _finishrebase(self):
674 def _finishrebase(self):
678 repo, ui, opts = self.repo, self.ui, self.opts
675 repo, ui, opts = self.repo, self.ui, self.opts
679 fm = ui.formatter(b'rebase', opts)
676 fm = ui.formatter(b'rebase', opts)
680 fm.startitem()
677 fm.startitem()
681 if self.collapsef:
678 if self.collapsef:
682 p1, p2, _base = defineparents(
679 p1, p2, _base = defineparents(
683 repo,
680 repo,
684 min(self.state),
681 min(self.state),
685 self.destmap,
682 self.destmap,
686 self.state,
683 self.state,
687 self.skipped,
684 self.skipped,
688 self.obsoletenotrebased,
685 self.obsoletenotrebased,
689 )
686 )
690 editopt = opts.get(b'edit')
687 editopt = opts.get(b'edit')
691 editform = b'rebase.collapse'
688 editform = b'rebase.collapse'
692 if self.collapsemsg:
689 if self.collapsemsg:
693 commitmsg = self.collapsemsg
690 commitmsg = self.collapsemsg
694 else:
691 else:
695 commitmsg = b'Collapsed revision'
692 commitmsg = b'Collapsed revision'
696 for rebased in sorted(self.state):
693 for rebased in sorted(self.state):
697 if rebased not in self.skipped:
694 if rebased not in self.skipped:
698 commitmsg += b'\n* %s' % repo[rebased].description()
695 commitmsg += b'\n* %s' % repo[rebased].description()
699 editopt = True
696 editopt = True
700 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
697 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
701 revtoreuse = max(self.state)
698 revtoreuse = max(self.state)
702
699
703 newnode = self._concludenode(
700 newnode = self._concludenode(
704 revtoreuse, p1, self.external, editor, commitmsg=commitmsg
701 revtoreuse, p1, self.external, editor, commitmsg=commitmsg
705 )
702 )
706
703
707 if newnode is not None:
704 if newnode is not None:
708 newrev = repo[newnode].rev()
705 newrev = repo[newnode].rev()
709 for oldrev in self.state:
706 for oldrev in self.state:
710 self.state[oldrev] = newrev
707 self.state[oldrev] = newrev
711
708
712 if b'qtip' in repo.tags():
709 if b'qtip' in repo.tags():
713 updatemq(repo, self.state, self.skipped, **pycompat.strkwargs(opts))
710 updatemq(repo, self.state, self.skipped, **pycompat.strkwargs(opts))
714
711
715 # restore original working directory
712 # restore original working directory
716 # (we do this before stripping)
713 # (we do this before stripping)
717 newwd = self.state.get(self.originalwd, self.originalwd)
714 newwd = self.state.get(self.originalwd, self.originalwd)
718 if newwd < 0:
715 if newwd < 0:
719 # original directory is a parent of rebase set root or ignored
716 # original directory is a parent of rebase set root or ignored
720 newwd = self.originalwd
717 newwd = self.originalwd
721 if newwd not in [c.rev() for c in repo[None].parents()]:
718 if newwd not in [c.rev() for c in repo[None].parents()]:
722 ui.note(_(b"update back to initial working directory parent\n"))
719 ui.note(_(b"update back to initial working directory parent\n"))
723 hg.updaterepo(repo, newwd, overwrite=False)
720 hg.updaterepo(repo, newwd, overwrite=False)
724
721
725 collapsedas = None
722 collapsedas = None
726 if self.collapsef and not self.keepf:
723 if self.collapsef and not self.keepf:
727 collapsedas = newnode
724 collapsedas = newnode
728 clearrebased(
725 clearrebased(
729 ui,
726 ui,
730 repo,
727 repo,
731 self.destmap,
728 self.destmap,
732 self.state,
729 self.state,
733 self.skipped,
730 self.skipped,
734 collapsedas,
731 collapsedas,
735 self.keepf,
732 self.keepf,
736 fm=fm,
733 fm=fm,
737 backup=self.backupf,
734 backup=self.backupf,
738 )
735 )
739
736
740 clearstatus(repo)
737 clearstatus(repo)
741 clearcollapsemsg(repo)
738 clearcollapsemsg(repo)
742
739
743 ui.note(_(b"rebase completed\n"))
740 ui.note(_(b"rebase completed\n"))
744 util.unlinkpath(repo.sjoin(b'undo'), ignoremissing=True)
741 util.unlinkpath(repo.sjoin(b'undo'), ignoremissing=True)
745 if self.skipped:
742 if self.skipped:
746 skippedlen = len(self.skipped)
743 skippedlen = len(self.skipped)
747 ui.note(_(b"%d revisions have been skipped\n") % skippedlen)
744 ui.note(_(b"%d revisions have been skipped\n") % skippedlen)
748 fm.end()
745 fm.end()
749
746
750 if (
747 if (
751 self.activebookmark
748 self.activebookmark
752 and self.activebookmark in repo._bookmarks
749 and self.activebookmark in repo._bookmarks
753 and repo[b'.'].node() == repo._bookmarks[self.activebookmark]
750 and repo[b'.'].node() == repo._bookmarks[self.activebookmark]
754 ):
751 ):
755 bookmarks.activate(repo, self.activebookmark)
752 bookmarks.activate(repo, self.activebookmark)
756
753
757 def _abort(self, backup=True, suppwarns=False):
754 def _abort(self, backup=True, suppwarns=False):
758 '''Restore the repository to its original state.'''
755 '''Restore the repository to its original state.'''
759
756
760 repo = self.repo
757 repo = self.repo
761 try:
758 try:
762 # If the first commits in the rebased set get skipped during the
759 # If the first commits in the rebased set get skipped during the
763 # rebase, their values within the state mapping will be the dest
760 # rebase, their values within the state mapping will be the dest
764 # rev id. The rebased list must must not contain the dest rev
761 # rev id. The rebased list must must not contain the dest rev
765 # (issue4896)
762 # (issue4896)
766 rebased = [
763 rebased = [
767 s
764 s
768 for r, s in self.state.items()
765 for r, s in self.state.items()
769 if s >= 0 and s != r and s != self.destmap[r]
766 if s >= 0 and s != r and s != self.destmap[r]
770 ]
767 ]
771 immutable = [d for d in rebased if not repo[d].mutable()]
768 immutable = [d for d in rebased if not repo[d].mutable()]
772 cleanup = True
769 cleanup = True
773 if immutable:
770 if immutable:
774 repo.ui.warn(
771 repo.ui.warn(
775 _(b"warning: can't clean up public changesets %s\n")
772 _(b"warning: can't clean up public changesets %s\n")
776 % b', '.join(bytes(repo[r]) for r in immutable),
773 % b', '.join(bytes(repo[r]) for r in immutable),
777 hint=_(b"see 'hg help phases' for details"),
774 hint=_(b"see 'hg help phases' for details"),
778 )
775 )
779 cleanup = False
776 cleanup = False
780
777
781 descendants = set()
778 descendants = set()
782 if rebased:
779 if rebased:
783 descendants = set(repo.changelog.descendants(rebased))
780 descendants = set(repo.changelog.descendants(rebased))
784 if descendants - set(rebased):
781 if descendants - set(rebased):
785 repo.ui.warn(
782 repo.ui.warn(
786 _(
783 _(
787 b"warning: new changesets detected on "
784 b"warning: new changesets detected on "
788 b"destination branch, can't strip\n"
785 b"destination branch, can't strip\n"
789 )
786 )
790 )
787 )
791 cleanup = False
788 cleanup = False
792
789
793 if cleanup:
790 if cleanup:
794 if rebased:
791 if rebased:
795 strippoints = [
792 strippoints = [
796 c.node() for c in repo.set(b'roots(%ld)', rebased)
793 c.node() for c in repo.set(b'roots(%ld)', rebased)
797 ]
794 ]
798
795
799 updateifonnodes = set(rebased)
796 updateifonnodes = set(rebased)
800 updateifonnodes.update(self.destmap.values())
797 updateifonnodes.update(self.destmap.values())
801 updateifonnodes.add(self.originalwd)
798 updateifonnodes.add(self.originalwd)
802 shouldupdate = repo[b'.'].rev() in updateifonnodes
799 shouldupdate = repo[b'.'].rev() in updateifonnodes
803
800
804 # Update away from the rebase if necessary
801 # Update away from the rebase if necessary
805 if shouldupdate:
802 if shouldupdate:
806 mergemod.clean_update(repo[self.originalwd])
803 mergemod.clean_update(repo[self.originalwd])
807
804
808 # Strip from the first rebased revision
805 # Strip from the first rebased revision
809 if rebased:
806 if rebased:
810 repair.strip(repo.ui, repo, strippoints, backup=backup)
807 repair.strip(repo.ui, repo, strippoints, backup=backup)
811
808
812 if self.activebookmark and self.activebookmark in repo._bookmarks:
809 if self.activebookmark and self.activebookmark in repo._bookmarks:
813 bookmarks.activate(repo, self.activebookmark)
810 bookmarks.activate(repo, self.activebookmark)
814
811
815 finally:
812 finally:
816 clearstatus(repo)
813 clearstatus(repo)
817 clearcollapsemsg(repo)
814 clearcollapsemsg(repo)
818 if not suppwarns:
815 if not suppwarns:
819 repo.ui.warn(_(b'rebase aborted\n'))
816 repo.ui.warn(_(b'rebase aborted\n'))
820 return 0
817 return 0
821
818
822
819
823 @command(
820 @command(
824 b'rebase',
821 b'rebase',
825 [
822 [
826 (
823 (
827 b's',
824 b's',
828 b'source',
825 b'source',
829 b'',
826 b'',
830 _(b'rebase the specified changeset and descendants'),
827 _(b'rebase the specified changeset and descendants'),
831 _(b'REV'),
828 _(b'REV'),
832 ),
829 ),
833 (
830 (
834 b'b',
831 b'b',
835 b'base',
832 b'base',
836 b'',
833 b'',
837 _(b'rebase everything from branching point of specified changeset'),
834 _(b'rebase everything from branching point of specified changeset'),
838 _(b'REV'),
835 _(b'REV'),
839 ),
836 ),
840 (b'r', b'rev', [], _(b'rebase these revisions'), _(b'REV')),
837 (b'r', b'rev', [], _(b'rebase these revisions'), _(b'REV')),
841 (
838 (
842 b'd',
839 b'd',
843 b'dest',
840 b'dest',
844 b'',
841 b'',
845 _(b'rebase onto the specified changeset'),
842 _(b'rebase onto the specified changeset'),
846 _(b'REV'),
843 _(b'REV'),
847 ),
844 ),
848 (b'', b'collapse', False, _(b'collapse the rebased changesets')),
845 (b'', b'collapse', False, _(b'collapse the rebased changesets')),
849 (
846 (
850 b'm',
847 b'm',
851 b'message',
848 b'message',
852 b'',
849 b'',
853 _(b'use text as collapse commit message'),
850 _(b'use text as collapse commit message'),
854 _(b'TEXT'),
851 _(b'TEXT'),
855 ),
852 ),
856 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
853 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
857 (
854 (
858 b'l',
855 b'l',
859 b'logfile',
856 b'logfile',
860 b'',
857 b'',
861 _(b'read collapse commit message from file'),
858 _(b'read collapse commit message from file'),
862 _(b'FILE'),
859 _(b'FILE'),
863 ),
860 ),
864 (b'k', b'keep', False, _(b'keep original changesets')),
861 (b'k', b'keep', False, _(b'keep original changesets')),
865 (b'', b'keepbranches', False, _(b'keep original branch names')),
862 (b'', b'keepbranches', False, _(b'keep original branch names')),
866 (b'D', b'detach', False, _(b'(DEPRECATED)')),
863 (b'D', b'detach', False, _(b'(DEPRECATED)')),
867 (b'i', b'interactive', False, _(b'(DEPRECATED)')),
864 (b'i', b'interactive', False, _(b'(DEPRECATED)')),
868 (b't', b'tool', b'', _(b'specify merge tool')),
865 (b't', b'tool', b'', _(b'specify merge tool')),
869 (b'', b'stop', False, _(b'stop interrupted rebase')),
866 (b'', b'stop', False, _(b'stop interrupted rebase')),
870 (b'c', b'continue', False, _(b'continue an interrupted rebase')),
867 (b'c', b'continue', False, _(b'continue an interrupted rebase')),
871 (b'a', b'abort', False, _(b'abort an interrupted rebase')),
868 (b'a', b'abort', False, _(b'abort an interrupted rebase')),
872 (
869 (
873 b'',
870 b'',
874 b'auto-orphans',
871 b'auto-orphans',
875 b'',
872 b'',
876 _(
873 _(
877 b'automatically rebase orphan revisions '
874 b'automatically rebase orphan revisions '
878 b'in the specified revset (EXPERIMENTAL)'
875 b'in the specified revset (EXPERIMENTAL)'
879 ),
876 ),
880 ),
877 ),
881 ]
878 ]
882 + cmdutil.dryrunopts
879 + cmdutil.dryrunopts
883 + cmdutil.formatteropts
880 + cmdutil.formatteropts
884 + cmdutil.confirmopts,
881 + cmdutil.confirmopts,
885 _(b'[-s REV | -b REV] [-d REV] [OPTION]'),
882 _(b'[-s REV | -b REV] [-d REV] [OPTION]'),
886 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
883 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
887 )
884 )
888 def rebase(ui, repo, **opts):
885 def rebase(ui, repo, **opts):
889 """move changeset (and descendants) to a different branch
886 """move changeset (and descendants) to a different branch
890
887
891 Rebase uses repeated merging to graft changesets from one part of
888 Rebase uses repeated merging to graft changesets from one part of
892 history (the source) onto another (the destination). This can be
889 history (the source) onto another (the destination). This can be
893 useful for linearizing *local* changes relative to a master
890 useful for linearizing *local* changes relative to a master
894 development tree.
891 development tree.
895
892
896 Published commits cannot be rebased (see :hg:`help phases`).
893 Published commits cannot be rebased (see :hg:`help phases`).
897 To copy commits, see :hg:`help graft`.
894 To copy commits, see :hg:`help graft`.
898
895
899 If you don't specify a destination changeset (``-d/--dest``), rebase
896 If you don't specify a destination changeset (``-d/--dest``), rebase
900 will use the same logic as :hg:`merge` to pick a destination. if
897 will use the same logic as :hg:`merge` to pick a destination. if
901 the current branch contains exactly one other head, the other head
898 the current branch contains exactly one other head, the other head
902 is merged with by default. Otherwise, an explicit revision with
899 is merged with by default. Otherwise, an explicit revision with
903 which to merge with must be provided. (destination changeset is not
900 which to merge with must be provided. (destination changeset is not
904 modified by rebasing, but new changesets are added as its
901 modified by rebasing, but new changesets are added as its
905 descendants.)
902 descendants.)
906
903
907 Here are the ways to select changesets:
904 Here are the ways to select changesets:
908
905
909 1. Explicitly select them using ``--rev``.
906 1. Explicitly select them using ``--rev``.
910
907
911 2. Use ``--source`` to select a root changeset and include all of its
908 2. Use ``--source`` to select a root changeset and include all of its
912 descendants.
909 descendants.
913
910
914 3. Use ``--base`` to select a changeset; rebase will find ancestors
911 3. Use ``--base`` to select a changeset; rebase will find ancestors
915 and their descendants which are not also ancestors of the destination.
912 and their descendants which are not also ancestors of the destination.
916
913
917 4. If you do not specify any of ``--rev``, ``--source``, or ``--base``,
914 4. If you do not specify any of ``--rev``, ``--source``, or ``--base``,
918 rebase will use ``--base .`` as above.
915 rebase will use ``--base .`` as above.
919
916
920 If ``--source`` or ``--rev`` is used, special names ``SRC`` and ``ALLSRC``
917 If ``--source`` or ``--rev`` is used, special names ``SRC`` and ``ALLSRC``
921 can be used in ``--dest``. Destination would be calculated per source
918 can be used in ``--dest``. Destination would be calculated per source
922 revision with ``SRC`` substituted by that single source revision and
919 revision with ``SRC`` substituted by that single source revision and
923 ``ALLSRC`` substituted by all source revisions.
920 ``ALLSRC`` substituted by all source revisions.
924
921
925 Rebase will destroy original changesets unless you use ``--keep``.
922 Rebase will destroy original changesets unless you use ``--keep``.
926 It will also move your bookmarks (even if you do).
923 It will also move your bookmarks (even if you do).
927
924
928 Some changesets may be dropped if they do not contribute changes
925 Some changesets may be dropped if they do not contribute changes
929 (e.g. merges from the destination branch).
926 (e.g. merges from the destination branch).
930
927
931 Unlike ``merge``, rebase will do nothing if you are at the branch tip of
928 Unlike ``merge``, rebase will do nothing if you are at the branch tip of
932 a named branch with two heads. You will need to explicitly specify source
929 a named branch with two heads. You will need to explicitly specify source
933 and/or destination.
930 and/or destination.
934
931
935 If you need to use a tool to automate merge/conflict decisions, you
932 If you need to use a tool to automate merge/conflict decisions, you
936 can specify one with ``--tool``, see :hg:`help merge-tools`.
933 can specify one with ``--tool``, see :hg:`help merge-tools`.
937 As a caveat: the tool will not be used to mediate when a file was
934 As a caveat: the tool will not be used to mediate when a file was
938 deleted, there is no hook presently available for this.
935 deleted, there is no hook presently available for this.
939
936
940 If a rebase is interrupted to manually resolve a conflict, it can be
937 If a rebase is interrupted to manually resolve a conflict, it can be
941 continued with --continue/-c, aborted with --abort/-a, or stopped with
938 continued with --continue/-c, aborted with --abort/-a, or stopped with
942 --stop.
939 --stop.
943
940
944 .. container:: verbose
941 .. container:: verbose
945
942
946 Examples:
943 Examples:
947
944
948 - move "local changes" (current commit back to branching point)
945 - move "local changes" (current commit back to branching point)
949 to the current branch tip after a pull::
946 to the current branch tip after a pull::
950
947
951 hg rebase
948 hg rebase
952
949
953 - move a single changeset to the stable branch::
950 - move a single changeset to the stable branch::
954
951
955 hg rebase -r 5f493448 -d stable
952 hg rebase -r 5f493448 -d stable
956
953
957 - splice a commit and all its descendants onto another part of history::
954 - splice a commit and all its descendants onto another part of history::
958
955
959 hg rebase --source c0c3 --dest 4cf9
956 hg rebase --source c0c3 --dest 4cf9
960
957
961 - rebase everything on a branch marked by a bookmark onto the
958 - rebase everything on a branch marked by a bookmark onto the
962 default branch::
959 default branch::
963
960
964 hg rebase --base myfeature --dest default
961 hg rebase --base myfeature --dest default
965
962
966 - collapse a sequence of changes into a single commit::
963 - collapse a sequence of changes into a single commit::
967
964
968 hg rebase --collapse -r 1520:1525 -d .
965 hg rebase --collapse -r 1520:1525 -d .
969
966
970 - move a named branch while preserving its name::
967 - move a named branch while preserving its name::
971
968
972 hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
969 hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
973
970
974 - stabilize orphaned changesets so history looks linear::
971 - stabilize orphaned changesets so history looks linear::
975
972
976 hg rebase -r 'orphan()-obsolete()'\
973 hg rebase -r 'orphan()-obsolete()'\
977 -d 'first(max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::) +\
974 -d 'first(max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::) +\
978 max(::((roots(ALLSRC) & ::SRC)^)-obsolete()))'
975 max(::((roots(ALLSRC) & ::SRC)^)-obsolete()))'
979
976
980 Configuration Options:
977 Configuration Options:
981
978
982 You can make rebase require a destination if you set the following config
979 You can make rebase require a destination if you set the following config
983 option::
980 option::
984
981
985 [commands]
982 [commands]
986 rebase.requiredest = True
983 rebase.requiredest = True
987
984
988 By default, rebase will close the transaction after each commit. For
985 By default, rebase will close the transaction after each commit. For
989 performance purposes, you can configure rebase to use a single transaction
986 performance purposes, you can configure rebase to use a single transaction
990 across the entire rebase. WARNING: This setting introduces a significant
987 across the entire rebase. WARNING: This setting introduces a significant
991 risk of losing the work you've done in a rebase if the rebase aborts
988 risk of losing the work you've done in a rebase if the rebase aborts
992 unexpectedly::
989 unexpectedly::
993
990
994 [rebase]
991 [rebase]
995 singletransaction = True
992 singletransaction = True
996
993
997 By default, rebase writes to the working copy, but you can configure it to
994 By default, rebase writes to the working copy, but you can configure it to
998 run in-memory for better performance. When the rebase is not moving the
995 run in-memory for better performance. When the rebase is not moving the
999 parent(s) of the working copy (AKA the "currently checked out changesets"),
996 parent(s) of the working copy (AKA the "currently checked out changesets"),
1000 this may also allow it to run even if the working copy is dirty::
997 this may also allow it to run even if the working copy is dirty::
1001
998
1002 [rebase]
999 [rebase]
1003 experimental.inmemory = True
1000 experimental.inmemory = True
1004
1001
1005 Return Values:
1002 Return Values:
1006
1003
1007 Returns 0 on success, 1 if nothing to rebase or there are
1004 Returns 0 on success, 1 if nothing to rebase or there are
1008 unresolved conflicts.
1005 unresolved conflicts.
1009
1006
1010 """
1007 """
1011 opts = pycompat.byteskwargs(opts)
1008 opts = pycompat.byteskwargs(opts)
1012 inmemory = ui.configbool(b'rebase', b'experimental.inmemory')
1009 inmemory = ui.configbool(b'rebase', b'experimental.inmemory')
1013 action = cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
1010 action = cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue')
1014 if action:
1011 if action:
1015 cmdutil.check_incompatible_arguments(
1012 cmdutil.check_incompatible_arguments(
1016 opts, action, [b'confirm', b'dry_run']
1013 opts, action, [b'confirm', b'dry_run']
1017 )
1014 )
1018 cmdutil.check_incompatible_arguments(
1015 cmdutil.check_incompatible_arguments(
1019 opts, action, [b'rev', b'source', b'base', b'dest']
1016 opts, action, [b'rev', b'source', b'base', b'dest']
1020 )
1017 )
1021 cmdutil.check_at_most_one_arg(opts, b'confirm', b'dry_run')
1018 cmdutil.check_at_most_one_arg(opts, b'confirm', b'dry_run')
1022 cmdutil.check_at_most_one_arg(opts, b'rev', b'source', b'base')
1019 cmdutil.check_at_most_one_arg(opts, b'rev', b'source', b'base')
1023
1020
1024 if action or repo.currenttransaction() is not None:
1021 if action or repo.currenttransaction() is not None:
1025 # in-memory rebase is not compatible with resuming rebases.
1022 # in-memory rebase is not compatible with resuming rebases.
1026 # (Or if it is run within a transaction, since the restart logic can
1023 # (Or if it is run within a transaction, since the restart logic can
1027 # fail the entire transaction.)
1024 # fail the entire transaction.)
1028 inmemory = False
1025 inmemory = False
1029
1026
1030 if opts.get(b'auto_orphans'):
1027 if opts.get(b'auto_orphans'):
1031 disallowed_opts = set(opts) - {b'auto_orphans'}
1028 disallowed_opts = set(opts) - {b'auto_orphans'}
1032 cmdutil.check_incompatible_arguments(
1029 cmdutil.check_incompatible_arguments(
1033 opts, b'auto_orphans', disallowed_opts
1030 opts, b'auto_orphans', disallowed_opts
1034 )
1031 )
1035
1032
1036 userrevs = list(repo.revs(opts.get(b'auto_orphans')))
1033 userrevs = list(repo.revs(opts.get(b'auto_orphans')))
1037 opts[b'rev'] = [revsetlang.formatspec(b'%ld and orphan()', userrevs)]
1034 opts[b'rev'] = [revsetlang.formatspec(b'%ld and orphan()', userrevs)]
1038 opts[b'dest'] = b'_destautoorphanrebase(SRC)'
1035 opts[b'dest'] = b'_destautoorphanrebase(SRC)'
1039
1036
1040 if opts.get(b'dry_run') or opts.get(b'confirm'):
1037 if opts.get(b'dry_run') or opts.get(b'confirm'):
1041 return _dryrunrebase(ui, repo, action, opts)
1038 return _dryrunrebase(ui, repo, action, opts)
1042 elif action == b'stop':
1039 elif action == b'stop':
1043 rbsrt = rebaseruntime(repo, ui)
1040 rbsrt = rebaseruntime(repo, ui)
1044 with repo.wlock(), repo.lock():
1041 with repo.wlock(), repo.lock():
1045 rbsrt.restorestatus()
1042 rbsrt.restorestatus()
1046 if rbsrt.collapsef:
1043 if rbsrt.collapsef:
1047 raise error.Abort(_(b"cannot stop in --collapse session"))
1044 raise error.Abort(_(b"cannot stop in --collapse session"))
1048 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1045 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1049 if not (rbsrt.keepf or allowunstable):
1046 if not (rbsrt.keepf or allowunstable):
1050 raise error.Abort(
1047 raise error.Abort(
1051 _(
1048 _(
1052 b"cannot remove original changesets with"
1049 b"cannot remove original changesets with"
1053 b" unrebased descendants"
1050 b" unrebased descendants"
1054 ),
1051 ),
1055 hint=_(
1052 hint=_(
1056 b'either enable obsmarkers to allow unstable '
1053 b'either enable obsmarkers to allow unstable '
1057 b'revisions or use --keep to keep original '
1054 b'revisions or use --keep to keep original '
1058 b'changesets'
1055 b'changesets'
1059 ),
1056 ),
1060 )
1057 )
1061 # update to the current working revision
1058 # update to the current working revision
1062 # to clear interrupted merge
1059 # to clear interrupted merge
1063 hg.updaterepo(repo, rbsrt.originalwd, overwrite=True)
1060 hg.updaterepo(repo, rbsrt.originalwd, overwrite=True)
1064 rbsrt._finishrebase()
1061 rbsrt._finishrebase()
1065 return 0
1062 return 0
1066 elif inmemory:
1063 elif inmemory:
1067 try:
1064 try:
1068 # in-memory merge doesn't support conflicts, so if we hit any, abort
1065 # in-memory merge doesn't support conflicts, so if we hit any, abort
1069 # and re-run as an on-disk merge.
1066 # and re-run as an on-disk merge.
1070 overrides = {(b'rebase', b'singletransaction'): True}
1067 overrides = {(b'rebase', b'singletransaction'): True}
1071 with ui.configoverride(overrides, b'rebase'):
1068 with ui.configoverride(overrides, b'rebase'):
1072 return _dorebase(ui, repo, action, opts, inmemory=inmemory)
1069 return _dorebase(ui, repo, action, opts, inmemory=inmemory)
1073 except error.InMemoryMergeConflictsError:
1070 except error.InMemoryMergeConflictsError:
1074 ui.warn(
1071 ui.warn(
1075 _(
1072 _(
1076 b'hit merge conflicts; re-running rebase without in-memory'
1073 b'hit merge conflicts; re-running rebase without in-memory'
1077 b' merge\n'
1074 b' merge\n'
1078 )
1075 )
1079 )
1076 )
1080 # TODO: Make in-memory merge not use the on-disk merge state, so
1077 # TODO: Make in-memory merge not use the on-disk merge state, so
1081 # we don't have to clean it here
1078 # we don't have to clean it here
1082 mergemod.mergestate.clean(repo)
1079 mergemod.mergestate.clean(repo)
1083 clearstatus(repo)
1080 clearstatus(repo)
1084 clearcollapsemsg(repo)
1081 clearcollapsemsg(repo)
1085 return _dorebase(ui, repo, action, opts, inmemory=False)
1082 return _dorebase(ui, repo, action, opts, inmemory=False)
1086 else:
1083 else:
1087 return _dorebase(ui, repo, action, opts)
1084 return _dorebase(ui, repo, action, opts)
1088
1085
1089
1086
1090 def _dryrunrebase(ui, repo, action, opts):
1087 def _dryrunrebase(ui, repo, action, opts):
1091 rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts)
1088 rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts)
1092 confirm = opts.get(b'confirm')
1089 confirm = opts.get(b'confirm')
1093 if confirm:
1090 if confirm:
1094 ui.status(_(b'starting in-memory rebase\n'))
1091 ui.status(_(b'starting in-memory rebase\n'))
1095 else:
1092 else:
1096 ui.status(
1093 ui.status(
1097 _(b'starting dry-run rebase; repository will not be changed\n')
1094 _(b'starting dry-run rebase; repository will not be changed\n')
1098 )
1095 )
1099 with repo.wlock(), repo.lock():
1096 with repo.wlock(), repo.lock():
1100 needsabort = True
1097 needsabort = True
1101 try:
1098 try:
1102 overrides = {(b'rebase', b'singletransaction'): True}
1099 overrides = {(b'rebase', b'singletransaction'): True}
1103 with ui.configoverride(overrides, b'rebase'):
1100 with ui.configoverride(overrides, b'rebase'):
1104 _origrebase(
1101 _origrebase(
1105 ui,
1102 ui,
1106 repo,
1103 repo,
1107 action,
1104 action,
1108 opts,
1105 opts,
1109 rbsrt,
1106 rbsrt,
1110 inmemory=True,
1107 inmemory=True,
1111 leaveunfinished=True,
1108 leaveunfinished=True,
1112 )
1109 )
1113 except error.InMemoryMergeConflictsError:
1110 except error.InMemoryMergeConflictsError:
1114 ui.status(_(b'hit a merge conflict\n'))
1111 ui.status(_(b'hit a merge conflict\n'))
1115 return 1
1112 return 1
1116 except error.Abort:
1113 except error.Abort:
1117 needsabort = False
1114 needsabort = False
1118 raise
1115 raise
1119 else:
1116 else:
1120 if confirm:
1117 if confirm:
1121 ui.status(_(b'rebase completed successfully\n'))
1118 ui.status(_(b'rebase completed successfully\n'))
1122 if not ui.promptchoice(_(b'apply changes (yn)?$$ &Yes $$ &No')):
1119 if not ui.promptchoice(_(b'apply changes (yn)?$$ &Yes $$ &No')):
1123 # finish unfinished rebase
1120 # finish unfinished rebase
1124 rbsrt._finishrebase()
1121 rbsrt._finishrebase()
1125 else:
1122 else:
1126 rbsrt._prepareabortorcontinue(
1123 rbsrt._prepareabortorcontinue(
1127 isabort=True, backup=False, suppwarns=True
1124 isabort=True, backup=False, suppwarns=True
1128 )
1125 )
1129 needsabort = False
1126 needsabort = False
1130 else:
1127 else:
1131 ui.status(
1128 ui.status(
1132 _(
1129 _(
1133 b'dry-run rebase completed successfully; run without'
1130 b'dry-run rebase completed successfully; run without'
1134 b' -n/--dry-run to perform this rebase\n'
1131 b' -n/--dry-run to perform this rebase\n'
1135 )
1132 )
1136 )
1133 )
1137 return 0
1134 return 0
1138 finally:
1135 finally:
1139 if needsabort:
1136 if needsabort:
1140 # no need to store backup in case of dryrun
1137 # no need to store backup in case of dryrun
1141 rbsrt._prepareabortorcontinue(
1138 rbsrt._prepareabortorcontinue(
1142 isabort=True, backup=False, suppwarns=True
1139 isabort=True, backup=False, suppwarns=True
1143 )
1140 )
1144
1141
1145
1142
1146 def _dorebase(ui, repo, action, opts, inmemory=False):
1143 def _dorebase(ui, repo, action, opts, inmemory=False):
1147 rbsrt = rebaseruntime(repo, ui, inmemory, opts)
1144 rbsrt = rebaseruntime(repo, ui, inmemory, opts)
1148 return _origrebase(ui, repo, action, opts, rbsrt, inmemory=inmemory)
1145 return _origrebase(ui, repo, action, opts, rbsrt, inmemory=inmemory)
1149
1146
1150
1147
1151 def _origrebase(
1148 def _origrebase(
1152 ui, repo, action, opts, rbsrt, inmemory=False, leaveunfinished=False
1149 ui, repo, action, opts, rbsrt, inmemory=False, leaveunfinished=False
1153 ):
1150 ):
1154 assert action != b'stop'
1151 assert action != b'stop'
1155 with repo.wlock(), repo.lock():
1152 with repo.wlock(), repo.lock():
1156 if opts.get(b'interactive'):
1153 if opts.get(b'interactive'):
1157 try:
1154 try:
1158 if extensions.find(b'histedit'):
1155 if extensions.find(b'histedit'):
1159 enablehistedit = b''
1156 enablehistedit = b''
1160 except KeyError:
1157 except KeyError:
1161 enablehistedit = b" --config extensions.histedit="
1158 enablehistedit = b" --config extensions.histedit="
1162 help = b"hg%s help -e histedit" % enablehistedit
1159 help = b"hg%s help -e histedit" % enablehistedit
1163 msg = (
1160 msg = (
1164 _(
1161 _(
1165 b"interactive history editing is supported by the "
1162 b"interactive history editing is supported by the "
1166 b"'histedit' extension (see \"%s\")"
1163 b"'histedit' extension (see \"%s\")"
1167 )
1164 )
1168 % help
1165 % help
1169 )
1166 )
1170 raise error.Abort(msg)
1167 raise error.Abort(msg)
1171
1168
1172 if rbsrt.collapsemsg and not rbsrt.collapsef:
1169 if rbsrt.collapsemsg and not rbsrt.collapsef:
1173 raise error.Abort(_(b'message can only be specified with collapse'))
1170 raise error.Abort(_(b'message can only be specified with collapse'))
1174
1171
1175 if action:
1172 if action:
1176 if rbsrt.collapsef:
1173 if rbsrt.collapsef:
1177 raise error.Abort(
1174 raise error.Abort(
1178 _(b'cannot use collapse with continue or abort')
1175 _(b'cannot use collapse with continue or abort')
1179 )
1176 )
1180 if action == b'abort' and opts.get(b'tool', False):
1177 if action == b'abort' and opts.get(b'tool', False):
1181 ui.warn(_(b'tool option will be ignored\n'))
1178 ui.warn(_(b'tool option will be ignored\n'))
1182 if action == b'continue':
1179 if action == b'continue':
1183 ms = mergemod.mergestate.read(repo)
1180 ms = mergemod.mergestate.read(repo)
1184 mergeutil.checkunresolved(ms)
1181 mergeutil.checkunresolved(ms)
1185
1182
1186 retcode = rbsrt._prepareabortorcontinue(
1183 retcode = rbsrt._prepareabortorcontinue(
1187 isabort=(action == b'abort')
1184 isabort=(action == b'abort')
1188 )
1185 )
1189 if retcode is not None:
1186 if retcode is not None:
1190 return retcode
1187 return retcode
1191 else:
1188 else:
1192 # search default destination in this space
1189 # search default destination in this space
1193 # used in the 'hg pull --rebase' case, see issue 5214.
1190 # used in the 'hg pull --rebase' case, see issue 5214.
1194 destspace = opts.get(b'_destspace')
1191 destspace = opts.get(b'_destspace')
1195 destmap = _definedestmap(
1192 destmap = _definedestmap(
1196 ui,
1193 ui,
1197 repo,
1194 repo,
1198 inmemory,
1195 inmemory,
1199 opts.get(b'dest', None),
1196 opts.get(b'dest', None),
1200 opts.get(b'source', None),
1197 opts.get(b'source', None),
1201 opts.get(b'base', None),
1198 opts.get(b'base', None),
1202 opts.get(b'rev', []),
1199 opts.get(b'rev', []),
1203 destspace=destspace,
1200 destspace=destspace,
1204 )
1201 )
1205 retcode = rbsrt._preparenewrebase(destmap)
1202 retcode = rbsrt._preparenewrebase(destmap)
1206 if retcode is not None:
1203 if retcode is not None:
1207 return retcode
1204 return retcode
1208 storecollapsemsg(repo, rbsrt.collapsemsg)
1205 storecollapsemsg(repo, rbsrt.collapsemsg)
1209
1206
1210 tr = None
1207 tr = None
1211
1208
1212 singletr = ui.configbool(b'rebase', b'singletransaction')
1209 singletr = ui.configbool(b'rebase', b'singletransaction')
1213 if singletr:
1210 if singletr:
1214 tr = repo.transaction(b'rebase')
1211 tr = repo.transaction(b'rebase')
1215
1212
1216 # If `rebase.singletransaction` is enabled, wrap the entire operation in
1213 # If `rebase.singletransaction` is enabled, wrap the entire operation in
1217 # one transaction here. Otherwise, transactions are obtained when
1214 # one transaction here. Otherwise, transactions are obtained when
1218 # committing each node, which is slower but allows partial success.
1215 # committing each node, which is slower but allows partial success.
1219 with util.acceptintervention(tr):
1216 with util.acceptintervention(tr):
1220 # Same logic for the dirstate guard, except we don't create one when
1217 # Same logic for the dirstate guard, except we don't create one when
1221 # rebasing in-memory (it's not needed).
1218 # rebasing in-memory (it's not needed).
1222 dsguard = None
1219 dsguard = None
1223 if singletr and not inmemory:
1220 if singletr and not inmemory:
1224 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1221 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1225 with util.acceptintervention(dsguard):
1222 with util.acceptintervention(dsguard):
1226 rbsrt._performrebase(tr)
1223 rbsrt._performrebase(tr)
1227 if not leaveunfinished:
1224 if not leaveunfinished:
1228 rbsrt._finishrebase()
1225 rbsrt._finishrebase()
1229
1226
1230
1227
1231 def _definedestmap(
1228 def _definedestmap(
1232 ui,
1229 ui,
1233 repo,
1230 repo,
1234 inmemory,
1231 inmemory,
1235 destf=None,
1232 destf=None,
1236 srcf=None,
1233 srcf=None,
1237 basef=None,
1234 basef=None,
1238 revf=None,
1235 revf=None,
1239 destspace=None,
1236 destspace=None,
1240 ):
1237 ):
1241 """use revisions argument to define destmap {srcrev: destrev}"""
1238 """use revisions argument to define destmap {srcrev: destrev}"""
1242 if revf is None:
1239 if revf is None:
1243 revf = []
1240 revf = []
1244
1241
1245 # destspace is here to work around issues with `hg pull --rebase` see
1242 # destspace is here to work around issues with `hg pull --rebase` see
1246 # issue5214 for details
1243 # issue5214 for details
1247
1244
1248 cmdutil.checkunfinished(repo)
1245 cmdutil.checkunfinished(repo)
1249 if not inmemory:
1246 if not inmemory:
1250 cmdutil.bailifchanged(repo)
1247 cmdutil.bailifchanged(repo)
1251
1248
1252 if ui.configbool(b'commands', b'rebase.requiredest') and not destf:
1249 if ui.configbool(b'commands', b'rebase.requiredest') and not destf:
1253 raise error.Abort(
1250 raise error.Abort(
1254 _(b'you must specify a destination'),
1251 _(b'you must specify a destination'),
1255 hint=_(b'use: hg rebase -d REV'),
1252 hint=_(b'use: hg rebase -d REV'),
1256 )
1253 )
1257
1254
1258 dest = None
1255 dest = None
1259
1256
1260 if revf:
1257 if revf:
1261 rebaseset = scmutil.revrange(repo, revf)
1258 rebaseset = scmutil.revrange(repo, revf)
1262 if not rebaseset:
1259 if not rebaseset:
1263 ui.status(_(b'empty "rev" revision set - nothing to rebase\n'))
1260 ui.status(_(b'empty "rev" revision set - nothing to rebase\n'))
1264 return None
1261 return None
1265 elif srcf:
1262 elif srcf:
1266 src = scmutil.revrange(repo, [srcf])
1263 src = scmutil.revrange(repo, [srcf])
1267 if not src:
1264 if not src:
1268 ui.status(_(b'empty "source" revision set - nothing to rebase\n'))
1265 ui.status(_(b'empty "source" revision set - nothing to rebase\n'))
1269 return None
1266 return None
1270 rebaseset = repo.revs(b'(%ld)::', src) or src
1267 rebaseset = repo.revs(b'(%ld)::', src) or src
1271 else:
1268 else:
1272 base = scmutil.revrange(repo, [basef or b'.'])
1269 base = scmutil.revrange(repo, [basef or b'.'])
1273 if not base:
1270 if not base:
1274 ui.status(
1271 ui.status(
1275 _(b'empty "base" revision set - ' b"can't compute rebase set\n")
1272 _(b'empty "base" revision set - ' b"can't compute rebase set\n")
1276 )
1273 )
1277 return None
1274 return None
1278 if destf:
1275 if destf:
1279 # --base does not support multiple destinations
1276 # --base does not support multiple destinations
1280 dest = scmutil.revsingle(repo, destf)
1277 dest = scmutil.revsingle(repo, destf)
1281 else:
1278 else:
1282 dest = repo[_destrebase(repo, base, destspace=destspace)]
1279 dest = repo[_destrebase(repo, base, destspace=destspace)]
1283 destf = bytes(dest)
1280 destf = bytes(dest)
1284
1281
1285 roots = [] # selected children of branching points
1282 roots = [] # selected children of branching points
1286 bpbase = {} # {branchingpoint: [origbase]}
1283 bpbase = {} # {branchingpoint: [origbase]}
1287 for b in base: # group bases by branching points
1284 for b in base: # group bases by branching points
1288 bp = repo.revs(b'ancestor(%d, %d)', b, dest.rev()).first()
1285 bp = repo.revs(b'ancestor(%d, %d)', b, dest.rev()).first()
1289 bpbase[bp] = bpbase.get(bp, []) + [b]
1286 bpbase[bp] = bpbase.get(bp, []) + [b]
1290 if None in bpbase:
1287 if None in bpbase:
1291 # emulate the old behavior, showing "nothing to rebase" (a better
1288 # emulate the old behavior, showing "nothing to rebase" (a better
1292 # behavior may be abort with "cannot find branching point" error)
1289 # behavior may be abort with "cannot find branching point" error)
1293 bpbase.clear()
1290 bpbase.clear()
1294 for bp, bs in pycompat.iteritems(bpbase): # calculate roots
1291 for bp, bs in pycompat.iteritems(bpbase): # calculate roots
1295 roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
1292 roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
1296
1293
1297 rebaseset = repo.revs(b'%ld::', roots)
1294 rebaseset = repo.revs(b'%ld::', roots)
1298
1295
1299 if not rebaseset:
1296 if not rebaseset:
1300 # transform to list because smartsets are not comparable to
1297 # transform to list because smartsets are not comparable to
1301 # lists. This should be improved to honor laziness of
1298 # lists. This should be improved to honor laziness of
1302 # smartset.
1299 # smartset.
1303 if list(base) == [dest.rev()]:
1300 if list(base) == [dest.rev()]:
1304 if basef:
1301 if basef:
1305 ui.status(
1302 ui.status(
1306 _(
1303 _(
1307 b'nothing to rebase - %s is both "base"'
1304 b'nothing to rebase - %s is both "base"'
1308 b' and destination\n'
1305 b' and destination\n'
1309 )
1306 )
1310 % dest
1307 % dest
1311 )
1308 )
1312 else:
1309 else:
1313 ui.status(
1310 ui.status(
1314 _(
1311 _(
1315 b'nothing to rebase - working directory '
1312 b'nothing to rebase - working directory '
1316 b'parent is also destination\n'
1313 b'parent is also destination\n'
1317 )
1314 )
1318 )
1315 )
1319 elif not repo.revs(b'%ld - ::%d', base, dest.rev()):
1316 elif not repo.revs(b'%ld - ::%d', base, dest.rev()):
1320 if basef:
1317 if basef:
1321 ui.status(
1318 ui.status(
1322 _(
1319 _(
1323 b'nothing to rebase - "base" %s is '
1320 b'nothing to rebase - "base" %s is '
1324 b'already an ancestor of destination '
1321 b'already an ancestor of destination '
1325 b'%s\n'
1322 b'%s\n'
1326 )
1323 )
1327 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1324 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1328 )
1325 )
1329 else:
1326 else:
1330 ui.status(
1327 ui.status(
1331 _(
1328 _(
1332 b'nothing to rebase - working '
1329 b'nothing to rebase - working '
1333 b'directory parent is already an '
1330 b'directory parent is already an '
1334 b'ancestor of destination %s\n'
1331 b'ancestor of destination %s\n'
1335 )
1332 )
1336 % dest
1333 % dest
1337 )
1334 )
1338 else: # can it happen?
1335 else: # can it happen?
1339 ui.status(
1336 ui.status(
1340 _(b'nothing to rebase from %s to %s\n')
1337 _(b'nothing to rebase from %s to %s\n')
1341 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1338 % (b'+'.join(bytes(repo[r]) for r in base), dest)
1342 )
1339 )
1343 return None
1340 return None
1344
1341
1345 if nodemod.wdirrev in rebaseset:
1342 if nodemod.wdirrev in rebaseset:
1346 raise error.Abort(_(b'cannot rebase the working copy'))
1343 raise error.Abort(_(b'cannot rebase the working copy'))
1347 rebasingwcp = repo[b'.'].rev() in rebaseset
1344 rebasingwcp = repo[b'.'].rev() in rebaseset
1348 ui.log(
1345 ui.log(
1349 b"rebase",
1346 b"rebase",
1350 b"rebasing working copy parent: %r\n",
1347 b"rebasing working copy parent: %r\n",
1351 rebasingwcp,
1348 rebasingwcp,
1352 rebase_rebasing_wcp=rebasingwcp,
1349 rebase_rebasing_wcp=rebasingwcp,
1353 )
1350 )
1354 if inmemory and rebasingwcp:
1351 if inmemory and rebasingwcp:
1355 # Check these since we did not before.
1352 # Check these since we did not before.
1356 cmdutil.checkunfinished(repo)
1353 cmdutil.checkunfinished(repo)
1357 cmdutil.bailifchanged(repo)
1354 cmdutil.bailifchanged(repo)
1358
1355
1359 if not destf:
1356 if not destf:
1360 dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
1357 dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
1361 destf = bytes(dest)
1358 destf = bytes(dest)
1362
1359
1363 allsrc = revsetlang.formatspec(b'%ld', rebaseset)
1360 allsrc = revsetlang.formatspec(b'%ld', rebaseset)
1364 alias = {b'ALLSRC': allsrc}
1361 alias = {b'ALLSRC': allsrc}
1365
1362
1366 if dest is None:
1363 if dest is None:
1367 try:
1364 try:
1368 # fast path: try to resolve dest without SRC alias
1365 # fast path: try to resolve dest without SRC alias
1369 dest = scmutil.revsingle(repo, destf, localalias=alias)
1366 dest = scmutil.revsingle(repo, destf, localalias=alias)
1370 except error.RepoLookupError:
1367 except error.RepoLookupError:
1371 # multi-dest path: resolve dest for each SRC separately
1368 # multi-dest path: resolve dest for each SRC separately
1372 destmap = {}
1369 destmap = {}
1373 for r in rebaseset:
1370 for r in rebaseset:
1374 alias[b'SRC'] = revsetlang.formatspec(b'%d', r)
1371 alias[b'SRC'] = revsetlang.formatspec(b'%d', r)
1375 # use repo.anyrevs instead of scmutil.revsingle because we
1372 # use repo.anyrevs instead of scmutil.revsingle because we
1376 # don't want to abort if destset is empty.
1373 # don't want to abort if destset is empty.
1377 destset = repo.anyrevs([destf], user=True, localalias=alias)
1374 destset = repo.anyrevs([destf], user=True, localalias=alias)
1378 size = len(destset)
1375 size = len(destset)
1379 if size == 1:
1376 if size == 1:
1380 destmap[r] = destset.first()
1377 destmap[r] = destset.first()
1381 elif size == 0:
1378 elif size == 0:
1382 ui.note(_(b'skipping %s - empty destination\n') % repo[r])
1379 ui.note(_(b'skipping %s - empty destination\n') % repo[r])
1383 else:
1380 else:
1384 raise error.Abort(
1381 raise error.Abort(
1385 _(b'rebase destination for %s is not unique') % repo[r]
1382 _(b'rebase destination for %s is not unique') % repo[r]
1386 )
1383 )
1387
1384
1388 if dest is not None:
1385 if dest is not None:
1389 # single-dest case: assign dest to each rev in rebaseset
1386 # single-dest case: assign dest to each rev in rebaseset
1390 destrev = dest.rev()
1387 destrev = dest.rev()
1391 destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
1388 destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
1392
1389
1393 if not destmap:
1390 if not destmap:
1394 ui.status(_(b'nothing to rebase - empty destination\n'))
1391 ui.status(_(b'nothing to rebase - empty destination\n'))
1395 return None
1392 return None
1396
1393
1397 return destmap
1394 return destmap
1398
1395
1399
1396
1400 def externalparent(repo, state, destancestors):
1397 def externalparent(repo, state, destancestors):
1401 """Return the revision that should be used as the second parent
1398 """Return the revision that should be used as the second parent
1402 when the revisions in state is collapsed on top of destancestors.
1399 when the revisions in state is collapsed on top of destancestors.
1403 Abort if there is more than one parent.
1400 Abort if there is more than one parent.
1404 """
1401 """
1405 parents = set()
1402 parents = set()
1406 source = min(state)
1403 source = min(state)
1407 for rev in state:
1404 for rev in state:
1408 if rev == source:
1405 if rev == source:
1409 continue
1406 continue
1410 for p in repo[rev].parents():
1407 for p in repo[rev].parents():
1411 if p.rev() not in state and p.rev() not in destancestors:
1408 if p.rev() not in state and p.rev() not in destancestors:
1412 parents.add(p.rev())
1409 parents.add(p.rev())
1413 if not parents:
1410 if not parents:
1414 return nullrev
1411 return nullrev
1415 if len(parents) == 1:
1412 if len(parents) == 1:
1416 return parents.pop()
1413 return parents.pop()
1417 raise error.Abort(
1414 raise error.Abort(
1418 _(
1415 _(
1419 b'unable to collapse on top of %d, there is more '
1416 b'unable to collapse on top of %d, there is more '
1420 b'than one external parent: %s'
1417 b'than one external parent: %s'
1421 )
1418 )
1422 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents)))
1419 % (max(destancestors), b', '.join(b"%d" % p for p in sorted(parents)))
1423 )
1420 )
1424
1421
1425
1422
1426 def commitmemorynode(repo, p1, p2, wctx, editor, extra, user, date, commitmsg):
1423 def commitmemorynode(repo, p1, p2, wctx, editor, extra, user, date, commitmsg):
1427 '''Commit the memory changes with parents p1 and p2.
1424 '''Commit the memory changes with parents p1 and p2.
1428 Return node of committed revision.'''
1425 Return node of committed revision.'''
1429 # Replicates the empty check in ``repo.commit``.
1426 # Replicates the empty check in ``repo.commit``.
1430 if wctx.isempty() and not repo.ui.configbool(b'ui', b'allowemptycommit'):
1427 if wctx.isempty() and not repo.ui.configbool(b'ui', b'allowemptycommit'):
1431 return None
1428 return None
1432
1429
1433 # By convention, ``extra['branch']`` (set by extrafn) clobbers
1430 # By convention, ``extra['branch']`` (set by extrafn) clobbers
1434 # ``branch`` (used when passing ``--keepbranches``).
1431 # ``branch`` (used when passing ``--keepbranches``).
1435 branch = None
1432 branch = None
1436 if b'branch' in extra:
1433 if b'branch' in extra:
1437 branch = extra[b'branch']
1434 branch = extra[b'branch']
1438
1435
1439 wctx.setparents(repo[p1].node(), repo[p2].node())
1436 wctx.setparents(repo[p1].node(), repo[p2].node())
1440 memctx = wctx.tomemctx(
1437 memctx = wctx.tomemctx(
1441 commitmsg,
1438 commitmsg,
1442 date=date,
1439 date=date,
1443 extra=extra,
1440 extra=extra,
1444 user=user,
1441 user=user,
1445 branch=branch,
1442 branch=branch,
1446 editor=editor,
1443 editor=editor,
1447 )
1444 )
1448 commitres = repo.commitctx(memctx)
1445 commitres = repo.commitctx(memctx)
1449 wctx.clean() # Might be reused
1446 wctx.clean() # Might be reused
1450 return commitres
1447 return commitres
1451
1448
1452
1449
1453 def commitnode(repo, p1, p2, editor, extra, user, date, commitmsg):
1450 def commitnode(repo, p1, p2, editor, extra, user, date, commitmsg):
1454 '''Commit the wd changes with parents p1 and p2.
1451 '''Commit the wd changes with parents p1 and p2.
1455 Return node of committed revision.'''
1452 Return node of committed revision.'''
1456 dsguard = util.nullcontextmanager()
1453 dsguard = util.nullcontextmanager()
1457 if not repo.ui.configbool(b'rebase', b'singletransaction'):
1454 if not repo.ui.configbool(b'rebase', b'singletransaction'):
1458 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1455 dsguard = dirstateguard.dirstateguard(repo, b'rebase')
1459 with dsguard:
1456 with dsguard:
1460 repo.setparents(repo[p1].node(), repo[p2].node())
1457 repo.setparents(repo[p1].node(), repo[p2].node())
1461
1458
1462 # Commit might fail if unresolved files exist
1459 # Commit might fail if unresolved files exist
1463 newnode = repo.commit(
1460 newnode = repo.commit(
1464 text=commitmsg, user=user, date=date, extra=extra, editor=editor
1461 text=commitmsg, user=user, date=date, extra=extra, editor=editor
1465 )
1462 )
1466
1463
1467 repo.dirstate.setbranch(repo[newnode].branch())
1464 repo.dirstate.setbranch(repo[newnode].branch())
1468 return newnode
1465 return newnode
1469
1466
1470
1467
1471 def rebasenode(repo, rev, p1, base, collapse, dest, wctx):
1468 def rebasenode(repo, rev, p1, p2, base, collapse, dest, wctx):
1472 """Rebase a single revision rev on top of p1 using base as merge ancestor"""
1469 """Rebase a single revision rev on top of p1 using base as merge ancestor"""
1473 # Merge phase
1470 # Merge phase
1474 # Update to destination and merge it with local
1471 # Update to destination and merge it with local
1475 p1ctx = repo[p1]
1472 p1ctx = repo[p1]
1476 if wctx.isinmemory():
1473 if wctx.isinmemory():
1477 wctx.setbase(p1ctx)
1474 wctx.setbase(p1ctx)
1478 else:
1475 else:
1479 if repo[b'.'].rev() != p1:
1476 if repo[b'.'].rev() != p1:
1480 repo.ui.debug(b" update to %d:%s\n" % (p1, p1ctx))
1477 repo.ui.debug(b" update to %d:%s\n" % (p1, p1ctx))
1481 mergemod.clean_update(p1ctx)
1478 mergemod.clean_update(p1ctx)
1482 else:
1479 else:
1483 repo.ui.debug(b" already in destination\n")
1480 repo.ui.debug(b" already in destination\n")
1484 # This is, alas, necessary to invalidate workingctx's manifest cache,
1481 # This is, alas, necessary to invalidate workingctx's manifest cache,
1485 # as well as other data we litter on it in other places.
1482 # as well as other data we litter on it in other places.
1486 wctx = repo[None]
1483 wctx = repo[None]
1487 repo.dirstate.write(repo.currenttransaction())
1484 repo.dirstate.write(repo.currenttransaction())
1488 ctx = repo[rev]
1485 ctx = repo[rev]
1489 repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
1486 repo.ui.debug(b" merge against %d:%s\n" % (rev, ctx))
1490 if base is not None:
1487 if base is not None:
1491 repo.ui.debug(b" detach base %d:%s\n" % (base, repo[base]))
1488 repo.ui.debug(b" detach base %d:%s\n" % (base, repo[base]))
1492
1489
1493 # See explanation in merge.graft()
1490 # See explanation in merge.graft()
1494 mergeancestor = repo.changelog.isancestor(p1ctx.node(), ctx.node())
1491 mergeancestor = repo.changelog.isancestor(p1ctx.node(), ctx.node())
1495 stats = mergemod.update(
1492 stats = mergemod.update(
1496 repo,
1493 repo,
1497 rev,
1494 rev,
1498 branchmerge=True,
1495 branchmerge=True,
1499 force=True,
1496 force=True,
1500 ancestor=base,
1497 ancestor=base,
1501 mergeancestor=mergeancestor,
1498 mergeancestor=mergeancestor,
1502 labels=[b'dest', b'source'],
1499 labels=[b'dest', b'source'],
1503 wc=wctx,
1500 wc=wctx,
1504 )
1501 )
1502 wctx.setparents(p1ctx.node(), repo[p2].node())
1505 if collapse:
1503 if collapse:
1506 copies.graftcopies(wctx, ctx, repo[dest])
1504 copies.graftcopies(wctx, ctx, repo[dest])
1507 else:
1505 else:
1508 # If we're not using --collapse, we need to
1506 # If we're not using --collapse, we need to
1509 # duplicate copies between the revision we're
1507 # duplicate copies between the revision we're
1510 # rebasing and its first parent.
1508 # rebasing and its first parent.
1511 copies.graftcopies(wctx, ctx, ctx.p1())
1509 copies.graftcopies(wctx, ctx, ctx.p1())
1512 return stats
1510 return stats
1513
1511
1514
1512
1515 def adjustdest(repo, rev, destmap, state, skipped):
1513 def adjustdest(repo, rev, destmap, state, skipped):
1516 r"""adjust rebase destination given the current rebase state
1514 r"""adjust rebase destination given the current rebase state
1517
1515
1518 rev is what is being rebased. Return a list of two revs, which are the
1516 rev is what is being rebased. Return a list of two revs, which are the
1519 adjusted destinations for rev's p1 and p2, respectively. If a parent is
1517 adjusted destinations for rev's p1 and p2, respectively. If a parent is
1520 nullrev, return dest without adjustment for it.
1518 nullrev, return dest without adjustment for it.
1521
1519
1522 For example, when doing rebasing B+E to F, C to G, rebase will first move B
1520 For example, when doing rebasing B+E to F, C to G, rebase will first move B
1523 to B1, and E's destination will be adjusted from F to B1.
1521 to B1, and E's destination will be adjusted from F to B1.
1524
1522
1525 B1 <- written during rebasing B
1523 B1 <- written during rebasing B
1526 |
1524 |
1527 F <- original destination of B, E
1525 F <- original destination of B, E
1528 |
1526 |
1529 | E <- rev, which is being rebased
1527 | E <- rev, which is being rebased
1530 | |
1528 | |
1531 | D <- prev, one parent of rev being checked
1529 | D <- prev, one parent of rev being checked
1532 | |
1530 | |
1533 | x <- skipped, ex. no successor or successor in (::dest)
1531 | x <- skipped, ex. no successor or successor in (::dest)
1534 | |
1532 | |
1535 | C <- rebased as C', different destination
1533 | C <- rebased as C', different destination
1536 | |
1534 | |
1537 | B <- rebased as B1 C'
1535 | B <- rebased as B1 C'
1538 |/ |
1536 |/ |
1539 A G <- destination of C, different
1537 A G <- destination of C, different
1540
1538
1541 Another example about merge changeset, rebase -r C+G+H -d K, rebase will
1539 Another example about merge changeset, rebase -r C+G+H -d K, rebase will
1542 first move C to C1, G to G1, and when it's checking H, the adjusted
1540 first move C to C1, G to G1, and when it's checking H, the adjusted
1543 destinations will be [C1, G1].
1541 destinations will be [C1, G1].
1544
1542
1545 H C1 G1
1543 H C1 G1
1546 /| | /
1544 /| | /
1547 F G |/
1545 F G |/
1548 K | | -> K
1546 K | | -> K
1549 | C D |
1547 | C D |
1550 | |/ |
1548 | |/ |
1551 | B | ...
1549 | B | ...
1552 |/ |/
1550 |/ |/
1553 A A
1551 A A
1554
1552
1555 Besides, adjust dest according to existing rebase information. For example,
1553 Besides, adjust dest according to existing rebase information. For example,
1556
1554
1557 B C D B needs to be rebased on top of C, C needs to be rebased on top
1555 B C D B needs to be rebased on top of C, C needs to be rebased on top
1558 \|/ of D. We will rebase C first.
1556 \|/ of D. We will rebase C first.
1559 A
1557 A
1560
1558
1561 C' After rebasing C, when considering B's destination, use C'
1559 C' After rebasing C, when considering B's destination, use C'
1562 | instead of the original C.
1560 | instead of the original C.
1563 B D
1561 B D
1564 \ /
1562 \ /
1565 A
1563 A
1566 """
1564 """
1567 # pick already rebased revs with same dest from state as interesting source
1565 # pick already rebased revs with same dest from state as interesting source
1568 dest = destmap[rev]
1566 dest = destmap[rev]
1569 source = [
1567 source = [
1570 s
1568 s
1571 for s, d in state.items()
1569 for s, d in state.items()
1572 if d > 0 and destmap[s] == dest and s not in skipped
1570 if d > 0 and destmap[s] == dest and s not in skipped
1573 ]
1571 ]
1574
1572
1575 result = []
1573 result = []
1576 for prev in repo.changelog.parentrevs(rev):
1574 for prev in repo.changelog.parentrevs(rev):
1577 adjusted = dest
1575 adjusted = dest
1578 if prev != nullrev:
1576 if prev != nullrev:
1579 candidate = repo.revs(b'max(%ld and (::%d))', source, prev).first()
1577 candidate = repo.revs(b'max(%ld and (::%d))', source, prev).first()
1580 if candidate is not None:
1578 if candidate is not None:
1581 adjusted = state[candidate]
1579 adjusted = state[candidate]
1582 if adjusted == dest and dest in state:
1580 if adjusted == dest and dest in state:
1583 adjusted = state[dest]
1581 adjusted = state[dest]
1584 if adjusted == revtodo:
1582 if adjusted == revtodo:
1585 # sortsource should produce an order that makes this impossible
1583 # sortsource should produce an order that makes this impossible
1586 raise error.ProgrammingError(
1584 raise error.ProgrammingError(
1587 b'rev %d should be rebased already at this time' % dest
1585 b'rev %d should be rebased already at this time' % dest
1588 )
1586 )
1589 result.append(adjusted)
1587 result.append(adjusted)
1590 return result
1588 return result
1591
1589
1592
1590
1593 def _checkobsrebase(repo, ui, rebaseobsrevs, rebaseobsskipped):
1591 def _checkobsrebase(repo, ui, rebaseobsrevs, rebaseobsskipped):
1594 """
1592 """
1595 Abort if rebase will create divergence or rebase is noop because of markers
1593 Abort if rebase will create divergence or rebase is noop because of markers
1596
1594
1597 `rebaseobsrevs`: set of obsolete revision in source
1595 `rebaseobsrevs`: set of obsolete revision in source
1598 `rebaseobsskipped`: set of revisions from source skipped because they have
1596 `rebaseobsskipped`: set of revisions from source skipped because they have
1599 successors in destination or no non-obsolete successor.
1597 successors in destination or no non-obsolete successor.
1600 """
1598 """
1601 # Obsolete node with successors not in dest leads to divergence
1599 # Obsolete node with successors not in dest leads to divergence
1602 divergenceok = ui.configbool(b'experimental', b'evolution.allowdivergence')
1600 divergenceok = ui.configbool(b'experimental', b'evolution.allowdivergence')
1603 divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
1601 divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
1604
1602
1605 if divergencebasecandidates and not divergenceok:
1603 if divergencebasecandidates and not divergenceok:
1606 divhashes = (bytes(repo[r]) for r in divergencebasecandidates)
1604 divhashes = (bytes(repo[r]) for r in divergencebasecandidates)
1607 msg = _(b"this rebase will cause divergences from: %s")
1605 msg = _(b"this rebase will cause divergences from: %s")
1608 h = _(
1606 h = _(
1609 b"to force the rebase please set "
1607 b"to force the rebase please set "
1610 b"experimental.evolution.allowdivergence=True"
1608 b"experimental.evolution.allowdivergence=True"
1611 )
1609 )
1612 raise error.Abort(msg % (b",".join(divhashes),), hint=h)
1610 raise error.Abort(msg % (b",".join(divhashes),), hint=h)
1613
1611
1614
1612
1615 def successorrevs(unfi, rev):
1613 def successorrevs(unfi, rev):
1616 """yield revision numbers for successors of rev"""
1614 """yield revision numbers for successors of rev"""
1617 assert unfi.filtername is None
1615 assert unfi.filtername is None
1618 get_rev = unfi.changelog.index.get_rev
1616 get_rev = unfi.changelog.index.get_rev
1619 for s in obsutil.allsuccessors(unfi.obsstore, [unfi[rev].node()]):
1617 for s in obsutil.allsuccessors(unfi.obsstore, [unfi[rev].node()]):
1620 r = get_rev(s)
1618 r = get_rev(s)
1621 if r is not None:
1619 if r is not None:
1622 yield r
1620 yield r
1623
1621
1624
1622
1625 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1623 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1626 """Return new parents and optionally a merge base for rev being rebased
1624 """Return new parents and optionally a merge base for rev being rebased
1627
1625
1628 The destination specified by "dest" cannot always be used directly because
1626 The destination specified by "dest" cannot always be used directly because
1629 previously rebase result could affect destination. For example,
1627 previously rebase result could affect destination. For example,
1630
1628
1631 D E rebase -r C+D+E -d B
1629 D E rebase -r C+D+E -d B
1632 |/ C will be rebased to C'
1630 |/ C will be rebased to C'
1633 B C D's new destination will be C' instead of B
1631 B C D's new destination will be C' instead of B
1634 |/ E's new destination will be C' instead of B
1632 |/ E's new destination will be C' instead of B
1635 A
1633 A
1636
1634
1637 The new parents of a merge is slightly more complicated. See the comment
1635 The new parents of a merge is slightly more complicated. See the comment
1638 block below.
1636 block below.
1639 """
1637 """
1640 # use unfiltered changelog since successorrevs may return filtered nodes
1638 # use unfiltered changelog since successorrevs may return filtered nodes
1641 assert repo.filtername is None
1639 assert repo.filtername is None
1642 cl = repo.changelog
1640 cl = repo.changelog
1643 isancestor = cl.isancestorrev
1641 isancestor = cl.isancestorrev
1644
1642
1645 dest = destmap[rev]
1643 dest = destmap[rev]
1646 oldps = repo.changelog.parentrevs(rev) # old parents
1644 oldps = repo.changelog.parentrevs(rev) # old parents
1647 newps = [nullrev, nullrev] # new parents
1645 newps = [nullrev, nullrev] # new parents
1648 dests = adjustdest(repo, rev, destmap, state, skipped)
1646 dests = adjustdest(repo, rev, destmap, state, skipped)
1649 bases = list(oldps) # merge base candidates, initially just old parents
1647 bases = list(oldps) # merge base candidates, initially just old parents
1650
1648
1651 if all(r == nullrev for r in oldps[1:]):
1649 if all(r == nullrev for r in oldps[1:]):
1652 # For non-merge changeset, just move p to adjusted dest as requested.
1650 # For non-merge changeset, just move p to adjusted dest as requested.
1653 newps[0] = dests[0]
1651 newps[0] = dests[0]
1654 else:
1652 else:
1655 # For merge changeset, if we move p to dests[i] unconditionally, both
1653 # For merge changeset, if we move p to dests[i] unconditionally, both
1656 # parents may change and the end result looks like "the merge loses a
1654 # parents may change and the end result looks like "the merge loses a
1657 # parent", which is a surprise. This is a limit because "--dest" only
1655 # parent", which is a surprise. This is a limit because "--dest" only
1658 # accepts one dest per src.
1656 # accepts one dest per src.
1659 #
1657 #
1660 # Therefore, only move p with reasonable conditions (in this order):
1658 # Therefore, only move p with reasonable conditions (in this order):
1661 # 1. use dest, if dest is a descendent of (p or one of p's successors)
1659 # 1. use dest, if dest is a descendent of (p or one of p's successors)
1662 # 2. use p's rebased result, if p is rebased (state[p] > 0)
1660 # 2. use p's rebased result, if p is rebased (state[p] > 0)
1663 #
1661 #
1664 # Comparing with adjustdest, the logic here does some additional work:
1662 # Comparing with adjustdest, the logic here does some additional work:
1665 # 1. decide which parents will not be moved towards dest
1663 # 1. decide which parents will not be moved towards dest
1666 # 2. if the above decision is "no", should a parent still be moved
1664 # 2. if the above decision is "no", should a parent still be moved
1667 # because it was rebased?
1665 # because it was rebased?
1668 #
1666 #
1669 # For example:
1667 # For example:
1670 #
1668 #
1671 # C # "rebase -r C -d D" is an error since none of the parents
1669 # C # "rebase -r C -d D" is an error since none of the parents
1672 # /| # can be moved. "rebase -r B+C -d D" will move C's parent
1670 # /| # can be moved. "rebase -r B+C -d D" will move C's parent
1673 # A B D # B (using rule "2."), since B will be rebased.
1671 # A B D # B (using rule "2."), since B will be rebased.
1674 #
1672 #
1675 # The loop tries to be not rely on the fact that a Mercurial node has
1673 # The loop tries to be not rely on the fact that a Mercurial node has
1676 # at most 2 parents.
1674 # at most 2 parents.
1677 for i, p in enumerate(oldps):
1675 for i, p in enumerate(oldps):
1678 np = p # new parent
1676 np = p # new parent
1679 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)):
1677 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)):
1680 np = dests[i]
1678 np = dests[i]
1681 elif p in state and state[p] > 0:
1679 elif p in state and state[p] > 0:
1682 np = state[p]
1680 np = state[p]
1683
1681
1684 # If one parent becomes an ancestor of the other, drop the ancestor
1682 # If one parent becomes an ancestor of the other, drop the ancestor
1685 for j, x in enumerate(newps[:i]):
1683 for j, x in enumerate(newps[:i]):
1686 if x == nullrev:
1684 if x == nullrev:
1687 continue
1685 continue
1688 if isancestor(np, x): # CASE-1
1686 if isancestor(np, x): # CASE-1
1689 np = nullrev
1687 np = nullrev
1690 elif isancestor(x, np): # CASE-2
1688 elif isancestor(x, np): # CASE-2
1691 newps[j] = np
1689 newps[j] = np
1692 np = nullrev
1690 np = nullrev
1693 # New parents forming an ancestor relationship does not
1691 # New parents forming an ancestor relationship does not
1694 # mean the old parents have a similar relationship. Do not
1692 # mean the old parents have a similar relationship. Do not
1695 # set bases[x] to nullrev.
1693 # set bases[x] to nullrev.
1696 bases[j], bases[i] = bases[i], bases[j]
1694 bases[j], bases[i] = bases[i], bases[j]
1697
1695
1698 newps[i] = np
1696 newps[i] = np
1699
1697
1700 # "rebasenode" updates to new p1, and the old p1 will be used as merge
1698 # "rebasenode" updates to new p1, and the old p1 will be used as merge
1701 # base. If only p2 changes, merging using unchanged p1 as merge base is
1699 # base. If only p2 changes, merging using unchanged p1 as merge base is
1702 # suboptimal. Therefore swap parents to make the merge sane.
1700 # suboptimal. Therefore swap parents to make the merge sane.
1703 if newps[1] != nullrev and oldps[0] == newps[0]:
1701 if newps[1] != nullrev and oldps[0] == newps[0]:
1704 assert len(newps) == 2 and len(oldps) == 2
1702 assert len(newps) == 2 and len(oldps) == 2
1705 newps.reverse()
1703 newps.reverse()
1706 bases.reverse()
1704 bases.reverse()
1707
1705
1708 # No parent change might be an error because we fail to make rev a
1706 # No parent change might be an error because we fail to make rev a
1709 # descendent of requested dest. This can happen, for example:
1707 # descendent of requested dest. This can happen, for example:
1710 #
1708 #
1711 # C # rebase -r C -d D
1709 # C # rebase -r C -d D
1712 # /| # None of A and B will be changed to D and rebase fails.
1710 # /| # None of A and B will be changed to D and rebase fails.
1713 # A B D
1711 # A B D
1714 if set(newps) == set(oldps) and dest not in newps:
1712 if set(newps) == set(oldps) and dest not in newps:
1715 raise error.Abort(
1713 raise error.Abort(
1716 _(
1714 _(
1717 b'cannot rebase %d:%s without '
1715 b'cannot rebase %d:%s without '
1718 b'moving at least one of its parents'
1716 b'moving at least one of its parents'
1719 )
1717 )
1720 % (rev, repo[rev])
1718 % (rev, repo[rev])
1721 )
1719 )
1722
1720
1723 # Source should not be ancestor of dest. The check here guarantees it's
1721 # Source should not be ancestor of dest. The check here guarantees it's
1724 # impossible. With multi-dest, the initial check does not cover complex
1722 # impossible. With multi-dest, the initial check does not cover complex
1725 # cases since we don't have abstractions to dry-run rebase cheaply.
1723 # cases since we don't have abstractions to dry-run rebase cheaply.
1726 if any(p != nullrev and isancestor(rev, p) for p in newps):
1724 if any(p != nullrev and isancestor(rev, p) for p in newps):
1727 raise error.Abort(_(b'source is ancestor of destination'))
1725 raise error.Abort(_(b'source is ancestor of destination'))
1728
1726
1729 # Check if the merge will contain unwanted changes. That may happen if
1727 # Check if the merge will contain unwanted changes. That may happen if
1730 # there are multiple special (non-changelog ancestor) merge bases, which
1728 # there are multiple special (non-changelog ancestor) merge bases, which
1731 # cannot be handled well by the 3-way merge algorithm. For example:
1729 # cannot be handled well by the 3-way merge algorithm. For example:
1732 #
1730 #
1733 # F
1731 # F
1734 # /|
1732 # /|
1735 # D E # "rebase -r D+E+F -d Z", when rebasing F, if "D" was chosen
1733 # D E # "rebase -r D+E+F -d Z", when rebasing F, if "D" was chosen
1736 # | | # as merge base, the difference between D and F will include
1734 # | | # as merge base, the difference between D and F will include
1737 # B C # C, so the rebased F will contain C surprisingly. If "E" was
1735 # B C # C, so the rebased F will contain C surprisingly. If "E" was
1738 # |/ # chosen, the rebased F will contain B.
1736 # |/ # chosen, the rebased F will contain B.
1739 # A Z
1737 # A Z
1740 #
1738 #
1741 # But our merge base candidates (D and E in above case) could still be
1739 # But our merge base candidates (D and E in above case) could still be
1742 # better than the default (ancestor(F, Z) == null). Therefore still
1740 # better than the default (ancestor(F, Z) == null). Therefore still
1743 # pick one (so choose p1 above).
1741 # pick one (so choose p1 above).
1744 if sum(1 for b in set(bases) if b != nullrev and b not in newps) > 1:
1742 if sum(1 for b in set(bases) if b != nullrev and b not in newps) > 1:
1745 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i]
1743 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i]
1746 for i, base in enumerate(bases):
1744 for i, base in enumerate(bases):
1747 if base == nullrev or base in newps:
1745 if base == nullrev or base in newps:
1748 continue
1746 continue
1749 # Revisions in the side (not chosen as merge base) branch that
1747 # Revisions in the side (not chosen as merge base) branch that
1750 # might contain "surprising" contents
1748 # might contain "surprising" contents
1751 other_bases = set(bases) - {base}
1749 other_bases = set(bases) - {base}
1752 siderevs = list(
1750 siderevs = list(
1753 repo.revs(b'(%ld %% (%d+%d))', other_bases, base, dest)
1751 repo.revs(b'(%ld %% (%d+%d))', other_bases, base, dest)
1754 )
1752 )
1755
1753
1756 # If those revisions are covered by rebaseset, the result is good.
1754 # If those revisions are covered by rebaseset, the result is good.
1757 # A merge in rebaseset would be considered to cover its ancestors.
1755 # A merge in rebaseset would be considered to cover its ancestors.
1758 if siderevs:
1756 if siderevs:
1759 rebaseset = [
1757 rebaseset = [
1760 r for r, d in state.items() if d > 0 and r not in obsskipped
1758 r for r, d in state.items() if d > 0 and r not in obsskipped
1761 ]
1759 ]
1762 merges = [
1760 merges = [
1763 r for r in rebaseset if cl.parentrevs(r)[1] != nullrev
1761 r for r in rebaseset if cl.parentrevs(r)[1] != nullrev
1764 ]
1762 ]
1765 unwanted[i] = list(
1763 unwanted[i] = list(
1766 repo.revs(
1764 repo.revs(
1767 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset
1765 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset
1768 )
1766 )
1769 )
1767 )
1770
1768
1771 if any(revs is not None for revs in unwanted):
1769 if any(revs is not None for revs in unwanted):
1772 # Choose a merge base that has a minimal number of unwanted revs.
1770 # Choose a merge base that has a minimal number of unwanted revs.
1773 l, i = min(
1771 l, i = min(
1774 (len(revs), i)
1772 (len(revs), i)
1775 for i, revs in enumerate(unwanted)
1773 for i, revs in enumerate(unwanted)
1776 if revs is not None
1774 if revs is not None
1777 )
1775 )
1778
1776
1779 # The merge will include unwanted revisions. Abort now. Revisit this if
1777 # The merge will include unwanted revisions. Abort now. Revisit this if
1780 # we have a more advanced merge algorithm that handles multiple bases.
1778 # we have a more advanced merge algorithm that handles multiple bases.
1781 if l > 0:
1779 if l > 0:
1782 unwanteddesc = _(b' or ').join(
1780 unwanteddesc = _(b' or ').join(
1783 (
1781 (
1784 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs)
1782 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs)
1785 for revs in unwanted
1783 for revs in unwanted
1786 if revs is not None
1784 if revs is not None
1787 )
1785 )
1788 )
1786 )
1789 raise error.Abort(
1787 raise error.Abort(
1790 _(b'rebasing %d:%s will include unwanted changes from %s')
1788 _(b'rebasing %d:%s will include unwanted changes from %s')
1791 % (rev, repo[rev], unwanteddesc)
1789 % (rev, repo[rev], unwanteddesc)
1792 )
1790 )
1793
1791
1794 # newps[0] should match merge base if possible. Currently, if newps[i]
1792 # newps[0] should match merge base if possible. Currently, if newps[i]
1795 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is
1793 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is
1796 # the other's ancestor. In that case, it's fine to not swap newps here.
1794 # the other's ancestor. In that case, it's fine to not swap newps here.
1797 # (see CASE-1 and CASE-2 above)
1795 # (see CASE-1 and CASE-2 above)
1798 if i != 0:
1796 if i != 0:
1799 if newps[i] != nullrev:
1797 if newps[i] != nullrev:
1800 newps[0], newps[i] = newps[i], newps[0]
1798 newps[0], newps[i] = newps[i], newps[0]
1801 bases[0], bases[i] = bases[i], bases[0]
1799 bases[0], bases[i] = bases[i], bases[0]
1802
1800
1803 # "rebasenode" updates to new p1, use the corresponding merge base.
1801 # "rebasenode" updates to new p1, use the corresponding merge base.
1804 base = bases[0]
1802 base = bases[0]
1805
1803
1806 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps))
1804 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps))
1807
1805
1808 return newps[0], newps[1], base
1806 return newps[0], newps[1], base
1809
1807
1810
1808
1811 def isagitpatch(repo, patchname):
1809 def isagitpatch(repo, patchname):
1812 """Return true if the given patch is in git format"""
1810 """Return true if the given patch is in git format"""
1813 mqpatch = os.path.join(repo.mq.path, patchname)
1811 mqpatch = os.path.join(repo.mq.path, patchname)
1814 for line in patch.linereader(open(mqpatch, b'rb')):
1812 for line in patch.linereader(open(mqpatch, b'rb')):
1815 if line.startswith(b'diff --git'):
1813 if line.startswith(b'diff --git'):
1816 return True
1814 return True
1817 return False
1815 return False
1818
1816
1819
1817
1820 def updatemq(repo, state, skipped, **opts):
1818 def updatemq(repo, state, skipped, **opts):
1821 """Update rebased mq patches - finalize and then import them"""
1819 """Update rebased mq patches - finalize and then import them"""
1822 mqrebase = {}
1820 mqrebase = {}
1823 mq = repo.mq
1821 mq = repo.mq
1824 original_series = mq.fullseries[:]
1822 original_series = mq.fullseries[:]
1825 skippedpatches = set()
1823 skippedpatches = set()
1826
1824
1827 for p in mq.applied:
1825 for p in mq.applied:
1828 rev = repo[p.node].rev()
1826 rev = repo[p.node].rev()
1829 if rev in state:
1827 if rev in state:
1830 repo.ui.debug(
1828 repo.ui.debug(
1831 b'revision %d is an mq patch (%s), finalize it.\n'
1829 b'revision %d is an mq patch (%s), finalize it.\n'
1832 % (rev, p.name)
1830 % (rev, p.name)
1833 )
1831 )
1834 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
1832 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
1835 else:
1833 else:
1836 # Applied but not rebased, not sure this should happen
1834 # Applied but not rebased, not sure this should happen
1837 skippedpatches.add(p.name)
1835 skippedpatches.add(p.name)
1838
1836
1839 if mqrebase:
1837 if mqrebase:
1840 mq.finish(repo, mqrebase.keys())
1838 mq.finish(repo, mqrebase.keys())
1841
1839
1842 # We must start import from the newest revision
1840 # We must start import from the newest revision
1843 for rev in sorted(mqrebase, reverse=True):
1841 for rev in sorted(mqrebase, reverse=True):
1844 if rev not in skipped:
1842 if rev not in skipped:
1845 name, isgit = mqrebase[rev]
1843 name, isgit = mqrebase[rev]
1846 repo.ui.note(
1844 repo.ui.note(
1847 _(b'updating mq patch %s to %d:%s\n')
1845 _(b'updating mq patch %s to %d:%s\n')
1848 % (name, state[rev], repo[state[rev]])
1846 % (name, state[rev], repo[state[rev]])
1849 )
1847 )
1850 mq.qimport(
1848 mq.qimport(
1851 repo,
1849 repo,
1852 (),
1850 (),
1853 patchname=name,
1851 patchname=name,
1854 git=isgit,
1852 git=isgit,
1855 rev=[b"%d" % state[rev]],
1853 rev=[b"%d" % state[rev]],
1856 )
1854 )
1857 else:
1855 else:
1858 # Rebased and skipped
1856 # Rebased and skipped
1859 skippedpatches.add(mqrebase[rev][0])
1857 skippedpatches.add(mqrebase[rev][0])
1860
1858
1861 # Patches were either applied and rebased and imported in
1859 # Patches were either applied and rebased and imported in
1862 # order, applied and removed or unapplied. Discard the removed
1860 # order, applied and removed or unapplied. Discard the removed
1863 # ones while preserving the original series order and guards.
1861 # ones while preserving the original series order and guards.
1864 newseries = [
1862 newseries = [
1865 s
1863 s
1866 for s in original_series
1864 for s in original_series
1867 if mq.guard_re.split(s, 1)[0] not in skippedpatches
1865 if mq.guard_re.split(s, 1)[0] not in skippedpatches
1868 ]
1866 ]
1869 mq.fullseries[:] = newseries
1867 mq.fullseries[:] = newseries
1870 mq.seriesdirty = True
1868 mq.seriesdirty = True
1871 mq.savedirty()
1869 mq.savedirty()
1872
1870
1873
1871
1874 def storecollapsemsg(repo, collapsemsg):
1872 def storecollapsemsg(repo, collapsemsg):
1875 """Store the collapse message to allow recovery"""
1873 """Store the collapse message to allow recovery"""
1876 collapsemsg = collapsemsg or b''
1874 collapsemsg = collapsemsg or b''
1877 f = repo.vfs(b"last-message.txt", b"w")
1875 f = repo.vfs(b"last-message.txt", b"w")
1878 f.write(b"%s\n" % collapsemsg)
1876 f.write(b"%s\n" % collapsemsg)
1879 f.close()
1877 f.close()
1880
1878
1881
1879
1882 def clearcollapsemsg(repo):
1880 def clearcollapsemsg(repo):
1883 """Remove collapse message file"""
1881 """Remove collapse message file"""
1884 repo.vfs.unlinkpath(b"last-message.txt", ignoremissing=True)
1882 repo.vfs.unlinkpath(b"last-message.txt", ignoremissing=True)
1885
1883
1886
1884
1887 def restorecollapsemsg(repo, isabort):
1885 def restorecollapsemsg(repo, isabort):
1888 """Restore previously stored collapse message"""
1886 """Restore previously stored collapse message"""
1889 try:
1887 try:
1890 f = repo.vfs(b"last-message.txt")
1888 f = repo.vfs(b"last-message.txt")
1891 collapsemsg = f.readline().strip()
1889 collapsemsg = f.readline().strip()
1892 f.close()
1890 f.close()
1893 except IOError as err:
1891 except IOError as err:
1894 if err.errno != errno.ENOENT:
1892 if err.errno != errno.ENOENT:
1895 raise
1893 raise
1896 if isabort:
1894 if isabort:
1897 # Oh well, just abort like normal
1895 # Oh well, just abort like normal
1898 collapsemsg = b''
1896 collapsemsg = b''
1899 else:
1897 else:
1900 raise error.Abort(_(b'missing .hg/last-message.txt for rebase'))
1898 raise error.Abort(_(b'missing .hg/last-message.txt for rebase'))
1901 return collapsemsg
1899 return collapsemsg
1902
1900
1903
1901
1904 def clearstatus(repo):
1902 def clearstatus(repo):
1905 """Remove the status files"""
1903 """Remove the status files"""
1906 # Make sure the active transaction won't write the state file
1904 # Make sure the active transaction won't write the state file
1907 tr = repo.currenttransaction()
1905 tr = repo.currenttransaction()
1908 if tr:
1906 if tr:
1909 tr.removefilegenerator(b'rebasestate')
1907 tr.removefilegenerator(b'rebasestate')
1910 repo.vfs.unlinkpath(b"rebasestate", ignoremissing=True)
1908 repo.vfs.unlinkpath(b"rebasestate", ignoremissing=True)
1911
1909
1912
1910
1913 def sortsource(destmap):
1911 def sortsource(destmap):
1914 """yield source revisions in an order that we only rebase things once
1912 """yield source revisions in an order that we only rebase things once
1915
1913
1916 If source and destination overlaps, we should filter out revisions
1914 If source and destination overlaps, we should filter out revisions
1917 depending on other revisions which hasn't been rebased yet.
1915 depending on other revisions which hasn't been rebased yet.
1918
1916
1919 Yield a sorted list of revisions each time.
1917 Yield a sorted list of revisions each time.
1920
1918
1921 For example, when rebasing A to B, B to C. This function yields [B], then
1919 For example, when rebasing A to B, B to C. This function yields [B], then
1922 [A], indicating B needs to be rebased first.
1920 [A], indicating B needs to be rebased first.
1923
1921
1924 Raise if there is a cycle so the rebase is impossible.
1922 Raise if there is a cycle so the rebase is impossible.
1925 """
1923 """
1926 srcset = set(destmap)
1924 srcset = set(destmap)
1927 while srcset:
1925 while srcset:
1928 srclist = sorted(srcset)
1926 srclist = sorted(srcset)
1929 result = []
1927 result = []
1930 for r in srclist:
1928 for r in srclist:
1931 if destmap[r] not in srcset:
1929 if destmap[r] not in srcset:
1932 result.append(r)
1930 result.append(r)
1933 if not result:
1931 if not result:
1934 raise error.Abort(_(b'source and destination form a cycle'))
1932 raise error.Abort(_(b'source and destination form a cycle'))
1935 srcset -= set(result)
1933 srcset -= set(result)
1936 yield result
1934 yield result
1937
1935
1938
1936
1939 def buildstate(repo, destmap, collapse):
1937 def buildstate(repo, destmap, collapse):
1940 '''Define which revisions are going to be rebased and where
1938 '''Define which revisions are going to be rebased and where
1941
1939
1942 repo: repo
1940 repo: repo
1943 destmap: {srcrev: destrev}
1941 destmap: {srcrev: destrev}
1944 '''
1942 '''
1945 rebaseset = destmap.keys()
1943 rebaseset = destmap.keys()
1946 originalwd = repo[b'.'].rev()
1944 originalwd = repo[b'.'].rev()
1947
1945
1948 # This check isn't strictly necessary, since mq detects commits over an
1946 # This check isn't strictly necessary, since mq detects commits over an
1949 # applied patch. But it prevents messing up the working directory when
1947 # applied patch. But it prevents messing up the working directory when
1950 # a partially completed rebase is blocked by mq.
1948 # a partially completed rebase is blocked by mq.
1951 if b'qtip' in repo.tags():
1949 if b'qtip' in repo.tags():
1952 mqapplied = set(repo[s.node].rev() for s in repo.mq.applied)
1950 mqapplied = set(repo[s.node].rev() for s in repo.mq.applied)
1953 if set(destmap.values()) & mqapplied:
1951 if set(destmap.values()) & mqapplied:
1954 raise error.Abort(_(b'cannot rebase onto an applied mq patch'))
1952 raise error.Abort(_(b'cannot rebase onto an applied mq patch'))
1955
1953
1956 # Get "cycle" error early by exhausting the generator.
1954 # Get "cycle" error early by exhausting the generator.
1957 sortedsrc = list(sortsource(destmap)) # a list of sorted revs
1955 sortedsrc = list(sortsource(destmap)) # a list of sorted revs
1958 if not sortedsrc:
1956 if not sortedsrc:
1959 raise error.Abort(_(b'no matching revisions'))
1957 raise error.Abort(_(b'no matching revisions'))
1960
1958
1961 # Only check the first batch of revisions to rebase not depending on other
1959 # Only check the first batch of revisions to rebase not depending on other
1962 # rebaseset. This means "source is ancestor of destination" for the second
1960 # rebaseset. This means "source is ancestor of destination" for the second
1963 # (and following) batches of revisions are not checked here. We rely on
1961 # (and following) batches of revisions are not checked here. We rely on
1964 # "defineparents" to do that check.
1962 # "defineparents" to do that check.
1965 roots = list(repo.set(b'roots(%ld)', sortedsrc[0]))
1963 roots = list(repo.set(b'roots(%ld)', sortedsrc[0]))
1966 if not roots:
1964 if not roots:
1967 raise error.Abort(_(b'no matching revisions'))
1965 raise error.Abort(_(b'no matching revisions'))
1968
1966
1969 def revof(r):
1967 def revof(r):
1970 return r.rev()
1968 return r.rev()
1971
1969
1972 roots = sorted(roots, key=revof)
1970 roots = sorted(roots, key=revof)
1973 state = dict.fromkeys(rebaseset, revtodo)
1971 state = dict.fromkeys(rebaseset, revtodo)
1974 emptyrebase = len(sortedsrc) == 1
1972 emptyrebase = len(sortedsrc) == 1
1975 for root in roots:
1973 for root in roots:
1976 dest = repo[destmap[root.rev()]]
1974 dest = repo[destmap[root.rev()]]
1977 commonbase = root.ancestor(dest)
1975 commonbase = root.ancestor(dest)
1978 if commonbase == root:
1976 if commonbase == root:
1979 raise error.Abort(_(b'source is ancestor of destination'))
1977 raise error.Abort(_(b'source is ancestor of destination'))
1980 if commonbase == dest:
1978 if commonbase == dest:
1981 wctx = repo[None]
1979 wctx = repo[None]
1982 if dest == wctx.p1():
1980 if dest == wctx.p1():
1983 # when rebasing to '.', it will use the current wd branch name
1981 # when rebasing to '.', it will use the current wd branch name
1984 samebranch = root.branch() == wctx.branch()
1982 samebranch = root.branch() == wctx.branch()
1985 else:
1983 else:
1986 samebranch = root.branch() == dest.branch()
1984 samebranch = root.branch() == dest.branch()
1987 if not collapse and samebranch and dest in root.parents():
1985 if not collapse and samebranch and dest in root.parents():
1988 # mark the revision as done by setting its new revision
1986 # mark the revision as done by setting its new revision
1989 # equal to its old (current) revisions
1987 # equal to its old (current) revisions
1990 state[root.rev()] = root.rev()
1988 state[root.rev()] = root.rev()
1991 repo.ui.debug(b'source is a child of destination\n')
1989 repo.ui.debug(b'source is a child of destination\n')
1992 continue
1990 continue
1993
1991
1994 emptyrebase = False
1992 emptyrebase = False
1995 repo.ui.debug(b'rebase onto %s starting from %s\n' % (dest, root))
1993 repo.ui.debug(b'rebase onto %s starting from %s\n' % (dest, root))
1996 if emptyrebase:
1994 if emptyrebase:
1997 return None
1995 return None
1998 for rev in sorted(state):
1996 for rev in sorted(state):
1999 parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
1997 parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
2000 # if all parents of this revision are done, then so is this revision
1998 # if all parents of this revision are done, then so is this revision
2001 if parents and all((state.get(p) == p for p in parents)):
1999 if parents and all((state.get(p) == p for p in parents)):
2002 state[rev] = rev
2000 state[rev] = rev
2003 return originalwd, destmap, state
2001 return originalwd, destmap, state
2004
2002
2005
2003
2006 def clearrebased(
2004 def clearrebased(
2007 ui,
2005 ui,
2008 repo,
2006 repo,
2009 destmap,
2007 destmap,
2010 state,
2008 state,
2011 skipped,
2009 skipped,
2012 collapsedas=None,
2010 collapsedas=None,
2013 keepf=False,
2011 keepf=False,
2014 fm=None,
2012 fm=None,
2015 backup=True,
2013 backup=True,
2016 ):
2014 ):
2017 """dispose of rebased revision at the end of the rebase
2015 """dispose of rebased revision at the end of the rebase
2018
2016
2019 If `collapsedas` is not None, the rebase was a collapse whose result if the
2017 If `collapsedas` is not None, the rebase was a collapse whose result if the
2020 `collapsedas` node.
2018 `collapsedas` node.
2021
2019
2022 If `keepf` is not True, the rebase has --keep set and no nodes should be
2020 If `keepf` is not True, the rebase has --keep set and no nodes should be
2023 removed (but bookmarks still need to be moved).
2021 removed (but bookmarks still need to be moved).
2024
2022
2025 If `backup` is False, no backup will be stored when stripping rebased
2023 If `backup` is False, no backup will be stored when stripping rebased
2026 revisions.
2024 revisions.
2027 """
2025 """
2028 tonode = repo.changelog.node
2026 tonode = repo.changelog.node
2029 replacements = {}
2027 replacements = {}
2030 moves = {}
2028 moves = {}
2031 stripcleanup = not obsolete.isenabled(repo, obsolete.createmarkersopt)
2029 stripcleanup = not obsolete.isenabled(repo, obsolete.createmarkersopt)
2032
2030
2033 collapsednodes = []
2031 collapsednodes = []
2034 for rev, newrev in sorted(state.items()):
2032 for rev, newrev in sorted(state.items()):
2035 if newrev >= 0 and newrev != rev:
2033 if newrev >= 0 and newrev != rev:
2036 oldnode = tonode(rev)
2034 oldnode = tonode(rev)
2037 newnode = collapsedas or tonode(newrev)
2035 newnode = collapsedas or tonode(newrev)
2038 moves[oldnode] = newnode
2036 moves[oldnode] = newnode
2039 succs = None
2037 succs = None
2040 if rev in skipped:
2038 if rev in skipped:
2041 if stripcleanup or not repo[rev].obsolete():
2039 if stripcleanup or not repo[rev].obsolete():
2042 succs = ()
2040 succs = ()
2043 elif collapsedas:
2041 elif collapsedas:
2044 collapsednodes.append(oldnode)
2042 collapsednodes.append(oldnode)
2045 else:
2043 else:
2046 succs = (newnode,)
2044 succs = (newnode,)
2047 if succs is not None:
2045 if succs is not None:
2048 replacements[(oldnode,)] = succs
2046 replacements[(oldnode,)] = succs
2049 if collapsednodes:
2047 if collapsednodes:
2050 replacements[tuple(collapsednodes)] = (collapsedas,)
2048 replacements[tuple(collapsednodes)] = (collapsedas,)
2051 if fm:
2049 if fm:
2052 hf = fm.hexfunc
2050 hf = fm.hexfunc
2053 fl = fm.formatlist
2051 fl = fm.formatlist
2054 fd = fm.formatdict
2052 fd = fm.formatdict
2055 changes = {}
2053 changes = {}
2056 for oldns, newn in pycompat.iteritems(replacements):
2054 for oldns, newn in pycompat.iteritems(replacements):
2057 for oldn in oldns:
2055 for oldn in oldns:
2058 changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
2056 changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
2059 nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
2057 nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
2060 fm.data(nodechanges=nodechanges)
2058 fm.data(nodechanges=nodechanges)
2061 if keepf:
2059 if keepf:
2062 replacements = {}
2060 replacements = {}
2063 scmutil.cleanupnodes(repo, replacements, b'rebase', moves, backup=backup)
2061 scmutil.cleanupnodes(repo, replacements, b'rebase', moves, backup=backup)
2064
2062
2065
2063
2066 def pullrebase(orig, ui, repo, *args, **opts):
2064 def pullrebase(orig, ui, repo, *args, **opts):
2067 """Call rebase after pull if the latter has been invoked with --rebase"""
2065 """Call rebase after pull if the latter has been invoked with --rebase"""
2068 if opts.get('rebase'):
2066 if opts.get('rebase'):
2069 if ui.configbool(b'commands', b'rebase.requiredest'):
2067 if ui.configbool(b'commands', b'rebase.requiredest'):
2070 msg = _(b'rebase destination required by configuration')
2068 msg = _(b'rebase destination required by configuration')
2071 hint = _(b'use hg pull followed by hg rebase -d DEST')
2069 hint = _(b'use hg pull followed by hg rebase -d DEST')
2072 raise error.Abort(msg, hint=hint)
2070 raise error.Abort(msg, hint=hint)
2073
2071
2074 with repo.wlock(), repo.lock():
2072 with repo.wlock(), repo.lock():
2075 if opts.get('update'):
2073 if opts.get('update'):
2076 del opts['update']
2074 del opts['update']
2077 ui.debug(
2075 ui.debug(
2078 b'--update and --rebase are not compatible, ignoring '
2076 b'--update and --rebase are not compatible, ignoring '
2079 b'the update flag\n'
2077 b'the update flag\n'
2080 )
2078 )
2081
2079
2082 cmdutil.checkunfinished(repo, skipmerge=True)
2080 cmdutil.checkunfinished(repo, skipmerge=True)
2083 cmdutil.bailifchanged(
2081 cmdutil.bailifchanged(
2084 repo,
2082 repo,
2085 hint=_(
2083 hint=_(
2086 b'cannot pull with rebase: '
2084 b'cannot pull with rebase: '
2087 b'please commit or shelve your changes first'
2085 b'please commit or shelve your changes first'
2088 ),
2086 ),
2089 )
2087 )
2090
2088
2091 revsprepull = len(repo)
2089 revsprepull = len(repo)
2092 origpostincoming = commands.postincoming
2090 origpostincoming = commands.postincoming
2093
2091
2094 def _dummy(*args, **kwargs):
2092 def _dummy(*args, **kwargs):
2095 pass
2093 pass
2096
2094
2097 commands.postincoming = _dummy
2095 commands.postincoming = _dummy
2098 try:
2096 try:
2099 ret = orig(ui, repo, *args, **opts)
2097 ret = orig(ui, repo, *args, **opts)
2100 finally:
2098 finally:
2101 commands.postincoming = origpostincoming
2099 commands.postincoming = origpostincoming
2102 revspostpull = len(repo)
2100 revspostpull = len(repo)
2103 if revspostpull > revsprepull:
2101 if revspostpull > revsprepull:
2104 # --rev option from pull conflict with rebase own --rev
2102 # --rev option from pull conflict with rebase own --rev
2105 # dropping it
2103 # dropping it
2106 if 'rev' in opts:
2104 if 'rev' in opts:
2107 del opts['rev']
2105 del opts['rev']
2108 # positional argument from pull conflicts with rebase's own
2106 # positional argument from pull conflicts with rebase's own
2109 # --source.
2107 # --source.
2110 if 'source' in opts:
2108 if 'source' in opts:
2111 del opts['source']
2109 del opts['source']
2112 # revsprepull is the len of the repo, not revnum of tip.
2110 # revsprepull is the len of the repo, not revnum of tip.
2113 destspace = list(repo.changelog.revs(start=revsprepull))
2111 destspace = list(repo.changelog.revs(start=revsprepull))
2114 opts['_destspace'] = destspace
2112 opts['_destspace'] = destspace
2115 try:
2113 try:
2116 rebase(ui, repo, **opts)
2114 rebase(ui, repo, **opts)
2117 except error.NoMergeDestAbort:
2115 except error.NoMergeDestAbort:
2118 # we can maybe update instead
2116 # we can maybe update instead
2119 rev, _a, _b = destutil.destupdate(repo)
2117 rev, _a, _b = destutil.destupdate(repo)
2120 if rev == repo[b'.'].rev():
2118 if rev == repo[b'.'].rev():
2121 ui.status(_(b'nothing to rebase\n'))
2119 ui.status(_(b'nothing to rebase\n'))
2122 else:
2120 else:
2123 ui.status(_(b'nothing to rebase - updating instead\n'))
2121 ui.status(_(b'nothing to rebase - updating instead\n'))
2124 # not passing argument to get the bare update behavior
2122 # not passing argument to get the bare update behavior
2125 # with warning and trumpets
2123 # with warning and trumpets
2126 commands.update(ui, repo)
2124 commands.update(ui, repo)
2127 else:
2125 else:
2128 if opts.get('tool'):
2126 if opts.get('tool'):
2129 raise error.Abort(_(b'--tool can only be used with --rebase'))
2127 raise error.Abort(_(b'--tool can only be used with --rebase'))
2130 ret = orig(ui, repo, *args, **opts)
2128 ret = orig(ui, repo, *args, **opts)
2131
2129
2132 return ret
2130 return ret
2133
2131
2134
2132
2135 def _filterobsoleterevs(repo, revs):
2133 def _filterobsoleterevs(repo, revs):
2136 """returns a set of the obsolete revisions in revs"""
2134 """returns a set of the obsolete revisions in revs"""
2137 return set(r for r in revs if repo[r].obsolete())
2135 return set(r for r in revs if repo[r].obsolete())
2138
2136
2139
2137
2140 def _computeobsoletenotrebased(repo, rebaseobsrevs, destmap):
2138 def _computeobsoletenotrebased(repo, rebaseobsrevs, destmap):
2141 """Return (obsoletenotrebased, obsoletewithoutsuccessorindestination).
2139 """Return (obsoletenotrebased, obsoletewithoutsuccessorindestination).
2142
2140
2143 `obsoletenotrebased` is a mapping mapping obsolete => successor for all
2141 `obsoletenotrebased` is a mapping mapping obsolete => successor for all
2144 obsolete nodes to be rebased given in `rebaseobsrevs`.
2142 obsolete nodes to be rebased given in `rebaseobsrevs`.
2145
2143
2146 `obsoletewithoutsuccessorindestination` is a set with obsolete revisions
2144 `obsoletewithoutsuccessorindestination` is a set with obsolete revisions
2147 without a successor in destination.
2145 without a successor in destination.
2148
2146
2149 `obsoleteextinctsuccessors` is a set of obsolete revisions with only
2147 `obsoleteextinctsuccessors` is a set of obsolete revisions with only
2150 obsolete successors.
2148 obsolete successors.
2151 """
2149 """
2152 obsoletenotrebased = {}
2150 obsoletenotrebased = {}
2153 obsoletewithoutsuccessorindestination = set()
2151 obsoletewithoutsuccessorindestination = set()
2154 obsoleteextinctsuccessors = set()
2152 obsoleteextinctsuccessors = set()
2155
2153
2156 assert repo.filtername is None
2154 assert repo.filtername is None
2157 cl = repo.changelog
2155 cl = repo.changelog
2158 get_rev = cl.index.get_rev
2156 get_rev = cl.index.get_rev
2159 extinctrevs = set(repo.revs(b'extinct()'))
2157 extinctrevs = set(repo.revs(b'extinct()'))
2160 for srcrev in rebaseobsrevs:
2158 for srcrev in rebaseobsrevs:
2161 srcnode = cl.node(srcrev)
2159 srcnode = cl.node(srcrev)
2162 # XXX: more advanced APIs are required to handle split correctly
2160 # XXX: more advanced APIs are required to handle split correctly
2163 successors = set(obsutil.allsuccessors(repo.obsstore, [srcnode]))
2161 successors = set(obsutil.allsuccessors(repo.obsstore, [srcnode]))
2164 # obsutil.allsuccessors includes node itself
2162 # obsutil.allsuccessors includes node itself
2165 successors.remove(srcnode)
2163 successors.remove(srcnode)
2166 succrevs = {get_rev(s) for s in successors}
2164 succrevs = {get_rev(s) for s in successors}
2167 succrevs.discard(None)
2165 succrevs.discard(None)
2168 if succrevs.issubset(extinctrevs):
2166 if succrevs.issubset(extinctrevs):
2169 # all successors are extinct
2167 # all successors are extinct
2170 obsoleteextinctsuccessors.add(srcrev)
2168 obsoleteextinctsuccessors.add(srcrev)
2171 if not successors:
2169 if not successors:
2172 # no successor
2170 # no successor
2173 obsoletenotrebased[srcrev] = None
2171 obsoletenotrebased[srcrev] = None
2174 else:
2172 else:
2175 dstrev = destmap[srcrev]
2173 dstrev = destmap[srcrev]
2176 for succrev in succrevs:
2174 for succrev in succrevs:
2177 if cl.isancestorrev(succrev, dstrev):
2175 if cl.isancestorrev(succrev, dstrev):
2178 obsoletenotrebased[srcrev] = succrev
2176 obsoletenotrebased[srcrev] = succrev
2179 break
2177 break
2180 else:
2178 else:
2181 # If 'srcrev' has a successor in rebase set but none in
2179 # If 'srcrev' has a successor in rebase set but none in
2182 # destination (which would be catched above), we shall skip it
2180 # destination (which would be catched above), we shall skip it
2183 # and its descendants to avoid divergence.
2181 # and its descendants to avoid divergence.
2184 if srcrev in extinctrevs or any(s in destmap for s in succrevs):
2182 if srcrev in extinctrevs or any(s in destmap for s in succrevs):
2185 obsoletewithoutsuccessorindestination.add(srcrev)
2183 obsoletewithoutsuccessorindestination.add(srcrev)
2186
2184
2187 return (
2185 return (
2188 obsoletenotrebased,
2186 obsoletenotrebased,
2189 obsoletewithoutsuccessorindestination,
2187 obsoletewithoutsuccessorindestination,
2190 obsoleteextinctsuccessors,
2188 obsoleteextinctsuccessors,
2191 )
2189 )
2192
2190
2193
2191
2194 def abortrebase(ui, repo):
2192 def abortrebase(ui, repo):
2195 with repo.wlock(), repo.lock():
2193 with repo.wlock(), repo.lock():
2196 rbsrt = rebaseruntime(repo, ui)
2194 rbsrt = rebaseruntime(repo, ui)
2197 rbsrt._prepareabortorcontinue(isabort=True)
2195 rbsrt._prepareabortorcontinue(isabort=True)
2198
2196
2199
2197
2200 def continuerebase(ui, repo):
2198 def continuerebase(ui, repo):
2201 with repo.wlock(), repo.lock():
2199 with repo.wlock(), repo.lock():
2202 rbsrt = rebaseruntime(repo, ui)
2200 rbsrt = rebaseruntime(repo, ui)
2203 ms = mergemod.mergestate.read(repo)
2201 ms = mergemod.mergestate.read(repo)
2204 mergeutil.checkunresolved(ms)
2202 mergeutil.checkunresolved(ms)
2205 retcode = rbsrt._prepareabortorcontinue(isabort=False)
2203 retcode = rbsrt._prepareabortorcontinue(isabort=False)
2206 if retcode is not None:
2204 if retcode is not None:
2207 return retcode
2205 return retcode
2208 rbsrt._performrebase(None)
2206 rbsrt._performrebase(None)
2209 rbsrt._finishrebase()
2207 rbsrt._finishrebase()
2210
2208
2211
2209
2212 def summaryhook(ui, repo):
2210 def summaryhook(ui, repo):
2213 if not repo.vfs.exists(b'rebasestate'):
2211 if not repo.vfs.exists(b'rebasestate'):
2214 return
2212 return
2215 try:
2213 try:
2216 rbsrt = rebaseruntime(repo, ui, {})
2214 rbsrt = rebaseruntime(repo, ui, {})
2217 rbsrt.restorestatus()
2215 rbsrt.restorestatus()
2218 state = rbsrt.state
2216 state = rbsrt.state
2219 except error.RepoLookupError:
2217 except error.RepoLookupError:
2220 # i18n: column positioning for "hg summary"
2218 # i18n: column positioning for "hg summary"
2221 msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
2219 msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
2222 ui.write(msg)
2220 ui.write(msg)
2223 return
2221 return
2224 numrebased = len([i for i in pycompat.itervalues(state) if i >= 0])
2222 numrebased = len([i for i in pycompat.itervalues(state) if i >= 0])
2225 # i18n: column positioning for "hg summary"
2223 # i18n: column positioning for "hg summary"
2226 ui.write(
2224 ui.write(
2227 _(b'rebase: %s, %s (rebase --continue)\n')
2225 _(b'rebase: %s, %s (rebase --continue)\n')
2228 % (
2226 % (
2229 ui.label(_(b'%d rebased'), b'rebase.rebased') % numrebased,
2227 ui.label(_(b'%d rebased'), b'rebase.rebased') % numrebased,
2230 ui.label(_(b'%d remaining'), b'rebase.remaining')
2228 ui.label(_(b'%d remaining'), b'rebase.remaining')
2231 % (len(state) - numrebased),
2229 % (len(state) - numrebased),
2232 )
2230 )
2233 )
2231 )
2234
2232
2235
2233
2236 def uisetup(ui):
2234 def uisetup(ui):
2237 # Replace pull with a decorator to provide --rebase option
2235 # Replace pull with a decorator to provide --rebase option
2238 entry = extensions.wrapcommand(commands.table, b'pull', pullrebase)
2236 entry = extensions.wrapcommand(commands.table, b'pull', pullrebase)
2239 entry[1].append(
2237 entry[1].append(
2240 (b'', b'rebase', None, _(b"rebase working directory to branch head"))
2238 (b'', b'rebase', None, _(b"rebase working directory to branch head"))
2241 )
2239 )
2242 entry[1].append((b't', b'tool', b'', _(b"specify merge tool for rebase")))
2240 entry[1].append((b't', b'tool', b'', _(b"specify merge tool for rebase")))
2243 cmdutil.summaryhooks.add(b'rebase', summaryhook)
2241 cmdutil.summaryhooks.add(b'rebase', summaryhook)
2244 statemod.addunfinished(
2242 statemod.addunfinished(
2245 b'rebase',
2243 b'rebase',
2246 fname=b'rebasestate',
2244 fname=b'rebasestate',
2247 stopflag=True,
2245 stopflag=True,
2248 continueflag=True,
2246 continueflag=True,
2249 abortfunc=abortrebase,
2247 abortfunc=abortrebase,
2250 continuefunc=continuerebase,
2248 continuefunc=continuerebase,
2251 )
2249 )
@@ -1,34 +1,39 b''
1 == New Features ==
1 == New Features ==
2
2
3 * `hg purge`/`hg clean` can now delete ignored files instead of
3 * `hg purge`/`hg clean` can now delete ignored files instead of
4 untracked files, with the new -i flag.
4 untracked files, with the new -i flag.
5
5
6 * `hg log` now defaults to using an '%' symbol for commits involved
6 * `hg log` now defaults to using an '%' symbol for commits involved
7 in unresolved merge conflicts. That includes unresolved conflicts
7 in unresolved merge conflicts. That includes unresolved conflicts
8 caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
8 caused by e.g. `hg update --merge` and `hg graft`. '@' still takes
9 precedence, so what used to be marked '@' still is.
9 precedence, so what used to be marked '@' still is.
10
10
11 * New `conflictlocal()` and `conflictother()` revsets return the
11 * New `conflictlocal()` and `conflictother()` revsets return the
12 commits that are being merged, when there are conflicts. Also works
12 commits that are being merged, when there are conflicts. Also works
13 for conflicts caused by e.g. `hg graft`.
13 for conflicts caused by e.g. `hg graft`.
14
14
15
15
16 == New Experimental Features ==
16 == New Experimental Features ==
17
17
18
18
19 == Bug Fixes ==
19 == Bug Fixes ==
20
20
21
21
22 == Backwards Compatibility Changes ==
22 == Backwards Compatibility Changes ==
23
23
24 * When `hg rebase` pauses for merge conflict resolution, the working
25 copy will no longer have the rebased node as a second parent. You
26 can use the new `conflictparents()` revset for finding the other
27 parent during a conflict.
28
24
29
25 == Internal API Changes ==
30 == Internal API Changes ==
26
31
27 * The deprecated `ui.progress()` has now been deleted. Please use
32 * The deprecated `ui.progress()` has now been deleted. Please use
28 `ui.makeprogress()` instead.
33 `ui.makeprogress()` instead.
29
34
30 * `hg.merge()` has lost its `abort` argument. Please call
35 * `hg.merge()` has lost its `abort` argument. Please call
31 `hg.abortmerge()` directly instead.
36 `hg.abortmerge()` directly instead.
32
37
33 * The `*others` argument of `cmdutil.check_incompatible_arguments()`
38 * The `*others` argument of `cmdutil.check_incompatible_arguments()`
34 changed from being varargs argument to being a single collection.
39 changed from being varargs argument to being a single collection.
@@ -1,525 +1,525 b''
1 #testcases abortcommand abortflag
1 #testcases abortcommand abortflag
2 #testcases continuecommand continueflag
2 #testcases continuecommand continueflag
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > rebase=
6 > rebase=
7 >
7 >
8 > [phases]
8 > [phases]
9 > publish=False
9 > publish=False
10 >
10 >
11 > [alias]
11 > [alias]
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
12 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 > EOF
13 > EOF
14
14
15 #if abortflag
15 #if abortflag
16 $ cat >> $HGRCPATH <<EOF
16 $ cat >> $HGRCPATH <<EOF
17 > [alias]
17 > [alias]
18 > abort = rebase --abort
18 > abort = rebase --abort
19 > EOF
19 > EOF
20 #endif
20 #endif
21
21
22 #if continueflag
22 #if continueflag
23 $ cat >> $HGRCPATH <<EOF
23 $ cat >> $HGRCPATH <<EOF
24 > [alias]
24 > [alias]
25 > continue = rebase --continue
25 > continue = rebase --continue
26 > EOF
26 > EOF
27 #endif
27 #endif
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31
31
32 $ touch .hg/rebasestate
32 $ touch .hg/rebasestate
33 $ hg sum
33 $ hg sum
34 parent: -1:000000000000 tip (empty repository)
34 parent: -1:000000000000 tip (empty repository)
35 branch: default
35 branch: default
36 commit: (clean)
36 commit: (clean)
37 update: (current)
37 update: (current)
38 abort: .hg/rebasestate is incomplete
38 abort: .hg/rebasestate is incomplete
39 [255]
39 [255]
40 $ rm .hg/rebasestate
40 $ rm .hg/rebasestate
41
41
42 $ echo c1 > common
42 $ echo c1 > common
43 $ hg add common
43 $ hg add common
44 $ hg ci -m C1
44 $ hg ci -m C1
45
45
46 $ echo c2 >> common
46 $ echo c2 >> common
47 $ hg ci -m C2
47 $ hg ci -m C2
48
48
49 $ echo c3 >> common
49 $ echo c3 >> common
50 $ hg ci -m C3
50 $ hg ci -m C3
51
51
52 $ hg up -q -C 1
52 $ hg up -q -C 1
53
53
54 $ echo l1 >> extra
54 $ echo l1 >> extra
55 $ hg add extra
55 $ hg add extra
56 $ hg ci -m L1
56 $ hg ci -m L1
57 created new head
57 created new head
58
58
59 $ sed -e 's/c2/l2/' common > common.new
59 $ sed -e 's/c2/l2/' common > common.new
60 $ mv common.new common
60 $ mv common.new common
61 $ hg ci -m L2
61 $ hg ci -m L2
62
62
63 $ hg phase --force --secret 2
63 $ hg phase --force --secret 2
64
64
65 $ hg tglog
65 $ hg tglog
66 @ 4:draft 'L2'
66 @ 4:draft 'L2'
67 |
67 |
68 o 3:draft 'L1'
68 o 3:draft 'L1'
69 |
69 |
70 | o 2:secret 'C3'
70 | o 2:secret 'C3'
71 |/
71 |/
72 o 1:draft 'C2'
72 o 1:draft 'C2'
73 |
73 |
74 o 0:draft 'C1'
74 o 0:draft 'C1'
75
75
76
76
77 Conflicting rebase:
77 Conflicting rebase:
78
78
79 $ hg rebase -s 3 -d 2
79 $ hg rebase -s 3 -d 2
80 rebasing 3:3163e20567cc "L1"
80 rebasing 3:3163e20567cc "L1"
81 rebasing 4:46f0b057b5c0 "L2" (tip)
81 rebasing 4:46f0b057b5c0 "L2" (tip)
82 merging common
82 merging common
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
83 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
84 unresolved conflicts (see hg resolve, then hg rebase --continue)
84 unresolved conflicts (see hg resolve, then hg rebase --continue)
85 [1]
85 [1]
86
86
87 Insert unsupported advisory merge record:
87 Insert unsupported advisory merge record:
88
88
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
89 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
90 $ hg debugmergestate
90 $ hg debugmergestate
91 * version 2 records
91 * version 2 records
92 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
92 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
93 other: 46f0b057b5c061d276b91491c22151f78698abd2
93 other: 46f0b057b5c061d276b91491c22151f78698abd2
94 labels:
94 labels:
95 local: dest
95 local: dest
96 other: source
96 other: source
97 unrecognized entry: x advisory record
97 unrecognized entry: x advisory record
98 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
98 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
99 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
99 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
100 local path: common (flags "")
100 local path: common (flags "")
101 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
101 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
102 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
102 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
103 $ hg resolve -l
103 $ hg resolve -l
104 U common
104 U common
105
105
106 Insert unsupported mandatory merge record:
106 Insert unsupported mandatory merge record:
107
107
108 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
108 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
109 $ hg debugmergestate
109 $ hg debugmergestate
110 * version 2 records
110 * version 2 records
111 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
111 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
112 other: 46f0b057b5c061d276b91491c22151f78698abd2
112 other: 46f0b057b5c061d276b91491c22151f78698abd2
113 labels:
113 labels:
114 local: dest
114 local: dest
115 other: source
115 other: source
116 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
116 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
117 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
117 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
118 local path: common (flags "")
118 local path: common (flags "")
119 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
119 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
120 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
120 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
121 unrecognized entry: X mandatory record
121 unrecognized entry: X mandatory record
122 $ hg resolve -l
122 $ hg resolve -l
123 abort: unsupported merge state records: X
123 abort: unsupported merge state records: X
124 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
124 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
125 [255]
125 [255]
126 $ hg resolve -ma
126 $ hg resolve -ma
127 abort: unsupported merge state records: X
127 abort: unsupported merge state records: X
128 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
128 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
129 [255]
129 [255]
130
130
131 Abort (should clear out unsupported merge state):
131 Abort (should clear out unsupported merge state):
132
132
133 #if abortcommand
133 #if abortcommand
134 when in dry-run mode
134 when in dry-run mode
135 $ hg abort --dry-run
135 $ hg abort --dry-run
136 rebase in progress, will be aborted
136 rebase in progress, will be aborted
137 #endif
137 #endif
138
138
139 $ hg abort
139 $ hg abort
140 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
140 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
141 rebase aborted
141 rebase aborted
142 $ hg debugmergestate
142 $ hg debugmergestate
143 no merge state found
143 no merge state found
144
144
145 $ hg tglog
145 $ hg tglog
146 @ 4:draft 'L2'
146 @ 4:draft 'L2'
147 |
147 |
148 o 3:draft 'L1'
148 o 3:draft 'L1'
149 |
149 |
150 | o 2:secret 'C3'
150 | o 2:secret 'C3'
151 |/
151 |/
152 o 1:draft 'C2'
152 o 1:draft 'C2'
153 |
153 |
154 o 0:draft 'C1'
154 o 0:draft 'C1'
155
155
156 Test safety for inconsistent rebase state, which may be created (and
156 Test safety for inconsistent rebase state, which may be created (and
157 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
157 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
158 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
158 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
159
159
160 $ hg rebase -s 3 -d 2
160 $ hg rebase -s 3 -d 2
161 rebasing 3:3163e20567cc "L1"
161 rebasing 3:3163e20567cc "L1"
162 rebasing 4:46f0b057b5c0 "L2" (tip)
162 rebasing 4:46f0b057b5c0 "L2" (tip)
163 merging common
163 merging common
164 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
164 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
165 unresolved conflicts (see hg resolve, then hg rebase --continue)
165 unresolved conflicts (see hg resolve, then hg rebase --continue)
166 [1]
166 [1]
167
167
168 $ mv .hg/rebasestate .hg/rebasestate.back
168 $ mv .hg/rebasestate .hg/rebasestate.back
169 $ hg update --quiet --clean 2
169 $ hg update --quiet --clean 2
170 $ hg --config extensions.mq= strip --quiet "destination()"
170 $ hg --config extensions.mq= strip --quiet "destination()"
171 $ mv .hg/rebasestate.back .hg/rebasestate
171 $ mv .hg/rebasestate.back .hg/rebasestate
172
172
173 $ hg continue
173 $ hg continue
174 abort: cannot continue inconsistent rebase
174 abort: cannot continue inconsistent rebase
175 (use "hg rebase --abort" to clear broken state)
175 (use "hg rebase --abort" to clear broken state)
176 [255]
176 [255]
177 $ hg summary | grep '^rebase: '
177 $ hg summary | grep '^rebase: '
178 rebase: (use "hg rebase --abort" to clear broken state)
178 rebase: (use "hg rebase --abort" to clear broken state)
179 $ hg abort
179 $ hg abort
180 rebase aborted (no revision is removed, only broken state is cleared)
180 rebase aborted (no revision is removed, only broken state is cleared)
181
181
182 $ cd ..
182 $ cd ..
183
183
184
184
185 Construct new repo:
185 Construct new repo:
186
186
187 $ hg init b
187 $ hg init b
188 $ cd b
188 $ cd b
189
189
190 $ echo a > a
190 $ echo a > a
191 $ hg ci -Am A
191 $ hg ci -Am A
192 adding a
192 adding a
193
193
194 $ echo b > b
194 $ echo b > b
195 $ hg ci -Am B
195 $ hg ci -Am B
196 adding b
196 adding b
197
197
198 $ echo c > c
198 $ echo c > c
199 $ hg ci -Am C
199 $ hg ci -Am C
200 adding c
200 adding c
201
201
202 $ hg up -q 0
202 $ hg up -q 0
203
203
204 $ echo b > b
204 $ echo b > b
205 $ hg ci -Am 'B bis'
205 $ hg ci -Am 'B bis'
206 adding b
206 adding b
207 created new head
207 created new head
208
208
209 $ echo c1 > c
209 $ echo c1 > c
210 $ hg ci -Am C1
210 $ hg ci -Am C1
211 adding c
211 adding c
212
212
213 $ hg phase --force --secret 1
213 $ hg phase --force --secret 1
214 $ hg phase --public 1
214 $ hg phase --public 1
215
215
216 Rebase and abort without generating new changesets:
216 Rebase and abort without generating new changesets:
217
217
218 $ hg tglog
218 $ hg tglog
219 @ 4:draft 'C1'
219 @ 4:draft 'C1'
220 |
220 |
221 o 3:draft 'B bis'
221 o 3:draft 'B bis'
222 |
222 |
223 | o 2:secret 'C'
223 | o 2:secret 'C'
224 | |
224 | |
225 | o 1:public 'B'
225 | o 1:public 'B'
226 |/
226 |/
227 o 0:public 'A'
227 o 0:public 'A'
228
228
229 $ hg rebase -b 4 -d 2
229 $ hg rebase -b 4 -d 2
230 rebasing 3:a6484957d6b9 "B bis"
230 rebasing 3:a6484957d6b9 "B bis"
231 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
231 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
232 rebasing 4:145842775fec "C1" (tip)
232 rebasing 4:145842775fec "C1" (tip)
233 merging c
233 merging c
234 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
234 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
235 unresolved conflicts (see hg resolve, then hg rebase --continue)
235 unresolved conflicts (see hg resolve, then hg rebase --continue)
236 [1]
236 [1]
237
237
238 $ hg tglog
238 $ hg tglog
239 @ 4:draft 'C1'
239 % 4:draft 'C1'
240 |
240 |
241 o 3:draft 'B bis'
241 o 3:draft 'B bis'
242 |
242 |
243 | @ 2:secret 'C'
243 | @ 2:secret 'C'
244 | |
244 | |
245 | o 1:public 'B'
245 | o 1:public 'B'
246 |/
246 |/
247 o 0:public 'A'
247 o 0:public 'A'
248
248
249 $ hg rebase -a
249 $ hg rebase -a
250 rebase aborted
250 rebase aborted
251
251
252 $ hg tglog
252 $ hg tglog
253 @ 4:draft 'C1'
253 @ 4:draft 'C1'
254 |
254 |
255 o 3:draft 'B bis'
255 o 3:draft 'B bis'
256 |
256 |
257 | o 2:secret 'C'
257 | o 2:secret 'C'
258 | |
258 | |
259 | o 1:public 'B'
259 | o 1:public 'B'
260 |/
260 |/
261 o 0:public 'A'
261 o 0:public 'A'
262
262
263
263
264 $ cd ..
264 $ cd ..
265
265
266 rebase abort should not leave working copy in a merge state if tip-1 is public
266 rebase abort should not leave working copy in a merge state if tip-1 is public
267 (issue4082)
267 (issue4082)
268
268
269 $ hg init abortpublic
269 $ hg init abortpublic
270 $ cd abortpublic
270 $ cd abortpublic
271 $ echo a > a && hg ci -Aqm a
271 $ echo a > a && hg ci -Aqm a
272 $ hg book master
272 $ hg book master
273 $ hg book foo
273 $ hg book foo
274 $ echo b > b && hg ci -Aqm b
274 $ echo b > b && hg ci -Aqm b
275 $ hg up -q master
275 $ hg up -q master
276 $ echo c > c && hg ci -Aqm c
276 $ echo c > c && hg ci -Aqm c
277 $ hg phase -p -r .
277 $ hg phase -p -r .
278 $ hg up -q foo
278 $ hg up -q foo
279 $ echo C > c && hg ci -Aqm C
279 $ echo C > c && hg ci -Aqm C
280 $ hg log -G --template "{rev} {desc} {bookmarks}"
280 $ hg log -G --template "{rev} {desc} {bookmarks}"
281 @ 3 C foo
281 @ 3 C foo
282 |
282 |
283 | o 2 c master
283 | o 2 c master
284 | |
284 | |
285 o | 1 b
285 o | 1 b
286 |/
286 |/
287 o 0 a
287 o 0 a
288
288
289
289
290 $ hg rebase -d master -r foo
290 $ hg rebase -d master -r foo
291 rebasing 3:6c0f977a22d8 "C" (foo tip)
291 rebasing 3:6c0f977a22d8 "C" (foo tip)
292 merging c
292 merging c
293 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
293 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
294 unresolved conflicts (see hg resolve, then hg rebase --continue)
294 unresolved conflicts (see hg resolve, then hg rebase --continue)
295 [1]
295 [1]
296 $ hg abort
296 $ hg abort
297 rebase aborted
297 rebase aborted
298 $ hg log -G --template "{rev} {desc} {bookmarks}"
298 $ hg log -G --template "{rev} {desc} {bookmarks}"
299 @ 3 C foo
299 @ 3 C foo
300 |
300 |
301 | o 2 c master
301 | o 2 c master
302 | |
302 | |
303 o | 1 b
303 o | 1 b
304 |/
304 |/
305 o 0 a
305 o 0 a
306
306
307 $ cd ..
307 $ cd ..
308
308
309 Make sure we don't clobber changes in the working directory when the
309 Make sure we don't clobber changes in the working directory when the
310 user has somehow managed to update to a different revision (issue4009)
310 user has somehow managed to update to a different revision (issue4009)
311
311
312 $ hg init noupdate
312 $ hg init noupdate
313 $ cd noupdate
313 $ cd noupdate
314 $ hg book @
314 $ hg book @
315 $ echo original > a
315 $ echo original > a
316 $ hg add a
316 $ hg add a
317 $ hg commit -m a
317 $ hg commit -m a
318 $ echo x > b
318 $ echo x > b
319 $ hg add b
319 $ hg add b
320 $ hg commit -m b1
320 $ hg commit -m b1
321 $ hg up 0
321 $ hg up 0
322 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
322 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 (leaving bookmark @)
323 (leaving bookmark @)
324 $ hg book foo
324 $ hg book foo
325 $ echo y > b
325 $ echo y > b
326 $ hg add b
326 $ hg add b
327 $ hg commit -m b2
327 $ hg commit -m b2
328 created new head
328 created new head
329
329
330 $ hg rebase -d @ -b foo --tool=internal:fail
330 $ hg rebase -d @ -b foo --tool=internal:fail
331 rebasing 2:070cf4580bb5 "b2" (foo tip)
331 rebasing 2:070cf4580bb5 "b2" (foo tip)
332 unresolved conflicts (see hg resolve, then hg rebase --continue)
332 unresolved conflicts (see hg resolve, then hg rebase --continue)
333 [1]
333 [1]
334
334
335 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
335 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
336 $ hg up -C 0 # user does other stuff in the repo
336 $ hg up -C 0 # user does other stuff in the repo
337 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
337 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
338
338
339 $ mv rebasestate .hg/ # user upgrades to 2.7
339 $ mv rebasestate .hg/ # user upgrades to 2.7
340
340
341 $ echo new > a
341 $ echo new > a
342 $ hg up 1 # user gets an error saying to run hg rebase --abort
342 $ hg up 1 # user gets an error saying to run hg rebase --abort
343 abort: rebase in progress
343 abort: rebase in progress
344 (use 'hg rebase --continue' or 'hg rebase --abort')
344 (use 'hg rebase --continue' or 'hg rebase --abort')
345 [255]
345 [255]
346
346
347 $ cat a
347 $ cat a
348 new
348 new
349 $ hg abort
349 $ hg abort
350 rebase aborted
350 rebase aborted
351 $ cat a
351 $ cat a
352 new
352 new
353
353
354 $ cd ..
354 $ cd ..
355
355
356 test aborting an interrupted series (issue5084)
356 test aborting an interrupted series (issue5084)
357 $ hg init interrupted
357 $ hg init interrupted
358 $ cd interrupted
358 $ cd interrupted
359 $ touch base
359 $ touch base
360 $ hg add base
360 $ hg add base
361 $ hg commit -m base
361 $ hg commit -m base
362 $ touch a
362 $ touch a
363 $ hg add a
363 $ hg add a
364 $ hg commit -m a
364 $ hg commit -m a
365 $ echo 1 > a
365 $ echo 1 > a
366 $ hg commit -m 1
366 $ hg commit -m 1
367 $ touch b
367 $ touch b
368 $ hg add b
368 $ hg add b
369 $ hg commit -m b
369 $ hg commit -m b
370 $ echo 2 >> a
370 $ echo 2 >> a
371 $ hg commit -m c
371 $ hg commit -m c
372 $ touch d
372 $ touch d
373 $ hg add d
373 $ hg add d
374 $ hg commit -m d
374 $ hg commit -m d
375 $ hg co -q 1
375 $ hg co -q 1
376 $ hg rm a
376 $ hg rm a
377 $ hg commit -m no-a
377 $ hg commit -m no-a
378 created new head
378 created new head
379 $ hg co 0
379 $ hg co 0
380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 $ hg log -G --template "{rev} {desc} {bookmarks}"
381 $ hg log -G --template "{rev} {desc} {bookmarks}"
382 o 6 no-a
382 o 6 no-a
383 |
383 |
384 | o 5 d
384 | o 5 d
385 | |
385 | |
386 | o 4 c
386 | o 4 c
387 | |
387 | |
388 | o 3 b
388 | o 3 b
389 | |
389 | |
390 | o 2 1
390 | o 2 1
391 |/
391 |/
392 o 1 a
392 o 1 a
393 |
393 |
394 @ 0 base
394 @ 0 base
395
395
396 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
396 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
397 rebasing 3:3a71550954f1 "b"
397 rebasing 3:3a71550954f1 "b"
398 rebasing 4:e80b69427d80 "c"
398 rebasing 4:e80b69427d80 "c"
399 abort: ^C
399 abort: ^C
400 [255]
400 [255]
401
401
402 New operations are blocked with the correct state message
402 New operations are blocked with the correct state message
403
403
404 $ find .hg -name '*state' -prune | sort
404 $ find .hg -name '*state' -prune | sort
405 .hg/dirstate
405 .hg/dirstate
406 .hg/merge/state
406 .hg/merge/state
407 .hg/rebasestate
407 .hg/rebasestate
408 .hg/undo.backup.dirstate
408 .hg/undo.backup.dirstate
409 .hg/undo.dirstate
409 .hg/undo.dirstate
410 .hg/updatestate
410 .hg/updatestate
411
411
412 $ hg rebase -s 3 -d tip
412 $ hg rebase -s 3 -d tip
413 abort: rebase in progress
413 abort: rebase in progress
414 (use 'hg rebase --continue' or 'hg rebase --abort')
414 (use 'hg rebase --continue' or 'hg rebase --abort')
415 [255]
415 [255]
416 $ hg up .
416 $ hg up .
417 abort: rebase in progress
417 abort: rebase in progress
418 (use 'hg rebase --continue' or 'hg rebase --abort')
418 (use 'hg rebase --continue' or 'hg rebase --abort')
419 [255]
419 [255]
420 $ hg up -C .
420 $ hg up -C .
421 abort: rebase in progress
421 abort: rebase in progress
422 (use 'hg rebase --continue' or 'hg rebase --abort')
422 (use 'hg rebase --continue' or 'hg rebase --abort')
423 [255]
423 [255]
424
424
425 $ hg graft 3
425 $ hg graft 3
426 abort: rebase in progress
426 abort: rebase in progress
427 (use 'hg rebase --continue' or 'hg rebase --abort')
427 (use 'hg rebase --continue' or 'hg rebase --abort')
428 [255]
428 [255]
429
429
430 $ hg abort
430 $ hg abort
431 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
431 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
432 rebase aborted
432 rebase aborted
433 $ hg log -G --template "{rev} {desc} {bookmarks}"
433 $ hg log -G --template "{rev} {desc} {bookmarks}"
434 o 6 no-a
434 o 6 no-a
435 |
435 |
436 | o 5 d
436 | o 5 d
437 | |
437 | |
438 | o 4 c
438 | o 4 c
439 | |
439 | |
440 | o 3 b
440 | o 3 b
441 | |
441 | |
442 | o 2 1
442 | o 2 1
443 |/
443 |/
444 o 1 a
444 o 1 a
445 |
445 |
446 @ 0 base
446 @ 0 base
447
447
448 $ hg summary
448 $ hg summary
449 parent: 0:df4f53cec30a
449 parent: 0:df4f53cec30a
450 base
450 base
451 branch: default
451 branch: default
452 commit: (clean)
452 commit: (clean)
453 update: 6 new changesets (update)
453 update: 6 new changesets (update)
454 phases: 7 draft
454 phases: 7 draft
455
455
456 $ cd ..
456 $ cd ..
457 On the other hand, make sure we *do* clobber changes whenever we
457 On the other hand, make sure we *do* clobber changes whenever we
458 haven't somehow managed to update the repo to a different revision
458 haven't somehow managed to update the repo to a different revision
459 during a rebase (issue4661)
459 during a rebase (issue4661)
460
460
461 $ hg ini yesupdate
461 $ hg ini yesupdate
462 $ cd yesupdate
462 $ cd yesupdate
463 $ echo "initial data" > foo.txt
463 $ echo "initial data" > foo.txt
464 $ hg add
464 $ hg add
465 adding foo.txt
465 adding foo.txt
466 $ hg ci -m "initial checkin"
466 $ hg ci -m "initial checkin"
467 $ echo "change 1" > foo.txt
467 $ echo "change 1" > foo.txt
468 $ hg ci -m "change 1"
468 $ hg ci -m "change 1"
469 $ hg up 0
469 $ hg up 0
470 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 $ echo "conflicting change 1" > foo.txt
471 $ echo "conflicting change 1" > foo.txt
472 $ hg ci -m "conflicting 1"
472 $ hg ci -m "conflicting 1"
473 created new head
473 created new head
474 $ echo "conflicting change 2" > foo.txt
474 $ echo "conflicting change 2" > foo.txt
475 $ hg ci -m "conflicting 2"
475 $ hg ci -m "conflicting 2"
476
476
477 $ hg rebase -d 1 --tool 'internal:fail'
477 $ hg rebase -d 1 --tool 'internal:fail'
478 rebasing 2:e4ea5cdc9789 "conflicting 1"
478 rebasing 2:e4ea5cdc9789 "conflicting 1"
479 unresolved conflicts (see hg resolve, then hg rebase --continue)
479 unresolved conflicts (see hg resolve, then hg rebase --continue)
480 [1]
480 [1]
481 $ hg abort
481 $ hg abort
482 rebase aborted
482 rebase aborted
483 $ hg summary
483 $ hg summary
484 parent: 3:b16646383533 tip
484 parent: 3:b16646383533 tip
485 conflicting 2
485 conflicting 2
486 branch: default
486 branch: default
487 commit: (clean)
487 commit: (clean)
488 update: 1 new changesets, 2 branch heads (merge)
488 update: 1 new changesets, 2 branch heads (merge)
489 phases: 4 draft
489 phases: 4 draft
490 $ cd ..
490 $ cd ..
491
491
492 test aborting a rebase succeeds after rebasing with skipped commits onto a
492 test aborting a rebase succeeds after rebasing with skipped commits onto a
493 public changeset (issue4896)
493 public changeset (issue4896)
494
494
495 $ hg init succeedonpublic
495 $ hg init succeedonpublic
496 $ cd succeedonpublic
496 $ cd succeedonpublic
497 $ echo 'content' > root
497 $ echo 'content' > root
498 $ hg commit -A -m 'root' -q
498 $ hg commit -A -m 'root' -q
499
499
500 set up public branch
500 set up public branch
501 $ echo 'content' > disappear
501 $ echo 'content' > disappear
502 $ hg commit -A -m 'disappear public' -q
502 $ hg commit -A -m 'disappear public' -q
503 commit will cause merge conflict on rebase
503 commit will cause merge conflict on rebase
504 $ echo '' > root
504 $ echo '' > root
505 $ hg commit -m 'remove content public' -q
505 $ hg commit -m 'remove content public' -q
506 $ hg phase --public
506 $ hg phase --public
507
507
508 setup the draft branch that will be rebased onto public commit
508 setup the draft branch that will be rebased onto public commit
509 $ hg up -r 0 -q
509 $ hg up -r 0 -q
510 $ echo 'content' > disappear
510 $ echo 'content' > disappear
511 commit will disappear
511 commit will disappear
512 $ hg commit -A -m 'disappear draft' -q
512 $ hg commit -A -m 'disappear draft' -q
513 $ echo 'addedcontADDEDentadded' > root
513 $ echo 'addedcontADDEDentadded' > root
514 commit will cause merge conflict on rebase
514 commit will cause merge conflict on rebase
515 $ hg commit -m 'add content draft' -q
515 $ hg commit -m 'add content draft' -q
516
516
517 $ hg rebase -d 'public()' --tool :merge -q
517 $ hg rebase -d 'public()' --tool :merge -q
518 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
518 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
519 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
519 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
520 unresolved conflicts (see hg resolve, then hg rebase --continue)
520 unresolved conflicts (see hg resolve, then hg rebase --continue)
521 [1]
521 [1]
522 $ hg abort
522 $ hg abort
523 rebase aborted
523 rebase aborted
524 $ cd ..
524 $ cd ..
525
525
@@ -1,776 +1,776 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 > mq=
4 > mq=
5 > drawdag=$TESTDIR/drawdag.py
5 > drawdag=$TESTDIR/drawdag.py
6 >
6 >
7 > [phases]
7 > [phases]
8 > publish=False
8 > publish=False
9 >
9 >
10 > [alias]
10 > [alias]
11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
13 > EOF
13 > EOF
14
14
15 Highest phase of source commits is used:
15 Highest phase of source commits is used:
16
16
17 $ hg init phase
17 $ hg init phase
18 $ cd phase
18 $ cd phase
19 $ hg debugdrawdag << 'EOF'
19 $ hg debugdrawdag << 'EOF'
20 > D
20 > D
21 > |
21 > |
22 > F C
22 > F C
23 > | |
23 > | |
24 > E B
24 > E B
25 > |/
25 > |/
26 > A
26 > A
27 > EOF
27 > EOF
28
28
29 $ hg phase --force --secret D
29 $ hg phase --force --secret D
30
30
31 $ cat > $TESTTMP/editor.sh <<EOF
31 $ cat > $TESTTMP/editor.sh <<EOF
32 > echo "==== before editing"
32 > echo "==== before editing"
33 > cat \$1
33 > cat \$1
34 > echo "===="
34 > echo "===="
35 > echo "edited manually" >> \$1
35 > echo "edited manually" >> \$1
36 > EOF
36 > EOF
37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
38 rebasing 1:112478962961 "B" (B)
38 rebasing 1:112478962961 "B" (B)
39 rebasing 3:26805aba1e60 "C" (C)
39 rebasing 3:26805aba1e60 "C" (C)
40 rebasing 5:f585351a92f8 "D" (D tip)
40 rebasing 5:f585351a92f8 "D" (D tip)
41 ==== before editing
41 ==== before editing
42 Collapsed revision
42 Collapsed revision
43 * B
43 * B
44 * C
44 * C
45 * D
45 * D
46
46
47
47
48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
49 HG: Leave message empty to abort commit.
49 HG: Leave message empty to abort commit.
50 HG: --
50 HG: --
51 HG: user: test
51 HG: user: test
52 HG: branch 'default'
52 HG: branch 'default'
53 HG: added B
53 HG: added B
54 HG: added C
54 HG: added C
55 HG: added D
55 HG: added D
56 ====
56 ====
57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
58
58
59 $ hg tglogp
59 $ hg tglogp
60 o 3: 92fa5f5fe108 secret 'Collapsed revision
60 o 3: 92fa5f5fe108 secret 'Collapsed revision
61 | * B
61 | * B
62 | * C
62 | * C
63 | * D
63 | * D
64 |
64 |
65 |
65 |
66 | edited manually'
66 | edited manually'
67 o 2: 64a8289d2492 draft 'F'
67 o 2: 64a8289d2492 draft 'F'
68 |
68 |
69 o 1: 7fb047a69f22 draft 'E'
69 o 1: 7fb047a69f22 draft 'E'
70 |
70 |
71 o 0: 426bada5c675 draft 'A'
71 o 0: 426bada5c675 draft 'A'
72
72
73 $ hg manifest --rev tip
73 $ hg manifest --rev tip
74 A
74 A
75 B
75 B
76 C
76 C
77 D
77 D
78 E
78 E
79 F
79 F
80
80
81 $ cd ..
81 $ cd ..
82
82
83
83
84 Merge gets linearized:
84 Merge gets linearized:
85
85
86 $ hg init linearized-merge
86 $ hg init linearized-merge
87 $ cd linearized-merge
87 $ cd linearized-merge
88
88
89 $ hg debugdrawdag << 'EOF'
89 $ hg debugdrawdag << 'EOF'
90 > F D
90 > F D
91 > |/|
91 > |/|
92 > C B
92 > C B
93 > |/
93 > |/
94 > A
94 > A
95 > EOF
95 > EOF
96
96
97 $ hg phase --force --secret D
97 $ hg phase --force --secret D
98 $ hg rebase --source B --collapse --dest F
98 $ hg rebase --source B --collapse --dest F
99 rebasing 1:112478962961 "B" (B)
99 rebasing 1:112478962961 "B" (B)
100 rebasing 3:4e4f9194f9f1 "D" (D)
100 rebasing 3:4e4f9194f9f1 "D" (D)
101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
102
102
103 $ hg tglog
103 $ hg tglog
104 o 3: 5bdc08b7da2b 'Collapsed revision
104 o 3: 5bdc08b7da2b 'Collapsed revision
105 | * B
105 | * B
106 | * D'
106 | * D'
107 o 2: afc707c82df0 'F'
107 o 2: afc707c82df0 'F'
108 |
108 |
109 o 1: dc0947a82db8 'C'
109 o 1: dc0947a82db8 'C'
110 |
110 |
111 o 0: 426bada5c675 'A'
111 o 0: 426bada5c675 'A'
112
112
113 $ hg manifest --rev tip
113 $ hg manifest --rev tip
114 A
114 A
115 B
115 B
116 C
116 C
117 F
117 F
118
118
119 $ cd ..
119 $ cd ..
120
120
121 Custom message:
121 Custom message:
122
122
123 $ hg init message
123 $ hg init message
124 $ cd message
124 $ cd message
125
125
126 $ hg debugdrawdag << 'EOF'
126 $ hg debugdrawdag << 'EOF'
127 > C
127 > C
128 > |
128 > |
129 > D B
129 > D B
130 > |/
130 > |/
131 > A
131 > A
132 > EOF
132 > EOF
133
133
134
134
135 $ hg rebase --base B -m 'custom message'
135 $ hg rebase --base B -m 'custom message'
136 abort: message can only be specified with collapse
136 abort: message can only be specified with collapse
137 [255]
137 [255]
138
138
139 $ cat > $TESTTMP/checkeditform.sh <<EOF
139 $ cat > $TESTTMP/checkeditform.sh <<EOF
140 > env | grep HGEDITFORM
140 > env | grep HGEDITFORM
141 > true
141 > true
142 > EOF
142 > EOF
143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
144 rebasing 1:112478962961 "B" (B)
144 rebasing 1:112478962961 "B" (B)
145 rebasing 3:26805aba1e60 "C" (C tip)
145 rebasing 3:26805aba1e60 "C" (C tip)
146 HGEDITFORM=rebase.collapse
146 HGEDITFORM=rebase.collapse
147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
148
148
149 $ hg tglog
149 $ hg tglog
150 o 2: 2f197b9a08f3 'custom message'
150 o 2: 2f197b9a08f3 'custom message'
151 |
151 |
152 o 1: b18e25de2cf5 'D'
152 o 1: b18e25de2cf5 'D'
153 |
153 |
154 o 0: 426bada5c675 'A'
154 o 0: 426bada5c675 'A'
155
155
156 $ hg manifest --rev tip
156 $ hg manifest --rev tip
157 A
157 A
158 B
158 B
159 C
159 C
160 D
160 D
161
161
162 $ cd ..
162 $ cd ..
163
163
164 Rebase and collapse - more than one external (fail):
164 Rebase and collapse - more than one external (fail):
165
165
166 $ hg init multiple-external-parents
166 $ hg init multiple-external-parents
167 $ cd multiple-external-parents
167 $ cd multiple-external-parents
168
168
169 $ hg debugdrawdag << 'EOF'
169 $ hg debugdrawdag << 'EOF'
170 > G
170 > G
171 > |\
171 > |\
172 > | F
172 > | F
173 > | |
173 > | |
174 > D E
174 > D E
175 > |\|
175 > |\|
176 > H C B
176 > H C B
177 > \|/
177 > \|/
178 > A
178 > A
179 > EOF
179 > EOF
180
180
181 $ hg rebase -s C --dest H --collapse
181 $ hg rebase -s C --dest H --collapse
182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
183 [255]
183 [255]
184
184
185 Rebase and collapse - E onto H:
185 Rebase and collapse - E onto H:
186
186
187 $ hg rebase -s E --dest I --collapse # root (E) is not a merge
187 $ hg rebase -s E --dest I --collapse # root (E) is not a merge
188 abort: unknown revision 'I'!
188 abort: unknown revision 'I'!
189 [255]
189 [255]
190
190
191 $ hg tglog
191 $ hg tglog
192 o 7: 64e264db77f0 'G'
192 o 7: 64e264db77f0 'G'
193 |\
193 |\
194 | o 6: 11abe3fb10b8 'F'
194 | o 6: 11abe3fb10b8 'F'
195 | |
195 | |
196 | o 5: 49cb92066bfd 'E'
196 | o 5: 49cb92066bfd 'E'
197 | |
197 | |
198 o | 4: 4e4f9194f9f1 'D'
198 o | 4: 4e4f9194f9f1 'D'
199 |\|
199 |\|
200 | | o 3: 575c4b5ec114 'H'
200 | | o 3: 575c4b5ec114 'H'
201 | | |
201 | | |
202 o---+ 2: dc0947a82db8 'C'
202 o---+ 2: dc0947a82db8 'C'
203 / /
203 / /
204 o / 1: 112478962961 'B'
204 o / 1: 112478962961 'B'
205 |/
205 |/
206 o 0: 426bada5c675 'A'
206 o 0: 426bada5c675 'A'
207
207
208 $ hg manifest --rev tip
208 $ hg manifest --rev tip
209 A
209 A
210 B
210 B
211 C
211 C
212 E
212 E
213 F
213 F
214
214
215 $ cd ..
215 $ cd ..
216
216
217
217
218
218
219
219
220 Test that branchheads cache is updated correctly when doing a strip in which
220 Test that branchheads cache is updated correctly when doing a strip in which
221 the parent of the ancestor node to be stripped does not become a head and also,
221 the parent of the ancestor node to be stripped does not become a head and also,
222 the parent of a node that is a child of the node stripped becomes a head (node
222 the parent of a node that is a child of the node stripped becomes a head (node
223 3). The code is now much simpler and we could just test a simpler scenario
223 3). The code is now much simpler and we could just test a simpler scenario
224 We keep it the test this way in case new complexity is injected.
224 We keep it the test this way in case new complexity is injected.
225
225
226 Create repo b:
226 Create repo b:
227
227
228 $ hg init branch-heads
228 $ hg init branch-heads
229 $ cd branch-heads
229 $ cd branch-heads
230
230
231 $ hg debugdrawdag << 'EOF'
231 $ hg debugdrawdag << 'EOF'
232 > G
232 > G
233 > |\
233 > |\
234 > | F
234 > | F
235 > | |
235 > | |
236 > D E
236 > D E
237 > |\|
237 > |\|
238 > H C B
238 > H C B
239 > \|/
239 > \|/
240 > A
240 > A
241 > EOF
241 > EOF
242
242
243 $ hg heads --template="{rev}:{node} {branch}\n"
243 $ hg heads --template="{rev}:{node} {branch}\n"
244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
246
246
247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
248 64e264db77f061f16d9132b70c5a58e2461fb630 7
248 64e264db77f061f16d9132b70c5a58e2461fb630 7
249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
251
251
252 $ hg strip 4
252 $ hg strip 4
253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
254
254
255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
256 11abe3fb10b8689b560681094b17fe161871d043 5
256 11abe3fb10b8689b560681094b17fe161871d043 5
257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
259 11abe3fb10b8689b560681094b17fe161871d043 o default
259 11abe3fb10b8689b560681094b17fe161871d043 o default
260
260
261 $ hg heads --template="{rev}:{node} {branch}\n"
261 $ hg heads --template="{rev}:{node} {branch}\n"
262 5:11abe3fb10b8689b560681094b17fe161871d043 default
262 5:11abe3fb10b8689b560681094b17fe161871d043 default
263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
265
265
266 $ cd ..
266 $ cd ..
267
267
268
268
269
269
270 Preserves external parent
270 Preserves external parent
271
271
272 $ hg init external-parent
272 $ hg init external-parent
273 $ cd external-parent
273 $ cd external-parent
274
274
275 $ hg debugdrawdag << 'EOF'
275 $ hg debugdrawdag << 'EOF'
276 > H
276 > H
277 > |\
277 > |\
278 > | G
278 > | G
279 > | |
279 > | |
280 > | F # F/E = F\n
280 > | F # F/E = F\n
281 > | |
281 > | |
282 > D E # D/D = D\n
282 > D E # D/D = D\n
283 > |\|
283 > |\|
284 > I C B
284 > I C B
285 > \|/
285 > \|/
286 > A
286 > A
287 > EOF
287 > EOF
288
288
289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
290 rebasing 6:c82b08f646f1 "F" (F)
290 rebasing 6:c82b08f646f1 "F" (F)
291 file 'E' was deleted in local [dest] but was modified in other [source].
291 file 'E' was deleted in local [dest] but was modified in other [source].
292 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
292 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
293 What do you want to do? u
293 What do you want to do? u
294 unresolved conflicts (see hg resolve, then hg rebase --continue)
294 unresolved conflicts (see hg resolve, then hg rebase --continue)
295 [1]
295 [1]
296
296
297 $ echo F > E
297 $ echo F > E
298 $ hg resolve -m
298 $ hg resolve -m
299 (no more unresolved files)
299 (no more unresolved files)
300 continue: hg rebase --continue
300 continue: hg rebase --continue
301 $ hg rebase -c
301 $ hg rebase -c
302 rebasing 6:c82b08f646f1 "F" (F)
302 rebasing 6:c82b08f646f1 "F" (F)
303 rebasing 7:a6db7fa104e1 "G" (G)
303 rebasing 7:a6db7fa104e1 "G" (G)
304 rebasing 8:e1d201b72d91 "H" (H tip)
304 rebasing 8:e1d201b72d91 "H" (H tip)
305 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
305 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
306
306
307 $ hg tglog
307 $ hg tglog
308 o 6: 681daa3e686d 'Collapsed revision
308 o 6: 681daa3e686d 'Collapsed revision
309 |\ * F
309 |\ * F
310 | | * G
310 | | * G
311 | | * H'
311 | | * H'
312 | | o 5: 49cb92066bfd 'E'
312 | | o 5: 49cb92066bfd 'E'
313 | | |
313 | | |
314 | o | 4: 09143c0bf13e 'D'
314 | o | 4: 09143c0bf13e 'D'
315 | |\|
315 | |\|
316 o | | 3: 08ebfeb61bac 'I'
316 o | | 3: 08ebfeb61bac 'I'
317 | | |
317 | | |
318 | o | 2: dc0947a82db8 'C'
318 | o | 2: dc0947a82db8 'C'
319 |/ /
319 |/ /
320 | o 1: 112478962961 'B'
320 | o 1: 112478962961 'B'
321 |/
321 |/
322 o 0: 426bada5c675 'A'
322 o 0: 426bada5c675 'A'
323
323
324 $ hg manifest --rev tip
324 $ hg manifest --rev tip
325 A
325 A
326 C
326 C
327 D
327 D
328 E
328 E
329 F
329 F
330 G
330 G
331 I
331 I
332
332
333 $ hg up tip -q
333 $ hg up tip -q
334 $ cat E
334 $ cat E
335 F
335 F
336
336
337 $ cd ..
337 $ cd ..
338
338
339 Rebasing from multiple bases:
339 Rebasing from multiple bases:
340
340
341 $ hg init multiple-bases
341 $ hg init multiple-bases
342 $ cd multiple-bases
342 $ cd multiple-bases
343 $ hg debugdrawdag << 'EOF'
343 $ hg debugdrawdag << 'EOF'
344 > C B
344 > C B
345 > D |/
345 > D |/
346 > |/
346 > |/
347 > A
347 > A
348 > EOF
348 > EOF
349 $ hg rebase --collapse -r 'B+C' -d D
349 $ hg rebase --collapse -r 'B+C' -d D
350 rebasing 1:fc2b737bb2e5 "B" (B)
350 rebasing 1:fc2b737bb2e5 "B" (B)
351 rebasing 2:dc0947a82db8 "C" (C)
351 rebasing 2:dc0947a82db8 "C" (C)
352 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
352 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
353 $ hg tglog
353 $ hg tglog
354 o 2: 2127ae44d291 'Collapsed revision
354 o 2: 2127ae44d291 'Collapsed revision
355 | * B
355 | * B
356 | * C'
356 | * C'
357 o 1: b18e25de2cf5 'D'
357 o 1: b18e25de2cf5 'D'
358 |
358 |
359 o 0: 426bada5c675 'A'
359 o 0: 426bada5c675 'A'
360
360
361 $ cd ..
361 $ cd ..
362
362
363 With non-contiguous commits:
363 With non-contiguous commits:
364
364
365 $ hg init non-contiguous
365 $ hg init non-contiguous
366 $ cd non-contiguous
366 $ cd non-contiguous
367 $ cat >> .hg/hgrc <<EOF
367 $ cat >> .hg/hgrc <<EOF
368 > [experimental]
368 > [experimental]
369 > evolution=all
369 > evolution=all
370 > EOF
370 > EOF
371
371
372 $ hg debugdrawdag << 'EOF'
372 $ hg debugdrawdag << 'EOF'
373 > F
373 > F
374 > |
374 > |
375 > E
375 > E
376 > |
376 > |
377 > D
377 > D
378 > |
378 > |
379 > C
379 > C
380 > |
380 > |
381 > B G
381 > B G
382 > |/
382 > |/
383 > A
383 > A
384 > EOF
384 > EOF
385
385
386 BROKEN: should be allowed
386 BROKEN: should be allowed
387 $ hg rebase --collapse -r 'B+D+F' -d G
387 $ hg rebase --collapse -r 'B+D+F' -d G
388 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
388 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
389 [255]
389 [255]
390 $ cd ..
390 $ cd ..
391
391
392
392
393 $ hg init multiple-external-parents-2
393 $ hg init multiple-external-parents-2
394 $ cd multiple-external-parents-2
394 $ cd multiple-external-parents-2
395 $ hg debugdrawdag << 'EOF'
395 $ hg debugdrawdag << 'EOF'
396 > D G
396 > D G
397 > |\ /|
397 > |\ /|
398 > B C E F
398 > B C E F
399 > \| |/
399 > \| |/
400 > \ H /
400 > \ H /
401 > \|/
401 > \|/
402 > A
402 > A
403 > EOF
403 > EOF
404
404
405 $ hg rebase --collapse -d H -s 'B+F'
405 $ hg rebase --collapse -d H -s 'B+F'
406 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
406 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
407 [255]
407 [255]
408 $ cd ..
408 $ cd ..
409
409
410 With internal merge:
410 With internal merge:
411
411
412 $ hg init internal-merge
412 $ hg init internal-merge
413 $ cd internal-merge
413 $ cd internal-merge
414
414
415 $ hg debugdrawdag << 'EOF'
415 $ hg debugdrawdag << 'EOF'
416 > E
416 > E
417 > |\
417 > |\
418 > C D
418 > C D
419 > |/
419 > |/
420 > F B
420 > F B
421 > |/
421 > |/
422 > A
422 > A
423 > EOF
423 > EOF
424
424
425
425
426 $ hg rebase -s B --collapse --dest F
426 $ hg rebase -s B --collapse --dest F
427 rebasing 1:112478962961 "B" (B)
427 rebasing 1:112478962961 "B" (B)
428 rebasing 3:26805aba1e60 "C" (C)
428 rebasing 3:26805aba1e60 "C" (C)
429 rebasing 4:be0ef73c17ad "D" (D)
429 rebasing 4:be0ef73c17ad "D" (D)
430 rebasing 5:02c4367d6973 "E" (E tip)
430 rebasing 5:02c4367d6973 "E" (E tip)
431 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
431 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
432
432
433 $ hg tglog
433 $ hg tglog
434 o 2: c0512a1797b0 'Collapsed revision
434 o 2: c0512a1797b0 'Collapsed revision
435 | * B
435 | * B
436 | * C
436 | * C
437 | * D
437 | * D
438 | * E'
438 | * E'
439 o 1: 8908a377a434 'F'
439 o 1: 8908a377a434 'F'
440 |
440 |
441 o 0: 426bada5c675 'A'
441 o 0: 426bada5c675 'A'
442
442
443 $ hg manifest --rev tip
443 $ hg manifest --rev tip
444 A
444 A
445 B
445 B
446 C
446 C
447 D
447 D
448 F
448 F
449 $ cd ..
449 $ cd ..
450
450
451 Interactions between collapse and keepbranches
451 Interactions between collapse and keepbranches
452 $ hg init e
452 $ hg init e
453 $ cd e
453 $ cd e
454 $ echo 'a' > a
454 $ echo 'a' > a
455 $ hg ci -Am 'A'
455 $ hg ci -Am 'A'
456 adding a
456 adding a
457
457
458 $ hg branch 'one'
458 $ hg branch 'one'
459 marked working directory as branch one
459 marked working directory as branch one
460 (branches are permanent and global, did you want a bookmark?)
460 (branches are permanent and global, did you want a bookmark?)
461 $ echo 'b' > b
461 $ echo 'b' > b
462 $ hg ci -Am 'B'
462 $ hg ci -Am 'B'
463 adding b
463 adding b
464
464
465 $ hg branch 'two'
465 $ hg branch 'two'
466 marked working directory as branch two
466 marked working directory as branch two
467 $ echo 'c' > c
467 $ echo 'c' > c
468 $ hg ci -Am 'C'
468 $ hg ci -Am 'C'
469 adding c
469 adding c
470
470
471 $ hg up -q 0
471 $ hg up -q 0
472 $ echo 'd' > d
472 $ echo 'd' > d
473 $ hg ci -Am 'D'
473 $ hg ci -Am 'D'
474 adding d
474 adding d
475
475
476 $ hg tglog
476 $ hg tglog
477 @ 3: 41acb9dca9eb 'D'
477 @ 3: 41acb9dca9eb 'D'
478 |
478 |
479 | o 2: 8ac4a08debf1 'C' two
479 | o 2: 8ac4a08debf1 'C' two
480 | |
480 | |
481 | o 1: 1ba175478953 'B' one
481 | o 1: 1ba175478953 'B' one
482 |/
482 |/
483 o 0: 1994f17a630e 'A'
483 o 0: 1994f17a630e 'A'
484
484
485 $ hg rebase --keepbranches --collapse -s 1 -d 3
485 $ hg rebase --keepbranches --collapse -s 1 -d 3
486 abort: cannot collapse multiple named branches
486 abort: cannot collapse multiple named branches
487 [255]
487 [255]
488
488
489 $ cd ..
489 $ cd ..
490
490
491 Rebase, collapse and copies
491 Rebase, collapse and copies
492
492
493 $ hg init copies
493 $ hg init copies
494 $ cd copies
494 $ cd copies
495 $ hg unbundle "$TESTDIR/bundles/renames.hg"
495 $ hg unbundle "$TESTDIR/bundles/renames.hg"
496 adding changesets
496 adding changesets
497 adding manifests
497 adding manifests
498 adding file changes
498 adding file changes
499 added 4 changesets with 11 changes to 7 files (+1 heads)
499 added 4 changesets with 11 changes to 7 files (+1 heads)
500 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
500 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
501 (run 'hg heads' to see heads, 'hg merge' to merge)
501 (run 'hg heads' to see heads, 'hg merge' to merge)
502 $ hg up -q tip
502 $ hg up -q tip
503 $ hg tglog
503 $ hg tglog
504 @ 3: 338e84e2e558 'move2'
504 @ 3: 338e84e2e558 'move2'
505 |
505 |
506 o 2: 6e7340ee38c0 'move1'
506 o 2: 6e7340ee38c0 'move1'
507 |
507 |
508 | o 1: 1352765a01d4 'change'
508 | o 1: 1352765a01d4 'change'
509 |/
509 |/
510 o 0: f447d5abf5ea 'add'
510 o 0: f447d5abf5ea 'add'
511
511
512 $ hg rebase --collapse -d 1
512 $ hg rebase --collapse -d 1
513 rebasing 2:6e7340ee38c0 "move1"
513 rebasing 2:6e7340ee38c0 "move1"
514 merging a and d to d
514 merging a and d to d
515 merging b and e to e
515 merging b and e to e
516 merging c and f to f
516 merging c and f to f
517 rebasing 3:338e84e2e558 "move2" (tip)
517 rebasing 3:338e84e2e558 "move2" (tip)
518 merging f and c to c
518 merging f and c to c
519 merging e and g to g
519 merging e and g to g
520 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
520 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
521 $ hg st
521 $ hg st
522 $ hg st --copies --change tip
522 $ hg st --copies --change tip
523 A d
523 A d
524 a
524 a
525 A g
525 A g
526 b
526 b
527 R b
527 R b
528 $ hg up tip -q
528 $ hg up tip -q
529 $ cat c
529 $ cat c
530 c
530 c
531 c
531 c
532 $ cat d
532 $ cat d
533 a
533 a
534 a
534 a
535 $ cat g
535 $ cat g
536 b
536 b
537 b
537 b
538 $ hg log -r . --template "{file_copies}\n"
538 $ hg log -r . --template "{file_copies}\n"
539 d (a)g (b)
539 d (a)g (b)
540
540
541 Test collapsing a middle revision in-place
541 Test collapsing a middle revision in-place
542
542
543 $ hg tglog
543 $ hg tglog
544 @ 2: 64b456429f67 'Collapsed revision
544 @ 2: 64b456429f67 'Collapsed revision
545 | * move1
545 | * move1
546 | * move2'
546 | * move2'
547 o 1: 1352765a01d4 'change'
547 o 1: 1352765a01d4 'change'
548 |
548 |
549 o 0: f447d5abf5ea 'add'
549 o 0: f447d5abf5ea 'add'
550
550
551 $ hg rebase --collapse -r 1 -d 0
551 $ hg rebase --collapse -r 1 -d 0
552 abort: cannot rebase changeset with children
552 abort: cannot rebase changeset with children
553 (use --keep to keep original changesets)
553 (use --keep to keep original changesets)
554 [255]
554 [255]
555
555
556 Test collapsing in place
556 Test collapsing in place
557
557
558 $ hg rebase --collapse -b . -d 0
558 $ hg rebase --collapse -b . -d 0
559 rebasing 1:1352765a01d4 "change"
559 rebasing 1:1352765a01d4 "change"
560 rebasing 2:64b456429f67 "Collapsed revision" (tip)
560 rebasing 2:64b456429f67 "Collapsed revision" (tip)
561 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
561 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
562 $ hg st --change tip --copies
562 $ hg st --change tip --copies
563 M a
563 M a
564 M c
564 M c
565 A d
565 A d
566 a
566 a
567 A g
567 A g
568 b
568 b
569 R b
569 R b
570 $ hg up tip -q
570 $ hg up tip -q
571 $ cat a
571 $ cat a
572 a
572 a
573 a
573 a
574 $ cat c
574 $ cat c
575 c
575 c
576 c
576 c
577 $ cat d
577 $ cat d
578 a
578 a
579 a
579 a
580 $ cat g
580 $ cat g
581 b
581 b
582 b
582 b
583 $ cd ..
583 $ cd ..
584
584
585
585
586 Test stripping a revision with another child
586 Test stripping a revision with another child
587
587
588 $ hg init f
588 $ hg init f
589 $ cd f
589 $ cd f
590
590
591 $ hg debugdrawdag << 'EOF'
591 $ hg debugdrawdag << 'EOF'
592 > C B
592 > C B
593 > |/
593 > |/
594 > A
594 > A
595 > EOF
595 > EOF
596
596
597 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
597 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
598 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
598 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
599 1:112478962961147124edd43549aedd1a335e44bf default: B
599 1:112478962961147124edd43549aedd1a335e44bf default: B
600
600
601 $ hg strip C
601 $ hg strip C
602 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
602 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
603
603
604 $ hg tglog
604 $ hg tglog
605 o 1: 112478962961 'B'
605 o 1: 112478962961 'B'
606 |
606 |
607 o 0: 426bada5c675 'A'
607 o 0: 426bada5c675 'A'
608
608
609
609
610
610
611 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
611 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
612 1:112478962961147124edd43549aedd1a335e44bf default: B
612 1:112478962961147124edd43549aedd1a335e44bf default: B
613
613
614 $ cd ..
614 $ cd ..
615
615
616 Test collapsing changes that add then remove a file
616 Test collapsing changes that add then remove a file
617
617
618 $ hg init collapseaddremove
618 $ hg init collapseaddremove
619 $ cd collapseaddremove
619 $ cd collapseaddremove
620
620
621 $ touch base
621 $ touch base
622 $ hg commit -Am base
622 $ hg commit -Am base
623 adding base
623 adding base
624 $ touch a
624 $ touch a
625 $ hg commit -Am a
625 $ hg commit -Am a
626 adding a
626 adding a
627 $ hg rm a
627 $ hg rm a
628 $ touch b
628 $ touch b
629 $ hg commit -Am b
629 $ hg commit -Am b
630 adding b
630 adding b
631 $ hg book foo
631 $ hg book foo
632 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
632 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
633 rebasing 1:6d8d9f24eec3 "a"
633 rebasing 1:6d8d9f24eec3 "a"
634 rebasing 2:1cc73eca5ecc "b" (foo tip)
634 rebasing 2:1cc73eca5ecc "b" (foo tip)
635 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
635 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
636 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
636 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
637 @ 1: 'collapsed' foo
637 @ 1: 'collapsed' foo
638 |
638 |
639 o 0: 'base'
639 o 0: 'base'
640
640
641 $ hg manifest --rev tip
641 $ hg manifest --rev tip
642 b
642 b
643 base
643 base
644
644
645 $ cd ..
645 $ cd ..
646
646
647 Test that rebase --collapse will remember message after
647 Test that rebase --collapse will remember message after
648 running into merge conflict and invoking rebase --continue.
648 running into merge conflict and invoking rebase --continue.
649
649
650 $ hg init collapse_remember_message
650 $ hg init collapse_remember_message
651 $ cd collapse_remember_message
651 $ cd collapse_remember_message
652 $ hg debugdrawdag << 'EOF'
652 $ hg debugdrawdag << 'EOF'
653 > C B # B/A = B\n
653 > C B # B/A = B\n
654 > |/ # C/A = C\n
654 > |/ # C/A = C\n
655 > A
655 > A
656 > EOF
656 > EOF
657 $ hg rebase --collapse -m "new message" -b B -d C
657 $ hg rebase --collapse -m "new message" -b B -d C
658 rebasing 1:81e5401e4d37 "B" (B)
658 rebasing 1:81e5401e4d37 "B" (B)
659 merging A
659 merging A
660 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
660 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
661 unresolved conflicts (see hg resolve, then hg rebase --continue)
661 unresolved conflicts (see hg resolve, then hg rebase --continue)
662 [1]
662 [1]
663 $ rm A.orig
663 $ rm A.orig
664 $ hg resolve --mark A
664 $ hg resolve --mark A
665 (no more unresolved files)
665 (no more unresolved files)
666 continue: hg rebase --continue
666 continue: hg rebase --continue
667 $ hg rebase --continue
667 $ hg rebase --continue
668 rebasing 1:81e5401e4d37 "B" (B)
668 rebasing 1:81e5401e4d37 "B" (B)
669 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
669 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
670 $ hg log
670 $ hg log
671 changeset: 2:17186933e123
671 changeset: 2:17186933e123
672 tag: tip
672 tag: tip
673 user: test
673 user: test
674 date: Thu Jan 01 00:00:00 1970 +0000
674 date: Thu Jan 01 00:00:00 1970 +0000
675 summary: new message
675 summary: new message
676
676
677 changeset: 1:043039e9df84
677 changeset: 1:043039e9df84
678 tag: C
678 tag: C
679 user: test
679 user: test
680 date: Thu Jan 01 00:00:00 1970 +0000
680 date: Thu Jan 01 00:00:00 1970 +0000
681 summary: C
681 summary: C
682
682
683 changeset: 0:426bada5c675
683 changeset: 0:426bada5c675
684 tag: A
684 tag: A
685 user: test
685 user: test
686 date: Thu Jan 01 00:00:00 1970 +0000
686 date: Thu Jan 01 00:00:00 1970 +0000
687 summary: A
687 summary: A
688
688
689 $ cd ..
689 $ cd ..
690
690
691 Test aborted editor on final message
691 Test aborted editor on final message
692
692
693 $ HGMERGE=:merge3
693 $ HGMERGE=:merge3
694 $ export HGMERGE
694 $ export HGMERGE
695 $ hg init aborted-editor
695 $ hg init aborted-editor
696 $ cd aborted-editor
696 $ cd aborted-editor
697 $ hg debugdrawdag << 'EOF'
697 $ hg debugdrawdag << 'EOF'
698 > C # D/A = D\n
698 > C # D/A = D\n
699 > | # C/A = C\n
699 > | # C/A = C\n
700 > B D # B/A = B\n
700 > B D # B/A = B\n
701 > |/ # A/A = A\n
701 > |/ # A/A = A\n
702 > A
702 > A
703 > EOF
703 > EOF
704 $ hg rebase --collapse -t internal:merge3 -s B -d D
704 $ hg rebase --collapse -t internal:merge3 -s B -d D
705 rebasing 1:f899f3910ce7 "B" (B)
705 rebasing 1:f899f3910ce7 "B" (B)
706 merging A
706 merging A
707 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
707 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
708 unresolved conflicts (see hg resolve, then hg rebase --continue)
708 unresolved conflicts (see hg resolve, then hg rebase --continue)
709 [1]
709 [1]
710 $ hg tglog
710 $ hg tglog
711 o 3: 63668d570d21 'C'
711 o 3: 63668d570d21 'C'
712 |
712 |
713 | @ 2: 82b8abf9c185 'D'
713 | @ 2: 82b8abf9c185 'D'
714 | |
714 | |
715 @ | 1: f899f3910ce7 'B'
715 % | 1: f899f3910ce7 'B'
716 |/
716 |/
717 o 0: 4a2df7238c3b 'A'
717 o 0: 4a2df7238c3b 'A'
718
718
719 $ cat A
719 $ cat A
720 <<<<<<< dest: 82b8abf9c185 D - test: D
720 <<<<<<< dest: 82b8abf9c185 D - test: D
721 D
721 D
722 ||||||| base
722 ||||||| base
723 A
723 A
724 =======
724 =======
725 B
725 B
726 >>>>>>> source: f899f3910ce7 B - test: B
726 >>>>>>> source: f899f3910ce7 B - test: B
727 $ echo BC > A
727 $ echo BC > A
728 $ hg resolve -m
728 $ hg resolve -m
729 (no more unresolved files)
729 (no more unresolved files)
730 continue: hg rebase --continue
730 continue: hg rebase --continue
731 $ hg rebase --continue
731 $ hg rebase --continue
732 rebasing 1:f899f3910ce7 "B" (B)
732 rebasing 1:f899f3910ce7 "B" (B)
733 rebasing 3:63668d570d21 "C" (C tip)
733 rebasing 3:63668d570d21 "C" (C tip)
734 merging A
734 merging A
735 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
735 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
736 unresolved conflicts (see hg resolve, then hg rebase --continue)
736 unresolved conflicts (see hg resolve, then hg rebase --continue)
737 [1]
737 [1]
738 $ hg tglog
738 $ hg tglog
739 @ 3: 63668d570d21 'C'
739 % 3: 63668d570d21 'C'
740 |
740 |
741 | @ 2: 82b8abf9c185 'D'
741 | @ 2: 82b8abf9c185 'D'
742 | |
742 | |
743 o | 1: f899f3910ce7 'B'
743 o | 1: f899f3910ce7 'B'
744 |/
744 |/
745 o 0: 4a2df7238c3b 'A'
745 o 0: 4a2df7238c3b 'A'
746
746
747 $ cat A
747 $ cat A
748 <<<<<<< dest: 82b8abf9c185 D - test: D
748 <<<<<<< dest: 82b8abf9c185 D - test: D
749 BC
749 BC
750 ||||||| base
750 ||||||| base
751 B
751 B
752 =======
752 =======
753 C
753 C
754 >>>>>>> source: 63668d570d21 C tip - test: C
754 >>>>>>> source: 63668d570d21 C tip - test: C
755 $ echo BD > A
755 $ echo BD > A
756 $ hg resolve -m
756 $ hg resolve -m
757 (no more unresolved files)
757 (no more unresolved files)
758 continue: hg rebase --continue
758 continue: hg rebase --continue
759 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
759 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
760 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
760 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
761 rebasing 3:63668d570d21 "C" (C tip)
761 rebasing 3:63668d570d21 "C" (C tip)
762 abort: edit failed: false exited with status 1
762 abort: edit failed: false exited with status 1
763 [255]
763 [255]
764 $ hg tglog
764 $ hg tglog
765 % 3: 63668d570d21 'C'
765 % 3: 63668d570d21 'C'
766 |
766 |
767 | @ 2: 82b8abf9c185 'D'
767 | @ 2: 82b8abf9c185 'D'
768 | |
768 | |
769 o | 1: f899f3910ce7 'B'
769 o | 1: f899f3910ce7 'B'
770 |/
770 |/
771 o 0: 4a2df7238c3b 'A'
771 o 0: 4a2df7238c3b 'A'
772
772
773 $ hg rebase --continue
773 $ hg rebase --continue
774 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
774 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
775 already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
775 already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
776 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
776 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
@@ -1,501 +1,500 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 > drawdag=$TESTDIR/drawdag.py
4 > drawdag=$TESTDIR/drawdag.py
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
10 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 > EOF
11 > EOF
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo c1 >common
15 $ echo c1 >common
16 $ hg add common
16 $ hg add common
17 $ hg ci -m C1
17 $ hg ci -m C1
18
18
19 $ echo c2 >>common
19 $ echo c2 >>common
20 $ hg ci -m C2
20 $ hg ci -m C2
21
21
22 $ echo c3 >>common
22 $ echo c3 >>common
23 $ hg ci -m C3
23 $ hg ci -m C3
24
24
25 $ hg up -q -C 1
25 $ hg up -q -C 1
26
26
27 $ echo l1 >>extra
27 $ echo l1 >>extra
28 $ hg add extra
28 $ hg add extra
29 $ hg ci -m L1
29 $ hg ci -m L1
30 created new head
30 created new head
31
31
32 $ sed -e 's/c2/l2/' common > common.new
32 $ sed -e 's/c2/l2/' common > common.new
33 $ mv common.new common
33 $ mv common.new common
34 $ hg ci -m L2
34 $ hg ci -m L2
35
35
36 $ echo l3 >> extra2
36 $ echo l3 >> extra2
37 $ hg add extra2
37 $ hg add extra2
38 $ hg ci -m L3
38 $ hg ci -m L3
39 $ hg bookmark mybook
39 $ hg bookmark mybook
40
40
41 $ hg phase --force --secret 4
41 $ hg phase --force --secret 4
42
42
43 $ hg tglog
43 $ hg tglog
44 @ 5:secret 'L3' mybook
44 @ 5:secret 'L3' mybook
45 |
45 |
46 o 4:secret 'L2'
46 o 4:secret 'L2'
47 |
47 |
48 o 3:draft 'L1'
48 o 3:draft 'L1'
49 |
49 |
50 | o 2:draft 'C3'
50 | o 2:draft 'C3'
51 |/
51 |/
52 o 1:draft 'C2'
52 o 1:draft 'C2'
53 |
53 |
54 o 0:draft 'C1'
54 o 0:draft 'C1'
55
55
56 Try to call --continue:
56 Try to call --continue:
57
57
58 $ hg rebase --continue
58 $ hg rebase --continue
59 abort: no rebase in progress
59 abort: no rebase in progress
60 [255]
60 [255]
61
61
62 Conflicting rebase:
62 Conflicting rebase:
63
63
64 $ hg rebase -s 3 -d 2
64 $ hg rebase -s 3 -d 2
65 rebasing 3:3163e20567cc "L1"
65 rebasing 3:3163e20567cc "L1"
66 rebasing 4:46f0b057b5c0 "L2"
66 rebasing 4:46f0b057b5c0 "L2"
67 merging common
67 merging common
68 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
68 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 unresolved conflicts (see hg resolve, then hg rebase --continue)
69 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 [1]
70 [1]
71
71
72 $ hg status --config commands.status.verbose=1
72 $ hg status --config commands.status.verbose=1
73 M common
73 M common
74 ? common.orig
74 ? common.orig
75 # The repository is in an unfinished *rebase* state.
75 # The repository is in an unfinished *rebase* state.
76
76
77 # Unresolved merge conflicts:
77 # Unresolved merge conflicts:
78 #
78 #
79 # common
79 # common
80 #
80 #
81 # To mark files as resolved: hg resolve --mark FILE
81 # To mark files as resolved: hg resolve --mark FILE
82
82
83 # To continue: hg rebase --continue
83 # To continue: hg rebase --continue
84 # To abort: hg rebase --abort
84 # To abort: hg rebase --abort
85 # To stop: hg rebase --stop
85 # To stop: hg rebase --stop
86
86
87
87
88 Try to continue without solving the conflict:
88 Try to continue without solving the conflict:
89
89
90 $ hg rebase --continue
90 $ hg rebase --continue
91 abort: unresolved merge conflicts (see 'hg help resolve')
91 abort: unresolved merge conflicts (see 'hg help resolve')
92 [255]
92 [255]
93
93
94 Conclude rebase:
94 Conclude rebase:
95
95
96 $ echo 'resolved merge' >common
96 $ echo 'resolved merge' >common
97 $ hg resolve -m common
97 $ hg resolve -m common
98 (no more unresolved files)
98 (no more unresolved files)
99 continue: hg rebase --continue
99 continue: hg rebase --continue
100 $ hg rebase --continue
100 $ hg rebase --continue
101 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
101 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
102 rebasing 4:46f0b057b5c0 "L2"
102 rebasing 4:46f0b057b5c0 "L2"
103 rebasing 5:8029388f38dc "L3" (mybook)
103 rebasing 5:8029388f38dc "L3" (mybook)
104 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
104 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
105
105
106 $ hg tglog
106 $ hg tglog
107 @ 5:secret 'L3' mybook
107 @ 5:secret 'L3' mybook
108 |
108 |
109 o 4:secret 'L2'
109 o 4:secret 'L2'
110 |
110 |
111 o 3:draft 'L1'
111 o 3:draft 'L1'
112 |
112 |
113 o 2:draft 'C3'
113 o 2:draft 'C3'
114 |
114 |
115 o 1:draft 'C2'
115 o 1:draft 'C2'
116 |
116 |
117 o 0:draft 'C1'
117 o 0:draft 'C1'
118
118
119 Check correctness:
119 Check correctness:
120
120
121 $ hg cat -r 0 common
121 $ hg cat -r 0 common
122 c1
122 c1
123
123
124 $ hg cat -r 1 common
124 $ hg cat -r 1 common
125 c1
125 c1
126 c2
126 c2
127
127
128 $ hg cat -r 2 common
128 $ hg cat -r 2 common
129 c1
129 c1
130 c2
130 c2
131 c3
131 c3
132
132
133 $ hg cat -r 3 common
133 $ hg cat -r 3 common
134 c1
134 c1
135 c2
135 c2
136 c3
136 c3
137
137
138 $ hg cat -r 4 common
138 $ hg cat -r 4 common
139 resolved merge
139 resolved merge
140
140
141 $ hg cat -r 5 common
141 $ hg cat -r 5 common
142 resolved merge
142 resolved merge
143
143
144 Bookmark stays active after --continue
144 Bookmark stays active after --continue
145 $ hg bookmarks
145 $ hg bookmarks
146 * mybook 5:d67b21408fc0
146 * mybook 5:d67b21408fc0
147
147
148 $ cd ..
148 $ cd ..
149
149
150 Check that the right ancestors is used while rebasing a merge (issue4041)
150 Check that the right ancestors is used while rebasing a merge (issue4041)
151
151
152 $ hg init issue4041
152 $ hg init issue4041
153 $ cd issue4041
153 $ cd issue4041
154 $ hg unbundle "$TESTDIR/bundles/issue4041.hg"
154 $ hg unbundle "$TESTDIR/bundles/issue4041.hg"
155 adding changesets
155 adding changesets
156 adding manifests
156 adding manifests
157 adding file changes
157 adding file changes
158 added 11 changesets with 8 changes to 3 files (+1 heads)
158 added 11 changesets with 8 changes to 3 files (+1 heads)
159 new changesets 24797d4f68de:2f2496ddf49d (11 drafts)
159 new changesets 24797d4f68de:2f2496ddf49d (11 drafts)
160 (run 'hg heads' to see heads)
160 (run 'hg heads' to see heads)
161 $ hg up default
161 $ hg up default
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 $ hg log -G
163 $ hg log -G
164 o changeset: 10:2f2496ddf49d
164 o changeset: 10:2f2496ddf49d
165 |\ branch: f1
165 |\ branch: f1
166 | | tag: tip
166 | | tag: tip
167 | | parent: 7:4c9fbe56a16f
167 | | parent: 7:4c9fbe56a16f
168 | | parent: 9:e31216eec445
168 | | parent: 9:e31216eec445
169 | | user: szhang
169 | | user: szhang
170 | | date: Thu Sep 05 12:59:39 2013 -0400
170 | | date: Thu Sep 05 12:59:39 2013 -0400
171 | | summary: merge
171 | | summary: merge
172 | |
172 | |
173 | o changeset: 9:e31216eec445
173 | o changeset: 9:e31216eec445
174 | | branch: f1
174 | | branch: f1
175 | | user: szhang
175 | | user: szhang
176 | | date: Thu Sep 05 12:59:10 2013 -0400
176 | | date: Thu Sep 05 12:59:10 2013 -0400
177 | | summary: more changes to f1
177 | | summary: more changes to f1
178 | |
178 | |
179 | o changeset: 8:8e4e2c1a07ae
179 | o changeset: 8:8e4e2c1a07ae
180 | |\ branch: f1
180 | |\ branch: f1
181 | | | parent: 2:4bc80088dc6b
181 | | | parent: 2:4bc80088dc6b
182 | | | parent: 6:400110238667
182 | | | parent: 6:400110238667
183 | | | user: szhang
183 | | | user: szhang
184 | | | date: Thu Sep 05 12:57:59 2013 -0400
184 | | | date: Thu Sep 05 12:57:59 2013 -0400
185 | | | summary: bad merge
185 | | | summary: bad merge
186 | | |
186 | | |
187 o | | changeset: 7:4c9fbe56a16f
187 o | | changeset: 7:4c9fbe56a16f
188 |/ / branch: f1
188 |/ / branch: f1
189 | | parent: 2:4bc80088dc6b
189 | | parent: 2:4bc80088dc6b
190 | | user: szhang
190 | | user: szhang
191 | | date: Thu Sep 05 12:54:00 2013 -0400
191 | | date: Thu Sep 05 12:54:00 2013 -0400
192 | | summary: changed f1
192 | | summary: changed f1
193 | |
193 | |
194 | o changeset: 6:400110238667
194 | o changeset: 6:400110238667
195 | | branch: f2
195 | | branch: f2
196 | | parent: 4:12e8ec6bb010
196 | | parent: 4:12e8ec6bb010
197 | | user: szhang
197 | | user: szhang
198 | | date: Tue Sep 03 13:58:02 2013 -0400
198 | | date: Tue Sep 03 13:58:02 2013 -0400
199 | | summary: changed f2 on f2
199 | | summary: changed f2 on f2
200 | |
200 | |
201 | | @ changeset: 5:d79e2059b5c0
201 | | @ changeset: 5:d79e2059b5c0
202 | | | parent: 3:8a951942e016
202 | | | parent: 3:8a951942e016
203 | | | user: szhang
203 | | | user: szhang
204 | | | date: Tue Sep 03 13:57:39 2013 -0400
204 | | | date: Tue Sep 03 13:57:39 2013 -0400
205 | | | summary: changed f2 on default
205 | | | summary: changed f2 on default
206 | | |
206 | | |
207 | o | changeset: 4:12e8ec6bb010
207 | o | changeset: 4:12e8ec6bb010
208 | |/ branch: f2
208 | |/ branch: f2
209 | | user: szhang
209 | | user: szhang
210 | | date: Tue Sep 03 13:57:18 2013 -0400
210 | | date: Tue Sep 03 13:57:18 2013 -0400
211 | | summary: created f2 branch
211 | | summary: created f2 branch
212 | |
212 | |
213 | o changeset: 3:8a951942e016
213 | o changeset: 3:8a951942e016
214 | | parent: 0:24797d4f68de
214 | | parent: 0:24797d4f68de
215 | | user: szhang
215 | | user: szhang
216 | | date: Tue Sep 03 13:57:11 2013 -0400
216 | | date: Tue Sep 03 13:57:11 2013 -0400
217 | | summary: added f2.txt
217 | | summary: added f2.txt
218 | |
218 | |
219 o | changeset: 2:4bc80088dc6b
219 o | changeset: 2:4bc80088dc6b
220 | | branch: f1
220 | | branch: f1
221 | | user: szhang
221 | | user: szhang
222 | | date: Tue Sep 03 13:56:20 2013 -0400
222 | | date: Tue Sep 03 13:56:20 2013 -0400
223 | | summary: added f1.txt
223 | | summary: added f1.txt
224 | |
224 | |
225 o | changeset: 1:ef53c9e6b608
225 o | changeset: 1:ef53c9e6b608
226 |/ branch: f1
226 |/ branch: f1
227 | user: szhang
227 | user: szhang
228 | date: Tue Sep 03 13:55:26 2013 -0400
228 | date: Tue Sep 03 13:55:26 2013 -0400
229 | summary: created f1 branch
229 | summary: created f1 branch
230 |
230 |
231 o changeset: 0:24797d4f68de
231 o changeset: 0:24797d4f68de
232 user: szhang
232 user: szhang
233 date: Tue Sep 03 13:55:08 2013 -0400
233 date: Tue Sep 03 13:55:08 2013 -0400
234 summary: added default.txt
234 summary: added default.txt
235
235
236 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
236 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
237 rebase onto 4bc80088dc6b starting from e31216eec445
237 rebase onto 4bc80088dc6b starting from e31216eec445
238 rebasing on disk
238 rebasing on disk
239 rebase status stored
239 rebase status stored
240 rebasing 9:e31216eec445 "more changes to f1"
240 rebasing 9:e31216eec445 "more changes to f1"
241 future parents are 2 and -1
241 future parents are 2 and -1
242 update to 2:4bc80088dc6b
242 update to 2:4bc80088dc6b
243 resolving manifests
243 resolving manifests
244 branchmerge: False, force: True, partial: False
244 branchmerge: False, force: True, partial: False
245 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
245 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
246 f2.txt: other deleted -> r
246 f2.txt: other deleted -> r
247 removing f2.txt
247 removing f2.txt
248 f1.txt: remote created -> g
248 f1.txt: remote created -> g
249 getting f1.txt
249 getting f1.txt
250 merge against 9:e31216eec445
250 merge against 9:e31216eec445
251 detach base 8:8e4e2c1a07ae
251 detach base 8:8e4e2c1a07ae
252 resolving manifests
252 resolving manifests
253 branchmerge: True, force: True, partial: False
253 branchmerge: True, force: True, partial: False
254 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
254 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
255 f1.txt: remote is newer -> g
255 f1.txt: remote is newer -> g
256 getting f1.txt
256 getting f1.txt
257 committing files:
257 committing files:
258 f1.txt
258 f1.txt
259 committing manifest
259 committing manifest
260 committing changelog
260 committing changelog
261 updating the branch cache
261 updating the branch cache
262 rebased as 19c888675e13
262 rebased as 19c888675e13
263 rebase status stored
263 rebase status stored
264 rebasing 10:2f2496ddf49d "merge" (tip)
264 rebasing 10:2f2496ddf49d "merge" (tip)
265 future parents are 11 and 7
265 future parents are 11 and 7
266 already in destination
266 already in destination
267 merge against 10:2f2496ddf49d
267 merge against 10:2f2496ddf49d
268 detach base 9:e31216eec445
268 detach base 9:e31216eec445
269 resolving manifests
269 resolving manifests
270 branchmerge: True, force: True, partial: False
270 branchmerge: True, force: True, partial: False
271 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
271 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
272 f1.txt: remote is newer -> g
272 f1.txt: remote is newer -> g
273 getting f1.txt
273 getting f1.txt
274 committing files:
274 committing files:
275 f1.txt
275 f1.txt
276 committing manifest
276 committing manifest
277 committing changelog
277 committing changelog
278 updating the branch cache
278 updating the branch cache
279 rebased as 2a7f09cac94c
279 rebased as 2a7f09cac94c
280 rebase status stored
280 rebase status stored
281 rebase merging completed
281 rebase merging completed
282 update back to initial working directory parent
282 update back to initial working directory parent
283 resolving manifests
283 resolving manifests
284 branchmerge: False, force: False, partial: False
284 branchmerge: False, force: False, partial: False
285 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
285 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
286 f1.txt: other deleted -> r
286 f1.txt: other deleted -> r
287 removing f1.txt
287 removing f1.txt
288 f2.txt: remote created -> g
288 f2.txt: remote created -> g
289 getting f2.txt
289 getting f2.txt
290 2 changesets found
290 2 changesets found
291 list of changesets:
291 list of changesets:
292 e31216eec445e44352c5f01588856059466a24c9
292 e31216eec445e44352c5f01588856059466a24c9
293 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
293 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
294 bundle2-output-bundle: "HG20", (1 params) 3 parts total
294 bundle2-output-bundle: "HG20", (1 params) 3 parts total
295 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
295 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
296 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
296 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
297 bundle2-output-part: "phase-heads" 24 bytes payload
297 bundle2-output-part: "phase-heads" 24 bytes payload
298 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-rebase.hg
298 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-rebase.hg
299 3 changesets found
299 3 changesets found
300 list of changesets:
300 list of changesets:
301 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
301 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
302 19c888675e133ab5dff84516926a65672eaf04d9
302 19c888675e133ab5dff84516926a65672eaf04d9
303 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
303 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
304 bundle2-output-bundle: "HG20", 3 parts total
304 bundle2-output-bundle: "HG20", 3 parts total
305 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
305 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
306 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
306 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
307 bundle2-output-part: "phase-heads" 24 bytes payload
307 bundle2-output-part: "phase-heads" 24 bytes payload
308 adding branch
308 adding branch
309 bundle2-input-bundle: with-transaction
309 bundle2-input-bundle: with-transaction
310 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
310 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
311 adding changesets
311 adding changesets
312 add changeset 4c9fbe56a16f
312 add changeset 4c9fbe56a16f
313 add changeset 19c888675e13
313 add changeset 19c888675e13
314 add changeset 2a7f09cac94c
314 add changeset 2a7f09cac94c
315 adding manifests
315 adding manifests
316 adding file changes
316 adding file changes
317 adding f1.txt revisions
317 adding f1.txt revisions
318 bundle2-input-part: total payload size 1686
318 bundle2-input-part: total payload size 1686
319 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
319 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
320 bundle2-input-part: total payload size 74
320 bundle2-input-part: total payload size 74
321 truncating cache/rbc-revs-v1 to 56
321 truncating cache/rbc-revs-v1 to 56
322 bundle2-input-part: "phase-heads" supported
322 bundle2-input-part: "phase-heads" supported
323 bundle2-input-part: total payload size 24
323 bundle2-input-part: total payload size 24
324 bundle2-input-bundle: 3 parts total
324 bundle2-input-bundle: 3 parts total
325 added 2 changesets with 2 changes to 1 files
325 added 2 changesets with 2 changes to 1 files
326 updating the branch cache
326 updating the branch cache
327 invalid branch cache (served): tip differs
327 invalid branch cache (served): tip differs
328 invalid branch cache (served.hidden): tip differs
328 invalid branch cache (served.hidden): tip differs
329 rebase completed
329 rebase completed
330
330
331 Test minimization of merge conflicts
331 Test minimization of merge conflicts
332 $ hg up -q null
332 $ hg up -q null
333 $ echo a > a
333 $ echo a > a
334 $ hg add a
334 $ hg add a
335 $ hg commit -q -m 'a'
335 $ hg commit -q -m 'a'
336 $ echo b >> a
336 $ echo b >> a
337 $ hg commit -q -m 'ab'
337 $ hg commit -q -m 'ab'
338 $ hg bookmark ab
338 $ hg bookmark ab
339 $ hg up -q '.^'
339 $ hg up -q '.^'
340 $ echo b >> a
340 $ echo b >> a
341 $ echo c >> a
341 $ echo c >> a
342 $ hg commit -q -m 'abc'
342 $ hg commit -q -m 'abc'
343 $ hg rebase -s 7bc217434fc1 -d ab --keep
343 $ hg rebase -s 7bc217434fc1 -d ab --keep
344 rebasing 13:7bc217434fc1 "abc" (tip)
344 rebasing 13:7bc217434fc1 "abc" (tip)
345 merging a
345 merging a
346 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
346 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
347 unresolved conflicts (see hg resolve, then hg rebase --continue)
347 unresolved conflicts (see hg resolve, then hg rebase --continue)
348 [1]
348 [1]
349 $ hg diff
349 $ hg diff
350 diff -r 328e4ab1f7cc a
350 diff -r 328e4ab1f7cc a
351 --- a/a Thu Jan 01 00:00:00 1970 +0000
351 --- a/a Thu Jan 01 00:00:00 1970 +0000
352 +++ b/a * (glob)
352 +++ b/a * (glob)
353 @@ -1,2 +1,6 @@
353 @@ -1,2 +1,6 @@
354 a
354 a
355 b
355 b
356 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
356 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
357 +=======
357 +=======
358 +c
358 +c
359 +>>>>>>> source: 7bc217434fc1 - test: abc
359 +>>>>>>> source: 7bc217434fc1 - test: abc
360 $ hg rebase --abort
360 $ hg rebase --abort
361 rebase aborted
361 rebase aborted
362 $ hg up -q -C 7bc217434fc1
362 $ hg up -q -C 7bc217434fc1
363 $ hg rebase -s . -d ab --keep -t internal:merge3
363 $ hg rebase -s . -d ab --keep -t internal:merge3
364 rebasing 13:7bc217434fc1 "abc" (tip)
364 rebasing 13:7bc217434fc1 "abc" (tip)
365 merging a
365 merging a
366 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
366 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
367 unresolved conflicts (see hg resolve, then hg rebase --continue)
367 unresolved conflicts (see hg resolve, then hg rebase --continue)
368 [1]
368 [1]
369 $ hg diff
369 $ hg diff
370 diff -r 328e4ab1f7cc a
370 diff -r 328e4ab1f7cc a
371 --- a/a Thu Jan 01 00:00:00 1970 +0000
371 --- a/a Thu Jan 01 00:00:00 1970 +0000
372 +++ b/a * (glob)
372 +++ b/a * (glob)
373 @@ -1,2 +1,8 @@
373 @@ -1,2 +1,8 @@
374 a
374 a
375 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
375 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
376 b
376 b
377 +||||||| base
377 +||||||| base
378 +=======
378 +=======
379 +b
379 +b
380 +c
380 +c
381 +>>>>>>> source: 7bc217434fc1 - test: abc
381 +>>>>>>> source: 7bc217434fc1 - test: abc
382
382
383 Test rebase with obsstore turned on and off (issue5606)
383 Test rebase with obsstore turned on and off (issue5606)
384
384
385 $ cd $TESTTMP
385 $ cd $TESTTMP
386 $ hg init b
386 $ hg init b
387 $ cd b
387 $ cd b
388 $ hg debugdrawdag <<'EOS'
388 $ hg debugdrawdag <<'EOS'
389 > D
389 > D
390 > |
390 > |
391 > C
391 > C
392 > |
392 > |
393 > B E
393 > B E
394 > |/
394 > |/
395 > A
395 > A
396 > EOS
396 > EOS
397
397
398 $ hg update E -q
398 $ hg update E -q
399 $ echo 3 > B
399 $ echo 3 > B
400 $ hg commit --amend -m E -A B -q
400 $ hg commit --amend -m E -A B -q
401 $ hg rebase -r B+D -d . --config experimental.evolution=true
401 $ hg rebase -r B+D -d . --config experimental.evolution=true
402 rebasing 1:112478962961 "B" (B)
402 rebasing 1:112478962961 "B" (B)
403 merging B
403 merging B
404 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
404 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
405 unresolved conflicts (see hg resolve, then hg rebase --continue)
405 unresolved conflicts (see hg resolve, then hg rebase --continue)
406 [1]
406 [1]
407
407
408 $ echo 4 > B
408 $ echo 4 > B
409 $ hg resolve -m
409 $ hg resolve -m
410 (no more unresolved files)
410 (no more unresolved files)
411 continue: hg rebase --continue
411 continue: hg rebase --continue
412 $ hg rebase --continue --config experimental.evolution=none
412 $ hg rebase --continue --config experimental.evolution=none
413 rebasing 1:112478962961 "B" (B)
413 rebasing 1:112478962961 "B" (B)
414 rebasing 3:f585351a92f8 "D" (D)
414 rebasing 3:f585351a92f8 "D" (D)
415 warning: orphaned descendants detected, not stripping 112478962961
415 warning: orphaned descendants detected, not stripping 112478962961
416 saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
416 saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
417
417
418 $ rm .hg/localtags
418 $ rm .hg/localtags
419 $ hg tglog
419 $ hg tglog
420 o 5:draft 'D'
420 o 5:draft 'D'
421 |
421 |
422 o 4:draft 'B'
422 o 4:draft 'B'
423 |
423 |
424 @ 3:draft 'E'
424 @ 3:draft 'E'
425 |
425 |
426 | o 2:draft 'C'
426 | o 2:draft 'C'
427 | |
427 | |
428 | o 1:draft 'B'
428 | o 1:draft 'B'
429 |/
429 |/
430 o 0:draft 'A'
430 o 0:draft 'A'
431
431
432
432
433 Test where the conflict happens when rebasing a merge commit
433 Test where the conflict happens when rebasing a merge commit
434
434
435 $ cd $TESTTMP
435 $ cd $TESTTMP
436 $ hg init conflict-in-merge
436 $ hg init conflict-in-merge
437 $ cd conflict-in-merge
437 $ cd conflict-in-merge
438 $ hg debugdrawdag <<'EOS'
438 $ hg debugdrawdag <<'EOS'
439 > F # F/conflict = foo\n
439 > F # F/conflict = foo\n
440 > |\
440 > |\
441 > D E
441 > D E
442 > |/
442 > |/
443 > C B # B/conflict = bar\n
443 > C B # B/conflict = bar\n
444 > |/
444 > |/
445 > A
445 > A
446 > EOS
446 > EOS
447
447
448 $ hg co F
448 $ hg co F
449 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 $ hg rebase -d B
450 $ hg rebase -d B
451 rebasing 2:dc0947a82db8 "C" (C)
451 rebasing 2:dc0947a82db8 "C" (C)
452 rebasing 3:e7b3f00ed42e "D" (D)
452 rebasing 3:e7b3f00ed42e "D" (D)
453 rebasing 4:03ca77807e91 "E" (E)
453 rebasing 4:03ca77807e91 "E" (E)
454 rebasing 5:9a6b91dc2044 "F" (F tip)
454 rebasing 5:9a6b91dc2044 "F" (F tip)
455 merging conflict
455 merging conflict
456 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
456 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
457 unresolved conflicts (see hg resolve, then hg rebase --continue)
457 unresolved conflicts (see hg resolve, then hg rebase --continue)
458 [1]
458 [1]
459 The current parents are not 7 and 8 even though that's what we're merging
460 $ hg tglog
459 $ hg tglog
461 @ 8:draft 'E'
460 @ 8:draft 'E'
462 |
461 |
463 | o 7:draft 'D'
462 | @ 7:draft 'D'
464 |/
463 |/
465 o 6:draft 'C'
464 o 6:draft 'C'
466 |
465 |
467 | @ 5:draft 'F'
466 | % 5:draft 'F'
468 | |\
467 | |\
469 | | o 4:draft 'E'
468 | | o 4:draft 'E'
470 | | |
469 | | |
471 | o | 3:draft 'D'
470 | o | 3:draft 'D'
472 | |/
471 | |/
473 | o 2:draft 'C'
472 | o 2:draft 'C'
474 | |
473 | |
475 o | 1:draft 'B'
474 o | 1:draft 'B'
476 |/
475 |/
477 o 0:draft 'A'
476 o 0:draft 'A'
478
477
479 $ echo baz > conflict
478 $ echo baz > conflict
480 $ hg resolve -m
479 $ hg resolve -m
481 (no more unresolved files)
480 (no more unresolved files)
482 continue: hg rebase --continue
481 continue: hg rebase --continue
483 $ hg rebase -c
482 $ hg rebase -c
484 already rebased 2:dc0947a82db8 "C" (C) as 0199610c343e
483 already rebased 2:dc0947a82db8 "C" (C) as 0199610c343e
485 already rebased 3:e7b3f00ed42e "D" (D) as f0dd538aaa63
484 already rebased 3:e7b3f00ed42e "D" (D) as f0dd538aaa63
486 already rebased 4:03ca77807e91 "E" (E) as cbf25af8347d
485 already rebased 4:03ca77807e91 "E" (E) as cbf25af8347d
487 rebasing 5:9a6b91dc2044 "F" (F)
486 rebasing 5:9a6b91dc2044 "F" (F)
488 saved backup bundle to $TESTTMP/conflict-in-merge/.hg/strip-backup/dc0947a82db8-ca7e7d5b-rebase.hg
487 saved backup bundle to $TESTTMP/conflict-in-merge/.hg/strip-backup/dc0947a82db8-ca7e7d5b-rebase.hg
489 $ hg tglog
488 $ hg tglog
490 @ 5:draft 'F'
489 @ 5:draft 'F'
491 |\
490 |\
492 | o 4:draft 'E'
491 | o 4:draft 'E'
493 | |
492 | |
494 o | 3:draft 'D'
493 o | 3:draft 'D'
495 |/
494 |/
496 o 2:draft 'C'
495 o 2:draft 'C'
497 |
496 |
498 o 1:draft 'B'
497 o 1:draft 'B'
499 |
498 |
500 o 0:draft 'A'
499 o 0:draft 'A'
501
500
@@ -1,480 +1,480 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 >
4 >
5 > [phases]
5 > [phases]
6 > publish=False
6 > publish=False
7 >
7 >
8 > [alias]
8 > [alias]
9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
10 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
10 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
11 > EOF
11 > EOF
12
12
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16
16
17 $ echo A > A
17 $ echo A > A
18 $ hg ci -Am A
18 $ hg ci -Am A
19 adding A
19 adding A
20
20
21 $ echo B > B
21 $ echo B > B
22 $ hg ci -Am B
22 $ hg ci -Am B
23 adding B
23 adding B
24
24
25 $ echo C >> A
25 $ echo C >> A
26 $ hg ci -m C
26 $ hg ci -m C
27
27
28 $ hg up -q -C 0
28 $ hg up -q -C 0
29
29
30 $ echo D >> A
30 $ echo D >> A
31 $ hg ci -m D
31 $ hg ci -m D
32 created new head
32 created new head
33
33
34 $ echo E > E
34 $ echo E > E
35 $ hg ci -Am E
35 $ hg ci -Am E
36 adding E
36 adding E
37
37
38 $ cd ..
38 $ cd ..
39
39
40
40
41 Changes during an interruption - continue:
41 Changes during an interruption - continue:
42
42
43 $ hg clone -q -u . a a1
43 $ hg clone -q -u . a a1
44 $ cd a1
44 $ cd a1
45
45
46 $ hg tglog
46 $ hg tglog
47 @ 4: ae36e8e3dfd7 'E'
47 @ 4: ae36e8e3dfd7 'E'
48 |
48 |
49 o 3: 46b37eabc604 'D'
49 o 3: 46b37eabc604 'D'
50 |
50 |
51 | o 2: 965c486023db 'C'
51 | o 2: 965c486023db 'C'
52 | |
52 | |
53 | o 1: 27547f69f254 'B'
53 | o 1: 27547f69f254 'B'
54 |/
54 |/
55 o 0: 4a2df7238c3b 'A'
55 o 0: 4a2df7238c3b 'A'
56
56
57 Rebasing B onto E:
57 Rebasing B onto E:
58
58
59 $ hg rebase -s 1 -d 4
59 $ hg rebase -s 1 -d 4
60 rebasing 1:27547f69f254 "B"
60 rebasing 1:27547f69f254 "B"
61 rebasing 2:965c486023db "C"
61 rebasing 2:965c486023db "C"
62 merging A
62 merging A
63 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
63 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
64 unresolved conflicts (see hg resolve, then hg rebase --continue)
64 unresolved conflicts (see hg resolve, then hg rebase --continue)
65 [1]
65 [1]
66
66
67 Force a commit on C during the interruption:
67 Force a commit on C during the interruption:
68
68
69 $ hg up -q -C 2 --config 'extensions.rebase=!'
69 $ hg up -q -C 2 --config 'extensions.rebase=!'
70
70
71 $ echo 'Extra' > Extra
71 $ echo 'Extra' > Extra
72 $ hg add Extra
72 $ hg add Extra
73 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
73 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
74
74
75 Force this commit onto secret phase
75 Force this commit onto secret phase
76
76
77 $ hg phase --force --secret 6
77 $ hg phase --force --secret 6
78
78
79 $ hg tglogp
79 $ hg tglogp
80 @ 6: deb5d2f93d8b secret 'Extra'
80 @ 6: deb5d2f93d8b secret 'Extra'
81 |
81 |
82 | o 5: 45396c49d53b draft 'B'
82 | o 5: 45396c49d53b draft 'B'
83 | |
83 | |
84 | o 4: ae36e8e3dfd7 draft 'E'
84 | o 4: ae36e8e3dfd7 draft 'E'
85 | |
85 | |
86 | o 3: 46b37eabc604 draft 'D'
86 | o 3: 46b37eabc604 draft 'D'
87 | |
87 | |
88 o | 2: 965c486023db draft 'C'
88 o | 2: 965c486023db draft 'C'
89 | |
89 | |
90 o | 1: 27547f69f254 draft 'B'
90 o | 1: 27547f69f254 draft 'B'
91 |/
91 |/
92 o 0: 4a2df7238c3b draft 'A'
92 o 0: 4a2df7238c3b draft 'A'
93
93
94 Resume the rebasing:
94 Resume the rebasing:
95
95
96 $ hg rebase --continue
96 $ hg rebase --continue
97 already rebased 1:27547f69f254 "B" as 45396c49d53b
97 already rebased 1:27547f69f254 "B" as 45396c49d53b
98 rebasing 2:965c486023db "C"
98 rebasing 2:965c486023db "C"
99 merging A
99 merging A
100 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
100 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
101 unresolved conflicts (see hg resolve, then hg rebase --continue)
101 unresolved conflicts (see hg resolve, then hg rebase --continue)
102 [1]
102 [1]
103
103
104 Solve the conflict and go on:
104 Solve the conflict and go on:
105
105
106 $ echo 'conflict solved' > A
106 $ echo 'conflict solved' > A
107 $ rm A.orig
107 $ rm A.orig
108 $ hg resolve -m A
108 $ hg resolve -m A
109 (no more unresolved files)
109 (no more unresolved files)
110 continue: hg rebase --continue
110 continue: hg rebase --continue
111
111
112 $ hg rebase --continue
112 $ hg rebase --continue
113 already rebased 1:27547f69f254 "B" as 45396c49d53b
113 already rebased 1:27547f69f254 "B" as 45396c49d53b
114 rebasing 2:965c486023db "C"
114 rebasing 2:965c486023db "C"
115 warning: orphaned descendants detected, not stripping 27547f69f254, 965c486023db
115 warning: orphaned descendants detected, not stripping 27547f69f254, 965c486023db
116
116
117 $ hg tglogp
117 $ hg tglogp
118 o 7: d2d25e26288e draft 'C'
118 o 7: d2d25e26288e draft 'C'
119 |
119 |
120 | o 6: deb5d2f93d8b secret 'Extra'
120 | o 6: deb5d2f93d8b secret 'Extra'
121 | |
121 | |
122 o | 5: 45396c49d53b draft 'B'
122 o | 5: 45396c49d53b draft 'B'
123 | |
123 | |
124 @ | 4: ae36e8e3dfd7 draft 'E'
124 @ | 4: ae36e8e3dfd7 draft 'E'
125 | |
125 | |
126 o | 3: 46b37eabc604 draft 'D'
126 o | 3: 46b37eabc604 draft 'D'
127 | |
127 | |
128 | o 2: 965c486023db draft 'C'
128 | o 2: 965c486023db draft 'C'
129 | |
129 | |
130 | o 1: 27547f69f254 draft 'B'
130 | o 1: 27547f69f254 draft 'B'
131 |/
131 |/
132 o 0: 4a2df7238c3b draft 'A'
132 o 0: 4a2df7238c3b draft 'A'
133
133
134 $ cd ..
134 $ cd ..
135
135
136
136
137 Changes during an interruption - abort:
137 Changes during an interruption - abort:
138
138
139 $ hg clone -q -u . a a2
139 $ hg clone -q -u . a a2
140 $ cd a2
140 $ cd a2
141
141
142 $ hg tglog
142 $ hg tglog
143 @ 4: ae36e8e3dfd7 'E'
143 @ 4: ae36e8e3dfd7 'E'
144 |
144 |
145 o 3: 46b37eabc604 'D'
145 o 3: 46b37eabc604 'D'
146 |
146 |
147 | o 2: 965c486023db 'C'
147 | o 2: 965c486023db 'C'
148 | |
148 | |
149 | o 1: 27547f69f254 'B'
149 | o 1: 27547f69f254 'B'
150 |/
150 |/
151 o 0: 4a2df7238c3b 'A'
151 o 0: 4a2df7238c3b 'A'
152
152
153 Rebasing B onto E:
153 Rebasing B onto E:
154
154
155 $ hg rebase -s 1 -d 4
155 $ hg rebase -s 1 -d 4
156 rebasing 1:27547f69f254 "B"
156 rebasing 1:27547f69f254 "B"
157 rebasing 2:965c486023db "C"
157 rebasing 2:965c486023db "C"
158 merging A
158 merging A
159 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
159 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
160 unresolved conflicts (see hg resolve, then hg rebase --continue)
160 unresolved conflicts (see hg resolve, then hg rebase --continue)
161 [1]
161 [1]
162
162
163 Force a commit on B' during the interruption:
163 Force a commit on B' during the interruption:
164
164
165 $ hg up -q -C 5 --config 'extensions.rebase=!'
165 $ hg up -q -C 5 --config 'extensions.rebase=!'
166
166
167 $ echo 'Extra' > Extra
167 $ echo 'Extra' > Extra
168 $ hg add Extra
168 $ hg add Extra
169 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
169 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
170
170
171 $ hg tglog
171 $ hg tglog
172 @ 6: 402ee3642b59 'Extra'
172 @ 6: 402ee3642b59 'Extra'
173 |
173 |
174 o 5: 45396c49d53b 'B'
174 o 5: 45396c49d53b 'B'
175 |
175 |
176 o 4: ae36e8e3dfd7 'E'
176 o 4: ae36e8e3dfd7 'E'
177 |
177 |
178 o 3: 46b37eabc604 'D'
178 o 3: 46b37eabc604 'D'
179 |
179 |
180 | o 2: 965c486023db 'C'
180 | o 2: 965c486023db 'C'
181 | |
181 | |
182 | o 1: 27547f69f254 'B'
182 | o 1: 27547f69f254 'B'
183 |/
183 |/
184 o 0: 4a2df7238c3b 'A'
184 o 0: 4a2df7238c3b 'A'
185
185
186 Abort the rebasing:
186 Abort the rebasing:
187
187
188 $ hg rebase --abort
188 $ hg rebase --abort
189 warning: new changesets detected on destination branch, can't strip
189 warning: new changesets detected on destination branch, can't strip
190 rebase aborted
190 rebase aborted
191
191
192 $ hg tglog
192 $ hg tglog
193 @ 6: 402ee3642b59 'Extra'
193 @ 6: 402ee3642b59 'Extra'
194 |
194 |
195 o 5: 45396c49d53b 'B'
195 o 5: 45396c49d53b 'B'
196 |
196 |
197 o 4: ae36e8e3dfd7 'E'
197 o 4: ae36e8e3dfd7 'E'
198 |
198 |
199 o 3: 46b37eabc604 'D'
199 o 3: 46b37eabc604 'D'
200 |
200 |
201 | o 2: 965c486023db 'C'
201 | o 2: 965c486023db 'C'
202 | |
202 | |
203 | o 1: 27547f69f254 'B'
203 | o 1: 27547f69f254 'B'
204 |/
204 |/
205 o 0: 4a2df7238c3b 'A'
205 o 0: 4a2df7238c3b 'A'
206
206
207 $ cd ..
207 $ cd ..
208
208
209 Changes during an interruption - abort (again):
209 Changes during an interruption - abort (again):
210
210
211 $ hg clone -q -u . a a3
211 $ hg clone -q -u . a a3
212 $ cd a3
212 $ cd a3
213
213
214 $ hg tglogp
214 $ hg tglogp
215 @ 4: ae36e8e3dfd7 draft 'E'
215 @ 4: ae36e8e3dfd7 draft 'E'
216 |
216 |
217 o 3: 46b37eabc604 draft 'D'
217 o 3: 46b37eabc604 draft 'D'
218 |
218 |
219 | o 2: 965c486023db draft 'C'
219 | o 2: 965c486023db draft 'C'
220 | |
220 | |
221 | o 1: 27547f69f254 draft 'B'
221 | o 1: 27547f69f254 draft 'B'
222 |/
222 |/
223 o 0: 4a2df7238c3b draft 'A'
223 o 0: 4a2df7238c3b draft 'A'
224
224
225 Rebasing B onto E:
225 Rebasing B onto E:
226
226
227 $ hg rebase -s 1 -d 4
227 $ hg rebase -s 1 -d 4
228 rebasing 1:27547f69f254 "B"
228 rebasing 1:27547f69f254 "B"
229 rebasing 2:965c486023db "C"
229 rebasing 2:965c486023db "C"
230 merging A
230 merging A
231 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
231 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
232 unresolved conflicts (see hg resolve, then hg rebase --continue)
232 unresolved conflicts (see hg resolve, then hg rebase --continue)
233 [1]
233 [1]
234
234
235 Change phase on B and B'
235 Change phase on B and B'
236
236
237 $ hg up -q -C 5 --config 'extensions.rebase=!'
237 $ hg up -q -C 5 --config 'extensions.rebase=!'
238 $ hg phase --public 1
238 $ hg phase --public 1
239 $ hg phase --public 5
239 $ hg phase --public 5
240 $ hg phase --secret -f 2
240 $ hg phase --secret -f 2
241
241
242 $ hg tglogp
242 $ hg tglogp
243 @ 5: 45396c49d53b public 'B'
243 @ 5: 45396c49d53b public 'B'
244 |
244 |
245 o 4: ae36e8e3dfd7 public 'E'
245 o 4: ae36e8e3dfd7 public 'E'
246 |
246 |
247 o 3: 46b37eabc604 public 'D'
247 o 3: 46b37eabc604 public 'D'
248 |
248 |
249 | o 2: 965c486023db secret 'C'
249 | o 2: 965c486023db secret 'C'
250 | |
250 | |
251 | o 1: 27547f69f254 public 'B'
251 | o 1: 27547f69f254 public 'B'
252 |/
252 |/
253 o 0: 4a2df7238c3b public 'A'
253 o 0: 4a2df7238c3b public 'A'
254
254
255 Abort the rebasing:
255 Abort the rebasing:
256
256
257 $ hg rebase --abort
257 $ hg rebase --abort
258 warning: can't clean up public changesets 45396c49d53b
258 warning: can't clean up public changesets 45396c49d53b
259 rebase aborted
259 rebase aborted
260
260
261 $ hg tglogp
261 $ hg tglogp
262 @ 5: 45396c49d53b public 'B'
262 @ 5: 45396c49d53b public 'B'
263 |
263 |
264 o 4: ae36e8e3dfd7 public 'E'
264 o 4: ae36e8e3dfd7 public 'E'
265 |
265 |
266 o 3: 46b37eabc604 public 'D'
266 o 3: 46b37eabc604 public 'D'
267 |
267 |
268 | o 2: 965c486023db secret 'C'
268 | o 2: 965c486023db secret 'C'
269 | |
269 | |
270 | o 1: 27547f69f254 public 'B'
270 | o 1: 27547f69f254 public 'B'
271 |/
271 |/
272 o 0: 4a2df7238c3b public 'A'
272 o 0: 4a2df7238c3b public 'A'
273
273
274 Test rebase interrupted by hooks
274 Test rebase interrupted by hooks
275
275
276 $ hg up 2
276 $ hg up 2
277 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
277 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
278 $ echo F > F
278 $ echo F > F
279 $ hg add F
279 $ hg add F
280 $ hg ci -m F
280 $ hg ci -m F
281
281
282 $ cd ..
282 $ cd ..
283
283
284 (precommit version)
284 (precommit version)
285
285
286 $ cp -R a3 hook-precommit
286 $ cp -R a3 hook-precommit
287 $ cd hook-precommit
287 $ cd hook-precommit
288 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.precommit=hg status | grep "M A"'
288 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.precommit=hg status | grep "M A"'
289 rebasing 2:965c486023db "C"
289 rebasing 2:965c486023db "C"
290 M A
290 M A
291 rebasing 6:a0b2430ebfb8 "F" (tip)
291 rebasing 6:a0b2430ebfb8 "F" (tip)
292 abort: precommit hook exited with status 1
292 abort: precommit hook exited with status 1
293 [255]
293 [255]
294 $ hg tglogp
294 $ hg tglogp
295 @ 7: 401ccec5e39f secret 'C'
295 @ 7: 401ccec5e39f secret 'C'
296 |
296 |
297 | @ 6: a0b2430ebfb8 secret 'F'
297 | o 6: a0b2430ebfb8 secret 'F'
298 | |
298 | |
299 o | 5: 45396c49d53b public 'B'
299 o | 5: 45396c49d53b public 'B'
300 | |
300 | |
301 o | 4: ae36e8e3dfd7 public 'E'
301 o | 4: ae36e8e3dfd7 public 'E'
302 | |
302 | |
303 o | 3: 46b37eabc604 public 'D'
303 o | 3: 46b37eabc604 public 'D'
304 | |
304 | |
305 | o 2: 965c486023db secret 'C'
305 | o 2: 965c486023db secret 'C'
306 | |
306 | |
307 | o 1: 27547f69f254 public 'B'
307 | o 1: 27547f69f254 public 'B'
308 |/
308 |/
309 o 0: 4a2df7238c3b public 'A'
309 o 0: 4a2df7238c3b public 'A'
310
310
311 $ hg rebase --continue
311 $ hg rebase --continue
312 already rebased 2:965c486023db "C" as 401ccec5e39f
312 already rebased 2:965c486023db "C" as 401ccec5e39f
313 rebasing 6:a0b2430ebfb8 "F"
313 rebasing 6:a0b2430ebfb8 "F"
314 saved backup bundle to $TESTTMP/hook-precommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
314 saved backup bundle to $TESTTMP/hook-precommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
315 $ hg tglogp
315 $ hg tglogp
316 @ 6: 6e92a149ac6b secret 'F'
316 @ 6: 6e92a149ac6b secret 'F'
317 |
317 |
318 o 5: 401ccec5e39f secret 'C'
318 o 5: 401ccec5e39f secret 'C'
319 |
319 |
320 o 4: 45396c49d53b public 'B'
320 o 4: 45396c49d53b public 'B'
321 |
321 |
322 o 3: ae36e8e3dfd7 public 'E'
322 o 3: ae36e8e3dfd7 public 'E'
323 |
323 |
324 o 2: 46b37eabc604 public 'D'
324 o 2: 46b37eabc604 public 'D'
325 |
325 |
326 | o 1: 27547f69f254 public 'B'
326 | o 1: 27547f69f254 public 'B'
327 |/
327 |/
328 o 0: 4a2df7238c3b public 'A'
328 o 0: 4a2df7238c3b public 'A'
329
329
330 $ cd ..
330 $ cd ..
331
331
332 (pretxncommit version)
332 (pretxncommit version)
333
333
334 $ cp -R a3 hook-pretxncommit
334 $ cp -R a3 hook-pretxncommit
335 $ cd hook-pretxncommit
335 $ cd hook-pretxncommit
336 $ hg rebase --source 2 --dest 5 --tool internal:other \
336 $ hg rebase --source 2 --dest 5 --tool internal:other \
337 > --config 'hooks.tonative.pretxncommit=True' --config 'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary: C"'
337 > --config 'hooks.tonative.pretxncommit=True' --config 'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary: C"'
338 rebasing 2:965c486023db "C"
338 rebasing 2:965c486023db "C"
339 summary: C
339 summary: C
340 rebasing 6:a0b2430ebfb8 "F" (tip)
340 rebasing 6:a0b2430ebfb8 "F" (tip)
341 transaction abort!
341 transaction abort!
342 rollback completed
342 rollback completed
343 abort: pretxncommit hook exited with status 1
343 abort: pretxncommit hook exited with status 1
344 [255]
344 [255]
345 $ hg tglogp
345 $ hg tglogp
346 @ 7: 401ccec5e39f secret 'C'
346 @ 7: 401ccec5e39f secret 'C'
347 |
347 |
348 | @ 6: a0b2430ebfb8 secret 'F'
348 | o 6: a0b2430ebfb8 secret 'F'
349 | |
349 | |
350 o | 5: 45396c49d53b public 'B'
350 o | 5: 45396c49d53b public 'B'
351 | |
351 | |
352 o | 4: ae36e8e3dfd7 public 'E'
352 o | 4: ae36e8e3dfd7 public 'E'
353 | |
353 | |
354 o | 3: 46b37eabc604 public 'D'
354 o | 3: 46b37eabc604 public 'D'
355 | |
355 | |
356 | o 2: 965c486023db secret 'C'
356 | o 2: 965c486023db secret 'C'
357 | |
357 | |
358 | o 1: 27547f69f254 public 'B'
358 | o 1: 27547f69f254 public 'B'
359 |/
359 |/
360 o 0: 4a2df7238c3b public 'A'
360 o 0: 4a2df7238c3b public 'A'
361
361
362 $ hg rebase --continue
362 $ hg rebase --continue
363 already rebased 2:965c486023db "C" as 401ccec5e39f
363 already rebased 2:965c486023db "C" as 401ccec5e39f
364 rebasing 6:a0b2430ebfb8 "F"
364 rebasing 6:a0b2430ebfb8 "F"
365 saved backup bundle to $TESTTMP/hook-pretxncommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
365 saved backup bundle to $TESTTMP/hook-pretxncommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
366 $ hg tglogp
366 $ hg tglogp
367 @ 6: 6e92a149ac6b secret 'F'
367 @ 6: 6e92a149ac6b secret 'F'
368 |
368 |
369 o 5: 401ccec5e39f secret 'C'
369 o 5: 401ccec5e39f secret 'C'
370 |
370 |
371 o 4: 45396c49d53b public 'B'
371 o 4: 45396c49d53b public 'B'
372 |
372 |
373 o 3: ae36e8e3dfd7 public 'E'
373 o 3: ae36e8e3dfd7 public 'E'
374 |
374 |
375 o 2: 46b37eabc604 public 'D'
375 o 2: 46b37eabc604 public 'D'
376 |
376 |
377 | o 1: 27547f69f254 public 'B'
377 | o 1: 27547f69f254 public 'B'
378 |/
378 |/
379 o 0: 4a2df7238c3b public 'A'
379 o 0: 4a2df7238c3b public 'A'
380
380
381 $ cd ..
381 $ cd ..
382
382
383 (pretxnclose version)
383 (pretxnclose version)
384
384
385 $ cp -R a3 hook-pretxnclose
385 $ cp -R a3 hook-pretxnclose
386 $ cd hook-pretxnclose
386 $ cd hook-pretxnclose
387 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.pretxnclose=hg log -r tip | grep "summary: C"'
387 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.pretxnclose=hg log -r tip | grep "summary: C"'
388 rebasing 2:965c486023db "C"
388 rebasing 2:965c486023db "C"
389 summary: C
389 summary: C
390 rebasing 6:a0b2430ebfb8 "F" (tip)
390 rebasing 6:a0b2430ebfb8 "F" (tip)
391 transaction abort!
391 transaction abort!
392 rollback completed
392 rollback completed
393 abort: pretxnclose hook exited with status 1
393 abort: pretxnclose hook exited with status 1
394 [255]
394 [255]
395 $ hg tglogp
395 $ hg tglogp
396 @ 7: 401ccec5e39f secret 'C'
396 @ 7: 401ccec5e39f secret 'C'
397 |
397 |
398 | @ 6: a0b2430ebfb8 secret 'F'
398 | o 6: a0b2430ebfb8 secret 'F'
399 | |
399 | |
400 o | 5: 45396c49d53b public 'B'
400 o | 5: 45396c49d53b public 'B'
401 | |
401 | |
402 o | 4: ae36e8e3dfd7 public 'E'
402 o | 4: ae36e8e3dfd7 public 'E'
403 | |
403 | |
404 o | 3: 46b37eabc604 public 'D'
404 o | 3: 46b37eabc604 public 'D'
405 | |
405 | |
406 | o 2: 965c486023db secret 'C'
406 | o 2: 965c486023db secret 'C'
407 | |
407 | |
408 | o 1: 27547f69f254 public 'B'
408 | o 1: 27547f69f254 public 'B'
409 |/
409 |/
410 o 0: 4a2df7238c3b public 'A'
410 o 0: 4a2df7238c3b public 'A'
411
411
412 $ hg rebase --continue
412 $ hg rebase --continue
413 already rebased 2:965c486023db "C" as 401ccec5e39f
413 already rebased 2:965c486023db "C" as 401ccec5e39f
414 rebasing 6:a0b2430ebfb8 "F"
414 rebasing 6:a0b2430ebfb8 "F"
415 saved backup bundle to $TESTTMP/hook-pretxnclose/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
415 saved backup bundle to $TESTTMP/hook-pretxnclose/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
416 $ hg tglogp
416 $ hg tglogp
417 @ 6: 6e92a149ac6b secret 'F'
417 @ 6: 6e92a149ac6b secret 'F'
418 |
418 |
419 o 5: 401ccec5e39f secret 'C'
419 o 5: 401ccec5e39f secret 'C'
420 |
420 |
421 o 4: 45396c49d53b public 'B'
421 o 4: 45396c49d53b public 'B'
422 |
422 |
423 o 3: ae36e8e3dfd7 public 'E'
423 o 3: ae36e8e3dfd7 public 'E'
424 |
424 |
425 o 2: 46b37eabc604 public 'D'
425 o 2: 46b37eabc604 public 'D'
426 |
426 |
427 | o 1: 27547f69f254 public 'B'
427 | o 1: 27547f69f254 public 'B'
428 |/
428 |/
429 o 0: 4a2df7238c3b public 'A'
429 o 0: 4a2df7238c3b public 'A'
430
430
431 $ cd ..
431 $ cd ..
432
432
433 Make sure merge state is cleaned up after a no-op rebase merge (issue5494)
433 Make sure merge state is cleaned up after a no-op rebase merge (issue5494)
434 $ hg init repo
434 $ hg init repo
435 $ cd repo
435 $ cd repo
436 $ echo a > a
436 $ echo a > a
437 $ hg commit -qAm base
437 $ hg commit -qAm base
438 $ echo b >> a
438 $ echo b >> a
439 $ hg commit -qm b
439 $ hg commit -qm b
440 $ hg up '.^'
440 $ hg up '.^'
441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 $ echo c >> a
442 $ echo c >> a
443 $ hg commit -qm c
443 $ hg commit -qm c
444 $ hg rebase -s 1 -d 2 --noninteractive
444 $ hg rebase -s 1 -d 2 --noninteractive
445 rebasing 1:fdaca8533b86 "b"
445 rebasing 1:fdaca8533b86 "b"
446 merging a
446 merging a
447 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
447 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
448 unresolved conflicts (see hg resolve, then hg rebase --continue)
448 unresolved conflicts (see hg resolve, then hg rebase --continue)
449 [1]
449 [1]
450 $ echo a > a
450 $ echo a > a
451 $ echo c >> a
451 $ echo c >> a
452 $ hg resolve --mark a
452 $ hg resolve --mark a
453 (no more unresolved files)
453 (no more unresolved files)
454 continue: hg rebase --continue
454 continue: hg rebase --continue
455 $ hg rebase --continue
455 $ hg rebase --continue
456 rebasing 1:fdaca8533b86 "b"
456 rebasing 1:fdaca8533b86 "b"
457 note: not rebasing 1:fdaca8533b86 "b", its destination already has all its changes
457 note: not rebasing 1:fdaca8533b86 "b", its destination already has all its changes
458 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
458 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
459 $ hg resolve --list
459 $ hg resolve --list
460 $ test -d .hg/merge
460 $ test -d .hg/merge
461 [1]
461 [1]
462 Now try again with --collapse
462 Now try again with --collapse
463 $ hg unbundle -q .hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
463 $ hg unbundle -q .hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
464 $ hg rebase -s 2 -d 1 --noninteractive --collapse
464 $ hg rebase -s 2 -d 1 --noninteractive --collapse
465 rebasing 2:fdaca8533b86 "b" (tip)
465 rebasing 2:fdaca8533b86 "b" (tip)
466 merging a
466 merging a
467 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
467 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
468 unresolved conflicts (see hg resolve, then hg rebase --continue)
468 unresolved conflicts (see hg resolve, then hg rebase --continue)
469 [1]
469 [1]
470 $ echo a > a
470 $ echo a > a
471 $ echo c >> a
471 $ echo c >> a
472 $ hg resolve --mark a
472 $ hg resolve --mark a
473 (no more unresolved files)
473 (no more unresolved files)
474 continue: hg rebase --continue
474 continue: hg rebase --continue
475 $ hg rebase --continue
475 $ hg rebase --continue
476 rebasing 2:fdaca8533b86 "b" (tip)
476 rebasing 2:fdaca8533b86 "b" (tip)
477 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
477 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
478 $ hg resolve --list
478 $ hg resolve --list
479 $ test -d .hg/merge
479 $ test -d .hg/merge
480 [1]
480 [1]
@@ -1,2142 +1,2138 b''
1 ==========================
1 ==========================
2 Test rebase with obsolete
2 Test rebase with obsolete
3 ==========================
3 ==========================
4
4
5 Enable obsolete
5 Enable obsolete
6
6
7 $ cat >> $HGRCPATH << EOF
7 $ cat >> $HGRCPATH << EOF
8 > [ui]
8 > [ui]
9 > logtemplate= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
9 > logtemplate= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
10 > [experimental]
10 > [experimental]
11 > evolution.createmarkers=True
11 > evolution.createmarkers=True
12 > evolution.allowunstable=True
12 > evolution.allowunstable=True
13 > [phases]
13 > [phases]
14 > publish=False
14 > publish=False
15 > [extensions]
15 > [extensions]
16 > rebase=
16 > rebase=
17 > drawdag=$TESTDIR/drawdag.py
17 > drawdag=$TESTDIR/drawdag.py
18 > strip=
18 > strip=
19 > EOF
19 > EOF
20
20
21 Setup rebase canonical repo
21 Setup rebase canonical repo
22
22
23 $ hg init base
23 $ hg init base
24 $ cd base
24 $ cd base
25 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
25 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
26 adding changesets
26 adding changesets
27 adding manifests
27 adding manifests
28 adding file changes
28 adding file changes
29 added 8 changesets with 7 changes to 7 files (+2 heads)
29 added 8 changesets with 7 changes to 7 files (+2 heads)
30 new changesets cd010b8cd998:02de42196ebe (8 drafts)
30 new changesets cd010b8cd998:02de42196ebe (8 drafts)
31 (run 'hg heads' to see heads, 'hg merge' to merge)
31 (run 'hg heads' to see heads, 'hg merge' to merge)
32 $ hg up tip
32 $ hg up tip
33 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 $ hg log -G
34 $ hg log -G
35 @ 7:02de42196ebe H
35 @ 7:02de42196ebe H
36 |
36 |
37 | o 6:eea13746799a G
37 | o 6:eea13746799a G
38 |/|
38 |/|
39 o | 5:24b6387c8c8c F
39 o | 5:24b6387c8c8c F
40 | |
40 | |
41 | o 4:9520eea781bc E
41 | o 4:9520eea781bc E
42 |/
42 |/
43 | o 3:32af7686d403 D
43 | o 3:32af7686d403 D
44 | |
44 | |
45 | o 2:5fddd98957c8 C
45 | o 2:5fddd98957c8 C
46 | |
46 | |
47 | o 1:42ccdea3bb16 B
47 | o 1:42ccdea3bb16 B
48 |/
48 |/
49 o 0:cd010b8cd998 A
49 o 0:cd010b8cd998 A
50
50
51 $ cd ..
51 $ cd ..
52
52
53 simple rebase
53 simple rebase
54 ---------------------------------
54 ---------------------------------
55
55
56 $ hg clone base simple
56 $ hg clone base simple
57 updating to branch default
57 updating to branch default
58 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 $ cd simple
59 $ cd simple
60 $ hg up 32af7686d403
60 $ hg up 32af7686d403
61 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
61 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
62 $ hg rebase -d eea13746799a
62 $ hg rebase -d eea13746799a
63 rebasing 1:42ccdea3bb16 "B"
63 rebasing 1:42ccdea3bb16 "B"
64 rebasing 2:5fddd98957c8 "C"
64 rebasing 2:5fddd98957c8 "C"
65 rebasing 3:32af7686d403 "D"
65 rebasing 3:32af7686d403 "D"
66 $ hg log -G
66 $ hg log -G
67 @ 10:8eeb3c33ad33 D
67 @ 10:8eeb3c33ad33 D
68 |
68 |
69 o 9:2327fea05063 C
69 o 9:2327fea05063 C
70 |
70 |
71 o 8:e4e5be0395b2 B
71 o 8:e4e5be0395b2 B
72 |
72 |
73 | o 7:02de42196ebe H
73 | o 7:02de42196ebe H
74 | |
74 | |
75 o | 6:eea13746799a G
75 o | 6:eea13746799a G
76 |\|
76 |\|
77 | o 5:24b6387c8c8c F
77 | o 5:24b6387c8c8c F
78 | |
78 | |
79 o | 4:9520eea781bc E
79 o | 4:9520eea781bc E
80 |/
80 |/
81 o 0:cd010b8cd998 A
81 o 0:cd010b8cd998 A
82
82
83 $ hg log --hidden -G
83 $ hg log --hidden -G
84 @ 10:8eeb3c33ad33 D
84 @ 10:8eeb3c33ad33 D
85 |
85 |
86 o 9:2327fea05063 C
86 o 9:2327fea05063 C
87 |
87 |
88 o 8:e4e5be0395b2 B
88 o 8:e4e5be0395b2 B
89 |
89 |
90 | o 7:02de42196ebe H
90 | o 7:02de42196ebe H
91 | |
91 | |
92 o | 6:eea13746799a G
92 o | 6:eea13746799a G
93 |\|
93 |\|
94 | o 5:24b6387c8c8c F
94 | o 5:24b6387c8c8c F
95 | |
95 | |
96 o | 4:9520eea781bc E
96 o | 4:9520eea781bc E
97 |/
97 |/
98 | x 3:32af7686d403 D (rewritten using rebase as 10:8eeb3c33ad33)
98 | x 3:32af7686d403 D (rewritten using rebase as 10:8eeb3c33ad33)
99 | |
99 | |
100 | x 2:5fddd98957c8 C (rewritten using rebase as 9:2327fea05063)
100 | x 2:5fddd98957c8 C (rewritten using rebase as 9:2327fea05063)
101 | |
101 | |
102 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:e4e5be0395b2)
102 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:e4e5be0395b2)
103 |/
103 |/
104 o 0:cd010b8cd998 A
104 o 0:cd010b8cd998 A
105
105
106 $ hg debugobsolete
106 $ hg debugobsolete
107 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
107 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
108 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
108 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
109 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
109 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
110
110
111
111
112 $ cd ..
112 $ cd ..
113
113
114 empty changeset
114 empty changeset
115 ---------------------------------
115 ---------------------------------
116
116
117 $ hg clone base empty
117 $ hg clone base empty
118 updating to branch default
118 updating to branch default
119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 $ cd empty
120 $ cd empty
121 $ hg up eea13746799a
121 $ hg up eea13746799a
122 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
122 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
123
123
124 We make a copy of both the first changeset in the rebased and some other in the
124 We make a copy of both the first changeset in the rebased and some other in the
125 set.
125 set.
126
126
127 $ hg graft 42ccdea3bb16 32af7686d403
127 $ hg graft 42ccdea3bb16 32af7686d403
128 grafting 1:42ccdea3bb16 "B"
128 grafting 1:42ccdea3bb16 "B"
129 grafting 3:32af7686d403 "D"
129 grafting 3:32af7686d403 "D"
130 $ hg rebase -s 42ccdea3bb16 -d .
130 $ hg rebase -s 42ccdea3bb16 -d .
131 rebasing 1:42ccdea3bb16 "B"
131 rebasing 1:42ccdea3bb16 "B"
132 note: not rebasing 1:42ccdea3bb16 "B", its destination already has all its changes
132 note: not rebasing 1:42ccdea3bb16 "B", its destination already has all its changes
133 rebasing 2:5fddd98957c8 "C"
133 rebasing 2:5fddd98957c8 "C"
134 rebasing 3:32af7686d403 "D"
134 rebasing 3:32af7686d403 "D"
135 note: not rebasing 3:32af7686d403 "D", its destination already has all its changes
135 note: not rebasing 3:32af7686d403 "D", its destination already has all its changes
136 $ hg log -G
136 $ hg log -G
137 o 10:5ae4c968c6ac C
137 o 10:5ae4c968c6ac C
138 |
138 |
139 @ 9:08483444fef9 D
139 @ 9:08483444fef9 D
140 |
140 |
141 o 8:8877864f1edb B
141 o 8:8877864f1edb B
142 |
142 |
143 | o 7:02de42196ebe H
143 | o 7:02de42196ebe H
144 | |
144 | |
145 o | 6:eea13746799a G
145 o | 6:eea13746799a G
146 |\|
146 |\|
147 | o 5:24b6387c8c8c F
147 | o 5:24b6387c8c8c F
148 | |
148 | |
149 o | 4:9520eea781bc E
149 o | 4:9520eea781bc E
150 |/
150 |/
151 o 0:cd010b8cd998 A
151 o 0:cd010b8cd998 A
152
152
153 $ hg log --hidden -G
153 $ hg log --hidden -G
154 o 10:5ae4c968c6ac C
154 o 10:5ae4c968c6ac C
155 |
155 |
156 @ 9:08483444fef9 D
156 @ 9:08483444fef9 D
157 |
157 |
158 o 8:8877864f1edb B
158 o 8:8877864f1edb B
159 |
159 |
160 | o 7:02de42196ebe H
160 | o 7:02de42196ebe H
161 | |
161 | |
162 o | 6:eea13746799a G
162 o | 6:eea13746799a G
163 |\|
163 |\|
164 | o 5:24b6387c8c8c F
164 | o 5:24b6387c8c8c F
165 | |
165 | |
166 o | 4:9520eea781bc E
166 o | 4:9520eea781bc E
167 |/
167 |/
168 | x 3:32af7686d403 D (pruned using rebase)
168 | x 3:32af7686d403 D (pruned using rebase)
169 | |
169 | |
170 | x 2:5fddd98957c8 C (rewritten using rebase as 10:5ae4c968c6ac)
170 | x 2:5fddd98957c8 C (rewritten using rebase as 10:5ae4c968c6ac)
171 | |
171 | |
172 | x 1:42ccdea3bb16 B (pruned using rebase)
172 | x 1:42ccdea3bb16 B (pruned using rebase)
173 |/
173 |/
174 o 0:cd010b8cd998 A
174 o 0:cd010b8cd998 A
175
175
176 $ hg debugobsolete
176 $ hg debugobsolete
177 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
177 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
178 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
178 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
179 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
179 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
180
180
181
181
182 More complex case where part of the rebase set were already rebased
182 More complex case where part of the rebase set were already rebased
183
183
184 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
184 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
185 rebasing 9:08483444fef9 "D"
185 rebasing 9:08483444fef9 "D"
186 1 new orphan changesets
186 1 new orphan changesets
187 $ hg debugobsolete
187 $ hg debugobsolete
188 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
188 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
189 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
189 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
190 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
190 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
191 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
191 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
192 $ hg log -G
192 $ hg log -G
193 @ 11:4596109a6a43 D
193 @ 11:4596109a6a43 D
194 |
194 |
195 | * 10:5ae4c968c6ac C
195 | * 10:5ae4c968c6ac C
196 | |
196 | |
197 | x 9:08483444fef9 D (rewritten using rebase as 11:4596109a6a43)
197 | x 9:08483444fef9 D (rewritten using rebase as 11:4596109a6a43)
198 | |
198 | |
199 | o 8:8877864f1edb B
199 | o 8:8877864f1edb B
200 | |
200 | |
201 o | 7:02de42196ebe H
201 o | 7:02de42196ebe H
202 | |
202 | |
203 | o 6:eea13746799a G
203 | o 6:eea13746799a G
204 |/|
204 |/|
205 o | 5:24b6387c8c8c F
205 o | 5:24b6387c8c8c F
206 | |
206 | |
207 | o 4:9520eea781bc E
207 | o 4:9520eea781bc E
208 |/
208 |/
209 o 0:cd010b8cd998 A
209 o 0:cd010b8cd998 A
210
210
211 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
211 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
212 rebasing 8:8877864f1edb "B"
212 rebasing 8:8877864f1edb "B"
213 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D" (tip)
213 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D" (tip)
214 rebasing 10:5ae4c968c6ac "C"
214 rebasing 10:5ae4c968c6ac "C"
215 $ hg debugobsolete
215 $ hg debugobsolete
216 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
216 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
217 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
217 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
218 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
218 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
219 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
219 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
220 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
220 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
221 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
221 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
222 $ hg log --rev 'contentdivergent()'
222 $ hg log --rev 'contentdivergent()'
223 $ hg log -G
223 $ hg log -G
224 o 13:98f6af4ee953 C
224 o 13:98f6af4ee953 C
225 |
225 |
226 o 12:462a34d07e59 B
226 o 12:462a34d07e59 B
227 |
227 |
228 @ 11:4596109a6a43 D
228 @ 11:4596109a6a43 D
229 |
229 |
230 o 7:02de42196ebe H
230 o 7:02de42196ebe H
231 |
231 |
232 | o 6:eea13746799a G
232 | o 6:eea13746799a G
233 |/|
233 |/|
234 o | 5:24b6387c8c8c F
234 o | 5:24b6387c8c8c F
235 | |
235 | |
236 | o 4:9520eea781bc E
236 | o 4:9520eea781bc E
237 |/
237 |/
238 o 0:cd010b8cd998 A
238 o 0:cd010b8cd998 A
239
239
240 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
240 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
241 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
241 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
242 phase: draft
242 phase: draft
243 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
243 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
244 parent: -1:0000000000000000000000000000000000000000
244 parent: -1:0000000000000000000000000000000000000000
245 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
245 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
246 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
246 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
247 date: Sat Apr 30 15:24:48 2011 +0200
247 date: Sat Apr 30 15:24:48 2011 +0200
248 files+: D
248 files+: D
249 extra: branch=default
249 extra: branch=default
250 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
250 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
251 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
251 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
252 description:
252 description:
253 D
253 D
254
254
255
255
256 $ hg up -qr 'desc(G)'
256 $ hg up -qr 'desc(G)'
257 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
257 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
258 grafting 11:4596109a6a43 "D"
258 grafting 11:4596109a6a43 "D"
259 $ hg up -qr 'desc(E)'
259 $ hg up -qr 'desc(E)'
260 $ hg rebase -s tip -d .
260 $ hg rebase -s tip -d .
261 rebasing 14:9e36056a46e3 "D" (tip)
261 rebasing 14:9e36056a46e3 "D" (tip)
262 $ hg log --style default --debug -r tip
262 $ hg log --style default --debug -r tip
263 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
263 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
264 tag: tip
264 tag: tip
265 phase: draft
265 phase: draft
266 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
266 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
267 parent: -1:0000000000000000000000000000000000000000
267 parent: -1:0000000000000000000000000000000000000000
268 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
268 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
269 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
269 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
270 date: Sat Apr 30 15:24:48 2011 +0200
270 date: Sat Apr 30 15:24:48 2011 +0200
271 files+: D
271 files+: D
272 extra: branch=default
272 extra: branch=default
273 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
273 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
274 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
274 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
275 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
275 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
276 description:
276 description:
277 D
277 D
278
278
279
279
280 Start rebase from a commit that is obsolete but not hidden only because it's
280 Start rebase from a commit that is obsolete but not hidden only because it's
281 a working copy parent. We should be moved back to the starting commit as usual
281 a working copy parent. We should be moved back to the starting commit as usual
282 even though it is hidden (until we're moved there).
282 even though it is hidden (until we're moved there).
283
283
284 $ hg --hidden up -qr 'first(hidden())'
284 $ hg --hidden up -qr 'first(hidden())'
285 updated to hidden changeset 42ccdea3bb16
285 updated to hidden changeset 42ccdea3bb16
286 (hidden revision '42ccdea3bb16' is pruned)
286 (hidden revision '42ccdea3bb16' is pruned)
287 $ hg rebase --rev 13 --dest 15
287 $ hg rebase --rev 13 --dest 15
288 rebasing 13:98f6af4ee953 "C"
288 rebasing 13:98f6af4ee953 "C"
289 $ hg log -G
289 $ hg log -G
290 o 16:294a2b93eb4d C
290 o 16:294a2b93eb4d C
291 |
291 |
292 o 15:627d46148090 D
292 o 15:627d46148090 D
293 |
293 |
294 | o 12:462a34d07e59 B
294 | o 12:462a34d07e59 B
295 | |
295 | |
296 | o 11:4596109a6a43 D
296 | o 11:4596109a6a43 D
297 | |
297 | |
298 | o 7:02de42196ebe H
298 | o 7:02de42196ebe H
299 | |
299 | |
300 +---o 6:eea13746799a G
300 +---o 6:eea13746799a G
301 | |/
301 | |/
302 | o 5:24b6387c8c8c F
302 | o 5:24b6387c8c8c F
303 | |
303 | |
304 o | 4:9520eea781bc E
304 o | 4:9520eea781bc E
305 |/
305 |/
306 | @ 1:42ccdea3bb16 B (pruned using rebase)
306 | @ 1:42ccdea3bb16 B (pruned using rebase)
307 |/
307 |/
308 o 0:cd010b8cd998 A
308 o 0:cd010b8cd998 A
309
309
310
310
311 $ cd ..
311 $ cd ..
312
312
313 collapse rebase
313 collapse rebase
314 ---------------------------------
314 ---------------------------------
315
315
316 $ hg clone base collapse
316 $ hg clone base collapse
317 updating to branch default
317 updating to branch default
318 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 $ cd collapse
319 $ cd collapse
320 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
320 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
321 rebasing 1:42ccdea3bb16 "B"
321 rebasing 1:42ccdea3bb16 "B"
322 rebasing 2:5fddd98957c8 "C"
322 rebasing 2:5fddd98957c8 "C"
323 rebasing 3:32af7686d403 "D"
323 rebasing 3:32af7686d403 "D"
324 $ hg log -G
324 $ hg log -G
325 o 8:4dc2197e807b Collapsed revision
325 o 8:4dc2197e807b Collapsed revision
326 |
326 |
327 | @ 7:02de42196ebe H
327 | @ 7:02de42196ebe H
328 | |
328 | |
329 o | 6:eea13746799a G
329 o | 6:eea13746799a G
330 |\|
330 |\|
331 | o 5:24b6387c8c8c F
331 | o 5:24b6387c8c8c F
332 | |
332 | |
333 o | 4:9520eea781bc E
333 o | 4:9520eea781bc E
334 |/
334 |/
335 o 0:cd010b8cd998 A
335 o 0:cd010b8cd998 A
336
336
337 $ hg log --hidden -G
337 $ hg log --hidden -G
338 o 8:4dc2197e807b Collapsed revision
338 o 8:4dc2197e807b Collapsed revision
339 |
339 |
340 | @ 7:02de42196ebe H
340 | @ 7:02de42196ebe H
341 | |
341 | |
342 o | 6:eea13746799a G
342 o | 6:eea13746799a G
343 |\|
343 |\|
344 | o 5:24b6387c8c8c F
344 | o 5:24b6387c8c8c F
345 | |
345 | |
346 o | 4:9520eea781bc E
346 o | 4:9520eea781bc E
347 |/
347 |/
348 | x 3:32af7686d403 D (rewritten using rebase as 8:4dc2197e807b)
348 | x 3:32af7686d403 D (rewritten using rebase as 8:4dc2197e807b)
349 | |
349 | |
350 | x 2:5fddd98957c8 C (rewritten using rebase as 8:4dc2197e807b)
350 | x 2:5fddd98957c8 C (rewritten using rebase as 8:4dc2197e807b)
351 | |
351 | |
352 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:4dc2197e807b)
352 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:4dc2197e807b)
353 |/
353 |/
354 o 0:cd010b8cd998 A
354 o 0:cd010b8cd998 A
355
355
356 $ hg id --debug -r tip
356 $ hg id --debug -r tip
357 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
357 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
358 $ hg debugobsolete
358 $ hg debugobsolete
359 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '1', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
359 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '1', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
360 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '2', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
360 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '2', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
361 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '3', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
361 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'fold-id': '6fb65cdc', 'fold-idx': '3', 'fold-size': '3', 'operation': 'rebase', 'user': 'test'}
362
362
363 $ cd ..
363 $ cd ..
364
364
365 Rebase set has hidden descendants
365 Rebase set has hidden descendants
366 ---------------------------------
366 ---------------------------------
367
367
368 We rebase a changeset which has hidden descendants. Hidden changesets must not
368 We rebase a changeset which has hidden descendants. Hidden changesets must not
369 be rebased.
369 be rebased.
370
370
371 $ hg clone base hidden
371 $ hg clone base hidden
372 updating to branch default
372 updating to branch default
373 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
373 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 $ cd hidden
374 $ cd hidden
375 $ hg log -G
375 $ hg log -G
376 @ 7:02de42196ebe H
376 @ 7:02de42196ebe H
377 |
377 |
378 | o 6:eea13746799a G
378 | o 6:eea13746799a G
379 |/|
379 |/|
380 o | 5:24b6387c8c8c F
380 o | 5:24b6387c8c8c F
381 | |
381 | |
382 | o 4:9520eea781bc E
382 | o 4:9520eea781bc E
383 |/
383 |/
384 | o 3:32af7686d403 D
384 | o 3:32af7686d403 D
385 | |
385 | |
386 | o 2:5fddd98957c8 C
386 | o 2:5fddd98957c8 C
387 | |
387 | |
388 | o 1:42ccdea3bb16 B
388 | o 1:42ccdea3bb16 B
389 |/
389 |/
390 o 0:cd010b8cd998 A
390 o 0:cd010b8cd998 A
391
391
392 $ hg rebase -s 5fddd98957c8 -d eea13746799a
392 $ hg rebase -s 5fddd98957c8 -d eea13746799a
393 rebasing 2:5fddd98957c8 "C"
393 rebasing 2:5fddd98957c8 "C"
394 rebasing 3:32af7686d403 "D"
394 rebasing 3:32af7686d403 "D"
395 $ hg log -G
395 $ hg log -G
396 o 9:cf44d2f5a9f4 D
396 o 9:cf44d2f5a9f4 D
397 |
397 |
398 o 8:e273c5e7d2d2 C
398 o 8:e273c5e7d2d2 C
399 |
399 |
400 | @ 7:02de42196ebe H
400 | @ 7:02de42196ebe H
401 | |
401 | |
402 o | 6:eea13746799a G
402 o | 6:eea13746799a G
403 |\|
403 |\|
404 | o 5:24b6387c8c8c F
404 | o 5:24b6387c8c8c F
405 | |
405 | |
406 o | 4:9520eea781bc E
406 o | 4:9520eea781bc E
407 |/
407 |/
408 | o 1:42ccdea3bb16 B
408 | o 1:42ccdea3bb16 B
409 |/
409 |/
410 o 0:cd010b8cd998 A
410 o 0:cd010b8cd998 A
411
411
412 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
412 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
413 rebasing 1:42ccdea3bb16 "B"
413 rebasing 1:42ccdea3bb16 "B"
414 $ hg log -G
414 $ hg log -G
415 o 10:7c6027df6a99 B
415 o 10:7c6027df6a99 B
416 |
416 |
417 | o 9:cf44d2f5a9f4 D
417 | o 9:cf44d2f5a9f4 D
418 | |
418 | |
419 | o 8:e273c5e7d2d2 C
419 | o 8:e273c5e7d2d2 C
420 | |
420 | |
421 @ | 7:02de42196ebe H
421 @ | 7:02de42196ebe H
422 | |
422 | |
423 | o 6:eea13746799a G
423 | o 6:eea13746799a G
424 |/|
424 |/|
425 o | 5:24b6387c8c8c F
425 o | 5:24b6387c8c8c F
426 | |
426 | |
427 | o 4:9520eea781bc E
427 | o 4:9520eea781bc E
428 |/
428 |/
429 o 0:cd010b8cd998 A
429 o 0:cd010b8cd998 A
430
430
431 $ hg log --hidden -G
431 $ hg log --hidden -G
432 o 10:7c6027df6a99 B
432 o 10:7c6027df6a99 B
433 |
433 |
434 | o 9:cf44d2f5a9f4 D
434 | o 9:cf44d2f5a9f4 D
435 | |
435 | |
436 | o 8:e273c5e7d2d2 C
436 | o 8:e273c5e7d2d2 C
437 | |
437 | |
438 @ | 7:02de42196ebe H
438 @ | 7:02de42196ebe H
439 | |
439 | |
440 | o 6:eea13746799a G
440 | o 6:eea13746799a G
441 |/|
441 |/|
442 o | 5:24b6387c8c8c F
442 o | 5:24b6387c8c8c F
443 | |
443 | |
444 | o 4:9520eea781bc E
444 | o 4:9520eea781bc E
445 |/
445 |/
446 | x 3:32af7686d403 D (rewritten using rebase as 9:cf44d2f5a9f4)
446 | x 3:32af7686d403 D (rewritten using rebase as 9:cf44d2f5a9f4)
447 | |
447 | |
448 | x 2:5fddd98957c8 C (rewritten using rebase as 8:e273c5e7d2d2)
448 | x 2:5fddd98957c8 C (rewritten using rebase as 8:e273c5e7d2d2)
449 | |
449 | |
450 | x 1:42ccdea3bb16 B (rewritten using rebase as 10:7c6027df6a99)
450 | x 1:42ccdea3bb16 B (rewritten using rebase as 10:7c6027df6a99)
451 |/
451 |/
452 o 0:cd010b8cd998 A
452 o 0:cd010b8cd998 A
453
453
454 $ hg debugobsolete
454 $ hg debugobsolete
455 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
455 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
456 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
456 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
457 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
457 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
458
458
459 Test that rewriting leaving instability behind is allowed
459 Test that rewriting leaving instability behind is allowed
460 ---------------------------------------------------------------------
460 ---------------------------------------------------------------------
461
461
462 $ hg log -r 'children(8)'
462 $ hg log -r 'children(8)'
463 9:cf44d2f5a9f4 D (no-eol)
463 9:cf44d2f5a9f4 D (no-eol)
464 $ hg rebase -r 8
464 $ hg rebase -r 8
465 rebasing 8:e273c5e7d2d2 "C"
465 rebasing 8:e273c5e7d2d2 "C"
466 1 new orphan changesets
466 1 new orphan changesets
467 $ hg log -G
467 $ hg log -G
468 o 11:0d8f238b634c C
468 o 11:0d8f238b634c C
469 |
469 |
470 o 10:7c6027df6a99 B
470 o 10:7c6027df6a99 B
471 |
471 |
472 | * 9:cf44d2f5a9f4 D
472 | * 9:cf44d2f5a9f4 D
473 | |
473 | |
474 | x 8:e273c5e7d2d2 C (rewritten using rebase as 11:0d8f238b634c)
474 | x 8:e273c5e7d2d2 C (rewritten using rebase as 11:0d8f238b634c)
475 | |
475 | |
476 @ | 7:02de42196ebe H
476 @ | 7:02de42196ebe H
477 | |
477 | |
478 | o 6:eea13746799a G
478 | o 6:eea13746799a G
479 |/|
479 |/|
480 o | 5:24b6387c8c8c F
480 o | 5:24b6387c8c8c F
481 | |
481 | |
482 | o 4:9520eea781bc E
482 | o 4:9520eea781bc E
483 |/
483 |/
484 o 0:cd010b8cd998 A
484 o 0:cd010b8cd998 A
485
485
486 $ cd ..
486 $ cd ..
487 $ cp -R hidden stabilize
487 $ cp -R hidden stabilize
488 $ cd stabilize
488 $ cd stabilize
489 $ hg rebase --auto-orphans '0::' -d 10
489 $ hg rebase --auto-orphans '0::' -d 10
490 abort: cannot specify both --auto-orphans and --dest
490 abort: cannot specify both --auto-orphans and --dest
491 [255]
491 [255]
492 $ hg rebase --auto-orphans '0::'
492 $ hg rebase --auto-orphans '0::'
493 rebasing 9:cf44d2f5a9f4 "D"
493 rebasing 9:cf44d2f5a9f4 "D"
494 $ hg log -G
494 $ hg log -G
495 o 12:7e3935feaa68 D
495 o 12:7e3935feaa68 D
496 |
496 |
497 o 11:0d8f238b634c C
497 o 11:0d8f238b634c C
498 |
498 |
499 o 10:7c6027df6a99 B
499 o 10:7c6027df6a99 B
500 |
500 |
501 @ 7:02de42196ebe H
501 @ 7:02de42196ebe H
502 |
502 |
503 | o 6:eea13746799a G
503 | o 6:eea13746799a G
504 |/|
504 |/|
505 o | 5:24b6387c8c8c F
505 o | 5:24b6387c8c8c F
506 | |
506 | |
507 | o 4:9520eea781bc E
507 | o 4:9520eea781bc E
508 |/
508 |/
509 o 0:cd010b8cd998 A
509 o 0:cd010b8cd998 A
510
510
511
511
512 $ cd ../hidden
512 $ cd ../hidden
513 $ rm -r ../stabilize
513 $ rm -r ../stabilize
514
514
515 Test multiple root handling
515 Test multiple root handling
516 ------------------------------------
516 ------------------------------------
517
517
518 $ hg rebase --dest 4 --rev '7+11+9'
518 $ hg rebase --dest 4 --rev '7+11+9'
519 rebasing 9:cf44d2f5a9f4 "D"
519 rebasing 9:cf44d2f5a9f4 "D"
520 rebasing 7:02de42196ebe "H"
520 rebasing 7:02de42196ebe "H"
521 rebasing 11:0d8f238b634c "C" (tip)
521 rebasing 11:0d8f238b634c "C" (tip)
522 $ hg log -G
522 $ hg log -G
523 o 14:1e8370e38cca C
523 o 14:1e8370e38cca C
524 |
524 |
525 @ 13:bfe264faf697 H
525 @ 13:bfe264faf697 H
526 |
526 |
527 | o 12:102b4c1d889b D
527 | o 12:102b4c1d889b D
528 |/
528 |/
529 | * 10:7c6027df6a99 B
529 | * 10:7c6027df6a99 B
530 | |
530 | |
531 | x 7:02de42196ebe H (rewritten using rebase as 13:bfe264faf697)
531 | x 7:02de42196ebe H (rewritten using rebase as 13:bfe264faf697)
532 | |
532 | |
533 +---o 6:eea13746799a G
533 +---o 6:eea13746799a G
534 | |/
534 | |/
535 | o 5:24b6387c8c8c F
535 | o 5:24b6387c8c8c F
536 | |
536 | |
537 o | 4:9520eea781bc E
537 o | 4:9520eea781bc E
538 |/
538 |/
539 o 0:cd010b8cd998 A
539 o 0:cd010b8cd998 A
540
540
541 $ cd ..
541 $ cd ..
542
542
543 Detach both parents
543 Detach both parents
544
544
545 $ hg init double-detach
545 $ hg init double-detach
546 $ cd double-detach
546 $ cd double-detach
547
547
548 $ hg debugdrawdag <<EOF
548 $ hg debugdrawdag <<EOF
549 > F
549 > F
550 > /|
550 > /|
551 > C E
551 > C E
552 > | |
552 > | |
553 > B D G
553 > B D G
554 > \|/
554 > \|/
555 > A
555 > A
556 > EOF
556 > EOF
557
557
558 $ hg rebase -d G -r 'B + D + F'
558 $ hg rebase -d G -r 'B + D + F'
559 rebasing 1:112478962961 "B" (B)
559 rebasing 1:112478962961 "B" (B)
560 rebasing 2:b18e25de2cf5 "D" (D)
560 rebasing 2:b18e25de2cf5 "D" (D)
561 rebasing 6:f15c3adaf214 "F" (F tip)
561 rebasing 6:f15c3adaf214 "F" (F tip)
562 abort: cannot rebase 6:f15c3adaf214 without moving at least one of its parents
562 abort: cannot rebase 6:f15c3adaf214 without moving at least one of its parents
563 [255]
563 [255]
564
564
565 $ cd ..
565 $ cd ..
566
566
567 test on rebase dropping a merge
567 test on rebase dropping a merge
568
568
569 (setup)
569 (setup)
570
570
571 $ hg init dropmerge
571 $ hg init dropmerge
572 $ cd dropmerge
572 $ cd dropmerge
573 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
573 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
574 adding changesets
574 adding changesets
575 adding manifests
575 adding manifests
576 adding file changes
576 adding file changes
577 added 8 changesets with 7 changes to 7 files (+2 heads)
577 added 8 changesets with 7 changes to 7 files (+2 heads)
578 new changesets cd010b8cd998:02de42196ebe (8 drafts)
578 new changesets cd010b8cd998:02de42196ebe (8 drafts)
579 (run 'hg heads' to see heads, 'hg merge' to merge)
579 (run 'hg heads' to see heads, 'hg merge' to merge)
580 $ hg up 3
580 $ hg up 3
581 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
581 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 $ hg merge 7
582 $ hg merge 7
583 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 (branch merge, don't forget to commit)
584 (branch merge, don't forget to commit)
585 $ hg ci -m 'M'
585 $ hg ci -m 'M'
586 $ echo I > I
586 $ echo I > I
587 $ hg add I
587 $ hg add I
588 $ hg ci -m I
588 $ hg ci -m I
589 $ hg log -G
589 $ hg log -G
590 @ 9:4bde274eefcf I
590 @ 9:4bde274eefcf I
591 |
591 |
592 o 8:53a6a128b2b7 M
592 o 8:53a6a128b2b7 M
593 |\
593 |\
594 | o 7:02de42196ebe H
594 | o 7:02de42196ebe H
595 | |
595 | |
596 | | o 6:eea13746799a G
596 | | o 6:eea13746799a G
597 | |/|
597 | |/|
598 | o | 5:24b6387c8c8c F
598 | o | 5:24b6387c8c8c F
599 | | |
599 | | |
600 | | o 4:9520eea781bc E
600 | | o 4:9520eea781bc E
601 | |/
601 | |/
602 o | 3:32af7686d403 D
602 o | 3:32af7686d403 D
603 | |
603 | |
604 o | 2:5fddd98957c8 C
604 o | 2:5fddd98957c8 C
605 | |
605 | |
606 o | 1:42ccdea3bb16 B
606 o | 1:42ccdea3bb16 B
607 |/
607 |/
608 o 0:cd010b8cd998 A
608 o 0:cd010b8cd998 A
609
609
610 (actual test)
610 (actual test)
611
611
612 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
612 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
613 rebasing 3:32af7686d403 "D"
613 rebasing 3:32af7686d403 "D"
614 rebasing 7:02de42196ebe "H"
614 rebasing 7:02de42196ebe "H"
615 rebasing 9:4bde274eefcf "I" (tip)
615 rebasing 9:4bde274eefcf "I" (tip)
616 1 new orphan changesets
616 1 new orphan changesets
617 $ hg log -G
617 $ hg log -G
618 @ 12:acd174b7ab39 I
618 @ 12:acd174b7ab39 I
619 |
619 |
620 o 11:6c11a6218c97 H
620 o 11:6c11a6218c97 H
621 |
621 |
622 | o 10:b5313c85b22e D
622 | o 10:b5313c85b22e D
623 |/
623 |/
624 | * 8:53a6a128b2b7 M
624 | * 8:53a6a128b2b7 M
625 | |\
625 | |\
626 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
626 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
627 | | |
627 | | |
628 o---+ 6:eea13746799a G
628 o---+ 6:eea13746799a G
629 | | |
629 | | |
630 | | o 5:24b6387c8c8c F
630 | | o 5:24b6387c8c8c F
631 | | |
631 | | |
632 o---+ 4:9520eea781bc E
632 o---+ 4:9520eea781bc E
633 / /
633 / /
634 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
634 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
635 | |
635 | |
636 o | 2:5fddd98957c8 C
636 o | 2:5fddd98957c8 C
637 | |
637 | |
638 o | 1:42ccdea3bb16 B
638 o | 1:42ccdea3bb16 B
639 |/
639 |/
640 o 0:cd010b8cd998 A
640 o 0:cd010b8cd998 A
641
641
642
642
643 Test hidden changesets in the rebase set (issue4504)
643 Test hidden changesets in the rebase set (issue4504)
644
644
645 $ hg up --hidden 9
645 $ hg up --hidden 9
646 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
646 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
647 updated to hidden changeset 4bde274eefcf
647 updated to hidden changeset 4bde274eefcf
648 (hidden revision '4bde274eefcf' was rewritten as: acd174b7ab39)
648 (hidden revision '4bde274eefcf' was rewritten as: acd174b7ab39)
649 $ echo J > J
649 $ echo J > J
650 $ hg add J
650 $ hg add J
651 $ hg commit -m J
651 $ hg commit -m J
652 1 new orphan changesets
652 1 new orphan changesets
653 $ hg debugobsolete `hg log --rev . -T '{node}'`
653 $ hg debugobsolete `hg log --rev . -T '{node}'`
654 1 new obsolescence markers
654 1 new obsolescence markers
655 obsoleted 1 changesets
655 obsoleted 1 changesets
656
656
657 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
657 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
658 rebasing 9:4bde274eefcf "I"
658 rebasing 9:4bde274eefcf "I"
659 rebasing 13:06edfc82198f "J" (tip)
659 rebasing 13:06edfc82198f "J" (tip)
660 2 new content-divergent changesets
660 2 new content-divergent changesets
661 $ hg log -G
661 $ hg log -G
662 @ 15:5ae8a643467b J
662 @ 15:5ae8a643467b J
663 |
663 |
664 * 14:9ad579b4a5de I
664 * 14:9ad579b4a5de I
665 |
665 |
666 | * 12:acd174b7ab39 I
666 | * 12:acd174b7ab39 I
667 | |
667 | |
668 | o 11:6c11a6218c97 H
668 | o 11:6c11a6218c97 H
669 | |
669 | |
670 o | 10:b5313c85b22e D
670 o | 10:b5313c85b22e D
671 |/
671 |/
672 | * 8:53a6a128b2b7 M
672 | * 8:53a6a128b2b7 M
673 | |\
673 | |\
674 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
674 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
675 | | |
675 | | |
676 o---+ 6:eea13746799a G
676 o---+ 6:eea13746799a G
677 | | |
677 | | |
678 | | o 5:24b6387c8c8c F
678 | | o 5:24b6387c8c8c F
679 | | |
679 | | |
680 o---+ 4:9520eea781bc E
680 o---+ 4:9520eea781bc E
681 / /
681 / /
682 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
682 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
683 | |
683 | |
684 o | 2:5fddd98957c8 C
684 o | 2:5fddd98957c8 C
685 | |
685 | |
686 o | 1:42ccdea3bb16 B
686 o | 1:42ccdea3bb16 B
687 |/
687 |/
688 o 0:cd010b8cd998 A
688 o 0:cd010b8cd998 A
689
689
690 $ hg up 14 -C
690 $ hg up 14 -C
691 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
691 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
692 $ echo "K" > K
692 $ echo "K" > K
693 $ hg add K
693 $ hg add K
694 $ hg commit --amend -m "K"
694 $ hg commit --amend -m "K"
695 1 new orphan changesets
695 1 new orphan changesets
696 $ echo "L" > L
696 $ echo "L" > L
697 $ hg add L
697 $ hg add L
698 $ hg commit -m "L"
698 $ hg commit -m "L"
699 $ hg up '.^'
699 $ hg up '.^'
700 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
700 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
701 $ echo "M" > M
701 $ echo "M" > M
702 $ hg add M
702 $ hg add M
703 $ hg commit --amend -m "M"
703 $ hg commit --amend -m "M"
704 1 new orphan changesets
704 1 new orphan changesets
705 $ hg log -G
705 $ hg log -G
706 @ 18:bfaedf8eb73b M
706 @ 18:bfaedf8eb73b M
707 |
707 |
708 | * 17:97219452e4bd L
708 | * 17:97219452e4bd L
709 | |
709 | |
710 | x 16:fc37a630c901 K (rewritten using amend as 18:bfaedf8eb73b)
710 | x 16:fc37a630c901 K (rewritten using amend as 18:bfaedf8eb73b)
711 |/
711 |/
712 | * 15:5ae8a643467b J
712 | * 15:5ae8a643467b J
713 | |
713 | |
714 | x 14:9ad579b4a5de I (rewritten using amend as 16:fc37a630c901)
714 | x 14:9ad579b4a5de I (rewritten using amend as 16:fc37a630c901)
715 |/
715 |/
716 | * 12:acd174b7ab39 I
716 | * 12:acd174b7ab39 I
717 | |
717 | |
718 | o 11:6c11a6218c97 H
718 | o 11:6c11a6218c97 H
719 | |
719 | |
720 o | 10:b5313c85b22e D
720 o | 10:b5313c85b22e D
721 |/
721 |/
722 | * 8:53a6a128b2b7 M
722 | * 8:53a6a128b2b7 M
723 | |\
723 | |\
724 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
724 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
725 | | |
725 | | |
726 o---+ 6:eea13746799a G
726 o---+ 6:eea13746799a G
727 | | |
727 | | |
728 | | o 5:24b6387c8c8c F
728 | | o 5:24b6387c8c8c F
729 | | |
729 | | |
730 o---+ 4:9520eea781bc E
730 o---+ 4:9520eea781bc E
731 / /
731 / /
732 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
732 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
733 | |
733 | |
734 o | 2:5fddd98957c8 C
734 o | 2:5fddd98957c8 C
735 | |
735 | |
736 o | 1:42ccdea3bb16 B
736 o | 1:42ccdea3bb16 B
737 |/
737 |/
738 o 0:cd010b8cd998 A
738 o 0:cd010b8cd998 A
739
739
740 $ hg rebase -s 14 -d 17 --config experimental.rebaseskipobsolete=True
740 $ hg rebase -s 14 -d 17 --config experimental.rebaseskipobsolete=True
741 note: not rebasing 14:9ad579b4a5de "I", already in destination as 16:fc37a630c901 "K"
741 note: not rebasing 14:9ad579b4a5de "I", already in destination as 16:fc37a630c901 "K"
742 rebasing 15:5ae8a643467b "J"
742 rebasing 15:5ae8a643467b "J"
743 1 new orphan changesets
743 1 new orphan changesets
744
744
745 $ cd ..
745 $ cd ..
746
746
747 Skip obsolete changeset even with multiple hops
747 Skip obsolete changeset even with multiple hops
748 -----------------------------------------------
748 -----------------------------------------------
749
749
750 setup
750 setup
751
751
752 $ hg init obsskip
752 $ hg init obsskip
753 $ cd obsskip
753 $ cd obsskip
754 $ cat << EOF >> .hg/hgrc
754 $ cat << EOF >> .hg/hgrc
755 > [experimental]
755 > [experimental]
756 > rebaseskipobsolete = True
756 > rebaseskipobsolete = True
757 > [extensions]
757 > [extensions]
758 > strip =
758 > strip =
759 > EOF
759 > EOF
760 $ echo A > A
760 $ echo A > A
761 $ hg add A
761 $ hg add A
762 $ hg commit -m A
762 $ hg commit -m A
763 $ echo B > B
763 $ echo B > B
764 $ hg add B
764 $ hg add B
765 $ hg commit -m B0
765 $ hg commit -m B0
766 $ hg commit --amend -m B1
766 $ hg commit --amend -m B1
767 $ hg commit --amend -m B2
767 $ hg commit --amend -m B2
768 $ hg up --hidden 'desc(B0)'
768 $ hg up --hidden 'desc(B0)'
769 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
769 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
770 updated to hidden changeset a8b11f55fb19
770 updated to hidden changeset a8b11f55fb19
771 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
771 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
772 $ echo C > C
772 $ echo C > C
773 $ hg add C
773 $ hg add C
774 $ hg commit -m C
774 $ hg commit -m C
775 1 new orphan changesets
775 1 new orphan changesets
776 $ hg log -G
776 $ hg log -G
777 @ 4:212cb178bcbb C
777 @ 4:212cb178bcbb C
778 |
778 |
779 | o 3:261e70097290 B2
779 | o 3:261e70097290 B2
780 | |
780 | |
781 x | 1:a8b11f55fb19 B0 (rewritten using amend as 3:261e70097290)
781 x | 1:a8b11f55fb19 B0 (rewritten using amend as 3:261e70097290)
782 |/
782 |/
783 o 0:4a2df7238c3b A
783 o 0:4a2df7238c3b A
784
784
785
785
786 Rebase finds its way in a chain of marker
786 Rebase finds its way in a chain of marker
787
787
788 $ hg rebase -d 'desc(B2)'
788 $ hg rebase -d 'desc(B2)'
789 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
789 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
790 rebasing 4:212cb178bcbb "C" (tip)
790 rebasing 4:212cb178bcbb "C" (tip)
791
791
792 Even when the chain include missing node
792 Even when the chain include missing node
793
793
794 $ hg up --hidden 'desc(B0)'
794 $ hg up --hidden 'desc(B0)'
795 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
795 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
796 updated to hidden changeset a8b11f55fb19
796 updated to hidden changeset a8b11f55fb19
797 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
797 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
798 $ echo D > D
798 $ echo D > D
799 $ hg add D
799 $ hg add D
800 $ hg commit -m D
800 $ hg commit -m D
801 1 new orphan changesets
801 1 new orphan changesets
802 $ hg --hidden strip -r 'desc(B1)'
802 $ hg --hidden strip -r 'desc(B1)'
803 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg
803 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg
804 1 new orphan changesets
804 1 new orphan changesets
805 $ hg log -G
805 $ hg log -G
806 @ 5:1a79b7535141 D
806 @ 5:1a79b7535141 D
807 |
807 |
808 | o 4:ff2c4d47b71d C
808 | o 4:ff2c4d47b71d C
809 | |
809 | |
810 | o 2:261e70097290 B2
810 | o 2:261e70097290 B2
811 | |
811 | |
812 x | 1:a8b11f55fb19 B0 (rewritten using amend as 2:261e70097290)
812 x | 1:a8b11f55fb19 B0 (rewritten using amend as 2:261e70097290)
813 |/
813 |/
814 o 0:4a2df7238c3b A
814 o 0:4a2df7238c3b A
815
815
816
816
817 $ hg rebase -d 'desc(B2)'
817 $ hg rebase -d 'desc(B2)'
818 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
818 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
819 rebasing 5:1a79b7535141 "D" (tip)
819 rebasing 5:1a79b7535141 "D" (tip)
820 $ hg up 4
820 $ hg up 4
821 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
821 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
822 $ echo "O" > O
822 $ echo "O" > O
823 $ hg add O
823 $ hg add O
824 $ hg commit -m O
824 $ hg commit -m O
825 $ echo "P" > P
825 $ echo "P" > P
826 $ hg add P
826 $ hg add P
827 $ hg commit -m P
827 $ hg commit -m P
828 $ hg log -G
828 $ hg log -G
829 @ 8:8d47583e023f P
829 @ 8:8d47583e023f P
830 |
830 |
831 o 7:360bbaa7d3ce O
831 o 7:360bbaa7d3ce O
832 |
832 |
833 | o 6:9c48361117de D
833 | o 6:9c48361117de D
834 | |
834 | |
835 o | 4:ff2c4d47b71d C
835 o | 4:ff2c4d47b71d C
836 |/
836 |/
837 o 2:261e70097290 B2
837 o 2:261e70097290 B2
838 |
838 |
839 o 0:4a2df7238c3b A
839 o 0:4a2df7238c3b A
840
840
841 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=true
841 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=true
842 1 new obsolescence markers
842 1 new obsolescence markers
843 obsoleted 1 changesets
843 obsoleted 1 changesets
844 1 new orphan changesets
844 1 new orphan changesets
845 $ hg rebase -d 6 -r "4::"
845 $ hg rebase -d 6 -r "4::"
846 rebasing 4:ff2c4d47b71d "C"
846 rebasing 4:ff2c4d47b71d "C"
847 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
847 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
848 rebasing 8:8d47583e023f "P" (tip)
848 rebasing 8:8d47583e023f "P" (tip)
849
849
850 If all the changeset to be rebased are obsolete and present in the destination, we
850 If all the changeset to be rebased are obsolete and present in the destination, we
851 should display a friendly error message
851 should display a friendly error message
852
852
853 $ hg log -G
853 $ hg log -G
854 @ 10:121d9e3bc4c6 P
854 @ 10:121d9e3bc4c6 P
855 |
855 |
856 o 9:4be60e099a77 C
856 o 9:4be60e099a77 C
857 |
857 |
858 o 6:9c48361117de D
858 o 6:9c48361117de D
859 |
859 |
860 o 2:261e70097290 B2
860 o 2:261e70097290 B2
861 |
861 |
862 o 0:4a2df7238c3b A
862 o 0:4a2df7238c3b A
863
863
864
864
865 $ hg up 9
865 $ hg up 9
866 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
866 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
867 $ echo "non-relevant change" > nonrelevant
867 $ echo "non-relevant change" > nonrelevant
868 $ hg add nonrelevant
868 $ hg add nonrelevant
869 $ hg commit -m nonrelevant
869 $ hg commit -m nonrelevant
870 created new head
870 created new head
871 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=true
871 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=true
872 1 new obsolescence markers
872 1 new obsolescence markers
873 obsoleted 1 changesets
873 obsoleted 1 changesets
874 $ hg log -G
874 $ hg log -G
875 @ 11:f44da1f4954c nonrelevant (pruned)
875 @ 11:f44da1f4954c nonrelevant (pruned)
876 |
876 |
877 | o 10:121d9e3bc4c6 P
877 | o 10:121d9e3bc4c6 P
878 |/
878 |/
879 o 9:4be60e099a77 C
879 o 9:4be60e099a77 C
880 |
880 |
881 o 6:9c48361117de D
881 o 6:9c48361117de D
882 |
882 |
883 o 2:261e70097290 B2
883 o 2:261e70097290 B2
884 |
884 |
885 o 0:4a2df7238c3b A
885 o 0:4a2df7238c3b A
886
886
887 $ hg rebase -r . -d 10
887 $ hg rebase -r . -d 10
888 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
888 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
889
889
890 If a rebase is going to create divergence, it should abort
890 If a rebase is going to create divergence, it should abort
891
891
892 $ hg log -G
892 $ hg log -G
893 @ 10:121d9e3bc4c6 P
893 @ 10:121d9e3bc4c6 P
894 |
894 |
895 o 9:4be60e099a77 C
895 o 9:4be60e099a77 C
896 |
896 |
897 o 6:9c48361117de D
897 o 6:9c48361117de D
898 |
898 |
899 o 2:261e70097290 B2
899 o 2:261e70097290 B2
900 |
900 |
901 o 0:4a2df7238c3b A
901 o 0:4a2df7238c3b A
902
902
903
903
904 $ hg up 9
904 $ hg up 9
905 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
905 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
906 $ echo "john" > doe
906 $ echo "john" > doe
907 $ hg add doe
907 $ hg add doe
908 $ hg commit -m "john doe"
908 $ hg commit -m "john doe"
909 created new head
909 created new head
910 $ hg up 10
910 $ hg up 10
911 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
911 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
912 $ echo "foo" > bar
912 $ echo "foo" > bar
913 $ hg add bar
913 $ hg add bar
914 $ hg commit --amend -m "10'"
914 $ hg commit --amend -m "10'"
915 $ hg up 10 --hidden
915 $ hg up 10 --hidden
916 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
916 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
917 updated to hidden changeset 121d9e3bc4c6
917 updated to hidden changeset 121d9e3bc4c6
918 (hidden revision '121d9e3bc4c6' was rewritten as: 77d874d096a2)
918 (hidden revision '121d9e3bc4c6' was rewritten as: 77d874d096a2)
919 $ echo "bar" > foo
919 $ echo "bar" > foo
920 $ hg add foo
920 $ hg add foo
921 $ hg commit -m "bar foo"
921 $ hg commit -m "bar foo"
922 1 new orphan changesets
922 1 new orphan changesets
923 $ hg log -G
923 $ hg log -G
924 @ 14:73568ab6879d bar foo
924 @ 14:73568ab6879d bar foo
925 |
925 |
926 | o 13:77d874d096a2 10'
926 | o 13:77d874d096a2 10'
927 | |
927 | |
928 | | o 12:3eb461388009 john doe
928 | | o 12:3eb461388009 john doe
929 | |/
929 | |/
930 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
930 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
931 |/
931 |/
932 o 9:4be60e099a77 C
932 o 9:4be60e099a77 C
933 |
933 |
934 o 6:9c48361117de D
934 o 6:9c48361117de D
935 |
935 |
936 o 2:261e70097290 B2
936 o 2:261e70097290 B2
937 |
937 |
938 o 0:4a2df7238c3b A
938 o 0:4a2df7238c3b A
939
939
940 $ hg summary
940 $ hg summary
941 parent: 14:73568ab6879d tip (orphan)
941 parent: 14:73568ab6879d tip (orphan)
942 bar foo
942 bar foo
943 branch: default
943 branch: default
944 commit: (clean)
944 commit: (clean)
945 update: 2 new changesets, 3 branch heads (merge)
945 update: 2 new changesets, 3 branch heads (merge)
946 phases: 8 draft
946 phases: 8 draft
947 orphan: 1 changesets
947 orphan: 1 changesets
948 $ hg rebase -s 10 -d 12
948 $ hg rebase -s 10 -d 12
949 abort: this rebase will cause divergences from: 121d9e3bc4c6
949 abort: this rebase will cause divergences from: 121d9e3bc4c6
950 (to force the rebase please set experimental.evolution.allowdivergence=True)
950 (to force the rebase please set experimental.evolution.allowdivergence=True)
951 [255]
951 [255]
952 $ hg log -G
952 $ hg log -G
953 @ 14:73568ab6879d bar foo
953 @ 14:73568ab6879d bar foo
954 |
954 |
955 | o 13:77d874d096a2 10'
955 | o 13:77d874d096a2 10'
956 | |
956 | |
957 | | o 12:3eb461388009 john doe
957 | | o 12:3eb461388009 john doe
958 | |/
958 | |/
959 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
959 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
960 |/
960 |/
961 o 9:4be60e099a77 C
961 o 9:4be60e099a77 C
962 |
962 |
963 o 6:9c48361117de D
963 o 6:9c48361117de D
964 |
964 |
965 o 2:261e70097290 B2
965 o 2:261e70097290 B2
966 |
966 |
967 o 0:4a2df7238c3b A
967 o 0:4a2df7238c3b A
968
968
969 With experimental.evolution.allowdivergence=True, rebase can create divergence
969 With experimental.evolution.allowdivergence=True, rebase can create divergence
970
970
971 $ hg rebase -s 10 -d 12 --config experimental.evolution.allowdivergence=True
971 $ hg rebase -s 10 -d 12 --config experimental.evolution.allowdivergence=True
972 rebasing 10:121d9e3bc4c6 "P"
972 rebasing 10:121d9e3bc4c6 "P"
973 rebasing 14:73568ab6879d "bar foo" (tip)
973 rebasing 14:73568ab6879d "bar foo" (tip)
974 2 new content-divergent changesets
974 2 new content-divergent changesets
975 $ hg summary
975 $ hg summary
976 parent: 16:61bd55f69bc4 tip
976 parent: 16:61bd55f69bc4 tip
977 bar foo
977 bar foo
978 branch: default
978 branch: default
979 commit: (clean)
979 commit: (clean)
980 update: 1 new changesets, 2 branch heads (merge)
980 update: 1 new changesets, 2 branch heads (merge)
981 phases: 8 draft
981 phases: 8 draft
982 content-divergent: 2 changesets
982 content-divergent: 2 changesets
983
983
984 rebase --continue + skipped rev because their successors are in destination
984 rebase --continue + skipped rev because their successors are in destination
985 we make a change in trunk and work on conflicting changes to make rebase abort.
985 we make a change in trunk and work on conflicting changes to make rebase abort.
986
986
987 $ hg log -G -r 16::
987 $ hg log -G -r 16::
988 @ 16:61bd55f69bc4 bar foo
988 @ 16:61bd55f69bc4 bar foo
989 |
989 |
990 ~
990 ~
991
991
992 Create the two changes in trunk
992 Create the two changes in trunk
993 $ printf "a" > willconflict
993 $ printf "a" > willconflict
994 $ hg add willconflict
994 $ hg add willconflict
995 $ hg commit -m "willconflict first version"
995 $ hg commit -m "willconflict first version"
996
996
997 $ printf "dummy" > C
997 $ printf "dummy" > C
998 $ hg commit -m "dummy change successor"
998 $ hg commit -m "dummy change successor"
999
999
1000 Create the changes that we will rebase
1000 Create the changes that we will rebase
1001 $ hg update -C 16 -q
1001 $ hg update -C 16 -q
1002 $ printf "b" > willconflict
1002 $ printf "b" > willconflict
1003 $ hg add willconflict
1003 $ hg add willconflict
1004 $ hg commit -m "willconflict second version"
1004 $ hg commit -m "willconflict second version"
1005 created new head
1005 created new head
1006 $ printf "dummy" > K
1006 $ printf "dummy" > K
1007 $ hg add K
1007 $ hg add K
1008 $ hg commit -m "dummy change"
1008 $ hg commit -m "dummy change"
1009 $ printf "dummy" > L
1009 $ printf "dummy" > L
1010 $ hg add L
1010 $ hg add L
1011 $ hg commit -m "dummy change"
1011 $ hg commit -m "dummy change"
1012 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 18 -T '{node}'` --config experimental.evolution=true
1012 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 18 -T '{node}'` --config experimental.evolution=true
1013 1 new obsolescence markers
1013 1 new obsolescence markers
1014 obsoleted 1 changesets
1014 obsoleted 1 changesets
1015 1 new orphan changesets
1015 1 new orphan changesets
1016
1016
1017 $ hg log -G -r 16::
1017 $ hg log -G -r 16::
1018 @ 21:7bdc8a87673d dummy change
1018 @ 21:7bdc8a87673d dummy change
1019 |
1019 |
1020 x 20:8b31da3c4919 dummy change (rewritten as 18:601db7a18f51)
1020 x 20:8b31da3c4919 dummy change (rewritten as 18:601db7a18f51)
1021 |
1021 |
1022 o 19:b82fb57ea638 willconflict second version
1022 o 19:b82fb57ea638 willconflict second version
1023 |
1023 |
1024 | o 18:601db7a18f51 dummy change successor
1024 | o 18:601db7a18f51 dummy change successor
1025 | |
1025 | |
1026 | o 17:357ddf1602d5 willconflict first version
1026 | o 17:357ddf1602d5 willconflict first version
1027 |/
1027 |/
1028 o 16:61bd55f69bc4 bar foo
1028 o 16:61bd55f69bc4 bar foo
1029 |
1029 |
1030 ~
1030 ~
1031 $ hg rebase -r ".^^ + .^ + ." -d 18
1031 $ hg rebase -r ".^^ + .^ + ." -d 18
1032 rebasing 19:b82fb57ea638 "willconflict second version"
1032 rebasing 19:b82fb57ea638 "willconflict second version"
1033 merging willconflict
1033 merging willconflict
1034 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
1034 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
1035 unresolved conflicts (see hg resolve, then hg rebase --continue)
1035 unresolved conflicts (see hg resolve, then hg rebase --continue)
1036 [1]
1036 [1]
1037
1037
1038 $ hg resolve --mark willconflict
1038 $ hg resolve --mark willconflict
1039 (no more unresolved files)
1039 (no more unresolved files)
1040 continue: hg rebase --continue
1040 continue: hg rebase --continue
1041 $ hg rebase --continue
1041 $ hg rebase --continue
1042 rebasing 19:b82fb57ea638 "willconflict second version"
1042 rebasing 19:b82fb57ea638 "willconflict second version"
1043 note: not rebasing 20:8b31da3c4919 "dummy change", already in destination as 18:601db7a18f51 "dummy change successor"
1043 note: not rebasing 20:8b31da3c4919 "dummy change", already in destination as 18:601db7a18f51 "dummy change successor"
1044 rebasing 21:7bdc8a87673d "dummy change" (tip)
1044 rebasing 21:7bdc8a87673d "dummy change" (tip)
1045 $ cd ..
1045 $ cd ..
1046
1046
1047 Divergence cases due to obsolete changesets
1047 Divergence cases due to obsolete changesets
1048 -------------------------------------------
1048 -------------------------------------------
1049
1049
1050 We should ignore branches with unstable changesets when they are based on an
1050 We should ignore branches with unstable changesets when they are based on an
1051 obsolete changeset which successor is in rebase set.
1051 obsolete changeset which successor is in rebase set.
1052
1052
1053 $ hg init divergence
1053 $ hg init divergence
1054 $ cd divergence
1054 $ cd divergence
1055 $ cat >> .hg/hgrc << EOF
1055 $ cat >> .hg/hgrc << EOF
1056 > [extensions]
1056 > [extensions]
1057 > strip =
1057 > strip =
1058 > [alias]
1058 > [alias]
1059 > strip = strip --no-backup --quiet
1059 > strip = strip --no-backup --quiet
1060 > [templates]
1060 > [templates]
1061 > instabilities = '{rev}:{node|short} {desc|firstline}{if(instabilities," ({instabilities})")}\n'
1061 > instabilities = '{rev}:{node|short} {desc|firstline}{if(instabilities," ({instabilities})")}\n'
1062 > EOF
1062 > EOF
1063
1063
1064 $ hg debugdrawdag <<EOF
1064 $ hg debugdrawdag <<EOF
1065 > e f
1065 > e f
1066 > | |
1066 > | |
1067 > d' d # replace: d -> d'
1067 > d' d # replace: d -> d'
1068 > \ /
1068 > \ /
1069 > c
1069 > c
1070 > |
1070 > |
1071 > x b
1071 > x b
1072 > \|
1072 > \|
1073 > a
1073 > a
1074 > EOF
1074 > EOF
1075 1 new orphan changesets
1075 1 new orphan changesets
1076 $ hg log -G -r 'a'::
1076 $ hg log -G -r 'a'::
1077 * 7:1143e9adc121 f
1077 * 7:1143e9adc121 f
1078 |
1078 |
1079 | o 6:d60ebfa0f1cb e
1079 | o 6:d60ebfa0f1cb e
1080 | |
1080 | |
1081 | o 5:027ad6c5830d d'
1081 | o 5:027ad6c5830d d'
1082 | |
1082 | |
1083 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1083 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1084 |/
1084 |/
1085 o 3:a82ac2b38757 c
1085 o 3:a82ac2b38757 c
1086 |
1086 |
1087 | o 2:630d7c95eff7 x
1087 | o 2:630d7c95eff7 x
1088 | |
1088 | |
1089 o | 1:488e1b7e7341 b
1089 o | 1:488e1b7e7341 b
1090 |/
1090 |/
1091 o 0:b173517d0057 a
1091 o 0:b173517d0057 a
1092
1092
1093
1093
1094 Changeset d and its descendants are excluded to avoid divergence of d, which
1094 Changeset d and its descendants are excluded to avoid divergence of d, which
1095 would occur because the successor of d (d') is also in rebaseset. As a
1095 would occur because the successor of d (d') is also in rebaseset. As a
1096 consequence f (descendant of d) is left behind.
1096 consequence f (descendant of d) is left behind.
1097
1097
1098 $ hg rebase -b 'e' -d 'x'
1098 $ hg rebase -b 'e' -d 'x'
1099 rebasing 1:488e1b7e7341 "b" (b)
1099 rebasing 1:488e1b7e7341 "b" (b)
1100 rebasing 3:a82ac2b38757 "c" (c)
1100 rebasing 3:a82ac2b38757 "c" (c)
1101 rebasing 5:027ad6c5830d "d'" (d')
1101 rebasing 5:027ad6c5830d "d'" (d')
1102 rebasing 6:d60ebfa0f1cb "e" (e)
1102 rebasing 6:d60ebfa0f1cb "e" (e)
1103 note: not rebasing 4:76be324c128b "d" (d) and its descendants as this would cause divergence
1103 note: not rebasing 4:76be324c128b "d" (d) and its descendants as this would cause divergence
1104 $ hg log -G -r 'a'::
1104 $ hg log -G -r 'a'::
1105 o 11:eb6d63fc4ed5 e
1105 o 11:eb6d63fc4ed5 e
1106 |
1106 |
1107 o 10:44d8c724a70c d'
1107 o 10:44d8c724a70c d'
1108 |
1108 |
1109 o 9:d008e6b4d3fd c
1109 o 9:d008e6b4d3fd c
1110 |
1110 |
1111 o 8:67e8f4a16c49 b
1111 o 8:67e8f4a16c49 b
1112 |
1112 |
1113 | * 7:1143e9adc121 f
1113 | * 7:1143e9adc121 f
1114 | |
1114 | |
1115 | | x 6:d60ebfa0f1cb e (rewritten using rebase as 11:eb6d63fc4ed5)
1115 | | x 6:d60ebfa0f1cb e (rewritten using rebase as 11:eb6d63fc4ed5)
1116 | | |
1116 | | |
1117 | | x 5:027ad6c5830d d' (rewritten using rebase as 10:44d8c724a70c)
1117 | | x 5:027ad6c5830d d' (rewritten using rebase as 10:44d8c724a70c)
1118 | | |
1118 | | |
1119 | x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1119 | x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1120 | |/
1120 | |/
1121 | x 3:a82ac2b38757 c (rewritten using rebase as 9:d008e6b4d3fd)
1121 | x 3:a82ac2b38757 c (rewritten using rebase as 9:d008e6b4d3fd)
1122 | |
1122 | |
1123 o | 2:630d7c95eff7 x
1123 o | 2:630d7c95eff7 x
1124 | |
1124 | |
1125 | x 1:488e1b7e7341 b (rewritten using rebase as 8:67e8f4a16c49)
1125 | x 1:488e1b7e7341 b (rewritten using rebase as 8:67e8f4a16c49)
1126 |/
1126 |/
1127 o 0:b173517d0057 a
1127 o 0:b173517d0057 a
1128
1128
1129 $ hg strip -r 8:
1129 $ hg strip -r 8:
1130 $ hg log -G -r 'a'::
1130 $ hg log -G -r 'a'::
1131 * 7:1143e9adc121 f
1131 * 7:1143e9adc121 f
1132 |
1132 |
1133 | o 6:d60ebfa0f1cb e
1133 | o 6:d60ebfa0f1cb e
1134 | |
1134 | |
1135 | o 5:027ad6c5830d d'
1135 | o 5:027ad6c5830d d'
1136 | |
1136 | |
1137 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1137 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1138 |/
1138 |/
1139 o 3:a82ac2b38757 c
1139 o 3:a82ac2b38757 c
1140 |
1140 |
1141 | o 2:630d7c95eff7 x
1141 | o 2:630d7c95eff7 x
1142 | |
1142 | |
1143 o | 1:488e1b7e7341 b
1143 o | 1:488e1b7e7341 b
1144 |/
1144 |/
1145 o 0:b173517d0057 a
1145 o 0:b173517d0057 a
1146
1146
1147
1147
1148 If the rebase set has an obsolete (d) with a successor (d') outside the rebase
1148 If the rebase set has an obsolete (d) with a successor (d') outside the rebase
1149 set and none in destination, we still get the divergence warning.
1149 set and none in destination, we still get the divergence warning.
1150 By allowing divergence, we can perform the rebase.
1150 By allowing divergence, we can perform the rebase.
1151
1151
1152 $ hg rebase -r 'c'::'f' -d 'x'
1152 $ hg rebase -r 'c'::'f' -d 'x'
1153 abort: this rebase will cause divergences from: 76be324c128b
1153 abort: this rebase will cause divergences from: 76be324c128b
1154 (to force the rebase please set experimental.evolution.allowdivergence=True)
1154 (to force the rebase please set experimental.evolution.allowdivergence=True)
1155 [255]
1155 [255]
1156 $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
1156 $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
1157 rebasing 3:a82ac2b38757 "c" (c)
1157 rebasing 3:a82ac2b38757 "c" (c)
1158 rebasing 4:76be324c128b "d" (d)
1158 rebasing 4:76be324c128b "d" (d)
1159 rebasing 7:1143e9adc121 "f" (f tip)
1159 rebasing 7:1143e9adc121 "f" (f tip)
1160 1 new orphan changesets
1160 1 new orphan changesets
1161 2 new content-divergent changesets
1161 2 new content-divergent changesets
1162 $ hg log -G -r 'a':: -T instabilities
1162 $ hg log -G -r 'a':: -T instabilities
1163 o 10:e1744ea07510 f
1163 o 10:e1744ea07510 f
1164 |
1164 |
1165 * 9:e2b36ea9a0a0 d (content-divergent)
1165 * 9:e2b36ea9a0a0 d (content-divergent)
1166 |
1166 |
1167 o 8:6a0376de376e c
1167 o 8:6a0376de376e c
1168 |
1168 |
1169 | x 7:1143e9adc121 f
1169 | x 7:1143e9adc121 f
1170 | |
1170 | |
1171 | | * 6:d60ebfa0f1cb e (orphan)
1171 | | * 6:d60ebfa0f1cb e (orphan)
1172 | | |
1172 | | |
1173 | | * 5:027ad6c5830d d' (orphan content-divergent)
1173 | | * 5:027ad6c5830d d' (orphan content-divergent)
1174 | | |
1174 | | |
1175 | x | 4:76be324c128b d
1175 | x | 4:76be324c128b d
1176 | |/
1176 | |/
1177 | x 3:a82ac2b38757 c
1177 | x 3:a82ac2b38757 c
1178 | |
1178 | |
1179 o | 2:630d7c95eff7 x
1179 o | 2:630d7c95eff7 x
1180 | |
1180 | |
1181 | o 1:488e1b7e7341 b
1181 | o 1:488e1b7e7341 b
1182 |/
1182 |/
1183 o 0:b173517d0057 a
1183 o 0:b173517d0057 a
1184
1184
1185 $ hg strip -r 8:
1185 $ hg strip -r 8:
1186
1186
1187 (Not skipping obsoletes means that divergence is allowed.)
1187 (Not skipping obsoletes means that divergence is allowed.)
1188
1188
1189 $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
1189 $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
1190 rebasing 3:a82ac2b38757 "c" (c)
1190 rebasing 3:a82ac2b38757 "c" (c)
1191 rebasing 4:76be324c128b "d" (d)
1191 rebasing 4:76be324c128b "d" (d)
1192 rebasing 7:1143e9adc121 "f" (f tip)
1192 rebasing 7:1143e9adc121 "f" (f tip)
1193 1 new orphan changesets
1193 1 new orphan changesets
1194 2 new content-divergent changesets
1194 2 new content-divergent changesets
1195
1195
1196 $ hg strip -r 0:
1196 $ hg strip -r 0:
1197
1197
1198 Similar test on a more complex graph
1198 Similar test on a more complex graph
1199
1199
1200 $ hg debugdrawdag <<EOF
1200 $ hg debugdrawdag <<EOF
1201 > g
1201 > g
1202 > |
1202 > |
1203 > f e
1203 > f e
1204 > | |
1204 > | |
1205 > e' d # replace: e -> e'
1205 > e' d # replace: e -> e'
1206 > \ /
1206 > \ /
1207 > c
1207 > c
1208 > |
1208 > |
1209 > x b
1209 > x b
1210 > \|
1210 > \|
1211 > a
1211 > a
1212 > EOF
1212 > EOF
1213 1 new orphan changesets
1213 1 new orphan changesets
1214 $ hg log -G -r 'a':
1214 $ hg log -G -r 'a':
1215 * 8:2876ce66c6eb g
1215 * 8:2876ce66c6eb g
1216 |
1216 |
1217 | o 7:3ffec603ab53 f
1217 | o 7:3ffec603ab53 f
1218 | |
1218 | |
1219 x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1219 x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1220 | |
1220 | |
1221 | o 5:63324dc512ea e'
1221 | o 5:63324dc512ea e'
1222 | |
1222 | |
1223 o | 4:76be324c128b d
1223 o | 4:76be324c128b d
1224 |/
1224 |/
1225 o 3:a82ac2b38757 c
1225 o 3:a82ac2b38757 c
1226 |
1226 |
1227 | o 2:630d7c95eff7 x
1227 | o 2:630d7c95eff7 x
1228 | |
1228 | |
1229 o | 1:488e1b7e7341 b
1229 o | 1:488e1b7e7341 b
1230 |/
1230 |/
1231 o 0:b173517d0057 a
1231 o 0:b173517d0057 a
1232
1232
1233 $ hg rebase -b 'f' -d 'x'
1233 $ hg rebase -b 'f' -d 'x'
1234 rebasing 1:488e1b7e7341 "b" (b)
1234 rebasing 1:488e1b7e7341 "b" (b)
1235 rebasing 3:a82ac2b38757 "c" (c)
1235 rebasing 3:a82ac2b38757 "c" (c)
1236 rebasing 5:63324dc512ea "e'" (e')
1236 rebasing 5:63324dc512ea "e'" (e')
1237 rebasing 7:3ffec603ab53 "f" (f)
1237 rebasing 7:3ffec603ab53 "f" (f)
1238 rebasing 4:76be324c128b "d" (d)
1238 rebasing 4:76be324c128b "d" (d)
1239 note: not rebasing 6:e36fae928aec "e" (e) and its descendants as this would cause divergence
1239 note: not rebasing 6:e36fae928aec "e" (e) and its descendants as this would cause divergence
1240 $ hg log -G -r 'a':
1240 $ hg log -G -r 'a':
1241 o 13:a1707a5b7c2c d
1241 o 13:a1707a5b7c2c d
1242 |
1242 |
1243 | o 12:ef6251596616 f
1243 | o 12:ef6251596616 f
1244 | |
1244 | |
1245 | o 11:b6f172e64af9 e'
1245 | o 11:b6f172e64af9 e'
1246 |/
1246 |/
1247 o 10:d008e6b4d3fd c
1247 o 10:d008e6b4d3fd c
1248 |
1248 |
1249 o 9:67e8f4a16c49 b
1249 o 9:67e8f4a16c49 b
1250 |
1250 |
1251 | * 8:2876ce66c6eb g
1251 | * 8:2876ce66c6eb g
1252 | |
1252 | |
1253 | | x 7:3ffec603ab53 f (rewritten using rebase as 12:ef6251596616)
1253 | | x 7:3ffec603ab53 f (rewritten using rebase as 12:ef6251596616)
1254 | | |
1254 | | |
1255 | x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1255 | x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1256 | | |
1256 | | |
1257 | | x 5:63324dc512ea e' (rewritten using rebase as 11:b6f172e64af9)
1257 | | x 5:63324dc512ea e' (rewritten using rebase as 11:b6f172e64af9)
1258 | | |
1258 | | |
1259 | x | 4:76be324c128b d (rewritten using rebase as 13:a1707a5b7c2c)
1259 | x | 4:76be324c128b d (rewritten using rebase as 13:a1707a5b7c2c)
1260 | |/
1260 | |/
1261 | x 3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
1261 | x 3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
1262 | |
1262 | |
1263 o | 2:630d7c95eff7 x
1263 o | 2:630d7c95eff7 x
1264 | |
1264 | |
1265 | x 1:488e1b7e7341 b (rewritten using rebase as 9:67e8f4a16c49)
1265 | x 1:488e1b7e7341 b (rewritten using rebase as 9:67e8f4a16c49)
1266 |/
1266 |/
1267 o 0:b173517d0057 a
1267 o 0:b173517d0057 a
1268
1268
1269
1269
1270 issue5782
1270 issue5782
1271 $ hg strip -r 0:
1271 $ hg strip -r 0:
1272 $ hg debugdrawdag <<EOF
1272 $ hg debugdrawdag <<EOF
1273 > d
1273 > d
1274 > |
1274 > |
1275 > c1 c # replace: c -> c1
1275 > c1 c # replace: c -> c1
1276 > \ /
1276 > \ /
1277 > b
1277 > b
1278 > |
1278 > |
1279 > a
1279 > a
1280 > EOF
1280 > EOF
1281 1 new orphan changesets
1281 1 new orphan changesets
1282 $ hg debugobsolete `hg log -T "{node}" --hidden -r 'desc("c1")'`
1282 $ hg debugobsolete `hg log -T "{node}" --hidden -r 'desc("c1")'`
1283 1 new obsolescence markers
1283 1 new obsolescence markers
1284 obsoleted 1 changesets
1284 obsoleted 1 changesets
1285 $ hg log -G -r 'a': --hidden
1285 $ hg log -G -r 'a': --hidden
1286 * 4:76be324c128b d
1286 * 4:76be324c128b d
1287 |
1287 |
1288 | x 3:ef8a456de8fa c1 (pruned)
1288 | x 3:ef8a456de8fa c1 (pruned)
1289 | |
1289 | |
1290 x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
1290 x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
1291 |/
1291 |/
1292 o 1:488e1b7e7341 b
1292 o 1:488e1b7e7341 b
1293 |
1293 |
1294 o 0:b173517d0057 a
1294 o 0:b173517d0057 a
1295
1295
1296 $ hg rebase -d 0 -r 2
1296 $ hg rebase -d 0 -r 2
1297 rebasing 2:a82ac2b38757 "c" (c)
1297 rebasing 2:a82ac2b38757 "c" (c)
1298 $ hg log -G -r 'a': --hidden
1298 $ hg log -G -r 'a': --hidden
1299 o 5:69ad416a4a26 c
1299 o 5:69ad416a4a26 c
1300 |
1300 |
1301 | * 4:76be324c128b d
1301 | * 4:76be324c128b d
1302 | |
1302 | |
1303 | | x 3:ef8a456de8fa c1 (pruned)
1303 | | x 3:ef8a456de8fa c1 (pruned)
1304 | | |
1304 | | |
1305 | x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa rewritten using rebase as 5:69ad416a4a26)
1305 | x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa rewritten using rebase as 5:69ad416a4a26)
1306 | |/
1306 | |/
1307 | o 1:488e1b7e7341 b
1307 | o 1:488e1b7e7341 b
1308 |/
1308 |/
1309 o 0:b173517d0057 a
1309 o 0:b173517d0057 a
1310
1310
1311 $ cd ..
1311 $ cd ..
1312
1312
1313 Rebase merge where successor of one parent is equal to destination (issue5198)
1313 Rebase merge where successor of one parent is equal to destination (issue5198)
1314
1314
1315 $ hg init p1-succ-is-dest
1315 $ hg init p1-succ-is-dest
1316 $ cd p1-succ-is-dest
1316 $ cd p1-succ-is-dest
1317
1317
1318 $ hg debugdrawdag <<EOF
1318 $ hg debugdrawdag <<EOF
1319 > F
1319 > F
1320 > /|
1320 > /|
1321 > E D B # replace: D -> B
1321 > E D B # replace: D -> B
1322 > \|/
1322 > \|/
1323 > A
1323 > A
1324 > EOF
1324 > EOF
1325 1 new orphan changesets
1325 1 new orphan changesets
1326
1326
1327 $ hg rebase -d B -s D
1327 $ hg rebase -d B -s D
1328 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1328 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1329 rebasing 4:66f1a38021c9 "F" (F tip)
1329 rebasing 4:66f1a38021c9 "F" (F tip)
1330 $ hg log -G
1330 $ hg log -G
1331 o 5:50e9d60b99c6 F
1331 o 5:50e9d60b99c6 F
1332 |\
1332 |\
1333 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:50e9d60b99c6)
1333 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:50e9d60b99c6)
1334 | |/|
1334 | |/|
1335 | o | 3:7fb047a69f22 E
1335 | o | 3:7fb047a69f22 E
1336 | | |
1336 | | |
1337 | | x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1337 | | x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1338 | |/
1338 | |/
1339 o | 1:112478962961 B
1339 o | 1:112478962961 B
1340 |/
1340 |/
1341 o 0:426bada5c675 A
1341 o 0:426bada5c675 A
1342
1342
1343 $ cd ..
1343 $ cd ..
1344
1344
1345 Rebase merge where successor of other parent is equal to destination
1345 Rebase merge where successor of other parent is equal to destination
1346
1346
1347 $ hg init p2-succ-is-dest
1347 $ hg init p2-succ-is-dest
1348 $ cd p2-succ-is-dest
1348 $ cd p2-succ-is-dest
1349
1349
1350 $ hg debugdrawdag <<EOF
1350 $ hg debugdrawdag <<EOF
1351 > F
1351 > F
1352 > /|
1352 > /|
1353 > E D B # replace: E -> B
1353 > E D B # replace: E -> B
1354 > \|/
1354 > \|/
1355 > A
1355 > A
1356 > EOF
1356 > EOF
1357 1 new orphan changesets
1357 1 new orphan changesets
1358
1358
1359 $ hg rebase -d B -s E
1359 $ hg rebase -d B -s E
1360 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1360 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1361 rebasing 4:66f1a38021c9 "F" (F tip)
1361 rebasing 4:66f1a38021c9 "F" (F tip)
1362 $ hg log -G
1362 $ hg log -G
1363 o 5:aae1787dacee F
1363 o 5:aae1787dacee F
1364 |\
1364 |\
1365 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:aae1787dacee)
1365 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:aae1787dacee)
1366 | |/|
1366 | |/|
1367 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1367 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1368 | | |
1368 | | |
1369 | o | 2:b18e25de2cf5 D
1369 | o | 2:b18e25de2cf5 D
1370 | |/
1370 | |/
1371 o / 1:112478962961 B
1371 o / 1:112478962961 B
1372 |/
1372 |/
1373 o 0:426bada5c675 A
1373 o 0:426bada5c675 A
1374
1374
1375 $ cd ..
1375 $ cd ..
1376
1376
1377 Rebase merge where successor of one parent is ancestor of destination
1377 Rebase merge where successor of one parent is ancestor of destination
1378
1378
1379 $ hg init p1-succ-in-dest
1379 $ hg init p1-succ-in-dest
1380 $ cd p1-succ-in-dest
1380 $ cd p1-succ-in-dest
1381
1381
1382 $ hg debugdrawdag <<EOF
1382 $ hg debugdrawdag <<EOF
1383 > F C
1383 > F C
1384 > /| |
1384 > /| |
1385 > E D B # replace: D -> B
1385 > E D B # replace: D -> B
1386 > \|/
1386 > \|/
1387 > A
1387 > A
1388 > EOF
1388 > EOF
1389 1 new orphan changesets
1389 1 new orphan changesets
1390
1390
1391 $ hg rebase -d C -s D
1391 $ hg rebase -d C -s D
1392 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1392 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1393 rebasing 5:66f1a38021c9 "F" (F tip)
1393 rebasing 5:66f1a38021c9 "F" (F tip)
1394
1394
1395 $ hg log -G
1395 $ hg log -G
1396 o 6:0913febf6439 F
1396 o 6:0913febf6439 F
1397 |\
1397 |\
1398 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:0913febf6439)
1398 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:0913febf6439)
1399 | | |
1399 | | |
1400 | o | 4:26805aba1e60 C
1400 | o | 4:26805aba1e60 C
1401 | | |
1401 | | |
1402 o | | 3:7fb047a69f22 E
1402 o | | 3:7fb047a69f22 E
1403 | | |
1403 | | |
1404 +---x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1404 +---x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1405 | |
1405 | |
1406 | o 1:112478962961 B
1406 | o 1:112478962961 B
1407 |/
1407 |/
1408 o 0:426bada5c675 A
1408 o 0:426bada5c675 A
1409
1409
1410 $ cd ..
1410 $ cd ..
1411
1411
1412 Rebase merge where successor of other parent is ancestor of destination
1412 Rebase merge where successor of other parent is ancestor of destination
1413
1413
1414 $ hg init p2-succ-in-dest
1414 $ hg init p2-succ-in-dest
1415 $ cd p2-succ-in-dest
1415 $ cd p2-succ-in-dest
1416
1416
1417 $ hg debugdrawdag <<EOF
1417 $ hg debugdrawdag <<EOF
1418 > F C
1418 > F C
1419 > /| |
1419 > /| |
1420 > E D B # replace: E -> B
1420 > E D B # replace: E -> B
1421 > \|/
1421 > \|/
1422 > A
1422 > A
1423 > EOF
1423 > EOF
1424 1 new orphan changesets
1424 1 new orphan changesets
1425
1425
1426 $ hg rebase -d C -s E
1426 $ hg rebase -d C -s E
1427 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1427 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1428 rebasing 5:66f1a38021c9 "F" (F tip)
1428 rebasing 5:66f1a38021c9 "F" (F tip)
1429 $ hg log -G
1429 $ hg log -G
1430 o 6:c6ab0cc6d220 F
1430 o 6:c6ab0cc6d220 F
1431 |\
1431 |\
1432 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:c6ab0cc6d220)
1432 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:c6ab0cc6d220)
1433 | | |
1433 | | |
1434 | o | 4:26805aba1e60 C
1434 | o | 4:26805aba1e60 C
1435 | | |
1435 | | |
1436 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1436 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1437 | | |
1437 | | |
1438 o---+ 2:b18e25de2cf5 D
1438 o---+ 2:b18e25de2cf5 D
1439 / /
1439 / /
1440 o / 1:112478962961 B
1440 o / 1:112478962961 B
1441 |/
1441 |/
1442 o 0:426bada5c675 A
1442 o 0:426bada5c675 A
1443
1443
1444 $ cd ..
1444 $ cd ..
1445
1445
1446 Rebase merge where successor of one parent is ancestor of destination
1446 Rebase merge where successor of one parent is ancestor of destination
1447
1447
1448 $ hg init p1-succ-in-dest-b
1448 $ hg init p1-succ-in-dest-b
1449 $ cd p1-succ-in-dest-b
1449 $ cd p1-succ-in-dest-b
1450
1450
1451 $ hg debugdrawdag <<EOF
1451 $ hg debugdrawdag <<EOF
1452 > F C
1452 > F C
1453 > /| |
1453 > /| |
1454 > E D B # replace: E -> B
1454 > E D B # replace: E -> B
1455 > \|/
1455 > \|/
1456 > A
1456 > A
1457 > EOF
1457 > EOF
1458 1 new orphan changesets
1458 1 new orphan changesets
1459
1459
1460 $ hg rebase -d C -b F
1460 $ hg rebase -d C -b F
1461 rebasing 2:b18e25de2cf5 "D" (D)
1461 rebasing 2:b18e25de2cf5 "D" (D)
1462 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1462 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1463 rebasing 5:66f1a38021c9 "F" (F tip)
1463 rebasing 5:66f1a38021c9 "F" (F tip)
1464 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1464 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1465 $ hg log -G
1465 $ hg log -G
1466 o 6:8f47515dda15 D
1466 o 6:8f47515dda15 D
1467 |
1467 |
1468 | x 5:66f1a38021c9 F (pruned using rebase)
1468 | x 5:66f1a38021c9 F (pruned using rebase)
1469 | |\
1469 | |\
1470 o | | 4:26805aba1e60 C
1470 o | | 4:26805aba1e60 C
1471 | | |
1471 | | |
1472 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1472 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1473 | | |
1473 | | |
1474 | x | 2:b18e25de2cf5 D (rewritten using rebase as 6:8f47515dda15)
1474 | x | 2:b18e25de2cf5 D (rewritten using rebase as 6:8f47515dda15)
1475 | |/
1475 | |/
1476 o / 1:112478962961 B
1476 o / 1:112478962961 B
1477 |/
1477 |/
1478 o 0:426bada5c675 A
1478 o 0:426bada5c675 A
1479
1479
1480 $ cd ..
1480 $ cd ..
1481
1481
1482 Rebase merge where successor of other parent is ancestor of destination
1482 Rebase merge where successor of other parent is ancestor of destination
1483
1483
1484 $ hg init p2-succ-in-dest-b
1484 $ hg init p2-succ-in-dest-b
1485 $ cd p2-succ-in-dest-b
1485 $ cd p2-succ-in-dest-b
1486
1486
1487 $ hg debugdrawdag <<EOF
1487 $ hg debugdrawdag <<EOF
1488 > F C
1488 > F C
1489 > /| |
1489 > /| |
1490 > E D B # replace: D -> B
1490 > E D B # replace: D -> B
1491 > \|/
1491 > \|/
1492 > A
1492 > A
1493 > EOF
1493 > EOF
1494 1 new orphan changesets
1494 1 new orphan changesets
1495
1495
1496 $ hg rebase -d C -b F
1496 $ hg rebase -d C -b F
1497 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1497 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1498 rebasing 3:7fb047a69f22 "E" (E)
1498 rebasing 3:7fb047a69f22 "E" (E)
1499 rebasing 5:66f1a38021c9 "F" (F tip)
1499 rebasing 5:66f1a38021c9 "F" (F tip)
1500 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1500 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1501
1501
1502 $ hg log -G
1502 $ hg log -G
1503 o 6:533690786a86 E
1503 o 6:533690786a86 E
1504 |
1504 |
1505 | x 5:66f1a38021c9 F (pruned using rebase)
1505 | x 5:66f1a38021c9 F (pruned using rebase)
1506 | |\
1506 | |\
1507 o | | 4:26805aba1e60 C
1507 o | | 4:26805aba1e60 C
1508 | | |
1508 | | |
1509 | | x 3:7fb047a69f22 E (rewritten using rebase as 6:533690786a86)
1509 | | x 3:7fb047a69f22 E (rewritten using rebase as 6:533690786a86)
1510 | | |
1510 | | |
1511 | x | 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1511 | x | 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1512 | |/
1512 | |/
1513 o / 1:112478962961 B
1513 o / 1:112478962961 B
1514 |/
1514 |/
1515 o 0:426bada5c675 A
1515 o 0:426bada5c675 A
1516
1516
1517 $ cd ..
1517 $ cd ..
1518
1518
1519 Rebase merge where extinct node has successor that is not an ancestor of
1519 Rebase merge where extinct node has successor that is not an ancestor of
1520 destination
1520 destination
1521
1521
1522 $ hg init extinct-with-succ-not-in-dest
1522 $ hg init extinct-with-succ-not-in-dest
1523 $ cd extinct-with-succ-not-in-dest
1523 $ cd extinct-with-succ-not-in-dest
1524
1524
1525 $ hg debugdrawdag <<EOF
1525 $ hg debugdrawdag <<EOF
1526 > E C # replace: C -> E
1526 > E C # replace: C -> E
1527 > | |
1527 > | |
1528 > D B
1528 > D B
1529 > |/
1529 > |/
1530 > A
1530 > A
1531 > EOF
1531 > EOF
1532
1532
1533 $ hg rebase -d D -s B
1533 $ hg rebase -d D -s B
1534 rebasing 1:112478962961 "B" (B)
1534 rebasing 1:112478962961 "B" (B)
1535 note: not rebasing 3:26805aba1e60 "C" (C) and its descendants as this would cause divergence
1535 note: not rebasing 3:26805aba1e60 "C" (C) and its descendants as this would cause divergence
1536
1536
1537 $ cd ..
1537 $ cd ..
1538
1538
1539 $ hg init p2-succ-in-dest-c
1539 $ hg init p2-succ-in-dest-c
1540 $ cd p2-succ-in-dest-c
1540 $ cd p2-succ-in-dest-c
1541
1541
1542 The scenario here was that B::D were developed on default. B was queued on
1542 The scenario here was that B::D were developed on default. B was queued on
1543 stable, but amended before being push to hg-committed. C was queued on default,
1543 stable, but amended before being push to hg-committed. C was queued on default,
1544 along with unrelated J.
1544 along with unrelated J.
1545
1545
1546 $ hg debugdrawdag <<EOF
1546 $ hg debugdrawdag <<EOF
1547 > J
1547 > J
1548 > |
1548 > |
1549 > F
1549 > F
1550 > |
1550 > |
1551 > E
1551 > E
1552 > | D
1552 > | D
1553 > | |
1553 > | |
1554 > | C # replace: C -> F
1554 > | C # replace: C -> F
1555 > | | H I # replace: B -> H -> I
1555 > | | H I # replace: B -> H -> I
1556 > | B |/
1556 > | B |/
1557 > |/ G
1557 > |/ G
1558 > A
1558 > A
1559 > EOF
1559 > EOF
1560 1 new orphan changesets
1560 1 new orphan changesets
1561
1561
1562 This strip seems to be the key to avoid an early divergence warning.
1562 This strip seems to be the key to avoid an early divergence warning.
1563 $ hg --config extensions.strip= --hidden strip -qr H
1563 $ hg --config extensions.strip= --hidden strip -qr H
1564 1 new orphan changesets
1564 1 new orphan changesets
1565
1565
1566 $ hg rebase -b 'desc("D")' -d 'desc("J")'
1566 $ hg rebase -b 'desc("D")' -d 'desc("J")'
1567 abort: this rebase will cause divergences from: 112478962961
1567 abort: this rebase will cause divergences from: 112478962961
1568 (to force the rebase please set experimental.evolution.allowdivergence=True)
1568 (to force the rebase please set experimental.evolution.allowdivergence=True)
1569 [255]
1569 [255]
1570
1570
1571 Rebase merge where both parents have successors in destination
1571 Rebase merge where both parents have successors in destination
1572
1572
1573 $ hg init p12-succ-in-dest
1573 $ hg init p12-succ-in-dest
1574 $ cd p12-succ-in-dest
1574 $ cd p12-succ-in-dest
1575 $ hg debugdrawdag <<'EOS'
1575 $ hg debugdrawdag <<'EOS'
1576 > E F
1576 > E F
1577 > /| /| # replace: A -> C
1577 > /| /| # replace: A -> C
1578 > A B C D # replace: B -> D
1578 > A B C D # replace: B -> D
1579 > | |
1579 > | |
1580 > X Y
1580 > X Y
1581 > EOS
1581 > EOS
1582 1 new orphan changesets
1582 1 new orphan changesets
1583 $ hg rebase -r A+B+E -d F
1583 $ hg rebase -r A+B+E -d F
1584 note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" (C)
1584 note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" (C)
1585 note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" (D)
1585 note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" (D)
1586 rebasing 7:dac5d11c5a7d "E" (E tip)
1586 rebasing 7:dac5d11c5a7d "E" (E tip)
1587 abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
1587 abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
1588 [255]
1588 [255]
1589 $ cd ..
1589 $ cd ..
1590
1590
1591 Rebase a non-clean merge. One parent has successor in destination, the other
1591 Rebase a non-clean merge. One parent has successor in destination, the other
1592 parent moves as requested.
1592 parent moves as requested.
1593
1593
1594 $ hg init p1-succ-p2-move
1594 $ hg init p1-succ-p2-move
1595 $ cd p1-succ-p2-move
1595 $ cd p1-succ-p2-move
1596 $ hg debugdrawdag <<'EOS'
1596 $ hg debugdrawdag <<'EOS'
1597 > D Z
1597 > D Z
1598 > /| | # replace: A -> C
1598 > /| | # replace: A -> C
1599 > A B C # D/D = D
1599 > A B C # D/D = D
1600 > EOS
1600 > EOS
1601 1 new orphan changesets
1601 1 new orphan changesets
1602 $ hg rebase -r A+B+D -d Z
1602 $ hg rebase -r A+B+D -d Z
1603 note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" (C)
1603 note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" (C)
1604 rebasing 1:fc2b737bb2e5 "B" (B)
1604 rebasing 1:fc2b737bb2e5 "B" (B)
1605 rebasing 3:b8ed089c80ad "D" (D)
1605 rebasing 3:b8ed089c80ad "D" (D)
1606
1606
1607 $ rm .hg/localtags
1607 $ rm .hg/localtags
1608 $ hg log -G
1608 $ hg log -G
1609 o 6:e4f78693cc88 D
1609 o 6:e4f78693cc88 D
1610 |
1610 |
1611 o 5:76840d832e98 B
1611 o 5:76840d832e98 B
1612 |
1612 |
1613 o 4:50e41c1f3950 Z
1613 o 4:50e41c1f3950 Z
1614 |
1614 |
1615 o 2:96cc3511f894 C
1615 o 2:96cc3511f894 C
1616
1616
1617 $ hg files -r tip
1617 $ hg files -r tip
1618 B
1618 B
1619 C
1619 C
1620 D
1620 D
1621 Z
1621 Z
1622
1622
1623 $ cd ..
1623 $ cd ..
1624
1624
1625 $ hg init p1-move-p2-succ
1625 $ hg init p1-move-p2-succ
1626 $ cd p1-move-p2-succ
1626 $ cd p1-move-p2-succ
1627 $ hg debugdrawdag <<'EOS'
1627 $ hg debugdrawdag <<'EOS'
1628 > D Z
1628 > D Z
1629 > /| | # replace: B -> C
1629 > /| | # replace: B -> C
1630 > A B C # D/D = D
1630 > A B C # D/D = D
1631 > EOS
1631 > EOS
1632 1 new orphan changesets
1632 1 new orphan changesets
1633 $ hg rebase -r B+A+D -d Z
1633 $ hg rebase -r B+A+D -d Z
1634 rebasing 0:426bada5c675 "A" (A)
1634 rebasing 0:426bada5c675 "A" (A)
1635 note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" (C)
1635 note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" (C)
1636 rebasing 3:b8ed089c80ad "D" (D)
1636 rebasing 3:b8ed089c80ad "D" (D)
1637
1637
1638 $ rm .hg/localtags
1638 $ rm .hg/localtags
1639 $ hg log -G
1639 $ hg log -G
1640 o 6:1b355ed94d82 D
1640 o 6:1b355ed94d82 D
1641 |
1641 |
1642 o 5:a81a74d764a6 A
1642 o 5:a81a74d764a6 A
1643 |
1643 |
1644 o 4:50e41c1f3950 Z
1644 o 4:50e41c1f3950 Z
1645 |
1645 |
1646 o 2:96cc3511f894 C
1646 o 2:96cc3511f894 C
1647
1647
1648 $ hg files -r tip
1648 $ hg files -r tip
1649 A
1649 A
1650 C
1650 C
1651 D
1651 D
1652 Z
1652 Z
1653
1653
1654 $ cd ..
1654 $ cd ..
1655
1655
1656 Test that bookmark is moved and working dir is updated when all changesets have
1656 Test that bookmark is moved and working dir is updated when all changesets have
1657 equivalents in destination
1657 equivalents in destination
1658 $ hg init rbsrepo && cd rbsrepo
1658 $ hg init rbsrepo && cd rbsrepo
1659 $ echo "[experimental]" > .hg/hgrc
1659 $ echo "[experimental]" > .hg/hgrc
1660 $ echo "evolution=true" >> .hg/hgrc
1660 $ echo "evolution=true" >> .hg/hgrc
1661 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
1661 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
1662 $ echo root > root && hg ci -Am root
1662 $ echo root > root && hg ci -Am root
1663 adding root
1663 adding root
1664 $ echo a > a && hg ci -Am a
1664 $ echo a > a && hg ci -Am a
1665 adding a
1665 adding a
1666 $ hg up 0
1666 $ hg up 0
1667 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1667 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1668 $ echo b > b && hg ci -Am b
1668 $ echo b > b && hg ci -Am b
1669 adding b
1669 adding b
1670 created new head
1670 created new head
1671 $ hg rebase -r 2 -d 1
1671 $ hg rebase -r 2 -d 1
1672 rebasing 2:1e9a3c00cbe9 "b" (tip)
1672 rebasing 2:1e9a3c00cbe9 "b" (tip)
1673 $ hg log -r . # working dir is at rev 3 (successor of 2)
1673 $ hg log -r . # working dir is at rev 3 (successor of 2)
1674 3:be1832deae9a b (no-eol)
1674 3:be1832deae9a b (no-eol)
1675 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
1675 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
1676 bookmarking hidden changeset 1e9a3c00cbe9
1676 bookmarking hidden changeset 1e9a3c00cbe9
1677 (hidden revision '1e9a3c00cbe9' was rewritten as: be1832deae9a)
1677 (hidden revision '1e9a3c00cbe9' was rewritten as: be1832deae9a)
1678 $ hg up 2 && hg log -r . # working dir is at rev 2 again
1678 $ hg up 2 && hg log -r . # working dir is at rev 2 again
1679 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1679 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1680 2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
1680 2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
1681 $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
1681 $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
1682 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b" (tip)
1682 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b" (tip)
1683 Check that working directory and bookmark was updated to rev 3 although rev 2
1683 Check that working directory and bookmark was updated to rev 3 although rev 2
1684 was skipped
1684 was skipped
1685 $ hg log -r .
1685 $ hg log -r .
1686 3:be1832deae9a b (no-eol)
1686 3:be1832deae9a b (no-eol)
1687 $ hg bookmarks
1687 $ hg bookmarks
1688 mybook 3:be1832deae9a
1688 mybook 3:be1832deae9a
1689 $ hg debugobsolete --rev tip
1689 $ hg debugobsolete --rev tip
1690 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
1690 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
1691
1691
1692 Obsoleted working parent and bookmark could be moved if an ancestor of working
1692 Obsoleted working parent and bookmark could be moved if an ancestor of working
1693 parent gets moved:
1693 parent gets moved:
1694
1694
1695 $ hg init $TESTTMP/ancestor-wd-move
1695 $ hg init $TESTTMP/ancestor-wd-move
1696 $ cd $TESTTMP/ancestor-wd-move
1696 $ cd $TESTTMP/ancestor-wd-move
1697 $ hg debugdrawdag <<'EOS'
1697 $ hg debugdrawdag <<'EOS'
1698 > E D1 # rebase: D1 -> D2
1698 > E D1 # rebase: D1 -> D2
1699 > | |
1699 > | |
1700 > | C
1700 > | C
1701 > D2 |
1701 > D2 |
1702 > | B
1702 > | B
1703 > |/
1703 > |/
1704 > A
1704 > A
1705 > EOS
1705 > EOS
1706 $ hg update D1 -q
1706 $ hg update D1 -q
1707 $ hg bookmark book -i
1707 $ hg bookmark book -i
1708 $ hg rebase -r B+D1 -d E
1708 $ hg rebase -r B+D1 -d E
1709 rebasing 1:112478962961 "B" (B)
1709 rebasing 1:112478962961 "B" (B)
1710 note: not rebasing 5:15ecf15e0114 "D1" (book D1 tip), already in destination as 2:0807738e0be9 "D2" (D2)
1710 note: not rebasing 5:15ecf15e0114 "D1" (book D1 tip), already in destination as 2:0807738e0be9 "D2" (D2)
1711 1 new orphan changesets
1711 1 new orphan changesets
1712 $ hg log -G -T '{desc} {bookmarks}'
1712 $ hg log -G -T '{desc} {bookmarks}'
1713 @ B book
1713 @ B book
1714 |
1714 |
1715 | x D1
1715 | x D1
1716 | |
1716 | |
1717 o | E
1717 o | E
1718 | |
1718 | |
1719 | * C
1719 | * C
1720 | |
1720 | |
1721 o | D2
1721 o | D2
1722 | |
1722 | |
1723 | x B
1723 | x B
1724 |/
1724 |/
1725 o A
1725 o A
1726
1726
1727 Rebasing a merge with one of its parent having a hidden successor
1727 Rebasing a merge with one of its parent having a hidden successor
1728
1728
1729 $ hg init $TESTTMP/merge-p1-hidden-successor
1729 $ hg init $TESTTMP/merge-p1-hidden-successor
1730 $ cd $TESTTMP/merge-p1-hidden-successor
1730 $ cd $TESTTMP/merge-p1-hidden-successor
1731
1731
1732 $ hg debugdrawdag <<'EOS'
1732 $ hg debugdrawdag <<'EOS'
1733 > E
1733 > E
1734 > |
1734 > |
1735 > B3 B2 # amend: B1 -> B2 -> B3
1735 > B3 B2 # amend: B1 -> B2 -> B3
1736 > |/ # B2 is hidden
1736 > |/ # B2 is hidden
1737 > | D
1737 > | D
1738 > | |\
1738 > | |\
1739 > | B1 C
1739 > | B1 C
1740 > |/
1740 > |/
1741 > A
1741 > A
1742 > EOS
1742 > EOS
1743 1 new orphan changesets
1743 1 new orphan changesets
1744
1744
1745 $ eval `hg tags -T '{tag}={node}\n'`
1745 $ eval `hg tags -T '{tag}={node}\n'`
1746 $ rm .hg/localtags
1746 $ rm .hg/localtags
1747
1747
1748 $ hg rebase -r $D -d $E
1748 $ hg rebase -r $D -d $E
1749 rebasing 5:9e62094e4d94 "D"
1749 rebasing 5:9e62094e4d94 "D"
1750
1750
1751 $ hg log -G
1751 $ hg log -G
1752 o 7:a699d059adcf D
1752 o 7:a699d059adcf D
1753 |\
1753 |\
1754 | o 6:ecc93090a95c E
1754 | o 6:ecc93090a95c E
1755 | |
1755 | |
1756 | o 4:0dc878468a23 B3
1756 | o 4:0dc878468a23 B3
1757 | |
1757 | |
1758 o | 1:96cc3511f894 C
1758 o | 1:96cc3511f894 C
1759 /
1759 /
1760 o 0:426bada5c675 A
1760 o 0:426bada5c675 A
1761
1761
1762 For some reasons (--hidden, rebaseskipobsolete=0, directaccess, etc.),
1762 For some reasons (--hidden, rebaseskipobsolete=0, directaccess, etc.),
1763 rebasestate may contain hidden hashes. "rebase --abort" should work regardless.
1763 rebasestate may contain hidden hashes. "rebase --abort" should work regardless.
1764
1764
1765 $ hg init $TESTTMP/hidden-state1
1765 $ hg init $TESTTMP/hidden-state1
1766 $ cd $TESTTMP/hidden-state1
1766 $ cd $TESTTMP/hidden-state1
1767 $ cat >> .hg/hgrc <<EOF
1767 $ cat >> .hg/hgrc <<EOF
1768 > [experimental]
1768 > [experimental]
1769 > rebaseskipobsolete=0
1769 > rebaseskipobsolete=0
1770 > EOF
1770 > EOF
1771
1771
1772 $ hg debugdrawdag <<'EOS'
1772 $ hg debugdrawdag <<'EOS'
1773 > C
1773 > C
1774 > |
1774 > |
1775 > D B # prune: B, C
1775 > D B # prune: B, C
1776 > |/ # B/D=B
1776 > |/ # B/D=B
1777 > A
1777 > A
1778 > EOS
1778 > EOS
1779
1779
1780 $ eval `hg tags -T '{tag}={node}\n'`
1780 $ eval `hg tags -T '{tag}={node}\n'`
1781 $ rm .hg/localtags
1781 $ rm .hg/localtags
1782
1782
1783 $ hg update -q $C --hidden
1783 $ hg update -q $C --hidden
1784 updated to hidden changeset 7829726be4dc
1784 updated to hidden changeset 7829726be4dc
1785 (hidden revision '7829726be4dc' is pruned)
1785 (hidden revision '7829726be4dc' is pruned)
1786 $ hg rebase -s $B -d $D
1786 $ hg rebase -s $B -d $D
1787 rebasing 1:2ec65233581b "B"
1787 rebasing 1:2ec65233581b "B"
1788 merging D
1788 merging D
1789 warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
1789 warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
1790 unresolved conflicts (see hg resolve, then hg rebase --continue)
1790 unresolved conflicts (see hg resolve, then hg rebase --continue)
1791 [1]
1791 [1]
1792
1792
1793 $ cp -R . $TESTTMP/hidden-state2
1793 $ cp -R . $TESTTMP/hidden-state2
1794
1794
1795 $ hg log -G
1795 $ hg log -G
1796 @ 2:b18e25de2cf5 D
1796 @ 2:b18e25de2cf5 D
1797 |
1797 |
1798 | @ 1:2ec65233581b B (pruned using prune)
1799 |/
1800 o 0:426bada5c675 A
1798 o 0:426bada5c675 A
1801
1799
1802 $ hg summary
1800 $ hg summary
1803 parent: 2:b18e25de2cf5 tip
1801 parent: 2:b18e25de2cf5 tip
1804 D
1802 D
1805 parent: 1:2ec65233581b (obsolete)
1806 B
1807 branch: default
1803 branch: default
1808 commit: 2 modified, 1 unknown, 1 unresolved (merge)
1804 commit: 1 modified, 1 added, 1 unknown, 1 unresolved
1809 update: (current)
1805 update: (current)
1810 phases: 3 draft
1806 phases: 2 draft
1811 rebase: 0 rebased, 2 remaining (rebase --continue)
1807 rebase: 0 rebased, 2 remaining (rebase --continue)
1812
1808
1813 $ hg rebase --abort
1809 $ hg rebase --abort
1814 rebase aborted
1810 rebase aborted
1815
1811
1816 Also test --continue for the above case
1812 Also test --continue for the above case
1817
1813
1818 $ cd $TESTTMP/hidden-state2
1814 $ cd $TESTTMP/hidden-state2
1819 $ hg resolve -m
1815 $ hg resolve -m
1820 (no more unresolved files)
1816 (no more unresolved files)
1821 continue: hg rebase --continue
1817 continue: hg rebase --continue
1822 $ hg rebase --continue
1818 $ hg rebase --continue
1823 rebasing 1:2ec65233581b "B"
1819 rebasing 1:2ec65233581b "B"
1824 rebasing 3:7829726be4dc "C" (tip)
1820 rebasing 3:7829726be4dc "C" (tip)
1825 $ hg log -G
1821 $ hg log -G
1826 @ 5:1964d5d5b547 C
1822 @ 5:1964d5d5b547 C
1827 |
1823 |
1828 o 4:68deb90c12a2 B
1824 o 4:68deb90c12a2 B
1829 |
1825 |
1830 o 2:b18e25de2cf5 D
1826 o 2:b18e25de2cf5 D
1831 |
1827 |
1832 o 0:426bada5c675 A
1828 o 0:426bada5c675 A
1833
1829
1834 ====================
1830 ====================
1835 Test --stop option |
1831 Test --stop option |
1836 ====================
1832 ====================
1837 $ cd ..
1833 $ cd ..
1838 $ hg init rbstop
1834 $ hg init rbstop
1839 $ cd rbstop
1835 $ cd rbstop
1840 $ echo a>a
1836 $ echo a>a
1841 $ hg ci -Aqma
1837 $ hg ci -Aqma
1842 $ echo b>b
1838 $ echo b>b
1843 $ hg ci -Aqmb
1839 $ hg ci -Aqmb
1844 $ echo c>c
1840 $ echo c>c
1845 $ hg ci -Aqmc
1841 $ hg ci -Aqmc
1846 $ echo d>d
1842 $ echo d>d
1847 $ hg ci -Aqmd
1843 $ hg ci -Aqmd
1848 $ hg up 0 -q
1844 $ hg up 0 -q
1849 $ echo f>f
1845 $ echo f>f
1850 $ hg ci -Aqmf
1846 $ hg ci -Aqmf
1851 $ echo D>d
1847 $ echo D>d
1852 $ hg ci -Aqm "conflict with d"
1848 $ hg ci -Aqm "conflict with d"
1853 $ hg up 3 -q
1849 $ hg up 3 -q
1854 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1850 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1855 o 5:00bfc9898aeb test
1851 o 5:00bfc9898aeb test
1856 | conflict with d
1852 | conflict with d
1857 |
1853 |
1858 o 4:dafd40200f93 test
1854 o 4:dafd40200f93 test
1859 | f
1855 | f
1860 |
1856 |
1861 | @ 3:055a42cdd887 test
1857 | @ 3:055a42cdd887 test
1862 | | d
1858 | | d
1863 | |
1859 | |
1864 | o 2:177f92b77385 test
1860 | o 2:177f92b77385 test
1865 | | c
1861 | | c
1866 | |
1862 | |
1867 | o 1:d2ae7f538514 test
1863 | o 1:d2ae7f538514 test
1868 |/ b
1864 |/ b
1869 |
1865 |
1870 o 0:cb9a9f314b8b test
1866 o 0:cb9a9f314b8b test
1871 a
1867 a
1872
1868
1873 $ hg rebase -s 1 -d 5
1869 $ hg rebase -s 1 -d 5
1874 rebasing 1:d2ae7f538514 "b"
1870 rebasing 1:d2ae7f538514 "b"
1875 rebasing 2:177f92b77385 "c"
1871 rebasing 2:177f92b77385 "c"
1876 rebasing 3:055a42cdd887 "d"
1872 rebasing 3:055a42cdd887 "d"
1877 merging d
1873 merging d
1878 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1874 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1879 unresolved conflicts (see hg resolve, then hg rebase --continue)
1875 unresolved conflicts (see hg resolve, then hg rebase --continue)
1880 [1]
1876 [1]
1881 $ hg rebase --stop
1877 $ hg rebase --stop
1882 1 new orphan changesets
1878 1 new orphan changesets
1883 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1879 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1884 o 7:7fffad344617 test
1880 o 7:7fffad344617 test
1885 | c
1881 | c
1886 |
1882 |
1887 o 6:b15528633407 test
1883 o 6:b15528633407 test
1888 | b
1884 | b
1889 |
1885 |
1890 o 5:00bfc9898aeb test
1886 o 5:00bfc9898aeb test
1891 | conflict with d
1887 | conflict with d
1892 |
1888 |
1893 o 4:dafd40200f93 test
1889 o 4:dafd40200f93 test
1894 | f
1890 | f
1895 |
1891 |
1896 | @ 3:055a42cdd887 test
1892 | @ 3:055a42cdd887 test
1897 | | d
1893 | | d
1898 | |
1894 | |
1899 | x 2:177f92b77385 test
1895 | x 2:177f92b77385 test
1900 | | c
1896 | | c
1901 | |
1897 | |
1902 | x 1:d2ae7f538514 test
1898 | x 1:d2ae7f538514 test
1903 |/ b
1899 |/ b
1904 |
1900 |
1905 o 0:cb9a9f314b8b test
1901 o 0:cb9a9f314b8b test
1906 a
1902 a
1907
1903
1908 Test it aborts if unstable csets is not allowed:
1904 Test it aborts if unstable csets is not allowed:
1909 ===============================================
1905 ===============================================
1910 $ cat >> $HGRCPATH << EOF
1906 $ cat >> $HGRCPATH << EOF
1911 > [experimental]
1907 > [experimental]
1912 > evolution.allowunstable=False
1908 > evolution.allowunstable=False
1913 > EOF
1909 > EOF
1914
1910
1915 $ hg strip 6 --no-backup -q
1911 $ hg strip 6 --no-backup -q
1916 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1912 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1917 o 5:00bfc9898aeb test
1913 o 5:00bfc9898aeb test
1918 | conflict with d
1914 | conflict with d
1919 |
1915 |
1920 o 4:dafd40200f93 test
1916 o 4:dafd40200f93 test
1921 | f
1917 | f
1922 |
1918 |
1923 | @ 3:055a42cdd887 test
1919 | @ 3:055a42cdd887 test
1924 | | d
1920 | | d
1925 | |
1921 | |
1926 | o 2:177f92b77385 test
1922 | o 2:177f92b77385 test
1927 | | c
1923 | | c
1928 | |
1924 | |
1929 | o 1:d2ae7f538514 test
1925 | o 1:d2ae7f538514 test
1930 |/ b
1926 |/ b
1931 |
1927 |
1932 o 0:cb9a9f314b8b test
1928 o 0:cb9a9f314b8b test
1933 a
1929 a
1934
1930
1935 $ hg rebase -s 1 -d 5
1931 $ hg rebase -s 1 -d 5
1936 rebasing 1:d2ae7f538514 "b"
1932 rebasing 1:d2ae7f538514 "b"
1937 rebasing 2:177f92b77385 "c"
1933 rebasing 2:177f92b77385 "c"
1938 rebasing 3:055a42cdd887 "d"
1934 rebasing 3:055a42cdd887 "d"
1939 merging d
1935 merging d
1940 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1936 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1941 unresolved conflicts (see hg resolve, then hg rebase --continue)
1937 unresolved conflicts (see hg resolve, then hg rebase --continue)
1942 [1]
1938 [1]
1943 $ hg rebase --stop
1939 $ hg rebase --stop
1944 abort: cannot remove original changesets with unrebased descendants
1940 abort: cannot remove original changesets with unrebased descendants
1945 (either enable obsmarkers to allow unstable revisions or use --keep to keep original changesets)
1941 (either enable obsmarkers to allow unstable revisions or use --keep to keep original changesets)
1946 [255]
1942 [255]
1947 $ hg rebase --abort
1943 $ hg rebase --abort
1948 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1944 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1949 rebase aborted
1945 rebase aborted
1950
1946
1951 Test --stop when --keep is passed:
1947 Test --stop when --keep is passed:
1952 ==================================
1948 ==================================
1953 $ hg rebase -s 1 -d 5 --keep
1949 $ hg rebase -s 1 -d 5 --keep
1954 rebasing 1:d2ae7f538514 "b"
1950 rebasing 1:d2ae7f538514 "b"
1955 rebasing 2:177f92b77385 "c"
1951 rebasing 2:177f92b77385 "c"
1956 rebasing 3:055a42cdd887 "d"
1952 rebasing 3:055a42cdd887 "d"
1957 merging d
1953 merging d
1958 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1954 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1959 unresolved conflicts (see hg resolve, then hg rebase --continue)
1955 unresolved conflicts (see hg resolve, then hg rebase --continue)
1960 [1]
1956 [1]
1961 $ hg rebase --stop
1957 $ hg rebase --stop
1962 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1958 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1963 o 7:7fffad344617 test
1959 o 7:7fffad344617 test
1964 | c
1960 | c
1965 |
1961 |
1966 o 6:b15528633407 test
1962 o 6:b15528633407 test
1967 | b
1963 | b
1968 |
1964 |
1969 o 5:00bfc9898aeb test
1965 o 5:00bfc9898aeb test
1970 | conflict with d
1966 | conflict with d
1971 |
1967 |
1972 o 4:dafd40200f93 test
1968 o 4:dafd40200f93 test
1973 | f
1969 | f
1974 |
1970 |
1975 | @ 3:055a42cdd887 test
1971 | @ 3:055a42cdd887 test
1976 | | d
1972 | | d
1977 | |
1973 | |
1978 | o 2:177f92b77385 test
1974 | o 2:177f92b77385 test
1979 | | c
1975 | | c
1980 | |
1976 | |
1981 | o 1:d2ae7f538514 test
1977 | o 1:d2ae7f538514 test
1982 |/ b
1978 |/ b
1983 |
1979 |
1984 o 0:cb9a9f314b8b test
1980 o 0:cb9a9f314b8b test
1985 a
1981 a
1986
1982
1987 Test --stop aborts when --collapse was passed:
1983 Test --stop aborts when --collapse was passed:
1988 =============================================
1984 =============================================
1989 $ cat >> $HGRCPATH << EOF
1985 $ cat >> $HGRCPATH << EOF
1990 > [experimental]
1986 > [experimental]
1991 > evolution.allowunstable=True
1987 > evolution.allowunstable=True
1992 > EOF
1988 > EOF
1993
1989
1994 $ hg strip 6
1990 $ hg strip 6
1995 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1991 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1996 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1992 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1997 o 5:00bfc9898aeb test
1993 o 5:00bfc9898aeb test
1998 | conflict with d
1994 | conflict with d
1999 |
1995 |
2000 o 4:dafd40200f93 test
1996 o 4:dafd40200f93 test
2001 | f
1997 | f
2002 |
1998 |
2003 | @ 3:055a42cdd887 test
1999 | @ 3:055a42cdd887 test
2004 | | d
2000 | | d
2005 | |
2001 | |
2006 | o 2:177f92b77385 test
2002 | o 2:177f92b77385 test
2007 | | c
2003 | | c
2008 | |
2004 | |
2009 | o 1:d2ae7f538514 test
2005 | o 1:d2ae7f538514 test
2010 |/ b
2006 |/ b
2011 |
2007 |
2012 o 0:cb9a9f314b8b test
2008 o 0:cb9a9f314b8b test
2013 a
2009 a
2014
2010
2015 $ hg rebase -s 1 -d 5 --collapse -m "collapsed b c d"
2011 $ hg rebase -s 1 -d 5 --collapse -m "collapsed b c d"
2016 rebasing 1:d2ae7f538514 "b"
2012 rebasing 1:d2ae7f538514 "b"
2017 rebasing 2:177f92b77385 "c"
2013 rebasing 2:177f92b77385 "c"
2018 rebasing 3:055a42cdd887 "d"
2014 rebasing 3:055a42cdd887 "d"
2019 merging d
2015 merging d
2020 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2016 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2021 unresolved conflicts (see hg resolve, then hg rebase --continue)
2017 unresolved conflicts (see hg resolve, then hg rebase --continue)
2022 [1]
2018 [1]
2023 $ hg rebase --stop
2019 $ hg rebase --stop
2024 abort: cannot stop in --collapse session
2020 abort: cannot stop in --collapse session
2025 [255]
2021 [255]
2026 $ hg rebase --abort
2022 $ hg rebase --abort
2027 rebase aborted
2023 rebase aborted
2028 $ hg diff
2024 $ hg diff
2029 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
2025 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
2030 o 5:00bfc9898aeb test
2026 o 5:00bfc9898aeb test
2031 | conflict with d
2027 | conflict with d
2032 |
2028 |
2033 o 4:dafd40200f93 test
2029 o 4:dafd40200f93 test
2034 | f
2030 | f
2035 |
2031 |
2036 | @ 3:055a42cdd887 test
2032 | @ 3:055a42cdd887 test
2037 | | d
2033 | | d
2038 | |
2034 | |
2039 | o 2:177f92b77385 test
2035 | o 2:177f92b77385 test
2040 | | c
2036 | | c
2041 | |
2037 | |
2042 | o 1:d2ae7f538514 test
2038 | o 1:d2ae7f538514 test
2043 |/ b
2039 |/ b
2044 |
2040 |
2045 o 0:cb9a9f314b8b test
2041 o 0:cb9a9f314b8b test
2046 a
2042 a
2047
2043
2048 Test --stop raise errors with conflicting options:
2044 Test --stop raise errors with conflicting options:
2049 =================================================
2045 =================================================
2050 $ hg rebase -s 3 -d 5
2046 $ hg rebase -s 3 -d 5
2051 rebasing 3:055a42cdd887 "d"
2047 rebasing 3:055a42cdd887 "d"
2052 merging d
2048 merging d
2053 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2049 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2054 unresolved conflicts (see hg resolve, then hg rebase --continue)
2050 unresolved conflicts (see hg resolve, then hg rebase --continue)
2055 [1]
2051 [1]
2056 $ hg rebase --stop --dry-run
2052 $ hg rebase --stop --dry-run
2057 abort: cannot specify both --stop and --dry-run
2053 abort: cannot specify both --stop and --dry-run
2058 [255]
2054 [255]
2059
2055
2060 $ hg rebase -s 3 -d 5
2056 $ hg rebase -s 3 -d 5
2061 abort: rebase in progress
2057 abort: rebase in progress
2062 (use 'hg rebase --continue' or 'hg rebase --abort')
2058 (use 'hg rebase --continue' or 'hg rebase --abort')
2063 [255]
2059 [255]
2064 $ hg rebase --stop --continue
2060 $ hg rebase --stop --continue
2065 abort: cannot specify both --stop and --continue
2061 abort: cannot specify both --stop and --continue
2066 [255]
2062 [255]
2067
2063
2068 Test --stop moves bookmarks of original revisions to new rebased nodes:
2064 Test --stop moves bookmarks of original revisions to new rebased nodes:
2069 ======================================================================
2065 ======================================================================
2070 $ cd ..
2066 $ cd ..
2071 $ hg init repo
2067 $ hg init repo
2072 $ cd repo
2068 $ cd repo
2073
2069
2074 $ echo a > a
2070 $ echo a > a
2075 $ hg ci -Am A
2071 $ hg ci -Am A
2076 adding a
2072 adding a
2077
2073
2078 $ echo b > b
2074 $ echo b > b
2079 $ hg ci -Am B
2075 $ hg ci -Am B
2080 adding b
2076 adding b
2081 $ hg book X
2077 $ hg book X
2082 $ hg book Y
2078 $ hg book Y
2083
2079
2084 $ echo c > c
2080 $ echo c > c
2085 $ hg ci -Am C
2081 $ hg ci -Am C
2086 adding c
2082 adding c
2087 $ hg book Z
2083 $ hg book Z
2088
2084
2089 $ echo d > d
2085 $ echo d > d
2090 $ hg ci -Am D
2086 $ hg ci -Am D
2091 adding d
2087 adding d
2092
2088
2093 $ hg up 0 -q
2089 $ hg up 0 -q
2094 $ echo e > e
2090 $ echo e > e
2095 $ hg ci -Am E
2091 $ hg ci -Am E
2096 adding e
2092 adding e
2097 created new head
2093 created new head
2098
2094
2099 $ echo doubt > d
2095 $ echo doubt > d
2100 $ hg ci -Am "conflict with d"
2096 $ hg ci -Am "conflict with d"
2101 adding d
2097 adding d
2102
2098
2103 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2099 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2104 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2100 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2105 |
2101 |
2106 o 4: 9c1e55f411b6 'E' bookmarks:
2102 o 4: 9c1e55f411b6 'E' bookmarks:
2107 |
2103 |
2108 | o 3: 67a385d4e6f2 'D' bookmarks: Z
2104 | o 3: 67a385d4e6f2 'D' bookmarks: Z
2109 | |
2105 | |
2110 | o 2: 49cb3485fa0c 'C' bookmarks: Y
2106 | o 2: 49cb3485fa0c 'C' bookmarks: Y
2111 | |
2107 | |
2112 | o 1: 6c81ed0049f8 'B' bookmarks: X
2108 | o 1: 6c81ed0049f8 'B' bookmarks: X
2113 |/
2109 |/
2114 o 0: 1994f17a630e 'A' bookmarks:
2110 o 0: 1994f17a630e 'A' bookmarks:
2115
2111
2116 $ hg rebase -s 1 -d 5
2112 $ hg rebase -s 1 -d 5
2117 rebasing 1:6c81ed0049f8 "B" (X)
2113 rebasing 1:6c81ed0049f8 "B" (X)
2118 rebasing 2:49cb3485fa0c "C" (Y)
2114 rebasing 2:49cb3485fa0c "C" (Y)
2119 rebasing 3:67a385d4e6f2 "D" (Z)
2115 rebasing 3:67a385d4e6f2 "D" (Z)
2120 merging d
2116 merging d
2121 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2117 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2122 unresolved conflicts (see hg resolve, then hg rebase --continue)
2118 unresolved conflicts (see hg resolve, then hg rebase --continue)
2123 [1]
2119 [1]
2124 $ hg rebase --stop
2120 $ hg rebase --stop
2125 1 new orphan changesets
2121 1 new orphan changesets
2126 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2122 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2127 o 7: 9c86c650b686 'C' bookmarks: Y
2123 o 7: 9c86c650b686 'C' bookmarks: Y
2128 |
2124 |
2129 o 6: 9b87b54e5fd8 'B' bookmarks: X
2125 o 6: 9b87b54e5fd8 'B' bookmarks: X
2130 |
2126 |
2131 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2127 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2132 |
2128 |
2133 o 4: 9c1e55f411b6 'E' bookmarks:
2129 o 4: 9c1e55f411b6 'E' bookmarks:
2134 |
2130 |
2135 | * 3: 67a385d4e6f2 'D' bookmarks: Z
2131 | * 3: 67a385d4e6f2 'D' bookmarks: Z
2136 | |
2132 | |
2137 | x 2: 49cb3485fa0c 'C' bookmarks:
2133 | x 2: 49cb3485fa0c 'C' bookmarks:
2138 | |
2134 | |
2139 | x 1: 6c81ed0049f8 'B' bookmarks:
2135 | x 1: 6c81ed0049f8 'B' bookmarks:
2140 |/
2136 |/
2141 o 0: 1994f17a630e 'A' bookmarks:
2137 o 0: 1994f17a630e 'A' bookmarks:
2142
2138
@@ -1,529 +1,527 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 >
4 >
5 > [phases]
5 > [phases]
6 > publish=False
6 > publish=False
7 >
7 >
8 > [alias]
8 > [alias]
9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
10 > EOF
10 > EOF
11
11
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
15 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 adding changesets
16 adding changesets
17 adding manifests
17 adding manifests
18 adding file changes
18 adding file changes
19 added 8 changesets with 7 changes to 7 files (+2 heads)
19 added 8 changesets with 7 changes to 7 files (+2 heads)
20 new changesets cd010b8cd998:02de42196ebe (8 drafts)
20 new changesets cd010b8cd998:02de42196ebe (8 drafts)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 $ hg up tip
22 $ hg up tip
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24
24
25 $ echo I > I
25 $ echo I > I
26 $ hg ci -AmI
26 $ hg ci -AmI
27 adding I
27 adding I
28
28
29 $ hg tglog
29 $ hg tglog
30 @ 8: e7ec4e813ba6 'I'
30 @ 8: e7ec4e813ba6 'I'
31 |
31 |
32 o 7: 02de42196ebe 'H'
32 o 7: 02de42196ebe 'H'
33 |
33 |
34 | o 6: eea13746799a 'G'
34 | o 6: eea13746799a 'G'
35 |/|
35 |/|
36 o | 5: 24b6387c8c8c 'F'
36 o | 5: 24b6387c8c8c 'F'
37 | |
37 | |
38 | o 4: 9520eea781bc 'E'
38 | o 4: 9520eea781bc 'E'
39 |/
39 |/
40 | o 3: 32af7686d403 'D'
40 | o 3: 32af7686d403 'D'
41 | |
41 | |
42 | o 2: 5fddd98957c8 'C'
42 | o 2: 5fddd98957c8 'C'
43 | |
43 | |
44 | o 1: 42ccdea3bb16 'B'
44 | o 1: 42ccdea3bb16 'B'
45 |/
45 |/
46 o 0: cd010b8cd998 'A'
46 o 0: cd010b8cd998 'A'
47
47
48 $ cd ..
48 $ cd ..
49
49
50 Version with only two heads (to allow default destination to work)
50 Version with only two heads (to allow default destination to work)
51
51
52 $ hg clone -q -u . a a2heads -r 3 -r 8
52 $ hg clone -q -u . a a2heads -r 3 -r 8
53
53
54 These fail:
54 These fail:
55
55
56 $ hg clone -q -u . a a0
56 $ hg clone -q -u . a a0
57 $ cd a0
57 $ cd a0
58
58
59 $ hg rebase -s 8 -d 7
59 $ hg rebase -s 8 -d 7
60 nothing to rebase
60 nothing to rebase
61 [1]
61 [1]
62
62
63 $ hg rebase --continue --abort
63 $ hg rebase --continue --abort
64 abort: cannot specify both --abort and --continue
64 abort: cannot specify both --abort and --continue
65 [255]
65 [255]
66
66
67 $ hg rebase --continue --collapse
67 $ hg rebase --continue --collapse
68 abort: cannot use collapse with continue or abort
68 abort: cannot use collapse with continue or abort
69 [255]
69 [255]
70
70
71 $ hg rebase --continue --dest 4
71 $ hg rebase --continue --dest 4
72 abort: cannot specify both --continue and --dest
72 abort: cannot specify both --continue and --dest
73 [255]
73 [255]
74
74
75 $ hg rebase --base 5 --source 4
75 $ hg rebase --base 5 --source 4
76 abort: cannot specify both --source and --base
76 abort: cannot specify both --source and --base
77 [255]
77 [255]
78
78
79 $ hg rebase --rev 5 --source 4
79 $ hg rebase --rev 5 --source 4
80 abort: cannot specify both --rev and --source
80 abort: cannot specify both --rev and --source
81 [255]
81 [255]
82 $ hg rebase --base 5 --rev 4
82 $ hg rebase --base 5 --rev 4
83 abort: cannot specify both --rev and --base
83 abort: cannot specify both --rev and --base
84 [255]
84 [255]
85
85
86 $ hg rebase --base 6
86 $ hg rebase --base 6
87 abort: branch 'default' has 3 heads - please rebase to an explicit rev
87 abort: branch 'default' has 3 heads - please rebase to an explicit rev
88 (run 'hg heads .' to see heads, specify destination with -d)
88 (run 'hg heads .' to see heads, specify destination with -d)
89 [255]
89 [255]
90
90
91 $ hg rebase --rev '1 & !1' --dest 8
91 $ hg rebase --rev '1 & !1' --dest 8
92 empty "rev" revision set - nothing to rebase
92 empty "rev" revision set - nothing to rebase
93 [1]
93 [1]
94
94
95 $ hg rebase --rev 'wdir()' --dest 6
95 $ hg rebase --rev 'wdir()' --dest 6
96 abort: cannot rebase the working copy
96 abort: cannot rebase the working copy
97 [255]
97 [255]
98
98
99 $ hg rebase --source 'wdir()' --dest 6
99 $ hg rebase --source 'wdir()' --dest 6
100 abort: cannot rebase the working copy
100 abort: cannot rebase the working copy
101 [255]
101 [255]
102
102
103 $ hg rebase --source '1 & !1' --dest 8
103 $ hg rebase --source '1 & !1' --dest 8
104 empty "source" revision set - nothing to rebase
104 empty "source" revision set - nothing to rebase
105 [1]
105 [1]
106
106
107 $ hg rebase --base '1 & !1' --dest 8
107 $ hg rebase --base '1 & !1' --dest 8
108 empty "base" revision set - can't compute rebase set
108 empty "base" revision set - can't compute rebase set
109 [1]
109 [1]
110
110
111 $ hg rebase --dest 8
111 $ hg rebase --dest 8
112 nothing to rebase - working directory parent is also destination
112 nothing to rebase - working directory parent is also destination
113 [1]
113 [1]
114
114
115 $ hg rebase -b . --dest 8
115 $ hg rebase -b . --dest 8
116 nothing to rebase - e7ec4e813ba6 is both "base" and destination
116 nothing to rebase - e7ec4e813ba6 is both "base" and destination
117 [1]
117 [1]
118
118
119 $ hg up -q 7
119 $ hg up -q 7
120
120
121 $ hg rebase --dest 8 --traceback
121 $ hg rebase --dest 8 --traceback
122 nothing to rebase - working directory parent is already an ancestor of destination e7ec4e813ba6
122 nothing to rebase - working directory parent is already an ancestor of destination e7ec4e813ba6
123 [1]
123 [1]
124
124
125 $ hg rebase --dest 8 -b.
125 $ hg rebase --dest 8 -b.
126 nothing to rebase - "base" 02de42196ebe is already an ancestor of destination e7ec4e813ba6
126 nothing to rebase - "base" 02de42196ebe is already an ancestor of destination e7ec4e813ba6
127 [1]
127 [1]
128
128
129 $ hg rebase --dest '1 & !1'
129 $ hg rebase --dest '1 & !1'
130 abort: empty revision set
130 abort: empty revision set
131 [255]
131 [255]
132
132
133 These work:
133 These work:
134
134
135 Rebase with no arguments (from 3 onto 8):
135 Rebase with no arguments (from 3 onto 8):
136
136
137 $ cd ..
137 $ cd ..
138 $ hg clone -q -u . a2heads a1
138 $ hg clone -q -u . a2heads a1
139 $ cd a1
139 $ cd a1
140 $ hg up -q -C 3
140 $ hg up -q -C 3
141
141
142 $ hg rebase
142 $ hg rebase
143 rebasing 1:42ccdea3bb16 "B"
143 rebasing 1:42ccdea3bb16 "B"
144 rebasing 2:5fddd98957c8 "C"
144 rebasing 2:5fddd98957c8 "C"
145 rebasing 3:32af7686d403 "D"
145 rebasing 3:32af7686d403 "D"
146 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
146 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
147
147
148 $ hg tglog
148 $ hg tglog
149 @ 6: ed65089c18f8 'D'
149 @ 6: ed65089c18f8 'D'
150 |
150 |
151 o 5: 7621bf1a2f17 'C'
151 o 5: 7621bf1a2f17 'C'
152 |
152 |
153 o 4: 9430a62369c6 'B'
153 o 4: 9430a62369c6 'B'
154 |
154 |
155 o 3: e7ec4e813ba6 'I'
155 o 3: e7ec4e813ba6 'I'
156 |
156 |
157 o 2: 02de42196ebe 'H'
157 o 2: 02de42196ebe 'H'
158 |
158 |
159 o 1: 24b6387c8c8c 'F'
159 o 1: 24b6387c8c8c 'F'
160 |
160 |
161 o 0: cd010b8cd998 'A'
161 o 0: cd010b8cd998 'A'
162
162
163 Try to rollback after a rebase (fail):
163 Try to rollback after a rebase (fail):
164
164
165 $ hg rollback
165 $ hg rollback
166 no rollback information available
166 no rollback information available
167 [1]
167 [1]
168
168
169 $ cd ..
169 $ cd ..
170
170
171 Rebase with base == '.' => same as no arguments (from 3 onto 8):
171 Rebase with base == '.' => same as no arguments (from 3 onto 8):
172
172
173 $ hg clone -q -u 3 a2heads a2
173 $ hg clone -q -u 3 a2heads a2
174 $ cd a2
174 $ cd a2
175
175
176 $ hg rebase --base .
176 $ hg rebase --base .
177 rebasing 1:42ccdea3bb16 "B"
177 rebasing 1:42ccdea3bb16 "B"
178 rebasing 2:5fddd98957c8 "C"
178 rebasing 2:5fddd98957c8 "C"
179 rebasing 3:32af7686d403 "D"
179 rebasing 3:32af7686d403 "D"
180 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
180 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
181
181
182 $ hg tglog
182 $ hg tglog
183 @ 6: ed65089c18f8 'D'
183 @ 6: ed65089c18f8 'D'
184 |
184 |
185 o 5: 7621bf1a2f17 'C'
185 o 5: 7621bf1a2f17 'C'
186 |
186 |
187 o 4: 9430a62369c6 'B'
187 o 4: 9430a62369c6 'B'
188 |
188 |
189 o 3: e7ec4e813ba6 'I'
189 o 3: e7ec4e813ba6 'I'
190 |
190 |
191 o 2: 02de42196ebe 'H'
191 o 2: 02de42196ebe 'H'
192 |
192 |
193 o 1: 24b6387c8c8c 'F'
193 o 1: 24b6387c8c8c 'F'
194 |
194 |
195 o 0: cd010b8cd998 'A'
195 o 0: cd010b8cd998 'A'
196
196
197 $ cd ..
197 $ cd ..
198
198
199
199
200 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
200 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
201
201
202 $ hg clone -q -u 3 a a3
202 $ hg clone -q -u 3 a a3
203 $ cd a3
203 $ cd a3
204
204
205 $ hg rebase --dest 'branch(.)'
205 $ hg rebase --dest 'branch(.)'
206 rebasing 1:42ccdea3bb16 "B"
206 rebasing 1:42ccdea3bb16 "B"
207 rebasing 2:5fddd98957c8 "C"
207 rebasing 2:5fddd98957c8 "C"
208 rebasing 3:32af7686d403 "D"
208 rebasing 3:32af7686d403 "D"
209 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
209 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
210
210
211 $ hg tglog
211 $ hg tglog
212 @ 8: ed65089c18f8 'D'
212 @ 8: ed65089c18f8 'D'
213 |
213 |
214 o 7: 7621bf1a2f17 'C'
214 o 7: 7621bf1a2f17 'C'
215 |
215 |
216 o 6: 9430a62369c6 'B'
216 o 6: 9430a62369c6 'B'
217 |
217 |
218 o 5: e7ec4e813ba6 'I'
218 o 5: e7ec4e813ba6 'I'
219 |
219 |
220 o 4: 02de42196ebe 'H'
220 o 4: 02de42196ebe 'H'
221 |
221 |
222 | o 3: eea13746799a 'G'
222 | o 3: eea13746799a 'G'
223 |/|
223 |/|
224 o | 2: 24b6387c8c8c 'F'
224 o | 2: 24b6387c8c8c 'F'
225 | |
225 | |
226 | o 1: 9520eea781bc 'E'
226 | o 1: 9520eea781bc 'E'
227 |/
227 |/
228 o 0: cd010b8cd998 'A'
228 o 0: cd010b8cd998 'A'
229
229
230 $ cd ..
230 $ cd ..
231
231
232
232
233 Specify only source (from 2 onto 8):
233 Specify only source (from 2 onto 8):
234
234
235 $ hg clone -q -u . a2heads a4
235 $ hg clone -q -u . a2heads a4
236 $ cd a4
236 $ cd a4
237
237
238 $ hg rebase --source 'desc("C")'
238 $ hg rebase --source 'desc("C")'
239 rebasing 2:5fddd98957c8 "C"
239 rebasing 2:5fddd98957c8 "C"
240 rebasing 3:32af7686d403 "D"
240 rebasing 3:32af7686d403 "D"
241 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
241 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
242
242
243 $ hg tglog
243 $ hg tglog
244 o 6: 7726e9fd58f7 'D'
244 o 6: 7726e9fd58f7 'D'
245 |
245 |
246 o 5: 72c8333623d0 'C'
246 o 5: 72c8333623d0 'C'
247 |
247 |
248 @ 4: e7ec4e813ba6 'I'
248 @ 4: e7ec4e813ba6 'I'
249 |
249 |
250 o 3: 02de42196ebe 'H'
250 o 3: 02de42196ebe 'H'
251 |
251 |
252 o 2: 24b6387c8c8c 'F'
252 o 2: 24b6387c8c8c 'F'
253 |
253 |
254 | o 1: 42ccdea3bb16 'B'
254 | o 1: 42ccdea3bb16 'B'
255 |/
255 |/
256 o 0: cd010b8cd998 'A'
256 o 0: cd010b8cd998 'A'
257
257
258 $ cd ..
258 $ cd ..
259
259
260
260
261 Specify only dest (from 3 onto 6):
261 Specify only dest (from 3 onto 6):
262
262
263 $ hg clone -q -u 3 a a5
263 $ hg clone -q -u 3 a a5
264 $ cd a5
264 $ cd a5
265
265
266 $ hg rebase --dest 6
266 $ hg rebase --dest 6
267 rebasing 1:42ccdea3bb16 "B"
267 rebasing 1:42ccdea3bb16 "B"
268 rebasing 2:5fddd98957c8 "C"
268 rebasing 2:5fddd98957c8 "C"
269 rebasing 3:32af7686d403 "D"
269 rebasing 3:32af7686d403 "D"
270 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
270 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
271
271
272 $ hg tglog
272 $ hg tglog
273 @ 8: 8eeb3c33ad33 'D'
273 @ 8: 8eeb3c33ad33 'D'
274 |
274 |
275 o 7: 2327fea05063 'C'
275 o 7: 2327fea05063 'C'
276 |
276 |
277 o 6: e4e5be0395b2 'B'
277 o 6: e4e5be0395b2 'B'
278 |
278 |
279 | o 5: e7ec4e813ba6 'I'
279 | o 5: e7ec4e813ba6 'I'
280 | |
280 | |
281 | o 4: 02de42196ebe 'H'
281 | o 4: 02de42196ebe 'H'
282 | |
282 | |
283 o | 3: eea13746799a 'G'
283 o | 3: eea13746799a 'G'
284 |\|
284 |\|
285 | o 2: 24b6387c8c8c 'F'
285 | o 2: 24b6387c8c8c 'F'
286 | |
286 | |
287 o | 1: 9520eea781bc 'E'
287 o | 1: 9520eea781bc 'E'
288 |/
288 |/
289 o 0: cd010b8cd998 'A'
289 o 0: cd010b8cd998 'A'
290
290
291 $ cd ..
291 $ cd ..
292
292
293
293
294 Specify only base (from 1 onto 8):
294 Specify only base (from 1 onto 8):
295
295
296 $ hg clone -q -u . a2heads a6
296 $ hg clone -q -u . a2heads a6
297 $ cd a6
297 $ cd a6
298
298
299 $ hg rebase --base 'desc("D")'
299 $ hg rebase --base 'desc("D")'
300 rebasing 1:42ccdea3bb16 "B"
300 rebasing 1:42ccdea3bb16 "B"
301 rebasing 2:5fddd98957c8 "C"
301 rebasing 2:5fddd98957c8 "C"
302 rebasing 3:32af7686d403 "D"
302 rebasing 3:32af7686d403 "D"
303 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
303 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
304
304
305 $ hg tglog
305 $ hg tglog
306 o 6: ed65089c18f8 'D'
306 o 6: ed65089c18f8 'D'
307 |
307 |
308 o 5: 7621bf1a2f17 'C'
308 o 5: 7621bf1a2f17 'C'
309 |
309 |
310 o 4: 9430a62369c6 'B'
310 o 4: 9430a62369c6 'B'
311 |
311 |
312 @ 3: e7ec4e813ba6 'I'
312 @ 3: e7ec4e813ba6 'I'
313 |
313 |
314 o 2: 02de42196ebe 'H'
314 o 2: 02de42196ebe 'H'
315 |
315 |
316 o 1: 24b6387c8c8c 'F'
316 o 1: 24b6387c8c8c 'F'
317 |
317 |
318 o 0: cd010b8cd998 'A'
318 o 0: cd010b8cd998 'A'
319
319
320 $ cd ..
320 $ cd ..
321
321
322
322
323 Specify source and dest (from 2 onto 7):
323 Specify source and dest (from 2 onto 7):
324
324
325 $ hg clone -q -u . a a7
325 $ hg clone -q -u . a a7
326 $ cd a7
326 $ cd a7
327
327
328 $ hg rebase --source 2 --dest 7
328 $ hg rebase --source 2 --dest 7
329 rebasing 2:5fddd98957c8 "C"
329 rebasing 2:5fddd98957c8 "C"
330 rebasing 3:32af7686d403 "D"
330 rebasing 3:32af7686d403 "D"
331 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
331 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
332
332
333 $ hg tglog
333 $ hg tglog
334 o 8: 668acadedd30 'D'
334 o 8: 668acadedd30 'D'
335 |
335 |
336 o 7: 09eb682ba906 'C'
336 o 7: 09eb682ba906 'C'
337 |
337 |
338 | @ 6: e7ec4e813ba6 'I'
338 | @ 6: e7ec4e813ba6 'I'
339 |/
339 |/
340 o 5: 02de42196ebe 'H'
340 o 5: 02de42196ebe 'H'
341 |
341 |
342 | o 4: eea13746799a 'G'
342 | o 4: eea13746799a 'G'
343 |/|
343 |/|
344 o | 3: 24b6387c8c8c 'F'
344 o | 3: 24b6387c8c8c 'F'
345 | |
345 | |
346 | o 2: 9520eea781bc 'E'
346 | o 2: 9520eea781bc 'E'
347 |/
347 |/
348 | o 1: 42ccdea3bb16 'B'
348 | o 1: 42ccdea3bb16 'B'
349 |/
349 |/
350 o 0: cd010b8cd998 'A'
350 o 0: cd010b8cd998 'A'
351
351
352 $ cd ..
352 $ cd ..
353
353
354
354
355 Specify base and dest (from 1 onto 7):
355 Specify base and dest (from 1 onto 7):
356
356
357 $ hg clone -q -u . a a8
357 $ hg clone -q -u . a a8
358 $ cd a8
358 $ cd a8
359
359
360 $ hg rebase --base 3 --dest 7
360 $ hg rebase --base 3 --dest 7
361 rebasing 1:42ccdea3bb16 "B"
361 rebasing 1:42ccdea3bb16 "B"
362 rebasing 2:5fddd98957c8 "C"
362 rebasing 2:5fddd98957c8 "C"
363 rebasing 3:32af7686d403 "D"
363 rebasing 3:32af7686d403 "D"
364 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
364 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
365
365
366 $ hg tglog
366 $ hg tglog
367 o 8: 287cc92ba5a4 'D'
367 o 8: 287cc92ba5a4 'D'
368 |
368 |
369 o 7: 6824f610a250 'C'
369 o 7: 6824f610a250 'C'
370 |
370 |
371 o 6: 7c6027df6a99 'B'
371 o 6: 7c6027df6a99 'B'
372 |
372 |
373 | @ 5: e7ec4e813ba6 'I'
373 | @ 5: e7ec4e813ba6 'I'
374 |/
374 |/
375 o 4: 02de42196ebe 'H'
375 o 4: 02de42196ebe 'H'
376 |
376 |
377 | o 3: eea13746799a 'G'
377 | o 3: eea13746799a 'G'
378 |/|
378 |/|
379 o | 2: 24b6387c8c8c 'F'
379 o | 2: 24b6387c8c8c 'F'
380 | |
380 | |
381 | o 1: 9520eea781bc 'E'
381 | o 1: 9520eea781bc 'E'
382 |/
382 |/
383 o 0: cd010b8cd998 'A'
383 o 0: cd010b8cd998 'A'
384
384
385 $ cd ..
385 $ cd ..
386
386
387
387
388 Specify only revs (from 2 onto 8)
388 Specify only revs (from 2 onto 8)
389
389
390 $ hg clone -q -u . a2heads a9
390 $ hg clone -q -u . a2heads a9
391 $ cd a9
391 $ cd a9
392
392
393 $ hg rebase --rev 'desc("C")::'
393 $ hg rebase --rev 'desc("C")::'
394 rebasing 2:5fddd98957c8 "C"
394 rebasing 2:5fddd98957c8 "C"
395 rebasing 3:32af7686d403 "D"
395 rebasing 3:32af7686d403 "D"
396 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
396 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
397
397
398 $ hg tglog
398 $ hg tglog
399 o 6: 7726e9fd58f7 'D'
399 o 6: 7726e9fd58f7 'D'
400 |
400 |
401 o 5: 72c8333623d0 'C'
401 o 5: 72c8333623d0 'C'
402 |
402 |
403 @ 4: e7ec4e813ba6 'I'
403 @ 4: e7ec4e813ba6 'I'
404 |
404 |
405 o 3: 02de42196ebe 'H'
405 o 3: 02de42196ebe 'H'
406 |
406 |
407 o 2: 24b6387c8c8c 'F'
407 o 2: 24b6387c8c8c 'F'
408 |
408 |
409 | o 1: 42ccdea3bb16 'B'
409 | o 1: 42ccdea3bb16 'B'
410 |/
410 |/
411 o 0: cd010b8cd998 'A'
411 o 0: cd010b8cd998 'A'
412
412
413 $ cd ..
413 $ cd ..
414
414
415 Rebasing both a single revision and a merge in one command
415 Rebasing both a single revision and a merge in one command
416
416
417 $ hg clone -q -u . a aX
417 $ hg clone -q -u . a aX
418 $ cd aX
418 $ cd aX
419 $ hg rebase -r 3 -r 6 --dest 8
419 $ hg rebase -r 3 -r 6 --dest 8
420 rebasing 3:32af7686d403 "D"
420 rebasing 3:32af7686d403 "D"
421 rebasing 6:eea13746799a "G"
421 rebasing 6:eea13746799a "G"
422 saved backup bundle to $TESTTMP/aX/.hg/strip-backup/eea13746799a-ad273fd6-rebase.hg
422 saved backup bundle to $TESTTMP/aX/.hg/strip-backup/eea13746799a-ad273fd6-rebase.hg
423 $ cd ..
423 $ cd ..
424
424
425 Test --tool parameter:
425 Test --tool parameter:
426
426
427 $ hg init b
427 $ hg init b
428 $ cd b
428 $ cd b
429
429
430 $ echo c1 > c1
430 $ echo c1 > c1
431 $ hg ci -Am c1
431 $ hg ci -Am c1
432 adding c1
432 adding c1
433
433
434 $ echo c2 > c2
434 $ echo c2 > c2
435 $ hg ci -Am c2
435 $ hg ci -Am c2
436 adding c2
436 adding c2
437
437
438 $ hg up -q 0
438 $ hg up -q 0
439 $ echo c2b > c2
439 $ echo c2b > c2
440 $ hg ci -Am c2b
440 $ hg ci -Am c2b
441 adding c2
441 adding c2
442 created new head
442 created new head
443
443
444 $ cd ..
444 $ cd ..
445
445
446 $ hg clone -q -u . b b1
446 $ hg clone -q -u . b b1
447 $ cd b1
447 $ cd b1
448
448
449 $ hg rebase -s 2 -d 1 --tool internal:local
449 $ hg rebase -s 2 -d 1 --tool internal:local
450 rebasing 2:e4e3f3546619 "c2b" (tip)
450 rebasing 2:e4e3f3546619 "c2b" (tip)
451 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
451 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
452 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
452 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
453
453
454 $ hg cat c2
454 $ hg cat c2
455 c2
455 c2
456
456
457 $ cd ..
457 $ cd ..
458
458
459
459
460 $ hg clone -q -u . b b2
460 $ hg clone -q -u . b b2
461 $ cd b2
461 $ cd b2
462
462
463 $ hg rebase -s 2 -d 1 --tool internal:other
463 $ hg rebase -s 2 -d 1 --tool internal:other
464 rebasing 2:e4e3f3546619 "c2b" (tip)
464 rebasing 2:e4e3f3546619 "c2b" (tip)
465 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
465 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
466
466
467 $ hg cat c2
467 $ hg cat c2
468 c2b
468 c2b
469
469
470 $ cd ..
470 $ cd ..
471
471
472
472
473 $ hg clone -q -u . b b3
473 $ hg clone -q -u . b b3
474 $ cd b3
474 $ cd b3
475
475
476 $ hg rebase -s 2 -d 1 --tool internal:fail
476 $ hg rebase -s 2 -d 1 --tool internal:fail
477 rebasing 2:e4e3f3546619 "c2b" (tip)
477 rebasing 2:e4e3f3546619 "c2b" (tip)
478 unresolved conflicts (see hg resolve, then hg rebase --continue)
478 unresolved conflicts (see hg resolve, then hg rebase --continue)
479 [1]
479 [1]
480
480
481 $ hg summary
481 $ hg summary
482 parent: 1:56daeba07f4b
482 parent: 1:56daeba07f4b
483 c2
483 c2
484 parent: 2:e4e3f3546619 tip
485 c2b
486 branch: default
484 branch: default
487 commit: 1 modified, 1 unresolved (merge)
485 commit: 1 unresolved (clean)
488 update: (current)
486 update: 1 new changesets, 2 branch heads (merge)
489 phases: 3 draft
487 phases: 3 draft
490 rebase: 0 rebased, 1 remaining (rebase --continue)
488 rebase: 0 rebased, 1 remaining (rebase --continue)
491
489
492 $ hg resolve -l
490 $ hg resolve -l
493 U c2
491 U c2
494
492
495 $ hg resolve -m c2
493 $ hg resolve -m c2
496 (no more unresolved files)
494 (no more unresolved files)
497 continue: hg rebase --continue
495 continue: hg rebase --continue
498 $ hg graft --continue
496 $ hg graft --continue
499 abort: no graft in progress
497 abort: no graft in progress
500 (continue: hg rebase --continue)
498 (continue: hg rebase --continue)
501 [255]
499 [255]
502 $ hg rebase -c --tool internal:fail
500 $ hg rebase -c --tool internal:fail
503 rebasing 2:e4e3f3546619 "c2b" (tip)
501 rebasing 2:e4e3f3546619 "c2b" (tip)
504 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
502 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
505 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
503 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
506
504
507 $ hg rebase -i
505 $ hg rebase -i
508 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
506 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
509 [255]
507 [255]
510
508
511 $ hg rebase --interactive
509 $ hg rebase --interactive
512 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
510 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
513 [255]
511 [255]
514
512
515 $ cd ..
513 $ cd ..
516
514
517 No common ancestor
515 No common ancestor
518
516
519 $ hg init separaterepo
517 $ hg init separaterepo
520 $ cd separaterepo
518 $ cd separaterepo
521 $ touch a
519 $ touch a
522 $ hg commit -Aqm a
520 $ hg commit -Aqm a
523 $ hg up -q null
521 $ hg up -q null
524 $ touch b
522 $ touch b
525 $ hg commit -Aqm b
523 $ hg commit -Aqm b
526 $ hg rebase -d 0
524 $ hg rebase -d 0
527 nothing to rebase from d7486e00c6f1 to 3903775176ed
525 nothing to rebase from d7486e00c6f1 to 3903775176ed
528 [1]
526 [1]
529 $ cd ..
527 $ cd ..
@@ -1,204 +1,204 b''
1 #testcases continuecommand continueflag
1 #testcases continuecommand continueflag
2 Rebasing using a single transaction
2 Rebasing using a single transaction
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > rebase=
6 > rebase=
7 > drawdag=$TESTDIR/drawdag.py
7 > drawdag=$TESTDIR/drawdag.py
8 >
8 >
9 > [rebase]
9 > [rebase]
10 > singletransaction=True
10 > singletransaction=True
11 >
11 >
12 > [phases]
12 > [phases]
13 > publish=False
13 > publish=False
14 >
14 >
15 > [alias]
15 > [alias]
16 > tglog = log -G --template "{rev}: {desc}"
16 > tglog = log -G --template "{rev}: {desc}"
17 > EOF
17 > EOF
18
18
19 #if continueflag
19 #if continueflag
20 $ cat >> $HGRCPATH <<EOF
20 $ cat >> $HGRCPATH <<EOF
21 > [alias]
21 > [alias]
22 > continue = rebase --continue
22 > continue = rebase --continue
23 > EOF
23 > EOF
24 #endif
24 #endif
25
25
26 Check that a simple rebase works
26 Check that a simple rebase works
27
27
28 $ hg init simple && cd simple
28 $ hg init simple && cd simple
29 $ hg debugdrawdag <<'EOF'
29 $ hg debugdrawdag <<'EOF'
30 > Z
30 > Z
31 > |
31 > |
32 > | D
32 > | D
33 > | |
33 > | |
34 > | C
34 > | C
35 > | |
35 > | |
36 > Y B
36 > Y B
37 > |/
37 > |/
38 > A
38 > A
39 > EOF
39 > EOF
40 - We should only see one status stored message. It comes from the start.
40 - We should only see one status stored message. It comes from the start.
41 $ hg rebase --debug -b D -d Z | grep 'status stored'
41 $ hg rebase --debug -b D -d Z | grep 'status stored'
42 rebase status stored
42 rebase status stored
43 $ hg tglog
43 $ hg tglog
44 o 5: D
44 o 5: D
45 |
45 |
46 o 4: C
46 o 4: C
47 |
47 |
48 o 3: B
48 o 3: B
49 |
49 |
50 o 2: Z
50 o 2: Z
51 |
51 |
52 o 1: Y
52 o 1: Y
53 |
53 |
54 o 0: A
54 o 0: A
55
55
56 $ cd ..
56 $ cd ..
57
57
58 Check that --collapse works
58 Check that --collapse works
59
59
60 $ hg init collapse && cd collapse
60 $ hg init collapse && cd collapse
61 $ hg debugdrawdag <<'EOF'
61 $ hg debugdrawdag <<'EOF'
62 > Z
62 > Z
63 > |
63 > |
64 > | D
64 > | D
65 > | |
65 > | |
66 > | C
66 > | C
67 > | |
67 > | |
68 > Y B
68 > Y B
69 > |/
69 > |/
70 > A
70 > A
71 > EOF
71 > EOF
72 - We should only see two status stored messages. One from the start, one from
72 - We should only see two status stored messages. One from the start, one from
73 - cmdutil.commitforceeditor() which forces tr.writepending()
73 - cmdutil.commitforceeditor() which forces tr.writepending()
74 $ hg rebase --collapse --debug -b D -d Z | grep 'status stored'
74 $ hg rebase --collapse --debug -b D -d Z | grep 'status stored'
75 rebase status stored
75 rebase status stored
76 rebase status stored
76 rebase status stored
77 $ hg tglog
77 $ hg tglog
78 o 3: Collapsed revision
78 o 3: Collapsed revision
79 | * B
79 | * B
80 | * C
80 | * C
81 | * D
81 | * D
82 o 2: Z
82 o 2: Z
83 |
83 |
84 o 1: Y
84 o 1: Y
85 |
85 |
86 o 0: A
86 o 0: A
87
87
88 $ cd ..
88 $ cd ..
89
89
90 With --collapse, check that conflicts can be resolved and rebase can then be
90 With --collapse, check that conflicts can be resolved and rebase can then be
91 continued
91 continued
92
92
93 $ hg init collapse-conflict && cd collapse-conflict
93 $ hg init collapse-conflict && cd collapse-conflict
94 $ hg debugdrawdag <<'EOF'
94 $ hg debugdrawdag <<'EOF'
95 > Z # Z/conflict=Z
95 > Z # Z/conflict=Z
96 > |
96 > |
97 > | D
97 > | D
98 > | |
98 > | |
99 > | C # C/conflict=C
99 > | C # C/conflict=C
100 > | |
100 > | |
101 > Y B
101 > Y B
102 > |/
102 > |/
103 > A
103 > A
104 > EOF
104 > EOF
105 $ hg rebase --collapse -b D -d Z
105 $ hg rebase --collapse -b D -d Z
106 rebasing 1:112478962961 "B" (B)
106 rebasing 1:112478962961 "B" (B)
107 rebasing 3:c26739dbe603 "C" (C)
107 rebasing 3:c26739dbe603 "C" (C)
108 merging conflict
108 merging conflict
109 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
109 warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
110 unresolved conflicts (see hg resolve, then hg rebase --continue)
110 unresolved conflicts (see hg resolve, then hg rebase --continue)
111 [1]
111 [1]
112 $ hg tglog
112 $ hg tglog
113 o 5: D
113 o 5: D
114 |
114 |
115 | @ 4: Z
115 | @ 4: Z
116 | |
116 | |
117 @ | 3: C
117 % | 3: C
118 | |
118 | |
119 | o 2: Y
119 | o 2: Y
120 | |
120 | |
121 o | 1: B
121 o | 1: B
122 |/
122 |/
123 o 0: A
123 o 0: A
124
124
125 $ hg st
125 $ hg st
126 M C
127 M conflict
126 M conflict
128 A B
127 A B
128 A C
129 ? conflict.orig
129 ? conflict.orig
130 $ echo resolved > conflict
130 $ echo resolved > conflict
131 $ hg resolve -m
131 $ hg resolve -m
132 (no more unresolved files)
132 (no more unresolved files)
133 continue: hg rebase --continue
133 continue: hg rebase --continue
134 $ hg continue
134 $ hg continue
135 already rebased 1:112478962961 "B" (B) as 79bc8f4973ce
135 already rebased 1:112478962961 "B" (B) as 79bc8f4973ce
136 rebasing 3:c26739dbe603 "C" (C)
136 rebasing 3:c26739dbe603 "C" (C)
137 rebasing 5:d24bb333861c "D" (D tip)
137 rebasing 5:d24bb333861c "D" (D tip)
138 saved backup bundle to $TESTTMP/collapse-conflict/.hg/strip-backup/112478962961-b5b34645-rebase.hg
138 saved backup bundle to $TESTTMP/collapse-conflict/.hg/strip-backup/112478962961-b5b34645-rebase.hg
139 $ hg tglog
139 $ hg tglog
140 o 3: Collapsed revision
140 o 3: Collapsed revision
141 | * B
141 | * B
142 | * C
142 | * C
143 | * D
143 | * D
144 o 2: Z
144 o 2: Z
145 |
145 |
146 o 1: Y
146 o 1: Y
147 |
147 |
148 o 0: A
148 o 0: A
149
149
150 $ cd ..
150 $ cd ..
151
151
152 With --collapse, check that the commit message editing can be canceled and
152 With --collapse, check that the commit message editing can be canceled and
153 rebase can then be continued
153 rebase can then be continued
154
154
155 $ hg init collapse-cancel-editor && cd collapse-cancel-editor
155 $ hg init collapse-cancel-editor && cd collapse-cancel-editor
156 $ hg debugdrawdag <<'EOF'
156 $ hg debugdrawdag <<'EOF'
157 > Z
157 > Z
158 > |
158 > |
159 > | D
159 > | D
160 > | |
160 > | |
161 > | C
161 > | C
162 > | |
162 > | |
163 > Y B
163 > Y B
164 > |/
164 > |/
165 > A
165 > A
166 > EOF
166 > EOF
167 $ HGEDITOR=false hg --config ui.interactive=1 rebase --collapse -b D -d Z
167 $ HGEDITOR=false hg --config ui.interactive=1 rebase --collapse -b D -d Z
168 rebasing 1:112478962961 "B" (B)
168 rebasing 1:112478962961 "B" (B)
169 rebasing 3:26805aba1e60 "C" (C)
169 rebasing 3:26805aba1e60 "C" (C)
170 rebasing 5:f585351a92f8 "D" (D tip)
170 rebasing 5:f585351a92f8 "D" (D tip)
171 transaction abort!
171 transaction abort!
172 rollback completed
172 rollback completed
173 abort: edit failed: false exited with status 1
173 abort: edit failed: false exited with status 1
174 [255]
174 [255]
175 $ hg tglog
175 $ hg tglog
176 o 5: D
176 o 5: D
177 |
177 |
178 | o 4: Z
178 | o 4: Z
179 | |
179 | |
180 o | 3: C
180 o | 3: C
181 | |
181 | |
182 | o 2: Y
182 | o 2: Y
183 | |
183 | |
184 o | 1: B
184 o | 1: B
185 |/
185 |/
186 o 0: A
186 o 0: A
187
187
188 $ hg continue
188 $ hg continue
189 rebasing 1:112478962961 "B" (B)
189 rebasing 1:112478962961 "B" (B)
190 rebasing 3:26805aba1e60 "C" (C)
190 rebasing 3:26805aba1e60 "C" (C)
191 rebasing 5:f585351a92f8 "D" (D tip)
191 rebasing 5:f585351a92f8 "D" (D tip)
192 saved backup bundle to $TESTTMP/collapse-cancel-editor/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
192 saved backup bundle to $TESTTMP/collapse-cancel-editor/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
193 $ hg tglog
193 $ hg tglog
194 o 3: Collapsed revision
194 o 3: Collapsed revision
195 | * B
195 | * B
196 | * C
196 | * C
197 | * D
197 | * D
198 o 2: Z
198 o 2: Z
199 |
199 |
200 o 1: Y
200 o 1: Y
201 |
201 |
202 o 0: A
202 o 0: A
203
203
204 $ cd ..
204 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now