##// END OF EJS Templates
rebase: clarify that commits that become empty are skipped...
Martin von Zweigbergk -
r40900:4edd427f default
parent child Browse files
Show More
@@ -1,1952 +1,1952 b''
1 1 # rebase.py - rebasing feature for mercurial
2 2 #
3 3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 '''command to move sets of revisions to a different ancestor
9 9
10 10 This extension lets you rebase changesets in an existing Mercurial
11 11 repository.
12 12
13 13 For more information:
14 14 https://mercurial-scm.org/wiki/RebaseExtension
15 15 '''
16 16
17 17 from __future__ import absolute_import
18 18
19 19 import errno
20 20 import os
21 21
22 22 from mercurial.i18n import _
23 23 from mercurial.node import (
24 24 nullrev,
25 25 short,
26 26 )
27 27 from mercurial import (
28 28 bookmarks,
29 29 cmdutil,
30 30 commands,
31 31 copies,
32 32 destutil,
33 33 dirstateguard,
34 34 error,
35 35 extensions,
36 36 hg,
37 37 merge as mergemod,
38 38 mergeutil,
39 39 obsolete,
40 40 obsutil,
41 41 patch,
42 42 phases,
43 43 pycompat,
44 44 registrar,
45 45 repair,
46 46 revset,
47 47 revsetlang,
48 48 scmutil,
49 49 smartset,
50 50 state as statemod,
51 51 util,
52 52 )
53 53
54 54 # The following constants are used throughout the rebase module. The ordering of
55 55 # their values must be maintained.
56 56
57 57 # Indicates that a revision needs to be rebased
58 58 revtodo = -1
59 59 revtodostr = '-1'
60 60
61 61 # legacy revstates no longer needed in current code
62 62 # -2: nullmerge, -3: revignored, -4: revprecursor, -5: revpruned
63 63 legacystates = {'-2', '-3', '-4', '-5'}
64 64
65 65 cmdtable = {}
66 66 command = registrar.command(cmdtable)
67 67 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
68 68 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
69 69 # be specifying the version(s) of Mercurial they are tested with, or
70 70 # leave the attribute unspecified.
71 71 testedwith = 'ships-with-hg-core'
72 72
73 73 def _nothingtorebase():
74 74 return 1
75 75
76 76 def _savegraft(ctx, extra):
77 77 s = ctx.extra().get('source', None)
78 78 if s is not None:
79 79 extra['source'] = s
80 80 s = ctx.extra().get('intermediate-source', None)
81 81 if s is not None:
82 82 extra['intermediate-source'] = s
83 83
84 84 def _savebranch(ctx, extra):
85 85 extra['branch'] = ctx.branch()
86 86
87 87 def _destrebase(repo, sourceset, destspace=None):
88 88 """small wrapper around destmerge to pass the right extra args
89 89
90 90 Please wrap destutil.destmerge instead."""
91 91 return destutil.destmerge(repo, action='rebase', sourceset=sourceset,
92 92 onheadcheck=False, destspace=destspace)
93 93
94 94 revsetpredicate = registrar.revsetpredicate()
95 95
96 96 @revsetpredicate('_destrebase')
97 97 def _revsetdestrebase(repo, subset, x):
98 98 # ``_rebasedefaultdest()``
99 99
100 100 # default destination for rebase.
101 101 # # XXX: Currently private because I expect the signature to change.
102 102 # # XXX: - bailing out in case of ambiguity vs returning all data.
103 103 # i18n: "_rebasedefaultdest" is a keyword
104 104 sourceset = None
105 105 if x is not None:
106 106 sourceset = revset.getset(repo, smartset.fullreposet(repo), x)
107 107 return subset & smartset.baseset([_destrebase(repo, sourceset)])
108 108
109 109 @revsetpredicate('_destautoorphanrebase')
110 110 def _revsetdestautoorphanrebase(repo, subset, x):
111 111 """automatic rebase destination for a single orphan revision"""
112 112 unfi = repo.unfiltered()
113 113 obsoleted = unfi.revs('obsolete()')
114 114
115 115 src = revset.getset(repo, subset, x).first()
116 116
117 117 # Empty src or already obsoleted - Do not return a destination
118 118 if not src or src in obsoleted:
119 119 return smartset.baseset()
120 120 dests = destutil.orphanpossibledestination(repo, src)
121 121 if len(dests) > 1:
122 122 raise error.Abort(
123 123 _("ambiguous automatic rebase: %r could end up on any of %r") % (
124 124 src, dests))
125 125 # We have zero or one destination, so we can just return here.
126 126 return smartset.baseset(dests)
127 127
128 128 def _ctxdesc(ctx):
129 129 """short description for a context"""
130 130 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
131 131 ctx.description().split('\n', 1)[0])
132 132 repo = ctx.repo()
133 133 names = []
134 134 for nsname, ns in repo.names.iteritems():
135 135 if nsname == 'branches':
136 136 continue
137 137 names.extend(ns.names(repo, ctx.node()))
138 138 if names:
139 139 desc += ' (%s)' % ' '.join(names)
140 140 return desc
141 141
142 142 class rebaseruntime(object):
143 143 """This class is a container for rebase runtime state"""
144 144 def __init__(self, repo, ui, inmemory=False, opts=None):
145 145 if opts is None:
146 146 opts = {}
147 147
148 148 # prepared: whether we have rebasestate prepared or not. Currently it
149 149 # decides whether "self.repo" is unfiltered or not.
150 150 # The rebasestate has explicit hash to hash instructions not depending
151 151 # on visibility. If rebasestate exists (in-memory or on-disk), use
152 152 # unfiltered repo to avoid visibility issues.
153 153 # Before knowing rebasestate (i.e. when starting a new rebase (not
154 154 # --continue or --abort)), the original repo should be used so
155 155 # visibility-dependent revsets are correct.
156 156 self.prepared = False
157 157 self._repo = repo
158 158
159 159 self.ui = ui
160 160 self.opts = opts
161 161 self.originalwd = None
162 162 self.external = nullrev
163 163 # Mapping between the old revision id and either what is the new rebased
164 164 # revision or what needs to be done with the old revision. The state
165 165 # dict will be what contains most of the rebase progress state.
166 166 self.state = {}
167 167 self.activebookmark = None
168 168 self.destmap = {}
169 169 self.skipped = set()
170 170
171 171 self.collapsef = opts.get('collapse', False)
172 172 self.collapsemsg = cmdutil.logmessage(ui, opts)
173 173 self.date = opts.get('date', None)
174 174
175 175 e = opts.get('extrafn') # internal, used by e.g. hgsubversion
176 176 self.extrafns = [_savegraft]
177 177 if e:
178 178 self.extrafns = [e]
179 179
180 180 self.backupf = ui.configbool('ui', 'history-editing-backup')
181 181 self.keepf = opts.get('keep', False)
182 182 self.keepbranchesf = opts.get('keepbranches', False)
183 183 self.obsoletenotrebased = {}
184 184 self.obsoletewithoutsuccessorindestination = set()
185 185 self.inmemory = inmemory
186 186 self.stateobj = statemod.cmdstate(repo, 'rebasestate')
187 187
188 188 @property
189 189 def repo(self):
190 190 if self.prepared:
191 191 return self._repo.unfiltered()
192 192 else:
193 193 return self._repo
194 194
195 195 def storestatus(self, tr=None):
196 196 """Store the current status to allow recovery"""
197 197 if tr:
198 198 tr.addfilegenerator('rebasestate', ('rebasestate',),
199 199 self._writestatus, location='plain')
200 200 else:
201 201 with self.repo.vfs("rebasestate", "w") as f:
202 202 self._writestatus(f)
203 203
204 204 def _writestatus(self, f):
205 205 repo = self.repo
206 206 assert repo.filtername is None
207 207 f.write(repo[self.originalwd].hex() + '\n')
208 208 # was "dest". we now write dest per src root below.
209 209 f.write('\n')
210 210 f.write(repo[self.external].hex() + '\n')
211 211 f.write('%d\n' % int(self.collapsef))
212 212 f.write('%d\n' % int(self.keepf))
213 213 f.write('%d\n' % int(self.keepbranchesf))
214 214 f.write('%s\n' % (self.activebookmark or ''))
215 215 destmap = self.destmap
216 216 for d, v in self.state.iteritems():
217 217 oldrev = repo[d].hex()
218 218 if v >= 0:
219 219 newrev = repo[v].hex()
220 220 else:
221 221 newrev = "%d" % v
222 222 destnode = repo[destmap[d]].hex()
223 223 f.write("%s:%s:%s\n" % (oldrev, newrev, destnode))
224 224 repo.ui.debug('rebase status stored\n')
225 225
226 226 def restorestatus(self):
227 227 """Restore a previously stored status"""
228 228 if not self.stateobj.exists():
229 229 cmdutil.wrongtooltocontinue(self.repo, _('rebase'))
230 230
231 231 data = self._read()
232 232 self.repo.ui.debug('rebase status resumed\n')
233 233
234 234 self.originalwd = data['originalwd']
235 235 self.destmap = data['destmap']
236 236 self.state = data['state']
237 237 self.skipped = data['skipped']
238 238 self.collapsef = data['collapse']
239 239 self.keepf = data['keep']
240 240 self.keepbranchesf = data['keepbranches']
241 241 self.external = data['external']
242 242 self.activebookmark = data['activebookmark']
243 243
244 244 def _read(self):
245 245 self.prepared = True
246 246 repo = self.repo
247 247 assert repo.filtername is None
248 248 data = {'keepbranches': None, 'collapse': None, 'activebookmark': None,
249 249 'external': nullrev, 'keep': None, 'originalwd': None}
250 250 legacydest = None
251 251 state = {}
252 252 destmap = {}
253 253
254 254 if True:
255 255 f = repo.vfs("rebasestate")
256 256 for i, l in enumerate(f.read().splitlines()):
257 257 if i == 0:
258 258 data['originalwd'] = repo[l].rev()
259 259 elif i == 1:
260 260 # this line should be empty in newer version. but legacy
261 261 # clients may still use it
262 262 if l:
263 263 legacydest = repo[l].rev()
264 264 elif i == 2:
265 265 data['external'] = repo[l].rev()
266 266 elif i == 3:
267 267 data['collapse'] = bool(int(l))
268 268 elif i == 4:
269 269 data['keep'] = bool(int(l))
270 270 elif i == 5:
271 271 data['keepbranches'] = bool(int(l))
272 272 elif i == 6 and not (len(l) == 81 and ':' in l):
273 273 # line 6 is a recent addition, so for backwards
274 274 # compatibility check that the line doesn't look like the
275 275 # oldrev:newrev lines
276 276 data['activebookmark'] = l
277 277 else:
278 278 args = l.split(':')
279 279 oldrev = repo[args[0]].rev()
280 280 newrev = args[1]
281 281 if newrev in legacystates:
282 282 continue
283 283 if len(args) > 2:
284 284 destrev = repo[args[2]].rev()
285 285 else:
286 286 destrev = legacydest
287 287 destmap[oldrev] = destrev
288 288 if newrev == revtodostr:
289 289 state[oldrev] = revtodo
290 290 # Legacy compat special case
291 291 else:
292 292 state[oldrev] = repo[newrev].rev()
293 293
294 294 if data['keepbranches'] is None:
295 295 raise error.Abort(_('.hg/rebasestate is incomplete'))
296 296
297 297 data['destmap'] = destmap
298 298 data['state'] = state
299 299 skipped = set()
300 300 # recompute the set of skipped revs
301 301 if not data['collapse']:
302 302 seen = set(destmap.values())
303 303 for old, new in sorted(state.items()):
304 304 if new != revtodo and new in seen:
305 305 skipped.add(old)
306 306 seen.add(new)
307 307 data['skipped'] = skipped
308 308 repo.ui.debug('computed skipped revs: %s\n' %
309 309 (' '.join('%d' % r for r in sorted(skipped)) or ''))
310 310
311 311 return data
312 312
313 313 def _handleskippingobsolete(self, obsoleterevs, destmap):
314 314 """Compute structures necessary for skipping obsolete revisions
315 315
316 316 obsoleterevs: iterable of all obsolete revisions in rebaseset
317 317 destmap: {srcrev: destrev} destination revisions
318 318 """
319 319 self.obsoletenotrebased = {}
320 320 if not self.ui.configbool('experimental', 'rebaseskipobsolete'):
321 321 return
322 322 obsoleteset = set(obsoleterevs)
323 323 (self.obsoletenotrebased,
324 324 self.obsoletewithoutsuccessorindestination,
325 325 obsoleteextinctsuccessors) = _computeobsoletenotrebased(
326 326 self.repo, obsoleteset, destmap)
327 327 skippedset = set(self.obsoletenotrebased)
328 328 skippedset.update(self.obsoletewithoutsuccessorindestination)
329 329 skippedset.update(obsoleteextinctsuccessors)
330 330 _checkobsrebase(self.repo, self.ui, obsoleteset, skippedset)
331 331
332 332 def _prepareabortorcontinue(self, isabort, backup=True, suppwarns=False):
333 333 try:
334 334 self.restorestatus()
335 335 self.collapsemsg = restorecollapsemsg(self.repo, isabort)
336 336 except error.RepoLookupError:
337 337 if isabort:
338 338 clearstatus(self.repo)
339 339 clearcollapsemsg(self.repo)
340 340 self.repo.ui.warn(_('rebase aborted (no revision is removed,'
341 341 ' only broken state is cleared)\n'))
342 342 return 0
343 343 else:
344 344 msg = _('cannot continue inconsistent rebase')
345 345 hint = _('use "hg rebase --abort" to clear broken state')
346 346 raise error.Abort(msg, hint=hint)
347 347
348 348 if isabort:
349 349 backup = backup and self.backupf
350 350 return self._abort(backup=backup, suppwarns=suppwarns)
351 351
352 352 def _preparenewrebase(self, destmap):
353 353 if not destmap:
354 354 return _nothingtorebase()
355 355
356 356 rebaseset = destmap.keys()
357 357 allowunstable = obsolete.isenabled(self.repo, obsolete.allowunstableopt)
358 358 if (not (self.keepf or allowunstable)
359 359 and self.repo.revs('first(children(%ld) - %ld)',
360 360 rebaseset, rebaseset)):
361 361 raise error.Abort(
362 362 _("can't remove original changesets with"
363 363 " unrebased descendants"),
364 364 hint=_('use --keep to keep original changesets'))
365 365
366 366 result = buildstate(self.repo, destmap, self.collapsef)
367 367
368 368 if not result:
369 369 # Empty state built, nothing to rebase
370 370 self.ui.status(_('nothing to rebase\n'))
371 371 return _nothingtorebase()
372 372
373 373 for root in self.repo.set('roots(%ld)', rebaseset):
374 374 if not self.keepf and not root.mutable():
375 375 raise error.Abort(_("can't rebase public changeset %s")
376 376 % root,
377 377 hint=_("see 'hg help phases' for details"))
378 378
379 379 (self.originalwd, self.destmap, self.state) = result
380 380 if self.collapsef:
381 381 dests = set(self.destmap.values())
382 382 if len(dests) != 1:
383 383 raise error.Abort(
384 384 _('--collapse does not work with multiple destinations'))
385 385 destrev = next(iter(dests))
386 386 destancestors = self.repo.changelog.ancestors([destrev],
387 387 inclusive=True)
388 388 self.external = externalparent(self.repo, self.state, destancestors)
389 389
390 390 for destrev in sorted(set(destmap.values())):
391 391 dest = self.repo[destrev]
392 392 if dest.closesbranch() and not self.keepbranchesf:
393 393 self.ui.status(_('reopening closed branch head %s\n') % dest)
394 394
395 395 self.prepared = True
396 396
397 397 def _assignworkingcopy(self):
398 398 if self.inmemory:
399 399 from mercurial.context import overlayworkingctx
400 400 self.wctx = overlayworkingctx(self.repo)
401 401 self.repo.ui.debug("rebasing in-memory\n")
402 402 else:
403 403 self.wctx = self.repo[None]
404 404 self.repo.ui.debug("rebasing on disk\n")
405 405 self.repo.ui.log("rebase",
406 406 "using in-memory rebase: %r\n", self.inmemory,
407 407 rebase_imm_used=self.inmemory)
408 408
409 409 def _performrebase(self, tr):
410 410 self._assignworkingcopy()
411 411 repo, ui = self.repo, self.ui
412 412 if self.keepbranchesf:
413 413 # insert _savebranch at the start of extrafns so if
414 414 # there's a user-provided extrafn it can clobber branch if
415 415 # desired
416 416 self.extrafns.insert(0, _savebranch)
417 417 if self.collapsef:
418 418 branches = set()
419 419 for rev in self.state:
420 420 branches.add(repo[rev].branch())
421 421 if len(branches) > 1:
422 422 raise error.Abort(_('cannot collapse multiple named '
423 423 'branches'))
424 424
425 425 # Calculate self.obsoletenotrebased
426 426 obsrevs = _filterobsoleterevs(self.repo, self.state)
427 427 self._handleskippingobsolete(obsrevs, self.destmap)
428 428
429 429 # Keep track of the active bookmarks in order to reset them later
430 430 self.activebookmark = self.activebookmark or repo._activebookmark
431 431 if self.activebookmark:
432 432 bookmarks.deactivate(repo)
433 433
434 434 # Store the state before we begin so users can run 'hg rebase --abort'
435 435 # if we fail before the transaction closes.
436 436 self.storestatus()
437 437 if tr:
438 438 # When using single transaction, store state when transaction
439 439 # commits.
440 440 self.storestatus(tr)
441 441
442 442 cands = [k for k, v in self.state.iteritems() if v == revtodo]
443 443 p = repo.ui.makeprogress(_("rebasing"), unit=_('changesets'),
444 444 total=len(cands))
445 445 def progress(ctx):
446 446 p.increment(item=("%d:%s" % (ctx.rev(), ctx)))
447 447 allowdivergence = self.ui.configbool(
448 448 'experimental', 'evolution.allowdivergence')
449 449 for subset in sortsource(self.destmap):
450 450 sortedrevs = self.repo.revs('sort(%ld, -topo)', subset)
451 451 if not allowdivergence:
452 452 sortedrevs -= self.repo.revs(
453 453 'descendants(%ld) and not %ld',
454 454 self.obsoletewithoutsuccessorindestination,
455 455 self.obsoletewithoutsuccessorindestination,
456 456 )
457 457 for rev in sortedrevs:
458 458 self._rebasenode(tr, rev, allowdivergence, progress)
459 459 p.complete()
460 460 ui.note(_('rebase merging completed\n'))
461 461
462 462 def _concludenode(self, rev, p1, p2, editor, commitmsg=None):
463 463 '''Commit the wd changes with parents p1 and p2.
464 464
465 465 Reuse commit info from rev but also store useful information in extra.
466 466 Return node of committed revision.'''
467 467 repo = self.repo
468 468 ctx = repo[rev]
469 469 if commitmsg is None:
470 470 commitmsg = ctx.description()
471 471 date = self.date
472 472 if date is None:
473 473 date = ctx.date()
474 474 extra = {'rebase_source': ctx.hex()}
475 475 for c in self.extrafns:
476 476 c(ctx, extra)
477 477 keepbranch = self.keepbranchesf and repo[p1].branch() != ctx.branch()
478 478 destphase = max(ctx.phase(), phases.draft)
479 479 overrides = {('phases', 'new-commit'): destphase}
480 480 if keepbranch:
481 481 overrides[('ui', 'allowemptycommit')] = True
482 482 with repo.ui.configoverride(overrides, 'rebase'):
483 483 if self.inmemory:
484 484 newnode = commitmemorynode(repo, p1, p2,
485 485 wctx=self.wctx,
486 486 extra=extra,
487 487 commitmsg=commitmsg,
488 488 editor=editor,
489 489 user=ctx.user(),
490 490 date=date)
491 491 mergemod.mergestate.clean(repo)
492 492 else:
493 493 newnode = commitnode(repo, p1, p2,
494 494 extra=extra,
495 495 commitmsg=commitmsg,
496 496 editor=editor,
497 497 user=ctx.user(),
498 498 date=date)
499 499
500 500 if newnode is None:
501 501 # If it ended up being a no-op commit, then the normal
502 502 # merge state clean-up path doesn't happen, so do it
503 503 # here. Fix issue5494
504 504 mergemod.mergestate.clean(repo)
505 505 return newnode
506 506
507 507 def _rebasenode(self, tr, rev, allowdivergence, progressfn):
508 508 repo, ui, opts = self.repo, self.ui, self.opts
509 509 dest = self.destmap[rev]
510 510 ctx = repo[rev]
511 511 desc = _ctxdesc(ctx)
512 512 if self.state[rev] == rev:
513 513 ui.status(_('already rebased %s\n') % desc)
514 514 elif (not allowdivergence
515 515 and rev in self.obsoletewithoutsuccessorindestination):
516 516 msg = _('note: not rebasing %s and its descendants as '
517 517 'this would cause divergence\n') % desc
518 518 repo.ui.status(msg)
519 519 self.skipped.add(rev)
520 520 elif rev in self.obsoletenotrebased:
521 521 succ = self.obsoletenotrebased[rev]
522 522 if succ is None:
523 523 msg = _('note: not rebasing %s, it has no '
524 524 'successor\n') % desc
525 525 else:
526 526 succdesc = _ctxdesc(repo[succ])
527 527 msg = (_('note: not rebasing %s, already in '
528 528 'destination as %s\n') % (desc, succdesc))
529 529 repo.ui.status(msg)
530 530 # Make clearrebased aware state[rev] is not a true successor
531 531 self.skipped.add(rev)
532 532 # Record rev as moved to its desired destination in self.state.
533 533 # This helps bookmark and working parent movement.
534 534 dest = max(adjustdest(repo, rev, self.destmap, self.state,
535 535 self.skipped))
536 536 self.state[rev] = dest
537 537 elif self.state[rev] == revtodo:
538 538 ui.status(_('rebasing %s\n') % desc)
539 539 progressfn(ctx)
540 540 p1, p2, base = defineparents(repo, rev, self.destmap,
541 541 self.state, self.skipped,
542 542 self.obsoletenotrebased)
543 543 if not self.inmemory and len(repo[None].parents()) == 2:
544 544 repo.ui.debug('resuming interrupted rebase\n')
545 545 else:
546 546 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
547 547 with ui.configoverride(overrides, 'rebase'):
548 548 stats = rebasenode(repo, rev, p1, base, self.collapsef,
549 549 dest, wctx=self.wctx)
550 550 if stats.unresolvedcount > 0:
551 551 if self.inmemory:
552 552 raise error.InMemoryMergeConflictsError()
553 553 else:
554 554 raise error.InterventionRequired(
555 555 _('unresolved conflicts (see hg '
556 556 'resolve, then hg rebase --continue)'))
557 557 if not self.collapsef:
558 558 merging = p2 != nullrev
559 559 editform = cmdutil.mergeeditform(merging, 'rebase')
560 560 editor = cmdutil.getcommiteditor(editform=editform,
561 561 **pycompat.strkwargs(opts))
562 562 newnode = self._concludenode(rev, p1, p2, editor)
563 563 else:
564 564 # Skip commit if we are collapsing
565 565 if self.inmemory:
566 566 self.wctx.setbase(repo[p1])
567 567 else:
568 568 repo.setparents(repo[p1].node())
569 569 newnode = None
570 570 # Update the state
571 571 if newnode is not None:
572 572 self.state[rev] = repo[newnode].rev()
573 573 ui.debug('rebased as %s\n' % short(newnode))
574 574 else:
575 575 if not self.collapsef:
576 ui.warn(_('note: rebase of %s created no changes '
577 'to commit\n') % desc)
576 ui.warn(_('note: not rebasing %s, its destination already '
577 'has all its changes\n') % desc)
578 578 self.skipped.add(rev)
579 579 self.state[rev] = p1
580 580 ui.debug('next revision set to %d\n' % p1)
581 581 else:
582 582 ui.status(_('already rebased %s as %s\n') %
583 583 (desc, repo[self.state[rev]]))
584 584 if not tr:
585 585 # When not using single transaction, store state after each
586 586 # commit is completely done. On InterventionRequired, we thus
587 587 # won't store the status. Instead, we'll hit the "len(parents) == 2"
588 588 # case and realize that the commit was in progress.
589 589 self.storestatus()
590 590
591 591 def _finishrebase(self):
592 592 repo, ui, opts = self.repo, self.ui, self.opts
593 593 fm = ui.formatter('rebase', opts)
594 594 fm.startitem()
595 595 if self.collapsef:
596 596 p1, p2, _base = defineparents(repo, min(self.state), self.destmap,
597 597 self.state, self.skipped,
598 598 self.obsoletenotrebased)
599 599 editopt = opts.get('edit')
600 600 editform = 'rebase.collapse'
601 601 if self.collapsemsg:
602 602 commitmsg = self.collapsemsg
603 603 else:
604 604 commitmsg = 'Collapsed revision'
605 605 for rebased in sorted(self.state):
606 606 if rebased not in self.skipped:
607 607 commitmsg += '\n* %s' % repo[rebased].description()
608 608 editopt = True
609 609 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform)
610 610 revtoreuse = max(self.state)
611 611
612 612 newnode = self._concludenode(revtoreuse, p1, self.external,
613 613 editor, commitmsg=commitmsg)
614 614
615 615 if newnode is not None:
616 616 newrev = repo[newnode].rev()
617 617 for oldrev in self.state:
618 618 self.state[oldrev] = newrev
619 619
620 620 if 'qtip' in repo.tags():
621 621 updatemq(repo, self.state, self.skipped,
622 622 **pycompat.strkwargs(opts))
623 623
624 624 # restore original working directory
625 625 # (we do this before stripping)
626 626 newwd = self.state.get(self.originalwd, self.originalwd)
627 627 if newwd < 0:
628 628 # original directory is a parent of rebase set root or ignored
629 629 newwd = self.originalwd
630 630 if newwd not in [c.rev() for c in repo[None].parents()]:
631 631 ui.note(_("update back to initial working directory parent\n"))
632 632 hg.updaterepo(repo, newwd, overwrite=False)
633 633
634 634 collapsedas = None
635 635 if self.collapsef and not self.keepf:
636 636 collapsedas = newnode
637 637 clearrebased(ui, repo, self.destmap, self.state, self.skipped,
638 638 collapsedas, self.keepf, fm=fm, backup=self.backupf)
639 639
640 640 clearstatus(repo)
641 641 clearcollapsemsg(repo)
642 642
643 643 ui.note(_("rebase completed\n"))
644 644 util.unlinkpath(repo.sjoin('undo'), ignoremissing=True)
645 645 if self.skipped:
646 646 skippedlen = len(self.skipped)
647 647 ui.note(_("%d revisions have been skipped\n") % skippedlen)
648 648 fm.end()
649 649
650 650 if (self.activebookmark and self.activebookmark in repo._bookmarks and
651 651 repo['.'].node() == repo._bookmarks[self.activebookmark]):
652 652 bookmarks.activate(repo, self.activebookmark)
653 653
654 654 def _abort(self, backup=True, suppwarns=False):
655 655 '''Restore the repository to its original state.'''
656 656
657 657 repo = self.repo
658 658 try:
659 659 # If the first commits in the rebased set get skipped during the
660 660 # rebase, their values within the state mapping will be the dest
661 661 # rev id. The rebased list must must not contain the dest rev
662 662 # (issue4896)
663 663 rebased = [s for r, s in self.state.items()
664 664 if s >= 0 and s != r and s != self.destmap[r]]
665 665 immutable = [d for d in rebased if not repo[d].mutable()]
666 666 cleanup = True
667 667 if immutable:
668 668 repo.ui.warn(_("warning: can't clean up public changesets %s\n")
669 669 % ', '.join(bytes(repo[r]) for r in immutable),
670 670 hint=_("see 'hg help phases' for details"))
671 671 cleanup = False
672 672
673 673 descendants = set()
674 674 if rebased:
675 675 descendants = set(repo.changelog.descendants(rebased))
676 676 if descendants - set(rebased):
677 677 repo.ui.warn(_("warning: new changesets detected on "
678 678 "destination branch, can't strip\n"))
679 679 cleanup = False
680 680
681 681 if cleanup:
682 682 shouldupdate = False
683 683 if rebased:
684 684 strippoints = [
685 685 c.node() for c in repo.set('roots(%ld)', rebased)]
686 686
687 687 updateifonnodes = set(rebased)
688 688 updateifonnodes.update(self.destmap.values())
689 689 updateifonnodes.add(self.originalwd)
690 690 shouldupdate = repo['.'].rev() in updateifonnodes
691 691
692 692 # Update away from the rebase if necessary
693 693 if shouldupdate or needupdate(repo, self.state):
694 694 mergemod.update(repo, self.originalwd, branchmerge=False,
695 695 force=True)
696 696
697 697 # Strip from the first rebased revision
698 698 if rebased:
699 699 repair.strip(repo.ui, repo, strippoints, backup=backup)
700 700
701 701 if self.activebookmark and self.activebookmark in repo._bookmarks:
702 702 bookmarks.activate(repo, self.activebookmark)
703 703
704 704 finally:
705 705 clearstatus(repo)
706 706 clearcollapsemsg(repo)
707 707 if not suppwarns:
708 708 repo.ui.warn(_('rebase aborted\n'))
709 709 return 0
710 710
711 711 @command('rebase',
712 712 [('s', 'source', '',
713 713 _('rebase the specified changeset and descendants'), _('REV')),
714 714 ('b', 'base', '',
715 715 _('rebase everything from branching point of specified changeset'),
716 716 _('REV')),
717 717 ('r', 'rev', [],
718 718 _('rebase these revisions'),
719 719 _('REV')),
720 720 ('d', 'dest', '',
721 721 _('rebase onto the specified changeset'), _('REV')),
722 722 ('', 'collapse', False, _('collapse the rebased changesets')),
723 723 ('m', 'message', '',
724 724 _('use text as collapse commit message'), _('TEXT')),
725 725 ('e', 'edit', False, _('invoke editor on commit messages')),
726 726 ('l', 'logfile', '',
727 727 _('read collapse commit message from file'), _('FILE')),
728 728 ('k', 'keep', False, _('keep original changesets')),
729 729 ('', 'keepbranches', False, _('keep original branch names')),
730 730 ('D', 'detach', False, _('(DEPRECATED)')),
731 731 ('i', 'interactive', False, _('(DEPRECATED)')),
732 732 ('t', 'tool', '', _('specify merge tool')),
733 733 ('', 'stop', False, _('stop interrupted rebase')),
734 734 ('c', 'continue', False, _('continue an interrupted rebase')),
735 735 ('a', 'abort', False, _('abort an interrupted rebase')),
736 736 ('', 'auto-orphans', '', _('automatically rebase orphan revisions '
737 737 'in the specified revset (EXPERIMENTAL)')),
738 738 ] + cmdutil.dryrunopts + cmdutil.formatteropts + cmdutil.confirmopts,
739 739 _('[-s REV | -b REV] [-d REV] [OPTION]'),
740 740 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
741 741 def rebase(ui, repo, **opts):
742 742 """move changeset (and descendants) to a different branch
743 743
744 744 Rebase uses repeated merging to graft changesets from one part of
745 745 history (the source) onto another (the destination). This can be
746 746 useful for linearizing *local* changes relative to a master
747 747 development tree.
748 748
749 749 Published commits cannot be rebased (see :hg:`help phases`).
750 750 To copy commits, see :hg:`help graft`.
751 751
752 752 If you don't specify a destination changeset (``-d/--dest``), rebase
753 753 will use the same logic as :hg:`merge` to pick a destination. if
754 754 the current branch contains exactly one other head, the other head
755 755 is merged with by default. Otherwise, an explicit revision with
756 756 which to merge with must be provided. (destination changeset is not
757 757 modified by rebasing, but new changesets are added as its
758 758 descendants.)
759 759
760 760 Here are the ways to select changesets:
761 761
762 762 1. Explicitly select them using ``--rev``.
763 763
764 764 2. Use ``--source`` to select a root changeset and include all of its
765 765 descendants.
766 766
767 767 3. Use ``--base`` to select a changeset; rebase will find ancestors
768 768 and their descendants which are not also ancestors of the destination.
769 769
770 770 4. If you do not specify any of ``--rev``, ``source``, or ``--base``,
771 771 rebase will use ``--base .`` as above.
772 772
773 773 If ``--source`` or ``--rev`` is used, special names ``SRC`` and ``ALLSRC``
774 774 can be used in ``--dest``. Destination would be calculated per source
775 775 revision with ``SRC`` substituted by that single source revision and
776 776 ``ALLSRC`` substituted by all source revisions.
777 777
778 778 Rebase will destroy original changesets unless you use ``--keep``.
779 779 It will also move your bookmarks (even if you do).
780 780
781 781 Some changesets may be dropped if they do not contribute changes
782 782 (e.g. merges from the destination branch).
783 783
784 784 Unlike ``merge``, rebase will do nothing if you are at the branch tip of
785 785 a named branch with two heads. You will need to explicitly specify source
786 786 and/or destination.
787 787
788 788 If you need to use a tool to automate merge/conflict decisions, you
789 789 can specify one with ``--tool``, see :hg:`help merge-tools`.
790 790 As a caveat: the tool will not be used to mediate when a file was
791 791 deleted, there is no hook presently available for this.
792 792
793 793 If a rebase is interrupted to manually resolve a conflict, it can be
794 794 continued with --continue/-c, aborted with --abort/-a, or stopped with
795 795 --stop.
796 796
797 797 .. container:: verbose
798 798
799 799 Examples:
800 800
801 801 - move "local changes" (current commit back to branching point)
802 802 to the current branch tip after a pull::
803 803
804 804 hg rebase
805 805
806 806 - move a single changeset to the stable branch::
807 807
808 808 hg rebase -r 5f493448 -d stable
809 809
810 810 - splice a commit and all its descendants onto another part of history::
811 811
812 812 hg rebase --source c0c3 --dest 4cf9
813 813
814 814 - rebase everything on a branch marked by a bookmark onto the
815 815 default branch::
816 816
817 817 hg rebase --base myfeature --dest default
818 818
819 819 - collapse a sequence of changes into a single commit::
820 820
821 821 hg rebase --collapse -r 1520:1525 -d .
822 822
823 823 - move a named branch while preserving its name::
824 824
825 825 hg rebase -r "branch(featureX)" -d 1.3 --keepbranches
826 826
827 827 - stabilize orphaned changesets so history looks linear::
828 828
829 829 hg rebase -r 'orphan()-obsolete()'\
830 830 -d 'first(max((successors(max(roots(ALLSRC) & ::SRC)^)-obsolete())::) +\
831 831 max(::((roots(ALLSRC) & ::SRC)^)-obsolete()))'
832 832
833 833 Configuration Options:
834 834
835 835 You can make rebase require a destination if you set the following config
836 836 option::
837 837
838 838 [commands]
839 839 rebase.requiredest = True
840 840
841 841 By default, rebase will close the transaction after each commit. For
842 842 performance purposes, you can configure rebase to use a single transaction
843 843 across the entire rebase. WARNING: This setting introduces a significant
844 844 risk of losing the work you've done in a rebase if the rebase aborts
845 845 unexpectedly::
846 846
847 847 [rebase]
848 848 singletransaction = True
849 849
850 850 By default, rebase writes to the working copy, but you can configure it to
851 851 run in-memory for for better performance, and to allow it to run if the
852 852 working copy is dirty::
853 853
854 854 [rebase]
855 855 experimental.inmemory = True
856 856
857 857 Return Values:
858 858
859 859 Returns 0 on success, 1 if nothing to rebase or there are
860 860 unresolved conflicts.
861 861
862 862 """
863 863 opts = pycompat.byteskwargs(opts)
864 864 inmemory = ui.configbool('rebase', 'experimental.inmemory')
865 865 dryrun = opts.get('dry_run')
866 866 confirm = opts.get('confirm')
867 867 selactions = [k for k in ['abort', 'stop', 'continue'] if opts.get(k)]
868 868 if len(selactions) > 1:
869 869 raise error.Abort(_('cannot use --%s with --%s')
870 870 % tuple(selactions[:2]))
871 871 action = selactions[0] if selactions else None
872 872 if dryrun and action:
873 873 raise error.Abort(_('cannot specify both --dry-run and --%s') % action)
874 874 if confirm and action:
875 875 raise error.Abort(_('cannot specify both --confirm and --%s') % action)
876 876 if dryrun and confirm:
877 877 raise error.Abort(_('cannot specify both --confirm and --dry-run'))
878 878
879 879 if action or repo.currenttransaction() is not None:
880 880 # in-memory rebase is not compatible with resuming rebases.
881 881 # (Or if it is run within a transaction, since the restart logic can
882 882 # fail the entire transaction.)
883 883 inmemory = False
884 884
885 885 if opts.get('auto_orphans'):
886 886 for key in opts:
887 887 if key != 'auto_orphans' and opts.get(key):
888 888 raise error.Abort(_('--auto-orphans is incompatible with %s') %
889 889 ('--' + key))
890 890 userrevs = list(repo.revs(opts.get('auto_orphans')))
891 891 opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)]
892 892 opts['dest'] = '_destautoorphanrebase(SRC)'
893 893
894 894 if dryrun or confirm:
895 895 return _dryrunrebase(ui, repo, action, opts)
896 896 elif action == 'stop':
897 897 rbsrt = rebaseruntime(repo, ui)
898 898 with repo.wlock(), repo.lock():
899 899 rbsrt.restorestatus()
900 900 if rbsrt.collapsef:
901 901 raise error.Abort(_("cannot stop in --collapse session"))
902 902 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
903 903 if not (rbsrt.keepf or allowunstable):
904 904 raise error.Abort(_("cannot remove original changesets with"
905 905 " unrebased descendants"),
906 906 hint=_('either enable obsmarkers to allow unstable '
907 907 'revisions or use --keep to keep original '
908 908 'changesets'))
909 909 if needupdate(repo, rbsrt.state):
910 910 # update to the current working revision
911 911 # to clear interrupted merge
912 912 hg.updaterepo(repo, rbsrt.originalwd, overwrite=True)
913 913 rbsrt._finishrebase()
914 914 return 0
915 915 elif inmemory:
916 916 try:
917 917 # in-memory merge doesn't support conflicts, so if we hit any, abort
918 918 # and re-run as an on-disk merge.
919 919 overrides = {('rebase', 'singletransaction'): True}
920 920 with ui.configoverride(overrides, 'rebase'):
921 921 return _dorebase(ui, repo, action, opts, inmemory=inmemory)
922 922 except error.InMemoryMergeConflictsError:
923 923 ui.warn(_('hit merge conflicts; re-running rebase without in-memory'
924 924 ' merge\n'))
925 925 # TODO: Make in-memory merge not use the on-disk merge state, so
926 926 # we don't have to clean it here
927 927 mergemod.mergestate.clean(repo)
928 928 clearstatus(repo)
929 929 clearcollapsemsg(repo)
930 930 return _dorebase(ui, repo, action, opts, inmemory=False)
931 931 else:
932 932 return _dorebase(ui, repo, action, opts)
933 933
934 934 def _dryrunrebase(ui, repo, action, opts):
935 935 rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts)
936 936 confirm = opts.get('confirm')
937 937 if confirm:
938 938 ui.status(_('starting in-memory rebase\n'))
939 939 else:
940 940 ui.status(_('starting dry-run rebase; repository will not be '
941 941 'changed\n'))
942 942 with repo.wlock(), repo.lock():
943 943 needsabort = True
944 944 try:
945 945 overrides = {('rebase', 'singletransaction'): True}
946 946 with ui.configoverride(overrides, 'rebase'):
947 947 _origrebase(ui, repo, action, opts, rbsrt, inmemory=True,
948 948 leaveunfinished=True)
949 949 except error.InMemoryMergeConflictsError:
950 950 ui.status(_('hit a merge conflict\n'))
951 951 return 1
952 952 else:
953 953 if confirm:
954 954 ui.status(_('rebase completed successfully\n'))
955 955 if not ui.promptchoice(_(b'apply changes (yn)?'
956 956 b'$$ &Yes $$ &No')):
957 957 # finish unfinished rebase
958 958 rbsrt._finishrebase()
959 959 else:
960 960 rbsrt._prepareabortorcontinue(isabort=True, backup=False,
961 961 suppwarns=True)
962 962 needsabort = False
963 963 else:
964 964 ui.status(_('dry-run rebase completed successfully; run without'
965 965 ' -n/--dry-run to perform this rebase\n'))
966 966 return 0
967 967 finally:
968 968 if needsabort:
969 969 # no need to store backup in case of dryrun
970 970 rbsrt._prepareabortorcontinue(isabort=True, backup=False,
971 971 suppwarns=True)
972 972
973 973 def _dorebase(ui, repo, action, opts, inmemory=False):
974 974 rbsrt = rebaseruntime(repo, ui, inmemory, opts)
975 975 return _origrebase(ui, repo, action, opts, rbsrt, inmemory=inmemory)
976 976
977 977 def _origrebase(ui, repo, action, opts, rbsrt, inmemory=False,
978 978 leaveunfinished=False):
979 979 assert action != 'stop'
980 980 with repo.wlock(), repo.lock():
981 981 # Validate input and define rebasing points
982 982 destf = opts.get('dest', None)
983 983 srcf = opts.get('source', None)
984 984 basef = opts.get('base', None)
985 985 revf = opts.get('rev', [])
986 986 # search default destination in this space
987 987 # used in the 'hg pull --rebase' case, see issue 5214.
988 988 destspace = opts.get('_destspace')
989 989 if opts.get('interactive'):
990 990 try:
991 991 if extensions.find('histedit'):
992 992 enablehistedit = ''
993 993 except KeyError:
994 994 enablehistedit = " --config extensions.histedit="
995 995 help = "hg%s help -e histedit" % enablehistedit
996 996 msg = _("interactive history editing is supported by the "
997 997 "'histedit' extension (see \"%s\")") % help
998 998 raise error.Abort(msg)
999 999
1000 1000 if rbsrt.collapsemsg and not rbsrt.collapsef:
1001 1001 raise error.Abort(
1002 1002 _('message can only be specified with collapse'))
1003 1003
1004 1004 if action:
1005 1005 if rbsrt.collapsef:
1006 1006 raise error.Abort(
1007 1007 _('cannot use collapse with continue or abort'))
1008 1008 if srcf or basef or destf:
1009 1009 raise error.Abort(
1010 1010 _('abort and continue do not allow specifying revisions'))
1011 1011 if action == 'abort' and opts.get('tool', False):
1012 1012 ui.warn(_('tool option will be ignored\n'))
1013 1013 if action == 'continue':
1014 1014 ms = mergemod.mergestate.read(repo)
1015 1015 mergeutil.checkunresolved(ms)
1016 1016
1017 1017 retcode = rbsrt._prepareabortorcontinue(isabort=(action == 'abort'))
1018 1018 if retcode is not None:
1019 1019 return retcode
1020 1020 else:
1021 1021 destmap = _definedestmap(ui, repo, inmemory, destf, srcf, basef,
1022 1022 revf, destspace=destspace)
1023 1023 retcode = rbsrt._preparenewrebase(destmap)
1024 1024 if retcode is not None:
1025 1025 return retcode
1026 1026 storecollapsemsg(repo, rbsrt.collapsemsg)
1027 1027
1028 1028 tr = None
1029 1029
1030 1030 singletr = ui.configbool('rebase', 'singletransaction')
1031 1031 if singletr:
1032 1032 tr = repo.transaction('rebase')
1033 1033
1034 1034 # If `rebase.singletransaction` is enabled, wrap the entire operation in
1035 1035 # one transaction here. Otherwise, transactions are obtained when
1036 1036 # committing each node, which is slower but allows partial success.
1037 1037 with util.acceptintervention(tr):
1038 1038 # Same logic for the dirstate guard, except we don't create one when
1039 1039 # rebasing in-memory (it's not needed).
1040 1040 dsguard = None
1041 1041 if singletr and not inmemory:
1042 1042 dsguard = dirstateguard.dirstateguard(repo, 'rebase')
1043 1043 with util.acceptintervention(dsguard):
1044 1044 rbsrt._performrebase(tr)
1045 1045 if not leaveunfinished:
1046 1046 rbsrt._finishrebase()
1047 1047
1048 1048 def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None,
1049 1049 revf=None, destspace=None):
1050 1050 """use revisions argument to define destmap {srcrev: destrev}"""
1051 1051 if revf is None:
1052 1052 revf = []
1053 1053
1054 1054 # destspace is here to work around issues with `hg pull --rebase` see
1055 1055 # issue5214 for details
1056 1056 if srcf and basef:
1057 1057 raise error.Abort(_('cannot specify both a source and a base'))
1058 1058 if revf and basef:
1059 1059 raise error.Abort(_('cannot specify both a revision and a base'))
1060 1060 if revf and srcf:
1061 1061 raise error.Abort(_('cannot specify both a revision and a source'))
1062 1062
1063 1063 if not inmemory:
1064 1064 cmdutil.checkunfinished(repo)
1065 1065 cmdutil.bailifchanged(repo)
1066 1066
1067 1067 if ui.configbool('commands', 'rebase.requiredest') and not destf:
1068 1068 raise error.Abort(_('you must specify a destination'),
1069 1069 hint=_('use: hg rebase -d REV'))
1070 1070
1071 1071 dest = None
1072 1072
1073 1073 if revf:
1074 1074 rebaseset = scmutil.revrange(repo, revf)
1075 1075 if not rebaseset:
1076 1076 ui.status(_('empty "rev" revision set - nothing to rebase\n'))
1077 1077 return None
1078 1078 elif srcf:
1079 1079 src = scmutil.revrange(repo, [srcf])
1080 1080 if not src:
1081 1081 ui.status(_('empty "source" revision set - nothing to rebase\n'))
1082 1082 return None
1083 1083 rebaseset = repo.revs('(%ld)::', src)
1084 1084 assert rebaseset
1085 1085 else:
1086 1086 base = scmutil.revrange(repo, [basef or '.'])
1087 1087 if not base:
1088 1088 ui.status(_('empty "base" revision set - '
1089 1089 "can't compute rebase set\n"))
1090 1090 return None
1091 1091 if destf:
1092 1092 # --base does not support multiple destinations
1093 1093 dest = scmutil.revsingle(repo, destf)
1094 1094 else:
1095 1095 dest = repo[_destrebase(repo, base, destspace=destspace)]
1096 1096 destf = bytes(dest)
1097 1097
1098 1098 roots = [] # selected children of branching points
1099 1099 bpbase = {} # {branchingpoint: [origbase]}
1100 1100 for b in base: # group bases by branching points
1101 1101 bp = repo.revs('ancestor(%d, %d)', b, dest.rev()).first()
1102 1102 bpbase[bp] = bpbase.get(bp, []) + [b]
1103 1103 if None in bpbase:
1104 1104 # emulate the old behavior, showing "nothing to rebase" (a better
1105 1105 # behavior may be abort with "cannot find branching point" error)
1106 1106 bpbase.clear()
1107 1107 for bp, bs in bpbase.iteritems(): # calculate roots
1108 1108 roots += list(repo.revs('children(%d) & ancestors(%ld)', bp, bs))
1109 1109
1110 1110 rebaseset = repo.revs('%ld::', roots)
1111 1111
1112 1112 if not rebaseset:
1113 1113 # transform to list because smartsets are not comparable to
1114 1114 # lists. This should be improved to honor laziness of
1115 1115 # smartset.
1116 1116 if list(base) == [dest.rev()]:
1117 1117 if basef:
1118 1118 ui.status(_('nothing to rebase - %s is both "base"'
1119 1119 ' and destination\n') % dest)
1120 1120 else:
1121 1121 ui.status(_('nothing to rebase - working directory '
1122 1122 'parent is also destination\n'))
1123 1123 elif not repo.revs('%ld - ::%d', base, dest.rev()):
1124 1124 if basef:
1125 1125 ui.status(_('nothing to rebase - "base" %s is '
1126 1126 'already an ancestor of destination '
1127 1127 '%s\n') %
1128 1128 ('+'.join(bytes(repo[r]) for r in base),
1129 1129 dest))
1130 1130 else:
1131 1131 ui.status(_('nothing to rebase - working '
1132 1132 'directory parent is already an '
1133 1133 'ancestor of destination %s\n') % dest)
1134 1134 else: # can it happen?
1135 1135 ui.status(_('nothing to rebase from %s to %s\n') %
1136 1136 ('+'.join(bytes(repo[r]) for r in base), dest))
1137 1137 return None
1138 1138
1139 1139 rebasingwcp = repo['.'].rev() in rebaseset
1140 1140 ui.log("rebase", "rebasing working copy parent: %r\n", rebasingwcp,
1141 1141 rebase_rebasing_wcp=rebasingwcp)
1142 1142 if inmemory and rebasingwcp:
1143 1143 # Check these since we did not before.
1144 1144 cmdutil.checkunfinished(repo)
1145 1145 cmdutil.bailifchanged(repo)
1146 1146
1147 1147 if not destf:
1148 1148 dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]
1149 1149 destf = bytes(dest)
1150 1150
1151 1151 allsrc = revsetlang.formatspec('%ld', rebaseset)
1152 1152 alias = {'ALLSRC': allsrc}
1153 1153
1154 1154 if dest is None:
1155 1155 try:
1156 1156 # fast path: try to resolve dest without SRC alias
1157 1157 dest = scmutil.revsingle(repo, destf, localalias=alias)
1158 1158 except error.RepoLookupError:
1159 1159 # multi-dest path: resolve dest for each SRC separately
1160 1160 destmap = {}
1161 1161 for r in rebaseset:
1162 1162 alias['SRC'] = revsetlang.formatspec('%d', r)
1163 1163 # use repo.anyrevs instead of scmutil.revsingle because we
1164 1164 # don't want to abort if destset is empty.
1165 1165 destset = repo.anyrevs([destf], user=True, localalias=alias)
1166 1166 size = len(destset)
1167 1167 if size == 1:
1168 1168 destmap[r] = destset.first()
1169 1169 elif size == 0:
1170 1170 ui.note(_('skipping %s - empty destination\n') % repo[r])
1171 1171 else:
1172 1172 raise error.Abort(_('rebase destination for %s is not '
1173 1173 'unique') % repo[r])
1174 1174
1175 1175 if dest is not None:
1176 1176 # single-dest case: assign dest to each rev in rebaseset
1177 1177 destrev = dest.rev()
1178 1178 destmap = {r: destrev for r in rebaseset} # {srcrev: destrev}
1179 1179
1180 1180 if not destmap:
1181 1181 ui.status(_('nothing to rebase - empty destination\n'))
1182 1182 return None
1183 1183
1184 1184 return destmap
1185 1185
1186 1186 def externalparent(repo, state, destancestors):
1187 1187 """Return the revision that should be used as the second parent
1188 1188 when the revisions in state is collapsed on top of destancestors.
1189 1189 Abort if there is more than one parent.
1190 1190 """
1191 1191 parents = set()
1192 1192 source = min(state)
1193 1193 for rev in state:
1194 1194 if rev == source:
1195 1195 continue
1196 1196 for p in repo[rev].parents():
1197 1197 if (p.rev() not in state
1198 1198 and p.rev() not in destancestors):
1199 1199 parents.add(p.rev())
1200 1200 if not parents:
1201 1201 return nullrev
1202 1202 if len(parents) == 1:
1203 1203 return parents.pop()
1204 1204 raise error.Abort(_('unable to collapse on top of %d, there is more '
1205 1205 'than one external parent: %s') %
1206 1206 (max(destancestors),
1207 1207 ', '.join("%d" % p for p in sorted(parents))))
1208 1208
1209 1209 def commitmemorynode(repo, p1, p2, wctx, editor, extra, user, date, commitmsg):
1210 1210 '''Commit the memory changes with parents p1 and p2.
1211 1211 Return node of committed revision.'''
1212 1212 # Replicates the empty check in ``repo.commit``.
1213 1213 if wctx.isempty() and not repo.ui.configbool('ui', 'allowemptycommit'):
1214 1214 return None
1215 1215
1216 1216 # By convention, ``extra['branch']`` (set by extrafn) clobbers
1217 1217 # ``branch`` (used when passing ``--keepbranches``).
1218 1218 branch = repo[p1].branch()
1219 1219 if 'branch' in extra:
1220 1220 branch = extra['branch']
1221 1221
1222 1222 memctx = wctx.tomemctx(commitmsg, parents=(p1, p2), date=date,
1223 1223 extra=extra, user=user, branch=branch, editor=editor)
1224 1224 commitres = repo.commitctx(memctx)
1225 1225 wctx.clean() # Might be reused
1226 1226 return commitres
1227 1227
1228 1228 def commitnode(repo, p1, p2, editor, extra, user, date, commitmsg):
1229 1229 '''Commit the wd changes with parents p1 and p2.
1230 1230 Return node of committed revision.'''
1231 1231 dsguard = util.nullcontextmanager()
1232 1232 if not repo.ui.configbool('rebase', 'singletransaction'):
1233 1233 dsguard = dirstateguard.dirstateguard(repo, 'rebase')
1234 1234 with dsguard:
1235 1235 repo.setparents(repo[p1].node(), repo[p2].node())
1236 1236
1237 1237 # Commit might fail if unresolved files exist
1238 1238 newnode = repo.commit(text=commitmsg, user=user, date=date,
1239 1239 extra=extra, editor=editor)
1240 1240
1241 1241 repo.dirstate.setbranch(repo[newnode].branch())
1242 1242 return newnode
1243 1243
1244 1244 def rebasenode(repo, rev, p1, base, collapse, dest, wctx):
1245 1245 'Rebase a single revision rev on top of p1 using base as merge ancestor'
1246 1246 # Merge phase
1247 1247 # Update to destination and merge it with local
1248 1248 if wctx.isinmemory():
1249 1249 wctx.setbase(repo[p1])
1250 1250 else:
1251 1251 if repo['.'].rev() != p1:
1252 1252 repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1]))
1253 1253 mergemod.update(repo, p1, branchmerge=False, force=True)
1254 1254 else:
1255 1255 repo.ui.debug(" already in destination\n")
1256 1256 # This is, alas, necessary to invalidate workingctx's manifest cache,
1257 1257 # as well as other data we litter on it in other places.
1258 1258 wctx = repo[None]
1259 1259 repo.dirstate.write(repo.currenttransaction())
1260 1260 repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev]))
1261 1261 if base is not None:
1262 1262 repo.ui.debug(" detach base %d:%s\n" % (base, repo[base]))
1263 1263 # When collapsing in-place, the parent is the common ancestor, we
1264 1264 # have to allow merging with it.
1265 1265 stats = mergemod.update(repo, rev, branchmerge=True, force=True,
1266 1266 ancestor=base, mergeancestor=collapse,
1267 1267 labels=['dest', 'source'], wc=wctx)
1268 1268 if collapse:
1269 1269 copies.duplicatecopies(repo, wctx, rev, dest)
1270 1270 else:
1271 1271 # If we're not using --collapse, we need to
1272 1272 # duplicate copies between the revision we're
1273 1273 # rebasing and its first parent, but *not*
1274 1274 # duplicate any copies that have already been
1275 1275 # performed in the destination.
1276 1276 p1rev = repo[rev].p1().rev()
1277 1277 copies.duplicatecopies(repo, wctx, rev, p1rev, skiprev=dest)
1278 1278 return stats
1279 1279
1280 1280 def adjustdest(repo, rev, destmap, state, skipped):
1281 1281 """adjust rebase destination given the current rebase state
1282 1282
1283 1283 rev is what is being rebased. Return a list of two revs, which are the
1284 1284 adjusted destinations for rev's p1 and p2, respectively. If a parent is
1285 1285 nullrev, return dest without adjustment for it.
1286 1286
1287 1287 For example, when doing rebasing B+E to F, C to G, rebase will first move B
1288 1288 to B1, and E's destination will be adjusted from F to B1.
1289 1289
1290 1290 B1 <- written during rebasing B
1291 1291 |
1292 1292 F <- original destination of B, E
1293 1293 |
1294 1294 | E <- rev, which is being rebased
1295 1295 | |
1296 1296 | D <- prev, one parent of rev being checked
1297 1297 | |
1298 1298 | x <- skipped, ex. no successor or successor in (::dest)
1299 1299 | |
1300 1300 | C <- rebased as C', different destination
1301 1301 | |
1302 1302 | B <- rebased as B1 C'
1303 1303 |/ |
1304 1304 A G <- destination of C, different
1305 1305
1306 1306 Another example about merge changeset, rebase -r C+G+H -d K, rebase will
1307 1307 first move C to C1, G to G1, and when it's checking H, the adjusted
1308 1308 destinations will be [C1, G1].
1309 1309
1310 1310 H C1 G1
1311 1311 /| | /
1312 1312 F G |/
1313 1313 K | | -> K
1314 1314 | C D |
1315 1315 | |/ |
1316 1316 | B | ...
1317 1317 |/ |/
1318 1318 A A
1319 1319
1320 1320 Besides, adjust dest according to existing rebase information. For example,
1321 1321
1322 1322 B C D B needs to be rebased on top of C, C needs to be rebased on top
1323 1323 \|/ of D. We will rebase C first.
1324 1324 A
1325 1325
1326 1326 C' After rebasing C, when considering B's destination, use C'
1327 1327 | instead of the original C.
1328 1328 B D
1329 1329 \ /
1330 1330 A
1331 1331 """
1332 1332 # pick already rebased revs with same dest from state as interesting source
1333 1333 dest = destmap[rev]
1334 1334 source = [s for s, d in state.items()
1335 1335 if d > 0 and destmap[s] == dest and s not in skipped]
1336 1336
1337 1337 result = []
1338 1338 for prev in repo.changelog.parentrevs(rev):
1339 1339 adjusted = dest
1340 1340 if prev != nullrev:
1341 1341 candidate = repo.revs('max(%ld and (::%d))', source, prev).first()
1342 1342 if candidate is not None:
1343 1343 adjusted = state[candidate]
1344 1344 if adjusted == dest and dest in state:
1345 1345 adjusted = state[dest]
1346 1346 if adjusted == revtodo:
1347 1347 # sortsource should produce an order that makes this impossible
1348 1348 raise error.ProgrammingError(
1349 1349 'rev %d should be rebased already at this time' % dest)
1350 1350 result.append(adjusted)
1351 1351 return result
1352 1352
1353 1353 def _checkobsrebase(repo, ui, rebaseobsrevs, rebaseobsskipped):
1354 1354 """
1355 1355 Abort if rebase will create divergence or rebase is noop because of markers
1356 1356
1357 1357 `rebaseobsrevs`: set of obsolete revision in source
1358 1358 `rebaseobsskipped`: set of revisions from source skipped because they have
1359 1359 successors in destination or no non-obsolete successor.
1360 1360 """
1361 1361 # Obsolete node with successors not in dest leads to divergence
1362 1362 divergenceok = ui.configbool('experimental',
1363 1363 'evolution.allowdivergence')
1364 1364 divergencebasecandidates = rebaseobsrevs - rebaseobsskipped
1365 1365
1366 1366 if divergencebasecandidates and not divergenceok:
1367 1367 divhashes = (bytes(repo[r])
1368 1368 for r in divergencebasecandidates)
1369 1369 msg = _("this rebase will cause "
1370 1370 "divergences from: %s")
1371 1371 h = _("to force the rebase please set "
1372 1372 "experimental.evolution.allowdivergence=True")
1373 1373 raise error.Abort(msg % (",".join(divhashes),), hint=h)
1374 1374
1375 1375 def successorrevs(unfi, rev):
1376 1376 """yield revision numbers for successors of rev"""
1377 1377 assert unfi.filtername is None
1378 1378 nodemap = unfi.changelog.nodemap
1379 1379 for s in obsutil.allsuccessors(unfi.obsstore, [unfi[rev].node()]):
1380 1380 if s in nodemap:
1381 1381 yield nodemap[s]
1382 1382
1383 1383 def defineparents(repo, rev, destmap, state, skipped, obsskipped):
1384 1384 """Return new parents and optionally a merge base for rev being rebased
1385 1385
1386 1386 The destination specified by "dest" cannot always be used directly because
1387 1387 previously rebase result could affect destination. For example,
1388 1388
1389 1389 D E rebase -r C+D+E -d B
1390 1390 |/ C will be rebased to C'
1391 1391 B C D's new destination will be C' instead of B
1392 1392 |/ E's new destination will be C' instead of B
1393 1393 A
1394 1394
1395 1395 The new parents of a merge is slightly more complicated. See the comment
1396 1396 block below.
1397 1397 """
1398 1398 # use unfiltered changelog since successorrevs may return filtered nodes
1399 1399 assert repo.filtername is None
1400 1400 cl = repo.changelog
1401 1401 isancestor = cl.isancestorrev
1402 1402
1403 1403 dest = destmap[rev]
1404 1404 oldps = repo.changelog.parentrevs(rev) # old parents
1405 1405 newps = [nullrev, nullrev] # new parents
1406 1406 dests = adjustdest(repo, rev, destmap, state, skipped)
1407 1407 bases = list(oldps) # merge base candidates, initially just old parents
1408 1408
1409 1409 if all(r == nullrev for r in oldps[1:]):
1410 1410 # For non-merge changeset, just move p to adjusted dest as requested.
1411 1411 newps[0] = dests[0]
1412 1412 else:
1413 1413 # For merge changeset, if we move p to dests[i] unconditionally, both
1414 1414 # parents may change and the end result looks like "the merge loses a
1415 1415 # parent", which is a surprise. This is a limit because "--dest" only
1416 1416 # accepts one dest per src.
1417 1417 #
1418 1418 # Therefore, only move p with reasonable conditions (in this order):
1419 1419 # 1. use dest, if dest is a descendent of (p or one of p's successors)
1420 1420 # 2. use p's rebased result, if p is rebased (state[p] > 0)
1421 1421 #
1422 1422 # Comparing with adjustdest, the logic here does some additional work:
1423 1423 # 1. decide which parents will not be moved towards dest
1424 1424 # 2. if the above decision is "no", should a parent still be moved
1425 1425 # because it was rebased?
1426 1426 #
1427 1427 # For example:
1428 1428 #
1429 1429 # C # "rebase -r C -d D" is an error since none of the parents
1430 1430 # /| # can be moved. "rebase -r B+C -d D" will move C's parent
1431 1431 # A B D # B (using rule "2."), since B will be rebased.
1432 1432 #
1433 1433 # The loop tries to be not rely on the fact that a Mercurial node has
1434 1434 # at most 2 parents.
1435 1435 for i, p in enumerate(oldps):
1436 1436 np = p # new parent
1437 1437 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)):
1438 1438 np = dests[i]
1439 1439 elif p in state and state[p] > 0:
1440 1440 np = state[p]
1441 1441
1442 1442 # "bases" only record "special" merge bases that cannot be
1443 1443 # calculated from changelog DAG (i.e. isancestor(p, np) is False).
1444 1444 # For example:
1445 1445 #
1446 1446 # B' # rebase -s B -d D, when B was rebased to B'. dest for C
1447 1447 # | C # is B', but merge base for C is B, instead of
1448 1448 # D | # changelog.ancestor(C, B') == A. If changelog DAG and
1449 1449 # | B # "state" edges are merged (so there will be an edge from
1450 1450 # |/ # B to B'), the merge base is still ancestor(C, B') in
1451 1451 # A # the merged graph.
1452 1452 #
1453 1453 # Also see https://bz.mercurial-scm.org/show_bug.cgi?id=1950#c8
1454 1454 # which uses "virtual null merge" to explain this situation.
1455 1455 if isancestor(p, np):
1456 1456 bases[i] = nullrev
1457 1457
1458 1458 # If one parent becomes an ancestor of the other, drop the ancestor
1459 1459 for j, x in enumerate(newps[:i]):
1460 1460 if x == nullrev:
1461 1461 continue
1462 1462 if isancestor(np, x): # CASE-1
1463 1463 np = nullrev
1464 1464 elif isancestor(x, np): # CASE-2
1465 1465 newps[j] = np
1466 1466 np = nullrev
1467 1467 # New parents forming an ancestor relationship does not
1468 1468 # mean the old parents have a similar relationship. Do not
1469 1469 # set bases[x] to nullrev.
1470 1470 bases[j], bases[i] = bases[i], bases[j]
1471 1471
1472 1472 newps[i] = np
1473 1473
1474 1474 # "rebasenode" updates to new p1, and the old p1 will be used as merge
1475 1475 # base. If only p2 changes, merging using unchanged p1 as merge base is
1476 1476 # suboptimal. Therefore swap parents to make the merge sane.
1477 1477 if newps[1] != nullrev and oldps[0] == newps[0]:
1478 1478 assert len(newps) == 2 and len(oldps) == 2
1479 1479 newps.reverse()
1480 1480 bases.reverse()
1481 1481
1482 1482 # No parent change might be an error because we fail to make rev a
1483 1483 # descendent of requested dest. This can happen, for example:
1484 1484 #
1485 1485 # C # rebase -r C -d D
1486 1486 # /| # None of A and B will be changed to D and rebase fails.
1487 1487 # A B D
1488 1488 if set(newps) == set(oldps) and dest not in newps:
1489 1489 raise error.Abort(_('cannot rebase %d:%s without '
1490 1490 'moving at least one of its parents')
1491 1491 % (rev, repo[rev]))
1492 1492
1493 1493 # Source should not be ancestor of dest. The check here guarantees it's
1494 1494 # impossible. With multi-dest, the initial check does not cover complex
1495 1495 # cases since we don't have abstractions to dry-run rebase cheaply.
1496 1496 if any(p != nullrev and isancestor(rev, p) for p in newps):
1497 1497 raise error.Abort(_('source is ancestor of destination'))
1498 1498
1499 1499 # "rebasenode" updates to new p1, use the corresponding merge base.
1500 1500 if bases[0] != nullrev:
1501 1501 base = bases[0]
1502 1502 else:
1503 1503 base = None
1504 1504
1505 1505 # Check if the merge will contain unwanted changes. That may happen if
1506 1506 # there are multiple special (non-changelog ancestor) merge bases, which
1507 1507 # cannot be handled well by the 3-way merge algorithm. For example:
1508 1508 #
1509 1509 # F
1510 1510 # /|
1511 1511 # D E # "rebase -r D+E+F -d Z", when rebasing F, if "D" was chosen
1512 1512 # | | # as merge base, the difference between D and F will include
1513 1513 # B C # C, so the rebased F will contain C surprisingly. If "E" was
1514 1514 # |/ # chosen, the rebased F will contain B.
1515 1515 # A Z
1516 1516 #
1517 1517 # But our merge base candidates (D and E in above case) could still be
1518 1518 # better than the default (ancestor(F, Z) == null). Therefore still
1519 1519 # pick one (so choose p1 above).
1520 1520 if sum(1 for b in bases if b != nullrev) > 1:
1521 1521 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i]
1522 1522 for i, base in enumerate(bases):
1523 1523 if base == nullrev:
1524 1524 continue
1525 1525 # Revisions in the side (not chosen as merge base) branch that
1526 1526 # might contain "surprising" contents
1527 1527 siderevs = list(repo.revs('((%ld-%d) %% (%d+%d))',
1528 1528 bases, base, base, dest))
1529 1529
1530 1530 # If those revisions are covered by rebaseset, the result is good.
1531 1531 # A merge in rebaseset would be considered to cover its ancestors.
1532 1532 if siderevs:
1533 1533 rebaseset = [r for r, d in state.items()
1534 1534 if d > 0 and r not in obsskipped]
1535 1535 merges = [r for r in rebaseset
1536 1536 if cl.parentrevs(r)[1] != nullrev]
1537 1537 unwanted[i] = list(repo.revs('%ld - (::%ld) - %ld',
1538 1538 siderevs, merges, rebaseset))
1539 1539
1540 1540 # Choose a merge base that has a minimal number of unwanted revs.
1541 1541 l, i = min((len(revs), i)
1542 1542 for i, revs in enumerate(unwanted) if revs is not None)
1543 1543 base = bases[i]
1544 1544
1545 1545 # newps[0] should match merge base if possible. Currently, if newps[i]
1546 1546 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is
1547 1547 # the other's ancestor. In that case, it's fine to not swap newps here.
1548 1548 # (see CASE-1 and CASE-2 above)
1549 1549 if i != 0 and newps[i] != nullrev:
1550 1550 newps[0], newps[i] = newps[i], newps[0]
1551 1551
1552 1552 # The merge will include unwanted revisions. Abort now. Revisit this if
1553 1553 # we have a more advanced merge algorithm that handles multiple bases.
1554 1554 if l > 0:
1555 1555 unwanteddesc = _(' or ').join(
1556 1556 (', '.join('%d:%s' % (r, repo[r]) for r in revs)
1557 1557 for revs in unwanted if revs is not None))
1558 1558 raise error.Abort(
1559 1559 _('rebasing %d:%s will include unwanted changes from %s')
1560 1560 % (rev, repo[rev], unwanteddesc))
1561 1561
1562 1562 repo.ui.debug(" future parents are %d and %d\n" % tuple(newps))
1563 1563
1564 1564 return newps[0], newps[1], base
1565 1565
1566 1566 def isagitpatch(repo, patchname):
1567 1567 'Return true if the given patch is in git format'
1568 1568 mqpatch = os.path.join(repo.mq.path, patchname)
1569 1569 for line in patch.linereader(open(mqpatch, 'rb')):
1570 1570 if line.startswith('diff --git'):
1571 1571 return True
1572 1572 return False
1573 1573
1574 1574 def updatemq(repo, state, skipped, **opts):
1575 1575 'Update rebased mq patches - finalize and then import them'
1576 1576 mqrebase = {}
1577 1577 mq = repo.mq
1578 1578 original_series = mq.fullseries[:]
1579 1579 skippedpatches = set()
1580 1580
1581 1581 for p in mq.applied:
1582 1582 rev = repo[p.node].rev()
1583 1583 if rev in state:
1584 1584 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
1585 1585 (rev, p.name))
1586 1586 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
1587 1587 else:
1588 1588 # Applied but not rebased, not sure this should happen
1589 1589 skippedpatches.add(p.name)
1590 1590
1591 1591 if mqrebase:
1592 1592 mq.finish(repo, mqrebase.keys())
1593 1593
1594 1594 # We must start import from the newest revision
1595 1595 for rev in sorted(mqrebase, reverse=True):
1596 1596 if rev not in skipped:
1597 1597 name, isgit = mqrebase[rev]
1598 1598 repo.ui.note(_('updating mq patch %s to %d:%s\n') %
1599 1599 (name, state[rev], repo[state[rev]]))
1600 1600 mq.qimport(repo, (), patchname=name, git=isgit,
1601 1601 rev=["%d" % state[rev]])
1602 1602 else:
1603 1603 # Rebased and skipped
1604 1604 skippedpatches.add(mqrebase[rev][0])
1605 1605
1606 1606 # Patches were either applied and rebased and imported in
1607 1607 # order, applied and removed or unapplied. Discard the removed
1608 1608 # ones while preserving the original series order and guards.
1609 1609 newseries = [s for s in original_series
1610 1610 if mq.guard_re.split(s, 1)[0] not in skippedpatches]
1611 1611 mq.fullseries[:] = newseries
1612 1612 mq.seriesdirty = True
1613 1613 mq.savedirty()
1614 1614
1615 1615 def storecollapsemsg(repo, collapsemsg):
1616 1616 'Store the collapse message to allow recovery'
1617 1617 collapsemsg = collapsemsg or ''
1618 1618 f = repo.vfs("last-message.txt", "w")
1619 1619 f.write("%s\n" % collapsemsg)
1620 1620 f.close()
1621 1621
1622 1622 def clearcollapsemsg(repo):
1623 1623 'Remove collapse message file'
1624 1624 repo.vfs.unlinkpath("last-message.txt", ignoremissing=True)
1625 1625
1626 1626 def restorecollapsemsg(repo, isabort):
1627 1627 'Restore previously stored collapse message'
1628 1628 try:
1629 1629 f = repo.vfs("last-message.txt")
1630 1630 collapsemsg = f.readline().strip()
1631 1631 f.close()
1632 1632 except IOError as err:
1633 1633 if err.errno != errno.ENOENT:
1634 1634 raise
1635 1635 if isabort:
1636 1636 # Oh well, just abort like normal
1637 1637 collapsemsg = ''
1638 1638 else:
1639 1639 raise error.Abort(_('missing .hg/last-message.txt for rebase'))
1640 1640 return collapsemsg
1641 1641
1642 1642 def clearstatus(repo):
1643 1643 'Remove the status files'
1644 1644 # Make sure the active transaction won't write the state file
1645 1645 tr = repo.currenttransaction()
1646 1646 if tr:
1647 1647 tr.removefilegenerator('rebasestate')
1648 1648 repo.vfs.unlinkpath("rebasestate", ignoremissing=True)
1649 1649
1650 1650 def needupdate(repo, state):
1651 1651 '''check whether we should `update --clean` away from a merge, or if
1652 1652 somehow the working dir got forcibly updated, e.g. by older hg'''
1653 1653 parents = [p.rev() for p in repo[None].parents()]
1654 1654
1655 1655 # Are we in a merge state at all?
1656 1656 if len(parents) < 2:
1657 1657 return False
1658 1658
1659 1659 # We should be standing on the first as-of-yet unrebased commit.
1660 1660 firstunrebased = min([old for old, new in state.iteritems()
1661 1661 if new == nullrev])
1662 1662 if firstunrebased in parents:
1663 1663 return True
1664 1664
1665 1665 return False
1666 1666
1667 1667 def sortsource(destmap):
1668 1668 """yield source revisions in an order that we only rebase things once
1669 1669
1670 1670 If source and destination overlaps, we should filter out revisions
1671 1671 depending on other revisions which hasn't been rebased yet.
1672 1672
1673 1673 Yield a sorted list of revisions each time.
1674 1674
1675 1675 For example, when rebasing A to B, B to C. This function yields [B], then
1676 1676 [A], indicating B needs to be rebased first.
1677 1677
1678 1678 Raise if there is a cycle so the rebase is impossible.
1679 1679 """
1680 1680 srcset = set(destmap)
1681 1681 while srcset:
1682 1682 srclist = sorted(srcset)
1683 1683 result = []
1684 1684 for r in srclist:
1685 1685 if destmap[r] not in srcset:
1686 1686 result.append(r)
1687 1687 if not result:
1688 1688 raise error.Abort(_('source and destination form a cycle'))
1689 1689 srcset -= set(result)
1690 1690 yield result
1691 1691
1692 1692 def buildstate(repo, destmap, collapse):
1693 1693 '''Define which revisions are going to be rebased and where
1694 1694
1695 1695 repo: repo
1696 1696 destmap: {srcrev: destrev}
1697 1697 '''
1698 1698 rebaseset = destmap.keys()
1699 1699 originalwd = repo['.'].rev()
1700 1700
1701 1701 # This check isn't strictly necessary, since mq detects commits over an
1702 1702 # applied patch. But it prevents messing up the working directory when
1703 1703 # a partially completed rebase is blocked by mq.
1704 1704 if 'qtip' in repo.tags():
1705 1705 mqapplied = set(repo[s.node].rev() for s in repo.mq.applied)
1706 1706 if set(destmap.values()) & mqapplied:
1707 1707 raise error.Abort(_('cannot rebase onto an applied mq patch'))
1708 1708
1709 1709 # Get "cycle" error early by exhausting the generator.
1710 1710 sortedsrc = list(sortsource(destmap)) # a list of sorted revs
1711 1711 if not sortedsrc:
1712 1712 raise error.Abort(_('no matching revisions'))
1713 1713
1714 1714 # Only check the first batch of revisions to rebase not depending on other
1715 1715 # rebaseset. This means "source is ancestor of destination" for the second
1716 1716 # (and following) batches of revisions are not checked here. We rely on
1717 1717 # "defineparents" to do that check.
1718 1718 roots = list(repo.set('roots(%ld)', sortedsrc[0]))
1719 1719 if not roots:
1720 1720 raise error.Abort(_('no matching revisions'))
1721 1721 def revof(r):
1722 1722 return r.rev()
1723 1723 roots = sorted(roots, key=revof)
1724 1724 state = dict.fromkeys(rebaseset, revtodo)
1725 1725 emptyrebase = (len(sortedsrc) == 1)
1726 1726 for root in roots:
1727 1727 dest = repo[destmap[root.rev()]]
1728 1728 commonbase = root.ancestor(dest)
1729 1729 if commonbase == root:
1730 1730 raise error.Abort(_('source is ancestor of destination'))
1731 1731 if commonbase == dest:
1732 1732 wctx = repo[None]
1733 1733 if dest == wctx.p1():
1734 1734 # when rebasing to '.', it will use the current wd branch name
1735 1735 samebranch = root.branch() == wctx.branch()
1736 1736 else:
1737 1737 samebranch = root.branch() == dest.branch()
1738 1738 if not collapse and samebranch and dest in root.parents():
1739 1739 # mark the revision as done by setting its new revision
1740 1740 # equal to its old (current) revisions
1741 1741 state[root.rev()] = root.rev()
1742 1742 repo.ui.debug('source is a child of destination\n')
1743 1743 continue
1744 1744
1745 1745 emptyrebase = False
1746 1746 repo.ui.debug('rebase onto %s starting from %s\n' % (dest, root))
1747 1747 if emptyrebase:
1748 1748 return None
1749 1749 for rev in sorted(state):
1750 1750 parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
1751 1751 # if all parents of this revision are done, then so is this revision
1752 1752 if parents and all((state.get(p) == p for p in parents)):
1753 1753 state[rev] = rev
1754 1754 return originalwd, destmap, state
1755 1755
1756 1756 def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None,
1757 1757 keepf=False, fm=None, backup=True):
1758 1758 """dispose of rebased revision at the end of the rebase
1759 1759
1760 1760 If `collapsedas` is not None, the rebase was a collapse whose result if the
1761 1761 `collapsedas` node.
1762 1762
1763 1763 If `keepf` is not True, the rebase has --keep set and no nodes should be
1764 1764 removed (but bookmarks still need to be moved).
1765 1765
1766 1766 If `backup` is False, no backup will be stored when stripping rebased
1767 1767 revisions.
1768 1768 """
1769 1769 tonode = repo.changelog.node
1770 1770 replacements = {}
1771 1771 moves = {}
1772 1772 stripcleanup = not obsolete.isenabled(repo, obsolete.createmarkersopt)
1773 1773
1774 1774 collapsednodes = []
1775 1775 for rev, newrev in sorted(state.items()):
1776 1776 if newrev >= 0 and newrev != rev:
1777 1777 oldnode = tonode(rev)
1778 1778 newnode = collapsedas or tonode(newrev)
1779 1779 moves[oldnode] = newnode
1780 1780 if not keepf:
1781 1781 succs = None
1782 1782 if rev in skipped:
1783 1783 if stripcleanup or not repo[rev].obsolete():
1784 1784 succs = ()
1785 1785 elif collapsedas:
1786 1786 collapsednodes.append(oldnode)
1787 1787 else:
1788 1788 succs = (newnode,)
1789 1789 if succs is not None:
1790 1790 replacements[(oldnode,)] = succs
1791 1791 if collapsednodes:
1792 1792 replacements[tuple(collapsednodes)] = (collapsedas,)
1793 1793 scmutil.cleanupnodes(repo, replacements, 'rebase', moves, backup=backup)
1794 1794 if fm:
1795 1795 hf = fm.hexfunc
1796 1796 fl = fm.formatlist
1797 1797 fd = fm.formatdict
1798 1798 changes = {}
1799 1799 for oldns, newn in replacements.iteritems():
1800 1800 for oldn in oldns:
1801 1801 changes[hf(oldn)] = fl([hf(n) for n in newn], name='node')
1802 1802 nodechanges = fd(changes, key="oldnode", value="newnodes")
1803 1803 fm.data(nodechanges=nodechanges)
1804 1804
1805 1805 def pullrebase(orig, ui, repo, *args, **opts):
1806 1806 'Call rebase after pull if the latter has been invoked with --rebase'
1807 1807 ret = None
1808 1808 if opts.get(r'rebase'):
1809 1809 if ui.configbool('commands', 'rebase.requiredest'):
1810 1810 msg = _('rebase destination required by configuration')
1811 1811 hint = _('use hg pull followed by hg rebase -d DEST')
1812 1812 raise error.Abort(msg, hint=hint)
1813 1813
1814 1814 with repo.wlock(), repo.lock():
1815 1815 if opts.get(r'update'):
1816 1816 del opts[r'update']
1817 1817 ui.debug('--update and --rebase are not compatible, ignoring '
1818 1818 'the update flag\n')
1819 1819
1820 1820 cmdutil.checkunfinished(repo)
1821 1821 cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: '
1822 1822 'please commit or shelve your changes first'))
1823 1823
1824 1824 revsprepull = len(repo)
1825 1825 origpostincoming = commands.postincoming
1826 1826 def _dummy(*args, **kwargs):
1827 1827 pass
1828 1828 commands.postincoming = _dummy
1829 1829 try:
1830 1830 ret = orig(ui, repo, *args, **opts)
1831 1831 finally:
1832 1832 commands.postincoming = origpostincoming
1833 1833 revspostpull = len(repo)
1834 1834 if revspostpull > revsprepull:
1835 1835 # --rev option from pull conflict with rebase own --rev
1836 1836 # dropping it
1837 1837 if r'rev' in opts:
1838 1838 del opts[r'rev']
1839 1839 # positional argument from pull conflicts with rebase's own
1840 1840 # --source.
1841 1841 if r'source' in opts:
1842 1842 del opts[r'source']
1843 1843 # revsprepull is the len of the repo, not revnum of tip.
1844 1844 destspace = list(repo.changelog.revs(start=revsprepull))
1845 1845 opts[r'_destspace'] = destspace
1846 1846 try:
1847 1847 rebase(ui, repo, **opts)
1848 1848 except error.NoMergeDestAbort:
1849 1849 # we can maybe update instead
1850 1850 rev, _a, _b = destutil.destupdate(repo)
1851 1851 if rev == repo['.'].rev():
1852 1852 ui.status(_('nothing to rebase\n'))
1853 1853 else:
1854 1854 ui.status(_('nothing to rebase - updating instead\n'))
1855 1855 # not passing argument to get the bare update behavior
1856 1856 # with warning and trumpets
1857 1857 commands.update(ui, repo)
1858 1858 else:
1859 1859 if opts.get(r'tool'):
1860 1860 raise error.Abort(_('--tool can only be used with --rebase'))
1861 1861 ret = orig(ui, repo, *args, **opts)
1862 1862
1863 1863 return ret
1864 1864
1865 1865 def _filterobsoleterevs(repo, revs):
1866 1866 """returns a set of the obsolete revisions in revs"""
1867 1867 return set(r for r in revs if repo[r].obsolete())
1868 1868
1869 1869 def _computeobsoletenotrebased(repo, rebaseobsrevs, destmap):
1870 1870 """Return (obsoletenotrebased, obsoletewithoutsuccessorindestination).
1871 1871
1872 1872 `obsoletenotrebased` is a mapping mapping obsolete => successor for all
1873 1873 obsolete nodes to be rebased given in `rebaseobsrevs`.
1874 1874
1875 1875 `obsoletewithoutsuccessorindestination` is a set with obsolete revisions
1876 1876 without a successor in destination.
1877 1877
1878 1878 `obsoleteextinctsuccessors` is a set of obsolete revisions with only
1879 1879 obsolete successors.
1880 1880 """
1881 1881 obsoletenotrebased = {}
1882 1882 obsoletewithoutsuccessorindestination = set([])
1883 1883 obsoleteextinctsuccessors = set([])
1884 1884
1885 1885 assert repo.filtername is None
1886 1886 cl = repo.changelog
1887 1887 nodemap = cl.nodemap
1888 1888 extinctrevs = set(repo.revs('extinct()'))
1889 1889 for srcrev in rebaseobsrevs:
1890 1890 srcnode = cl.node(srcrev)
1891 1891 # XXX: more advanced APIs are required to handle split correctly
1892 1892 successors = set(obsutil.allsuccessors(repo.obsstore, [srcnode]))
1893 1893 # obsutil.allsuccessors includes node itself
1894 1894 successors.remove(srcnode)
1895 1895 succrevs = {nodemap[s] for s in successors if s in nodemap}
1896 1896 if succrevs.issubset(extinctrevs):
1897 1897 # all successors are extinct
1898 1898 obsoleteextinctsuccessors.add(srcrev)
1899 1899 if not successors:
1900 1900 # no successor
1901 1901 obsoletenotrebased[srcrev] = None
1902 1902 else:
1903 1903 dstrev = destmap[srcrev]
1904 1904 for succrev in succrevs:
1905 1905 if cl.isancestorrev(succrev, dstrev):
1906 1906 obsoletenotrebased[srcrev] = succrev
1907 1907 break
1908 1908 else:
1909 1909 # If 'srcrev' has a successor in rebase set but none in
1910 1910 # destination (which would be catched above), we shall skip it
1911 1911 # and its descendants to avoid divergence.
1912 1912 if srcrev in extinctrevs or any(s in destmap for s in succrevs):
1913 1913 obsoletewithoutsuccessorindestination.add(srcrev)
1914 1914
1915 1915 return (
1916 1916 obsoletenotrebased,
1917 1917 obsoletewithoutsuccessorindestination,
1918 1918 obsoleteextinctsuccessors,
1919 1919 )
1920 1920
1921 1921 def summaryhook(ui, repo):
1922 1922 if not repo.vfs.exists('rebasestate'):
1923 1923 return
1924 1924 try:
1925 1925 rbsrt = rebaseruntime(repo, ui, {})
1926 1926 rbsrt.restorestatus()
1927 1927 state = rbsrt.state
1928 1928 except error.RepoLookupError:
1929 1929 # i18n: column positioning for "hg summary"
1930 1930 msg = _('rebase: (use "hg rebase --abort" to clear broken state)\n')
1931 1931 ui.write(msg)
1932 1932 return
1933 1933 numrebased = len([i for i in state.itervalues() if i >= 0])
1934 1934 # i18n: column positioning for "hg summary"
1935 1935 ui.write(_('rebase: %s, %s (rebase --continue)\n') %
1936 1936 (ui.label(_('%d rebased'), 'rebase.rebased') % numrebased,
1937 1937 ui.label(_('%d remaining'), 'rebase.remaining') %
1938 1938 (len(state) - numrebased)))
1939 1939
1940 1940 def uisetup(ui):
1941 1941 #Replace pull with a decorator to provide --rebase option
1942 1942 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
1943 1943 entry[1].append(('', 'rebase', None,
1944 1944 _("rebase working directory to branch head")))
1945 1945 entry[1].append(('t', 'tool', '',
1946 1946 _("specify merge tool for rebase")))
1947 1947 cmdutil.summaryhooks.add('rebase', summaryhook)
1948 1948 cmdutil.unfinishedstates.append(
1949 1949 ['rebasestate', False, False, _('rebase in progress'),
1950 1950 _("use 'hg rebase --continue' or 'hg rebase --abort'")])
1951 1951 cmdutil.afterresolvedstates.append(
1952 1952 ['rebasestate', _('hg rebase --continue')])
@@ -1,503 +1,503 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [phases]
6 6 > publish=False
7 7 >
8 8 > [alias]
9 9 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
10 10 > EOF
11 11
12 12
13 13 $ hg init a
14 14 $ cd a
15 15
16 16 $ touch .hg/rebasestate
17 17 $ hg sum
18 18 parent: -1:000000000000 tip (empty repository)
19 19 branch: default
20 20 commit: (clean)
21 21 update: (current)
22 22 abort: .hg/rebasestate is incomplete
23 23 [255]
24 24 $ rm .hg/rebasestate
25 25
26 26 $ echo c1 > common
27 27 $ hg add common
28 28 $ hg ci -m C1
29 29
30 30 $ echo c2 >> common
31 31 $ hg ci -m C2
32 32
33 33 $ echo c3 >> common
34 34 $ hg ci -m C3
35 35
36 36 $ hg up -q -C 1
37 37
38 38 $ echo l1 >> extra
39 39 $ hg add extra
40 40 $ hg ci -m L1
41 41 created new head
42 42
43 43 $ sed -e 's/c2/l2/' common > common.new
44 44 $ mv common.new common
45 45 $ hg ci -m L2
46 46
47 47 $ hg phase --force --secret 2
48 48
49 49 $ hg tglog
50 50 @ 4:draft 'L2'
51 51 |
52 52 o 3:draft 'L1'
53 53 |
54 54 | o 2:secret 'C3'
55 55 |/
56 56 o 1:draft 'C2'
57 57 |
58 58 o 0:draft 'C1'
59 59
60 60
61 61 Conflicting rebase:
62 62
63 63 $ hg rebase -s 3 -d 2
64 64 rebasing 3:3163e20567cc "L1"
65 65 rebasing 4:46f0b057b5c0 "L2" (tip)
66 66 merging common
67 67 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
68 68 unresolved conflicts (see hg resolve, then hg rebase --continue)
69 69 [1]
70 70
71 71 Insert unsupported advisory merge record:
72 72
73 73 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -x
74 74 $ hg debugmergestate
75 75 * version 2 records
76 76 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
77 77 other: 46f0b057b5c061d276b91491c22151f78698abd2
78 78 labels:
79 79 local: dest
80 80 other: source
81 81 unrecognized entry: x advisory record
82 82 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
83 83 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
84 84 local path: common (flags "")
85 85 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
86 86 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
87 87 $ hg resolve -l
88 88 U common
89 89
90 90 Insert unsupported mandatory merge record:
91 91
92 92 $ hg --config extensions.fakemergerecord=$TESTDIR/fakemergerecord.py fakemergerecord -X
93 93 $ hg debugmergestate
94 94 * version 2 records
95 95 local: 3e046f2ecedb793b97ed32108086edd1a162f8bc
96 96 other: 46f0b057b5c061d276b91491c22151f78698abd2
97 97 labels:
98 98 local: dest
99 99 other: source
100 100 file extras: common (ancestorlinknode = 3163e20567cc93074fbb7a53c8b93312e59dbf2c)
101 101 file: common (record type "F", state "u", hash 94c8c21d08740f5da9eaa38d1f175c592692f0d1)
102 102 local path: common (flags "")
103 103 ancestor path: common (node de0a666fdd9c1a0b0698b90d85064d8bd34f74b6)
104 104 other path: common (node 2f6411de53677f6f1048fef5bf888d67a342e0a5)
105 105 unrecognized entry: X mandatory record
106 106 $ hg resolve -l
107 107 abort: unsupported merge state records: X
108 108 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
109 109 [255]
110 110 $ hg resolve -ma
111 111 abort: unsupported merge state records: X
112 112 (see https://mercurial-scm.org/wiki/MergeStateRecords for more information)
113 113 [255]
114 114
115 115 Abort (should clear out unsupported merge state):
116 116
117 117 $ hg rebase --abort
118 118 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3e046f2ecedb-6beef7d5-backup.hg
119 119 rebase aborted
120 120 $ hg debugmergestate
121 121 no merge state found
122 122
123 123 $ hg tglog
124 124 @ 4:draft 'L2'
125 125 |
126 126 o 3:draft 'L1'
127 127 |
128 128 | o 2:secret 'C3'
129 129 |/
130 130 o 1:draft 'C2'
131 131 |
132 132 o 0:draft 'C1'
133 133
134 134 Test safety for inconsistent rebase state, which may be created (and
135 135 forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
136 136 earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
137 137
138 138 $ hg rebase -s 3 -d 2
139 139 rebasing 3:3163e20567cc "L1"
140 140 rebasing 4:46f0b057b5c0 "L2" (tip)
141 141 merging common
142 142 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
143 143 unresolved conflicts (see hg resolve, then hg rebase --continue)
144 144 [1]
145 145
146 146 $ mv .hg/rebasestate .hg/rebasestate.back
147 147 $ hg update --quiet --clean 2
148 148 $ hg --config extensions.mq= strip --quiet "destination()"
149 149 $ mv .hg/rebasestate.back .hg/rebasestate
150 150
151 151 $ hg rebase --continue
152 152 abort: cannot continue inconsistent rebase
153 153 (use "hg rebase --abort" to clear broken state)
154 154 [255]
155 155 $ hg summary | grep '^rebase: '
156 156 rebase: (use "hg rebase --abort" to clear broken state)
157 157 $ hg rebase --abort
158 158 rebase aborted (no revision is removed, only broken state is cleared)
159 159
160 160 $ cd ..
161 161
162 162
163 163 Construct new repo:
164 164
165 165 $ hg init b
166 166 $ cd b
167 167
168 168 $ echo a > a
169 169 $ hg ci -Am A
170 170 adding a
171 171
172 172 $ echo b > b
173 173 $ hg ci -Am B
174 174 adding b
175 175
176 176 $ echo c > c
177 177 $ hg ci -Am C
178 178 adding c
179 179
180 180 $ hg up -q 0
181 181
182 182 $ echo b > b
183 183 $ hg ci -Am 'B bis'
184 184 adding b
185 185 created new head
186 186
187 187 $ echo c1 > c
188 188 $ hg ci -Am C1
189 189 adding c
190 190
191 191 $ hg phase --force --secret 1
192 192 $ hg phase --public 1
193 193
194 194 Rebase and abort without generating new changesets:
195 195
196 196 $ hg tglog
197 197 @ 4:draft 'C1'
198 198 |
199 199 o 3:draft 'B bis'
200 200 |
201 201 | o 2:secret 'C'
202 202 | |
203 203 | o 1:public 'B'
204 204 |/
205 205 o 0:public 'A'
206 206
207 207 $ hg rebase -b 4 -d 2
208 208 rebasing 3:a6484957d6b9 "B bis"
209 note: rebase of 3:a6484957d6b9 "B bis" created no changes to commit
209 note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
210 210 rebasing 4:145842775fec "C1" (tip)
211 211 merging c
212 212 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
213 213 unresolved conflicts (see hg resolve, then hg rebase --continue)
214 214 [1]
215 215
216 216 $ hg tglog
217 217 @ 4:draft 'C1'
218 218 |
219 219 o 3:draft 'B bis'
220 220 |
221 221 | @ 2:secret 'C'
222 222 | |
223 223 | o 1:public 'B'
224 224 |/
225 225 o 0:public 'A'
226 226
227 227 $ hg rebase -a
228 228 rebase aborted
229 229
230 230 $ hg tglog
231 231 @ 4:draft 'C1'
232 232 |
233 233 o 3:draft 'B bis'
234 234 |
235 235 | o 2:secret 'C'
236 236 | |
237 237 | o 1:public 'B'
238 238 |/
239 239 o 0:public 'A'
240 240
241 241
242 242 $ cd ..
243 243
244 244 rebase abort should not leave working copy in a merge state if tip-1 is public
245 245 (issue4082)
246 246
247 247 $ hg init abortpublic
248 248 $ cd abortpublic
249 249 $ echo a > a && hg ci -Aqm a
250 250 $ hg book master
251 251 $ hg book foo
252 252 $ echo b > b && hg ci -Aqm b
253 253 $ hg up -q master
254 254 $ echo c > c && hg ci -Aqm c
255 255 $ hg phase -p -r .
256 256 $ hg up -q foo
257 257 $ echo C > c && hg ci -Aqm C
258 258 $ hg log -G --template "{rev} {desc} {bookmarks}"
259 259 @ 3 C foo
260 260 |
261 261 | o 2 c master
262 262 | |
263 263 o | 1 b
264 264 |/
265 265 o 0 a
266 266
267 267
268 268 $ hg rebase -d master -r foo
269 269 rebasing 3:6c0f977a22d8 "C" (foo tip)
270 270 merging c
271 271 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
272 272 unresolved conflicts (see hg resolve, then hg rebase --continue)
273 273 [1]
274 274 $ hg rebase --abort
275 275 rebase aborted
276 276 $ hg log -G --template "{rev} {desc} {bookmarks}"
277 277 @ 3 C foo
278 278 |
279 279 | o 2 c master
280 280 | |
281 281 o | 1 b
282 282 |/
283 283 o 0 a
284 284
285 285 $ cd ..
286 286
287 287 Make sure we don't clobber changes in the working directory when the
288 288 user has somehow managed to update to a different revision (issue4009)
289 289
290 290 $ hg init noupdate
291 291 $ cd noupdate
292 292 $ hg book @
293 293 $ echo original > a
294 294 $ hg add a
295 295 $ hg commit -m a
296 296 $ echo x > b
297 297 $ hg add b
298 298 $ hg commit -m b1
299 299 $ hg up 0
300 300 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
301 301 (leaving bookmark @)
302 302 $ hg book foo
303 303 $ echo y > b
304 304 $ hg add b
305 305 $ hg commit -m b2
306 306 created new head
307 307
308 308 $ hg rebase -d @ -b foo --tool=internal:fail
309 309 rebasing 2:070cf4580bb5 "b2" (foo tip)
310 310 unresolved conflicts (see hg resolve, then hg rebase --continue)
311 311 [1]
312 312
313 313 $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
314 314 $ hg up -C 0 # user does other stuff in the repo
315 315 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
316 316
317 317 $ mv rebasestate .hg/ # user upgrades to 2.7
318 318
319 319 $ echo new > a
320 320 $ hg up 1 # user gets an error saying to run hg rebase --abort
321 321 abort: rebase in progress
322 322 (use 'hg rebase --continue' or 'hg rebase --abort')
323 323 [255]
324 324
325 325 $ cat a
326 326 new
327 327 $ hg rebase --abort
328 328 rebase aborted
329 329 $ cat a
330 330 new
331 331
332 332 $ cd ..
333 333
334 334 test aborting an interrupted series (issue5084)
335 335 $ hg init interrupted
336 336 $ cd interrupted
337 337 $ touch base
338 338 $ hg add base
339 339 $ hg commit -m base
340 340 $ touch a
341 341 $ hg add a
342 342 $ hg commit -m a
343 343 $ echo 1 > a
344 344 $ hg commit -m 1
345 345 $ touch b
346 346 $ hg add b
347 347 $ hg commit -m b
348 348 $ echo 2 >> a
349 349 $ hg commit -m c
350 350 $ touch d
351 351 $ hg add d
352 352 $ hg commit -m d
353 353 $ hg co -q 1
354 354 $ hg rm a
355 355 $ hg commit -m no-a
356 356 created new head
357 357 $ hg co 0
358 358 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
359 359 $ hg log -G --template "{rev} {desc} {bookmarks}"
360 360 o 6 no-a
361 361 |
362 362 | o 5 d
363 363 | |
364 364 | o 4 c
365 365 | |
366 366 | o 3 b
367 367 | |
368 368 | o 2 1
369 369 |/
370 370 o 1 a
371 371 |
372 372 @ 0 base
373 373
374 374 $ hg --config extensions.n=$TESTDIR/failfilemerge.py rebase -s 3 -d tip
375 375 rebasing 3:3a71550954f1 "b"
376 376 rebasing 4:e80b69427d80 "c"
377 377 abort: ^C
378 378 [255]
379 379
380 380 New operations are blocked with the correct state message
381 381
382 382 $ find .hg -name '*state' -prune | sort
383 383 .hg/dirstate
384 384 .hg/merge/state
385 385 .hg/rebasestate
386 386 .hg/undo.backup.dirstate
387 387 .hg/undo.dirstate
388 388 .hg/updatestate
389 389
390 390 $ hg rebase -s 3 -d tip
391 391 abort: rebase in progress
392 392 (use 'hg rebase --continue' or 'hg rebase --abort')
393 393 [255]
394 394 $ hg up .
395 395 abort: rebase in progress
396 396 (use 'hg rebase --continue' or 'hg rebase --abort')
397 397 [255]
398 398 $ hg up -C .
399 399 abort: rebase in progress
400 400 (use 'hg rebase --continue' or 'hg rebase --abort')
401 401 [255]
402 402
403 403 $ hg graft 3
404 404 abort: rebase in progress
405 405 (use 'hg rebase --continue' or 'hg rebase --abort')
406 406 [255]
407 407
408 408 $ hg rebase --abort
409 409 saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg
410 410 rebase aborted
411 411 $ hg log -G --template "{rev} {desc} {bookmarks}"
412 412 o 6 no-a
413 413 |
414 414 | o 5 d
415 415 | |
416 416 | o 4 c
417 417 | |
418 418 | o 3 b
419 419 | |
420 420 | o 2 1
421 421 |/
422 422 o 1 a
423 423 |
424 424 @ 0 base
425 425
426 426 $ hg summary
427 427 parent: 0:df4f53cec30a
428 428 base
429 429 branch: default
430 430 commit: (clean)
431 431 update: 6 new changesets (update)
432 432 phases: 7 draft
433 433
434 434 $ cd ..
435 435 On the other hand, make sure we *do* clobber changes whenever we
436 436 haven't somehow managed to update the repo to a different revision
437 437 during a rebase (issue4661)
438 438
439 439 $ hg ini yesupdate
440 440 $ cd yesupdate
441 441 $ echo "initial data" > foo.txt
442 442 $ hg add
443 443 adding foo.txt
444 444 $ hg ci -m "initial checkin"
445 445 $ echo "change 1" > foo.txt
446 446 $ hg ci -m "change 1"
447 447 $ hg up 0
448 448 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 449 $ echo "conflicting change 1" > foo.txt
450 450 $ hg ci -m "conflicting 1"
451 451 created new head
452 452 $ echo "conflicting change 2" > foo.txt
453 453 $ hg ci -m "conflicting 2"
454 454
455 455 $ hg rebase -d 1 --tool 'internal:fail'
456 456 rebasing 2:e4ea5cdc9789 "conflicting 1"
457 457 unresolved conflicts (see hg resolve, then hg rebase --continue)
458 458 [1]
459 459 $ hg rebase --abort
460 460 rebase aborted
461 461 $ hg summary
462 462 parent: 3:b16646383533 tip
463 463 conflicting 2
464 464 branch: default
465 465 commit: (clean)
466 466 update: 1 new changesets, 2 branch heads (merge)
467 467 phases: 4 draft
468 468 $ cd ..
469 469
470 470 test aborting a rebase succeeds after rebasing with skipped commits onto a
471 471 public changeset (issue4896)
472 472
473 473 $ hg init succeedonpublic
474 474 $ cd succeedonpublic
475 475 $ echo 'content' > root
476 476 $ hg commit -A -m 'root' -q
477 477
478 478 set up public branch
479 479 $ echo 'content' > disappear
480 480 $ hg commit -A -m 'disappear public' -q
481 481 commit will cause merge conflict on rebase
482 482 $ echo '' > root
483 483 $ hg commit -m 'remove content public' -q
484 484 $ hg phase --public
485 485
486 486 setup the draft branch that will be rebased onto public commit
487 487 $ hg up -r 0 -q
488 488 $ echo 'content' > disappear
489 489 commit will disappear
490 490 $ hg commit -A -m 'disappear draft' -q
491 491 $ echo 'addedcontADDEDentadded' > root
492 492 commit will cause merge conflict on rebase
493 493 $ hg commit -m 'add content draft' -q
494 494
495 495 $ hg rebase -d 'public()' --tool :merge -q
496 note: rebase of 3:0682fd3dabf5 "disappear draft" created no changes to commit
496 note: not rebasing 3:0682fd3dabf5 "disappear draft", its destination already has all its changes
497 497 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
498 498 unresolved conflicts (see hg resolve, then hg rebase --continue)
499 499 [1]
500 500 $ hg rebase --abort
501 501 rebase aborted
502 502 $ cd ..
503 503
@@ -1,483 +1,483 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > mq=
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 11 > theads = heads --template "{rev}: '{desc}' {branches}\n"
12 12 > EOF
13 13
14 14 $ hg init a
15 15 $ cd a
16 16
17 17 $ echo a > a
18 18 $ hg ci -Am A
19 19 adding a
20 20
21 21 $ hg branch branch1
22 22 marked working directory as branch branch1
23 23 (branches are permanent and global, did you want a bookmark?)
24 24 $ hg ci -m 'branch1'
25 25
26 26 $ echo b > b
27 27 $ hg ci -Am B
28 28 adding b
29 29
30 30 $ hg up -q 0
31 31
32 32 $ hg branch branch2
33 33 marked working directory as branch branch2
34 34 $ hg ci -m 'branch2'
35 35
36 36 $ echo c > C
37 37 $ hg ci -Am C
38 38 adding C
39 39
40 40 $ hg up -q 2
41 41
42 42 $ hg branch -f branch2
43 43 marked working directory as branch branch2
44 44 $ echo d > d
45 45 $ hg ci -Am D
46 46 adding d
47 47 created new head
48 48
49 49 $ echo e > e
50 50 $ hg ci -Am E
51 51 adding e
52 52
53 53 $ hg update default
54 54 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
55 55
56 56 $ hg branch branch3
57 57 marked working directory as branch branch3
58 58 $ hg ci -m 'branch3'
59 59
60 60 $ echo f > f
61 61 $ hg ci -Am F
62 62 adding f
63 63
64 64 $ cd ..
65 65
66 66
67 67 Rebase part of branch2 (5-6) onto branch3 (8):
68 68
69 69 $ hg clone -q -u . a a1
70 70 $ cd a1
71 71
72 72 $ hg tglog
73 73 @ 8: 'F' branch3
74 74 |
75 75 o 7: 'branch3' branch3
76 76 |
77 77 | o 6: 'E' branch2
78 78 | |
79 79 | o 5: 'D' branch2
80 80 | |
81 81 | | o 4: 'C' branch2
82 82 | | |
83 83 +---o 3: 'branch2' branch2
84 84 | |
85 85 | o 2: 'B' branch1
86 86 | |
87 87 | o 1: 'branch1' branch1
88 88 |/
89 89 o 0: 'A'
90 90
91 91 $ hg branches
92 92 branch3 8:4666b71e8e32
93 93 branch2 6:5097051d331d
94 94 branch1 2:0a03079c47fd (inactive)
95 95 default 0:1994f17a630e (inactive)
96 96
97 97 $ hg theads
98 98 8: 'F' branch3
99 99 6: 'E' branch2
100 100 4: 'C' branch2
101 101 2: 'B' branch1
102 102 0: 'A'
103 103
104 104 $ hg rebase -s 5 -d 8
105 105 rebasing 5:635859577d0b "D"
106 106 rebasing 6:5097051d331d "E"
107 107 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/635859577d0b-89160bff-rebase.hg
108 108
109 109 $ hg branches
110 110 branch3 8:466cdfb14b62
111 111 branch2 4:e4fdb121d036
112 112 branch1 2:0a03079c47fd
113 113 default 0:1994f17a630e (inactive)
114 114
115 115 $ hg theads
116 116 8: 'E' branch3
117 117 4: 'C' branch2
118 118 2: 'B' branch1
119 119 0: 'A'
120 120
121 121 $ hg tglog
122 122 o 8: 'E' branch3
123 123 |
124 124 o 7: 'D' branch3
125 125 |
126 126 @ 6: 'F' branch3
127 127 |
128 128 o 5: 'branch3' branch3
129 129 |
130 130 | o 4: 'C' branch2
131 131 | |
132 132 | o 3: 'branch2' branch2
133 133 |/
134 134 | o 2: 'B' branch1
135 135 | |
136 136 | o 1: 'branch1' branch1
137 137 |/
138 138 o 0: 'A'
139 139
140 140 $ cd ..
141 141
142 142
143 143 Rebase head of branch3 (8) onto branch2 (6):
144 144
145 145 $ hg clone -q -u . a a2
146 146 $ cd a2
147 147
148 148 $ hg tglog
149 149 @ 8: 'F' branch3
150 150 |
151 151 o 7: 'branch3' branch3
152 152 |
153 153 | o 6: 'E' branch2
154 154 | |
155 155 | o 5: 'D' branch2
156 156 | |
157 157 | | o 4: 'C' branch2
158 158 | | |
159 159 +---o 3: 'branch2' branch2
160 160 | |
161 161 | o 2: 'B' branch1
162 162 | |
163 163 | o 1: 'branch1' branch1
164 164 |/
165 165 o 0: 'A'
166 166
167 167 $ hg rebase -s 8 -d 6
168 168 rebasing 8:4666b71e8e32 "F" (tip)
169 169 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/4666b71e8e32-fc1c4e96-rebase.hg
170 170
171 171 $ hg branches
172 172 branch2 8:6b4bdc1b5ac0
173 173 branch3 7:653b9feb4616
174 174 branch1 2:0a03079c47fd (inactive)
175 175 default 0:1994f17a630e (inactive)
176 176
177 177 $ hg theads
178 178 8: 'F' branch2
179 179 7: 'branch3' branch3
180 180 4: 'C' branch2
181 181 2: 'B' branch1
182 182 0: 'A'
183 183
184 184 $ hg tglog
185 185 @ 8: 'F' branch2
186 186 |
187 187 | o 7: 'branch3' branch3
188 188 | |
189 189 o | 6: 'E' branch2
190 190 | |
191 191 o | 5: 'D' branch2
192 192 | |
193 193 | | o 4: 'C' branch2
194 194 | | |
195 195 | | o 3: 'branch2' branch2
196 196 | |/
197 197 o | 2: 'B' branch1
198 198 | |
199 199 o | 1: 'branch1' branch1
200 200 |/
201 201 o 0: 'A'
202 202
203 203 $ hg verify -q
204 204
205 205 $ cd ..
206 206
207 207
208 208 Rebase entire branch3 (7-8) onto branch2 (6):
209 209
210 210 $ hg clone -q -u . a a3
211 211 $ cd a3
212 212
213 213 $ hg tglog
214 214 @ 8: 'F' branch3
215 215 |
216 216 o 7: 'branch3' branch3
217 217 |
218 218 | o 6: 'E' branch2
219 219 | |
220 220 | o 5: 'D' branch2
221 221 | |
222 222 | | o 4: 'C' branch2
223 223 | | |
224 224 +---o 3: 'branch2' branch2
225 225 | |
226 226 | o 2: 'B' branch1
227 227 | |
228 228 | o 1: 'branch1' branch1
229 229 |/
230 230 o 0: 'A'
231 231
232 232 $ hg rebase -s 7 -d 6
233 233 rebasing 7:653b9feb4616 "branch3"
234 note: rebase of 7:653b9feb4616 "branch3" created no changes to commit
234 note: not rebasing 7:653b9feb4616 "branch3", its destination already has all its changes
235 235 rebasing 8:4666b71e8e32 "F" (tip)
236 236 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/653b9feb4616-3c88de16-rebase.hg
237 237
238 238 $ hg branches
239 239 branch2 7:6b4bdc1b5ac0
240 240 branch1 2:0a03079c47fd (inactive)
241 241 default 0:1994f17a630e (inactive)
242 242
243 243 $ hg theads
244 244 7: 'F' branch2
245 245 4: 'C' branch2
246 246 2: 'B' branch1
247 247 0: 'A'
248 248
249 249 $ hg tglog
250 250 @ 7: 'F' branch2
251 251 |
252 252 o 6: 'E' branch2
253 253 |
254 254 o 5: 'D' branch2
255 255 |
256 256 | o 4: 'C' branch2
257 257 | |
258 258 | o 3: 'branch2' branch2
259 259 | |
260 260 o | 2: 'B' branch1
261 261 | |
262 262 o | 1: 'branch1' branch1
263 263 |/
264 264 o 0: 'A'
265 265
266 266 $ hg verify -q
267 267
268 268 Stripping multiple branches in one go bypasses the fast-case code to
269 269 update the branch cache.
270 270
271 271 $ hg strip 2
272 272 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
273 273 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/0a03079c47fd-11b7c407-backup.hg
274 274
275 275 $ hg tglog
276 276 o 3: 'C' branch2
277 277 |
278 278 o 2: 'branch2' branch2
279 279 |
280 280 | @ 1: 'branch1' branch1
281 281 |/
282 282 o 0: 'A'
283 283
284 284
285 285 $ hg branches
286 286 branch2 3:e4fdb121d036
287 287 branch1 1:63379ac49655
288 288 default 0:1994f17a630e (inactive)
289 289
290 290 $ hg theads
291 291 3: 'C' branch2
292 292 1: 'branch1' branch1
293 293 0: 'A'
294 294
295 295 Fast path branchcache code should not be invoked if branches stripped is not
296 296 the same as branches remaining.
297 297
298 298 $ hg init b
299 299 $ cd b
300 300
301 301 $ hg branch branch1
302 302 marked working directory as branch branch1
303 303 (branches are permanent and global, did you want a bookmark?)
304 304 $ hg ci -m 'branch1'
305 305
306 306 $ hg branch branch2
307 307 marked working directory as branch branch2
308 308 $ hg ci -m 'branch2'
309 309
310 310 $ hg branch -f branch1
311 311 marked working directory as branch branch1
312 312
313 313 $ echo a > A
314 314 $ hg ci -Am A
315 315 adding A
316 316 created new head
317 317
318 318 $ hg tglog
319 319 @ 2: 'A' branch1
320 320 |
321 321 o 1: 'branch2' branch2
322 322 |
323 323 o 0: 'branch1' branch1
324 324
325 325
326 326 $ hg theads
327 327 2: 'A' branch1
328 328 1: 'branch2' branch2
329 329
330 330 $ hg strip 2
331 331 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
332 332 saved backup bundle to $TESTTMP/a3/b/.hg/strip-backup/a5b4b27ed7b4-a3b6984e-backup.hg
333 333
334 334 $ hg theads
335 335 1: 'branch2' branch2
336 336 0: 'branch1' branch1
337 337
338 338
339 339 Make sure requesting to strip a revision already stripped does not confuse things.
340 340 Try both orders.
341 341
342 342 $ cd ..
343 343
344 344 $ hg init c
345 345 $ cd c
346 346
347 347 $ echo a > a
348 348 $ hg ci -Am A
349 349 adding a
350 350 $ echo b > b
351 351 $ hg ci -Am B
352 352 adding b
353 353 $ echo c > c
354 354 $ hg ci -Am C
355 355 adding c
356 356 $ echo d > d
357 357 $ hg ci -Am D
358 358 adding d
359 359 $ echo e > e
360 360 $ hg ci -Am E
361 361 adding e
362 362
363 363 $ hg tglog
364 364 @ 4: 'E'
365 365 |
366 366 o 3: 'D'
367 367 |
368 368 o 2: 'C'
369 369 |
370 370 o 1: 'B'
371 371 |
372 372 o 0: 'A'
373 373
374 374
375 375 $ hg strip 3 4
376 376 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
377 377 saved backup bundle to $TESTTMP/a3/c/.hg/strip-backup/67a385d4e6f2-b9243789-backup.hg
378 378
379 379 $ hg theads
380 380 2: 'C'
381 381
382 382 $ hg strip 2 1
383 383 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
384 384 saved backup bundle to $TESTTMP/a3/c/.hg/strip-backup/6c81ed0049f8-a687065f-backup.hg
385 385
386 386 $ hg theads
387 387 0: 'A'
388 388
389 389 Make sure rebase does not break for phase/filter related reason
390 390 ----------------------------------------------------------------
391 391 (issue3858)
392 392
393 393 $ cd ..
394 394
395 395 $ cat >> $HGRCPATH << EOF
396 396 > [ui]
397 397 > logtemplate={rev} {desc} {phase}\n
398 398 > EOF
399 399
400 400
401 401 $ hg init c4
402 402 $ cd c4
403 403
404 404 $ echo a > a
405 405 $ hg ci -Am A
406 406 adding a
407 407 $ echo b > b
408 408 $ hg ci -Am B
409 409 adding b
410 410 $ hg up 0
411 411 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
412 412 $ echo c > c
413 413 $ hg ci -Am C
414 414 adding c
415 415 created new head
416 416 $ hg up 1
417 417 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
418 418 $ hg merge
419 419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 420 (branch merge, don't forget to commit)
421 421 $ hg ci -m d
422 422 $ hg up 2
423 423 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
424 424 $ echo e > e
425 425 $ hg ci -Am E
426 426 adding e
427 427 created new head
428 428 $ hg merge 3
429 429 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
430 430 (branch merge, don't forget to commit)
431 431 $ hg ci -m F
432 432 $ hg up 3
433 433 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
434 434 $ echo g > g
435 435 $ hg ci -Am G
436 436 adding g
437 437 created new head
438 438 $ echo h > h
439 439 $ hg ci -Am H
440 440 adding h
441 441 $ hg up 5
442 442 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
443 443 $ echo i > i
444 444 $ hg ci -Am I
445 445 adding i
446 446
447 447 Turn most changeset public
448 448
449 449 $ hg ph -p 7
450 450
451 451 $ hg heads
452 452 8 I draft
453 453 7 H public
454 454 $ hg log -G
455 455 @ 8 I draft
456 456 |
457 457 | o 7 H public
458 458 | |
459 459 | o 6 G public
460 460 | |
461 461 o | 5 F draft
462 462 |\|
463 463 o | 4 E draft
464 464 | |
465 465 | o 3 d public
466 466 |/|
467 467 o | 2 C public
468 468 | |
469 469 | o 1 B public
470 470 |/
471 471 o 0 A public
472 472
473 473
474 474 $ cat > $TESTTMP/checkeditform.sh <<EOF
475 475 > env | grep HGEDITFORM
476 476 > true
477 477 > EOF
478 478 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --dest 7 --source 5 -e
479 479 rebasing 5:361a99976cc9 "F"
480 480 HGEDITFORM=rebase.merge
481 481 rebasing 8:326cfedc031c "I" (tip)
482 482 HGEDITFORM=rebase.normal
483 483 saved backup bundle to $TESTTMP/a3/c4/.hg/strip-backup/361a99976cc9-35e980d0-rebase.hg
@@ -1,819 +1,819 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > mq=
5 5 > drawdag=$TESTDIR/drawdag.py
6 6 >
7 7 > [phases]
8 8 > publish=False
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
12 12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 Highest phase of source commits is used:
16 16
17 17 $ hg init phase
18 18 $ cd phase
19 19 $ hg debugdrawdag << 'EOF'
20 20 > D
21 21 > |
22 22 > F C
23 23 > | |
24 24 > E B
25 25 > |/
26 26 > A
27 27 > EOF
28 28
29 29 $ hg phase --force --secret D
30 30
31 31 $ cat > $TESTTMP/editor.sh <<EOF
32 32 > echo "==== before editing"
33 33 > cat \$1
34 34 > echo "===="
35 35 > echo "edited manually" >> \$1
36 36 > EOF
37 37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --dest F
38 38 rebasing 1:112478962961 "B" (B)
39 39 rebasing 3:26805aba1e60 "C" (C)
40 40 rebasing 5:f585351a92f8 "D" (D tip)
41 41 ==== before editing
42 42 Collapsed revision
43 43 * B
44 44 * C
45 45 * D
46 46
47 47
48 48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
49 49 HG: Leave message empty to abort commit.
50 50 HG: --
51 51 HG: user: test
52 52 HG: branch 'default'
53 53 HG: added B
54 54 HG: added C
55 55 HG: added D
56 56 ====
57 57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
58 58
59 59 $ hg tglogp
60 60 o 3: 92fa5f5fe108 secret 'Collapsed revision
61 61 | * B
62 62 | * C
63 63 | * D
64 64 |
65 65 |
66 66 | edited manually'
67 67 o 2: 64a8289d2492 draft 'F'
68 68 |
69 69 o 1: 7fb047a69f22 draft 'E'
70 70 |
71 71 o 0: 426bada5c675 draft 'A'
72 72
73 73 $ hg manifest --rev tip
74 74 A
75 75 B
76 76 C
77 77 D
78 78 E
79 79 F
80 80
81 81 $ cd ..
82 82
83 83
84 84 Merge gets linearized:
85 85
86 86 $ hg init linearized-merge
87 87 $ cd linearized-merge
88 88
89 89 $ hg debugdrawdag << 'EOF'
90 90 > F D
91 91 > |/|
92 92 > C B
93 93 > |/
94 94 > A
95 95 > EOF
96 96
97 97 $ hg phase --force --secret D
98 98 $ hg rebase --source B --collapse --dest F
99 99 rebasing 1:112478962961 "B" (B)
100 100 rebasing 3:4e4f9194f9f1 "D" (D)
101 101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
102 102
103 103 $ hg tglog
104 104 o 3: 5bdc08b7da2b 'Collapsed revision
105 105 | * B
106 106 | * D'
107 107 o 2: afc707c82df0 'F'
108 108 |
109 109 o 1: dc0947a82db8 'C'
110 110 |
111 111 o 0: 426bada5c675 'A'
112 112
113 113 $ hg manifest --rev tip
114 114 A
115 115 B
116 116 C
117 117 F
118 118
119 119 $ cd ..
120 120
121 121 Custom message:
122 122
123 123 $ hg init message
124 124 $ cd message
125 125
126 126 $ hg debugdrawdag << 'EOF'
127 127 > C
128 128 > |
129 129 > D B
130 130 > |/
131 131 > A
132 132 > EOF
133 133
134 134
135 135 $ hg rebase --base B -m 'custom message'
136 136 abort: message can only be specified with collapse
137 137 [255]
138 138
139 139 $ cat > $TESTTMP/checkeditform.sh <<EOF
140 140 > env | grep HGEDITFORM
141 141 > true
142 142 > EOF
143 143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
144 144 rebasing 1:112478962961 "B" (B)
145 145 rebasing 3:26805aba1e60 "C" (C tip)
146 146 HGEDITFORM=rebase.collapse
147 147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
148 148
149 149 $ hg tglog
150 150 o 2: 2f197b9a08f3 'custom message'
151 151 |
152 152 o 1: b18e25de2cf5 'D'
153 153 |
154 154 o 0: 426bada5c675 'A'
155 155
156 156 $ hg manifest --rev tip
157 157 A
158 158 B
159 159 C
160 160 D
161 161
162 162 $ cd ..
163 163
164 164 Rebase and collapse - more than one external (fail):
165 165
166 166 $ hg init multiple-external-parents
167 167 $ cd multiple-external-parents
168 168
169 169 $ hg debugdrawdag << 'EOF'
170 170 > G
171 171 > |\
172 172 > | F
173 173 > | |
174 174 > D E
175 175 > |\|
176 176 > H C B
177 177 > \|/
178 178 > A
179 179 > EOF
180 180
181 181 $ hg rebase -s C --dest H --collapse
182 182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
183 183 [255]
184 184
185 185 Rebase and collapse - E onto H:
186 186
187 187 $ hg rebase -s E --dest I --collapse # root (E) is not a merge
188 188 abort: unknown revision 'I'!
189 189 [255]
190 190
191 191 $ hg tglog
192 192 o 7: 64e264db77f0 'G'
193 193 |\
194 194 | o 6: 11abe3fb10b8 'F'
195 195 | |
196 196 | o 5: 49cb92066bfd 'E'
197 197 | |
198 198 o | 4: 4e4f9194f9f1 'D'
199 199 |\|
200 200 | | o 3: 575c4b5ec114 'H'
201 201 | | |
202 202 o---+ 2: dc0947a82db8 'C'
203 203 / /
204 204 o / 1: 112478962961 'B'
205 205 |/
206 206 o 0: 426bada5c675 'A'
207 207
208 208 $ hg manifest --rev tip
209 209 A
210 210 B
211 211 C
212 212 E
213 213 F
214 214
215 215 $ cd ..
216 216
217 217
218 218
219 219
220 220 Test that branchheads cache is updated correctly when doing a strip in which
221 221 the parent of the ancestor node to be stripped does not become a head and also,
222 222 the parent of a node that is a child of the node stripped becomes a head (node
223 223 3). The code is now much simpler and we could just test a simpler scenario
224 224 We keep it the test this way in case new complexity is injected.
225 225
226 226 Create repo b:
227 227
228 228 $ hg init branch-heads
229 229 $ cd branch-heads
230 230
231 231 $ hg debugdrawdag << 'EOF'
232 232 > G
233 233 > |\
234 234 > | F
235 235 > | |
236 236 > D E
237 237 > |\|
238 238 > H C B
239 239 > \|/
240 240 > A
241 241 > EOF
242 242
243 243 $ hg heads --template="{rev}:{node} {branch}\n"
244 244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
245 245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
246 246
247 247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
248 248 64e264db77f061f16d9132b70c5a58e2461fb630 7
249 249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
250 250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
251 251
252 252 $ hg strip 4
253 253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
254 254
255 255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
256 256 11abe3fb10b8689b560681094b17fe161871d043 5
257 257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
258 258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
259 259 11abe3fb10b8689b560681094b17fe161871d043 o default
260 260
261 261 $ hg heads --template="{rev}:{node} {branch}\n"
262 262 5:11abe3fb10b8689b560681094b17fe161871d043 default
263 263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
264 264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
265 265
266 266 $ cd ..
267 267
268 268
269 269
270 270 Preserves external parent
271 271
272 272 $ hg init external-parent
273 273 $ cd external-parent
274 274
275 275 $ hg debugdrawdag << 'EOF'
276 276 > H
277 277 > |\
278 278 > | G
279 279 > | |
280 280 > | F # F/E = F\n
281 281 > | |
282 282 > D E # D/D = D\n
283 283 > |\|
284 284 > I C B
285 285 > \|/
286 286 > A
287 287 > EOF
288 288
289 289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
290 290 rebasing 6:c82b08f646f1 "F" (F)
291 291 rebasing 7:a6db7fa104e1 "G" (G)
292 292 rebasing 8:e1d201b72d91 "H" (H tip)
293 293 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
294 294
295 295 $ hg tglog
296 296 o 6: 681daa3e686d 'Collapsed revision
297 297 |\ * F
298 298 | | * G
299 299 | | * H'
300 300 | | o 5: 49cb92066bfd 'E'
301 301 | | |
302 302 | o | 4: 09143c0bf13e 'D'
303 303 | |\|
304 304 o | | 3: 08ebfeb61bac 'I'
305 305 | | |
306 306 | o | 2: dc0947a82db8 'C'
307 307 |/ /
308 308 | o 1: 112478962961 'B'
309 309 |/
310 310 o 0: 426bada5c675 'A'
311 311
312 312 $ hg manifest --rev tip
313 313 A
314 314 C
315 315 D
316 316 E
317 317 F
318 318 G
319 319 I
320 320
321 321 $ hg up tip -q
322 322 $ cat E
323 323 F
324 324
325 325 $ cd ..
326 326
327 327 Rebasing from multiple bases:
328 328
329 329 $ hg init multiple-bases
330 330 $ cd multiple-bases
331 331 $ hg debugdrawdag << 'EOF'
332 332 > C B
333 333 > D |/
334 334 > |/
335 335 > A
336 336 > EOF
337 337 $ hg rebase --collapse -r 'B+C' -d D
338 338 rebasing 1:fc2b737bb2e5 "B" (B)
339 339 rebasing 2:dc0947a82db8 "C" (C)
340 340 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
341 341 $ hg tglog
342 342 o 2: 2127ae44d291 'Collapsed revision
343 343 | * B
344 344 | * C'
345 345 o 1: b18e25de2cf5 'D'
346 346 |
347 347 o 0: 426bada5c675 'A'
348 348
349 349 $ cd ..
350 350
351 351 With non-contiguous commits:
352 352
353 353 $ hg init non-contiguous
354 354 $ cd non-contiguous
355 355 $ cat >> .hg/hgrc <<EOF
356 356 > [experimental]
357 357 > evolution=all
358 358 > EOF
359 359
360 360 $ hg debugdrawdag << 'EOF'
361 361 > F
362 362 > |
363 363 > E
364 364 > |
365 365 > D
366 366 > |
367 367 > C
368 368 > |
369 369 > B G
370 370 > |/
371 371 > A
372 372 > EOF
373 373
374 374 BROKEN: should be allowed
375 375 $ hg rebase --collapse -r 'B+D+F' -d G
376 376 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
377 377 [255]
378 378 $ cd ..
379 379
380 380
381 381 $ hg init multiple-external-parents-2
382 382 $ cd multiple-external-parents-2
383 383 $ hg debugdrawdag << 'EOF'
384 384 > D G
385 385 > |\ /|
386 386 > B C E F
387 387 > \| |/
388 388 > \ H /
389 389 > \|/
390 390 > A
391 391 > EOF
392 392
393 393 $ hg rebase --collapse -d H -s 'B+F'
394 394 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
395 395 [255]
396 396 $ cd ..
397 397
398 398 With internal merge:
399 399
400 400 $ hg init internal-merge
401 401 $ cd internal-merge
402 402
403 403 $ hg debugdrawdag << 'EOF'
404 404 > E
405 405 > |\
406 406 > C D
407 407 > |/
408 408 > F B
409 409 > |/
410 410 > A
411 411 > EOF
412 412
413 413
414 414 $ hg rebase -s B --collapse --dest F
415 415 rebasing 1:112478962961 "B" (B)
416 416 rebasing 3:26805aba1e60 "C" (C)
417 417 rebasing 4:be0ef73c17ad "D" (D)
418 418 rebasing 5:02c4367d6973 "E" (E tip)
419 419 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
420 420
421 421 $ hg tglog
422 422 o 2: c0512a1797b0 'Collapsed revision
423 423 | * B
424 424 | * C
425 425 | * D
426 426 | * E'
427 427 o 1: 8908a377a434 'F'
428 428 |
429 429 o 0: 426bada5c675 'A'
430 430
431 431 $ hg manifest --rev tip
432 432 A
433 433 B
434 434 C
435 435 D
436 436 F
437 437 $ cd ..
438 438
439 439 Interactions between collapse and keepbranches
440 440 $ hg init e
441 441 $ cd e
442 442 $ echo 'a' > a
443 443 $ hg ci -Am 'A'
444 444 adding a
445 445
446 446 $ hg branch 'one'
447 447 marked working directory as branch one
448 448 (branches are permanent and global, did you want a bookmark?)
449 449 $ echo 'b' > b
450 450 $ hg ci -Am 'B'
451 451 adding b
452 452
453 453 $ hg branch 'two'
454 454 marked working directory as branch two
455 455 $ echo 'c' > c
456 456 $ hg ci -Am 'C'
457 457 adding c
458 458
459 459 $ hg up -q 0
460 460 $ echo 'd' > d
461 461 $ hg ci -Am 'D'
462 462 adding d
463 463
464 464 $ hg tglog
465 465 @ 3: 41acb9dca9eb 'D'
466 466 |
467 467 | o 2: 8ac4a08debf1 'C' two
468 468 | |
469 469 | o 1: 1ba175478953 'B' one
470 470 |/
471 471 o 0: 1994f17a630e 'A'
472 472
473 473 $ hg rebase --keepbranches --collapse -s 1 -d 3
474 474 abort: cannot collapse multiple named branches
475 475 [255]
476 476
477 477 $ repeatchange() {
478 478 > hg checkout $1
479 479 > hg cp d z
480 480 > echo blah >> z
481 481 > hg commit -Am "$2" --user "$3"
482 482 > }
483 483 $ repeatchange 3 "E" "user1"
484 484 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 485 $ repeatchange 3 "E" "user2"
486 486 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
487 487 created new head
488 488 $ hg tglog
489 489 @ 5: fbfb97b1089a 'E'
490 490 |
491 491 | o 4: f338eb3c2c7c 'E'
492 492 |/
493 493 o 3: 41acb9dca9eb 'D'
494 494 |
495 495 | o 2: 8ac4a08debf1 'C' two
496 496 | |
497 497 | o 1: 1ba175478953 'B' one
498 498 |/
499 499 o 0: 1994f17a630e 'A'
500 500
501 501 $ hg rebase -s 5 -d 4
502 502 rebasing 5:fbfb97b1089a "E" (tip)
503 note: rebase of 5:fbfb97b1089a "E" (tip) created no changes to commit
503 note: not rebasing 5:fbfb97b1089a "E" (tip), its destination already has all its changes
504 504 saved backup bundle to $TESTTMP/e/.hg/strip-backup/fbfb97b1089a-553e1d85-rebase.hg
505 505 $ hg tglog
506 506 @ 4: f338eb3c2c7c 'E'
507 507 |
508 508 o 3: 41acb9dca9eb 'D'
509 509 |
510 510 | o 2: 8ac4a08debf1 'C' two
511 511 | |
512 512 | o 1: 1ba175478953 'B' one
513 513 |/
514 514 o 0: 1994f17a630e 'A'
515 515
516 516 $ hg export tip
517 517 # HG changeset patch
518 518 # User user1
519 519 # Date 0 0
520 520 # Thu Jan 01 00:00:00 1970 +0000
521 521 # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213
522 522 # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09
523 523 E
524 524
525 525 diff -r 41acb9dca9eb -r f338eb3c2c7c z
526 526 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
527 527 +++ b/z Thu Jan 01 00:00:00 1970 +0000
528 528 @@ -0,0 +1,2 @@
529 529 +d
530 530 +blah
531 531
532 532 $ cd ..
533 533
534 534 Rebase, collapse and copies
535 535
536 536 $ hg init copies
537 537 $ cd copies
538 538 $ hg unbundle "$TESTDIR/bundles/renames.hg"
539 539 adding changesets
540 540 adding manifests
541 541 adding file changes
542 542 added 4 changesets with 11 changes to 7 files (+1 heads)
543 543 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
544 544 (run 'hg heads' to see heads, 'hg merge' to merge)
545 545 $ hg up -q tip
546 546 $ hg tglog
547 547 @ 3: 338e84e2e558 'move2'
548 548 |
549 549 o 2: 6e7340ee38c0 'move1'
550 550 |
551 551 | o 1: 1352765a01d4 'change'
552 552 |/
553 553 o 0: f447d5abf5ea 'add'
554 554
555 555 $ hg rebase --collapse -d 1
556 556 rebasing 2:6e7340ee38c0 "move1"
557 557 merging a and d to d
558 558 merging b and e to e
559 559 merging c and f to f
560 560 rebasing 3:338e84e2e558 "move2" (tip)
561 561 merging f and c to c
562 562 merging e and g to g
563 563 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
564 564 $ hg st
565 565 $ hg st --copies --change tip
566 566 A d
567 567 a
568 568 A g
569 569 b
570 570 R b
571 571 $ hg up tip -q
572 572 $ cat c
573 573 c
574 574 c
575 575 $ cat d
576 576 a
577 577 a
578 578 $ cat g
579 579 b
580 580 b
581 581 $ hg log -r . --template "{file_copies}\n"
582 582 d (a)g (b)
583 583
584 584 Test collapsing a middle revision in-place
585 585
586 586 $ hg tglog
587 587 @ 2: 64b456429f67 'Collapsed revision
588 588 | * move1
589 589 | * move2'
590 590 o 1: 1352765a01d4 'change'
591 591 |
592 592 o 0: f447d5abf5ea 'add'
593 593
594 594 $ hg rebase --collapse -r 1 -d 0
595 595 abort: can't remove original changesets with unrebased descendants
596 596 (use --keep to keep original changesets)
597 597 [255]
598 598
599 599 Test collapsing in place
600 600
601 601 $ hg rebase --collapse -b . -d 0
602 602 rebasing 1:1352765a01d4 "change"
603 603 rebasing 2:64b456429f67 "Collapsed revision" (tip)
604 604 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
605 605 $ hg st --change tip --copies
606 606 M a
607 607 M c
608 608 A d
609 609 a
610 610 A g
611 611 b
612 612 R b
613 613 $ hg up tip -q
614 614 $ cat a
615 615 a
616 616 a
617 617 $ cat c
618 618 c
619 619 c
620 620 $ cat d
621 621 a
622 622 a
623 623 $ cat g
624 624 b
625 625 b
626 626 $ cd ..
627 627
628 628
629 629 Test stripping a revision with another child
630 630
631 631 $ hg init f
632 632 $ cd f
633 633
634 634 $ hg debugdrawdag << 'EOF'
635 635 > C B
636 636 > |/
637 637 > A
638 638 > EOF
639 639
640 640 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
641 641 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
642 642 1:112478962961147124edd43549aedd1a335e44bf default: B
643 643
644 644 $ hg strip C
645 645 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
646 646
647 647 $ hg tglog
648 648 o 1: 112478962961 'B'
649 649 |
650 650 o 0: 426bada5c675 'A'
651 651
652 652
653 653
654 654 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
655 655 1:112478962961147124edd43549aedd1a335e44bf default: B
656 656
657 657 $ cd ..
658 658
659 659 Test collapsing changes that add then remove a file
660 660
661 661 $ hg init collapseaddremove
662 662 $ cd collapseaddremove
663 663
664 664 $ touch base
665 665 $ hg commit -Am base
666 666 adding base
667 667 $ touch a
668 668 $ hg commit -Am a
669 669 adding a
670 670 $ hg rm a
671 671 $ touch b
672 672 $ hg commit -Am b
673 673 adding b
674 674 $ hg book foo
675 675 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
676 676 rebasing 1:6d8d9f24eec3 "a"
677 677 rebasing 2:1cc73eca5ecc "b" (foo tip)
678 678 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
679 679 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
680 680 @ 1: 'collapsed' foo
681 681 |
682 682 o 0: 'base'
683 683
684 684 $ hg manifest --rev tip
685 685 b
686 686 base
687 687
688 688 $ cd ..
689 689
690 690 Test that rebase --collapse will remember message after
691 691 running into merge conflict and invoking rebase --continue.
692 692
693 693 $ hg init collapse_remember_message
694 694 $ cd collapse_remember_message
695 695 $ hg debugdrawdag << 'EOF'
696 696 > C B # B/A = B\n
697 697 > |/ # C/A = C\n
698 698 > A
699 699 > EOF
700 700 $ hg rebase --collapse -m "new message" -b B -d C
701 701 rebasing 1:81e5401e4d37 "B" (B)
702 702 merging A
703 703 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
704 704 unresolved conflicts (see hg resolve, then hg rebase --continue)
705 705 [1]
706 706 $ rm A.orig
707 707 $ hg resolve --mark A
708 708 (no more unresolved files)
709 709 continue: hg rebase --continue
710 710 $ hg rebase --continue
711 711 rebasing 1:81e5401e4d37 "B" (B)
712 712 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
713 713 $ hg log
714 714 changeset: 2:17186933e123
715 715 tag: tip
716 716 user: test
717 717 date: Thu Jan 01 00:00:00 1970 +0000
718 718 summary: new message
719 719
720 720 changeset: 1:043039e9df84
721 721 tag: C
722 722 user: test
723 723 date: Thu Jan 01 00:00:00 1970 +0000
724 724 summary: C
725 725
726 726 changeset: 0:426bada5c675
727 727 tag: A
728 728 user: test
729 729 date: Thu Jan 01 00:00:00 1970 +0000
730 730 summary: A
731 731
732 732 $ cd ..
733 733
734 734 Test aborted editor on final message
735 735
736 736 $ HGMERGE=:merge3
737 737 $ export HGMERGE
738 738 $ hg init aborted-editor
739 739 $ cd aborted-editor
740 740 $ hg debugdrawdag << 'EOF'
741 741 > C # D/A = D\n
742 742 > | # C/A = C\n
743 743 > B D # B/A = B\n
744 744 > |/ # A/A = A\n
745 745 > A
746 746 > EOF
747 747 $ hg rebase --collapse -t internal:merge3 -s B -d D
748 748 rebasing 1:f899f3910ce7 "B" (B)
749 749 merging A
750 750 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
751 751 unresolved conflicts (see hg resolve, then hg rebase --continue)
752 752 [1]
753 753 $ hg tglog
754 754 o 3: 63668d570d21 'C'
755 755 |
756 756 | @ 2: 82b8abf9c185 'D'
757 757 | |
758 758 @ | 1: f899f3910ce7 'B'
759 759 |/
760 760 o 0: 4a2df7238c3b 'A'
761 761
762 762 $ cat A
763 763 <<<<<<< dest: 82b8abf9c185 D - test: D
764 764 D
765 765 ||||||| base
766 766 A
767 767 =======
768 768 B
769 769 >>>>>>> source: f899f3910ce7 B - test: B
770 770 $ echo BC > A
771 771 $ hg resolve -m
772 772 (no more unresolved files)
773 773 continue: hg rebase --continue
774 774 $ hg rebase --continue
775 775 rebasing 1:f899f3910ce7 "B" (B)
776 776 rebasing 3:63668d570d21 "C" (C tip)
777 777 merging A
778 778 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
779 779 unresolved conflicts (see hg resolve, then hg rebase --continue)
780 780 [1]
781 781 $ hg tglog
782 782 @ 3: 63668d570d21 'C'
783 783 |
784 784 | @ 2: 82b8abf9c185 'D'
785 785 | |
786 786 o | 1: f899f3910ce7 'B'
787 787 |/
788 788 o 0: 4a2df7238c3b 'A'
789 789
790 790 $ cat A
791 791 <<<<<<< dest: 82b8abf9c185 D - test: D
792 792 BC
793 793 ||||||| base
794 794 B
795 795 =======
796 796 C
797 797 >>>>>>> source: 63668d570d21 C tip - test: C
798 798 $ echo BD > A
799 799 $ hg resolve -m
800 800 (no more unresolved files)
801 801 continue: hg rebase --continue
802 802 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
803 803 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
804 804 rebasing 3:63668d570d21 "C" (C tip)
805 805 abort: edit failed: false exited with status 1
806 806 [255]
807 807 $ hg tglog
808 808 o 3: 63668d570d21 'C'
809 809 |
810 810 | @ 2: 82b8abf9c185 'D'
811 811 | |
812 812 o | 1: f899f3910ce7 'B'
813 813 |/
814 814 o 0: 4a2df7238c3b 'A'
815 815
816 816 $ hg rebase --continue
817 817 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
818 818 already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
819 819 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
@@ -1,317 +1,317 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [alias]
6 6 > tglog = log -G --template "{rev}: {node|short} '{desc}'\n"
7 7 >
8 8 > [extensions]
9 9 > drawdag=$TESTDIR/drawdag.py
10 10 > EOF
11 11
12 12 Rebasing D onto B detaching from C (one commit):
13 13
14 14 $ hg init a1
15 15 $ cd a1
16 16
17 17 $ hg debugdrawdag <<EOF
18 18 > D
19 19 > |
20 20 > C B
21 21 > |/
22 22 > A
23 23 > EOF
24 24 $ hg phase --force --secret D
25 25
26 26 $ hg rebase -s D -d B
27 27 rebasing 3:e7b3f00ed42e "D" (D tip)
28 28 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/e7b3f00ed42e-6f368371-rebase.hg
29 29
30 30 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
31 31 o 3:secret 'D'
32 32 |
33 33 | o 2:draft 'C'
34 34 | |
35 35 o | 1:draft 'B'
36 36 |/
37 37 o 0:draft 'A'
38 38
39 39 $ hg manifest --rev tip
40 40 A
41 41 B
42 42 D
43 43
44 44 $ cd ..
45 45
46 46
47 47 Rebasing D onto B detaching from C (two commits):
48 48
49 49 $ hg init a2
50 50 $ cd a2
51 51
52 52 $ hg debugdrawdag <<EOF
53 53 > E
54 54 > |
55 55 > D
56 56 > |
57 57 > C B
58 58 > |/
59 59 > A
60 60 > EOF
61 61
62 62 $ hg rebase -s D -d B
63 63 rebasing 3:e7b3f00ed42e "D" (D)
64 64 rebasing 4:69a34c08022a "E" (E tip)
65 65 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/e7b3f00ed42e-a2ec7cea-rebase.hg
66 66
67 67 $ hg tglog
68 68 o 4: ee79e0744528 'E'
69 69 |
70 70 o 3: 10530e1d72d9 'D'
71 71 |
72 72 | o 2: dc0947a82db8 'C'
73 73 | |
74 74 o | 1: 112478962961 'B'
75 75 |/
76 76 o 0: 426bada5c675 'A'
77 77
78 78 $ hg manifest --rev tip
79 79 A
80 80 B
81 81 D
82 82 E
83 83
84 84 $ cd ..
85 85
86 86 Rebasing C onto B using detach (same as not using it):
87 87
88 88 $ hg init a3
89 89 $ cd a3
90 90
91 91 $ hg debugdrawdag <<EOF
92 92 > D
93 93 > |
94 94 > C B
95 95 > |/
96 96 > A
97 97 > EOF
98 98
99 99 $ hg rebase -s C -d B
100 100 rebasing 2:dc0947a82db8 "C" (C)
101 101 rebasing 3:e7b3f00ed42e "D" (D tip)
102 102 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/dc0947a82db8-b8481714-rebase.hg
103 103
104 104 $ hg tglog
105 105 o 3: 7375f3dbfb0f 'D'
106 106 |
107 107 o 2: bbfdd6cb49aa 'C'
108 108 |
109 109 o 1: 112478962961 'B'
110 110 |
111 111 o 0: 426bada5c675 'A'
112 112
113 113 $ hg manifest --rev tip
114 114 A
115 115 B
116 116 C
117 117 D
118 118
119 119 $ cd ..
120 120
121 121
122 122 Rebasing D onto B detaching from C and collapsing:
123 123
124 124 $ hg init a4
125 125 $ cd a4
126 126
127 127 $ hg debugdrawdag <<EOF
128 128 > E
129 129 > |
130 130 > D
131 131 > |
132 132 > C B
133 133 > |/
134 134 > A
135 135 > EOF
136 136 $ hg phase --force --secret E
137 137
138 138 $ hg rebase --collapse -s D -d B
139 139 rebasing 3:e7b3f00ed42e "D" (D)
140 140 rebasing 4:69a34c08022a "E" (E tip)
141 141 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/e7b3f00ed42e-a2ec7cea-rebase.hg
142 142
143 143 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
144 144 o 3:secret 'Collapsed revision
145 145 | * D
146 146 | * E'
147 147 | o 2:draft 'C'
148 148 | |
149 149 o | 1:draft 'B'
150 150 |/
151 151 o 0:draft 'A'
152 152
153 153 $ hg manifest --rev tip
154 154 A
155 155 B
156 156 D
157 157 E
158 158
159 159 $ cd ..
160 160
161 161 Rebasing across null as ancestor
162 162 $ hg init a5
163 163 $ cd a5
164 164
165 165 $ hg debugdrawdag <<EOF
166 166 > E
167 167 > |
168 168 > D
169 169 > |
170 170 > C
171 171 > |
172 172 > A B
173 173 > EOF
174 174
175 175 $ hg rebase -s C -d B
176 176 rebasing 2:dc0947a82db8 "C" (C)
177 177 rebasing 3:e7b3f00ed42e "D" (D)
178 178 rebasing 4:69a34c08022a "E" (E tip)
179 179 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/dc0947a82db8-3eefec98-rebase.hg
180 180
181 181 $ hg tglog
182 182 o 4: e3d0c70d606d 'E'
183 183 |
184 184 o 3: e9153d36a1af 'D'
185 185 |
186 186 o 2: a7ac28b870a8 'C'
187 187 |
188 188 o 1: fc2b737bb2e5 'B'
189 189
190 190 o 0: 426bada5c675 'A'
191 191
192 192 $ hg rebase -d 1 -s 3
193 193 rebasing 3:e9153d36a1af "D"
194 194 rebasing 4:e3d0c70d606d "E" (tip)
195 195 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/e9153d36a1af-db7388ed-rebase.hg
196 196 $ hg tglog
197 197 o 4: 2c24e540eccd 'E'
198 198 |
199 199 o 3: 73f786ed52ff 'D'
200 200 |
201 201 | o 2: a7ac28b870a8 'C'
202 202 |/
203 203 o 1: fc2b737bb2e5 'B'
204 204
205 205 o 0: 426bada5c675 'A'
206 206
207 207 $ cd ..
208 208
209 209 Verify that target is not selected as external rev (issue3085)
210 210
211 211 $ hg init a6
212 212 $ cd a6
213 213
214 214 $ hg debugdrawdag <<EOF
215 215 > H
216 216 > | G
217 217 > |/|
218 218 > F E
219 219 > |/
220 220 > A
221 221 > EOF
222 222 $ hg up -q G
223 223
224 224 $ echo "I" >> E
225 225 $ hg ci -m "I"
226 226 $ hg tag --local I
227 227 $ hg merge H
228 228 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 229 (branch merge, don't forget to commit)
230 230 $ hg ci -m "Merge"
231 231 $ echo "J" >> F
232 232 $ hg ci -m "J"
233 233 $ hg tglog
234 234 @ 7: c6aaf0d259c0 'J'
235 235 |
236 236 o 6: 0cfbc7e8faaf 'Merge'
237 237 |\
238 238 | o 5: b92d164ad3cb 'I'
239 239 | |
240 240 o | 4: 4ea5b230dea3 'H'
241 241 | |
242 242 | o 3: c6001eacfde5 'G'
243 243 |/|
244 244 o | 2: 8908a377a434 'F'
245 245 | |
246 246 | o 1: 7fb047a69f22 'E'
247 247 |/
248 248 o 0: 426bada5c675 'A'
249 249
250 250 $ hg rebase -s I -d H --collapse --config ui.merge=internal:other
251 251 rebasing 5:b92d164ad3cb "I" (I)
252 252 rebasing 6:0cfbc7e8faaf "Merge"
253 253 rebasing 7:c6aaf0d259c0 "J" (tip)
254 254 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/b92d164ad3cb-88fd7ab7-rebase.hg
255 255
256 256 $ hg tglog
257 257 @ 5: 65079693dac4 'Collapsed revision
258 258 | * I
259 259 | * Merge
260 260 | * J'
261 261 o 4: 4ea5b230dea3 'H'
262 262 |
263 263 | o 3: c6001eacfde5 'G'
264 264 |/|
265 265 o | 2: 8908a377a434 'F'
266 266 | |
267 267 | o 1: 7fb047a69f22 'E'
268 268 |/
269 269 o 0: 426bada5c675 'A'
270 270
271 271
272 272 $ hg log --rev tip
273 273 changeset: 5:65079693dac4
274 274 tag: tip
275 275 user: test
276 276 date: Thu Jan 01 00:00:00 1970 +0000
277 277 summary: Collapsed revision
278 278
279 279
280 280 $ cd ..
281 281
282 282 Ensure --continue restores a correct state (issue3046) and phase:
283 283 $ hg init a7
284 284 $ cd a7
285 285
286 286 $ hg debugdrawdag <<EOF
287 287 > C B
288 288 > |/
289 289 > A
290 290 > EOF
291 291 $ hg up -q C
292 292 $ echo 'B2' > B
293 293 $ hg ci -A -m 'B2'
294 294 adding B
295 295 $ hg phase --force --secret .
296 296 $ hg rebase -s . -d B --config ui.merge=internal:merge
297 297 rebasing 3:17b4880d2402 "B2" (tip)
298 298 merging B
299 299 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
300 300 unresolved conflicts (see hg resolve, then hg rebase --continue)
301 301 [1]
302 302 $ hg resolve --all -t internal:local
303 303 (no more unresolved files)
304 304 continue: hg rebase --continue
305 305 $ hg rebase -c
306 306 rebasing 3:17b4880d2402 "B2" (tip)
307 note: rebase of 3:17b4880d2402 "B2" (tip) created no changes to commit
307 note: not rebasing 3:17b4880d2402 "B2" (tip), its destination already has all its changes
308 308 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/17b4880d2402-1ae1f6cc-rebase.hg
309 309 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
310 310 o 2:draft 'C'
311 311 |
312 312 | @ 1:draft 'B'
313 313 |/
314 314 o 0:draft 'A'
315 315
316 316
317 317 $ cd ..
@@ -1,207 +1,207 b''
1 1 $ cat >> $HGRCPATH<<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 > EOF
6 6
7 7 $ hg init non-merge
8 8 $ cd non-merge
9 9 $ hg debugdrawdag<<'EOS'
10 10 > F
11 11 > |
12 12 > E
13 13 > |
14 14 > D
15 15 > |
16 16 > B C
17 17 > |/
18 18 > A
19 19 > EOS
20 20
21 21 $ for i in C D E F; do
22 22 > hg bookmark -r $i -i BOOK-$i
23 23 > done
24 24
25 25 $ hg debugdrawdag<<'EOS'
26 26 > E
27 27 > |
28 28 > D
29 29 > |
30 30 > B
31 31 > EOS
32 32
33 33 $ hg log -G -T '{rev} {desc} {bookmarks}'
34 34 o 7 E
35 35 |
36 36 o 6 D
37 37 |
38 38 | o 5 F BOOK-F
39 39 | |
40 40 | o 4 E BOOK-E
41 41 | |
42 42 | o 3 D BOOK-D
43 43 | |
44 44 | o 2 C BOOK-C
45 45 | |
46 46 o | 1 B
47 47 |/
48 48 o 0 A
49 49
50 50 With --keep, bookmark should move
51 51
52 52 $ hg rebase -r 3+4 -d E --keep
53 53 rebasing 3:e7b3f00ed42e "D" (BOOK-D)
54 note: rebase of 3:e7b3f00ed42e "D" (BOOK-D) created no changes to commit
54 note: not rebasing 3:e7b3f00ed42e "D" (BOOK-D), its destination already has all its changes
55 55 rebasing 4:69a34c08022a "E" (BOOK-E)
56 note: rebase of 4:69a34c08022a "E" (BOOK-E) created no changes to commit
56 note: not rebasing 4:69a34c08022a "E" (BOOK-E), its destination already has all its changes
57 57 $ hg log -G -T '{rev} {desc} {bookmarks}'
58 58 o 7 E BOOK-D BOOK-E
59 59 |
60 60 o 6 D
61 61 |
62 62 | o 5 F BOOK-F
63 63 | |
64 64 | o 4 E
65 65 | |
66 66 | o 3 D
67 67 | |
68 68 | o 2 C BOOK-C
69 69 | |
70 70 o | 1 B
71 71 |/
72 72 o 0 A
73 73
74 74 Move D and E back for the next test
75 75
76 76 $ hg bookmark BOOK-D -fqir 3
77 77 $ hg bookmark BOOK-E -fqir 4
78 78
79 79 Bookmark is usually an indication of a head. For changes that are introduced by
80 80 an ancestor of bookmark B, after moving B to B-NEW, the changes are ideally
81 81 still introduced by an ancestor of changeset on B-NEW. In the below case,
82 82 "BOOK-D", and "BOOK-E" include changes introduced by "C".
83 83
84 84 $ hg rebase -s 2 -d E
85 85 rebasing 2:dc0947a82db8 "C" (BOOK-C C)
86 86 rebasing 3:e7b3f00ed42e "D" (BOOK-D)
87 note: rebase of 3:e7b3f00ed42e "D" (BOOK-D) created no changes to commit
87 note: not rebasing 3:e7b3f00ed42e "D" (BOOK-D), its destination already has all its changes
88 88 rebasing 4:69a34c08022a "E" (BOOK-E)
89 note: rebase of 4:69a34c08022a "E" (BOOK-E) created no changes to commit
89 note: not rebasing 4:69a34c08022a "E" (BOOK-E), its destination already has all its changes
90 90 rebasing 5:6b2aeab91270 "F" (BOOK-F F)
91 91 saved backup bundle to $TESTTMP/non-merge/.hg/strip-backup/dc0947a82db8-52bb4973-rebase.hg
92 92 $ hg log -G -T '{rev} {desc} {bookmarks}'
93 93 o 5 F BOOK-F
94 94 |
95 95 o 4 C BOOK-C BOOK-D BOOK-E
96 96 |
97 97 o 3 E
98 98 |
99 99 o 2 D
100 100 |
101 101 o 1 B
102 102 |
103 103 o 0 A
104 104
105 105 Merge and its ancestors all become empty
106 106
107 107 $ hg init $TESTTMP/merge1
108 108 $ cd $TESTTMP/merge1
109 109
110 110 $ hg debugdrawdag<<'EOS'
111 111 > E
112 112 > /|
113 113 > B C D
114 114 > \|/
115 115 > A
116 116 > EOS
117 117
118 118 $ for i in C D E; do
119 119 > hg bookmark -r $i -i BOOK-$i
120 120 > done
121 121
122 122 $ hg debugdrawdag<<'EOS'
123 123 > H
124 124 > |
125 125 > D
126 126 > |
127 127 > C
128 128 > |
129 129 > B
130 130 > EOS
131 131
132 132 $ hg rebase -r '(A::)-(B::)-A' -d H
133 133 rebasing 2:dc0947a82db8 "C" (BOOK-C)
134 note: rebase of 2:dc0947a82db8 "C" (BOOK-C) created no changes to commit
134 note: not rebasing 2:dc0947a82db8 "C" (BOOK-C), its destination already has all its changes
135 135 rebasing 3:b18e25de2cf5 "D" (BOOK-D)
136 note: rebase of 3:b18e25de2cf5 "D" (BOOK-D) created no changes to commit
136 note: not rebasing 3:b18e25de2cf5 "D" (BOOK-D), its destination already has all its changes
137 137 rebasing 4:86a1f6686812 "E" (BOOK-E E)
138 note: rebase of 4:86a1f6686812 "E" (BOOK-E E) created no changes to commit
138 note: not rebasing 4:86a1f6686812 "E" (BOOK-E E), its destination already has all its changes
139 139 saved backup bundle to $TESTTMP/merge1/.hg/strip-backup/b18e25de2cf5-1fd0a4ba-rebase.hg
140 140
141 141 $ hg log -G -T '{rev} {desc} {bookmarks}'
142 142 o 4 H BOOK-C BOOK-D BOOK-E
143 143 |
144 144 o 3 D
145 145 |
146 146 o 2 C
147 147 |
148 148 o 1 B
149 149 |
150 150 o 0 A
151 151
152 152 Part of ancestors of a merge become empty
153 153
154 154 $ hg init $TESTTMP/merge2
155 155 $ cd $TESTTMP/merge2
156 156
157 157 $ hg debugdrawdag<<'EOS'
158 158 > G
159 159 > /|
160 160 > E F
161 161 > | |
162 162 > B C D
163 163 > \|/
164 164 > A
165 165 > EOS
166 166
167 167 $ for i in C D E F G; do
168 168 > hg bookmark -r $i -i BOOK-$i
169 169 > done
170 170
171 171 $ hg debugdrawdag<<'EOS'
172 172 > H
173 173 > |
174 174 > F
175 175 > |
176 176 > C
177 177 > |
178 178 > B
179 179 > EOS
180 180
181 181 $ hg rebase -r '(A::)-(B::)-A' -d H
182 182 rebasing 2:dc0947a82db8 "C" (BOOK-C)
183 note: rebase of 2:dc0947a82db8 "C" (BOOK-C) created no changes to commit
183 note: not rebasing 2:dc0947a82db8 "C" (BOOK-C), its destination already has all its changes
184 184 rebasing 3:b18e25de2cf5 "D" (BOOK-D D)
185 185 rebasing 4:03ca77807e91 "E" (BOOK-E E)
186 186 rebasing 5:ad6717a6a58e "F" (BOOK-F)
187 note: rebase of 5:ad6717a6a58e "F" (BOOK-F) created no changes to commit
187 note: not rebasing 5:ad6717a6a58e "F" (BOOK-F), its destination already has all its changes
188 188 rebasing 6:c58e8bdac1f4 "G" (BOOK-G G)
189 189 saved backup bundle to $TESTTMP/merge2/.hg/strip-backup/b18e25de2cf5-2d487005-rebase.hg
190 190
191 191 $ hg log -G -T '{rev} {desc} {bookmarks}'
192 192 o 7 G BOOK-G
193 193 |\
194 194 | o 6 E BOOK-E
195 195 | |
196 196 o | 5 D BOOK-D BOOK-F
197 197 |/
198 198 o 4 H BOOK-C
199 199 |
200 200 o 3 F
201 201 |
202 202 o 2 C
203 203 |
204 204 o 1 B
205 205 |
206 206 o 0 A
207 207
@@ -1,480 +1,480 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [phases]
6 6 > publish=False
7 7 >
8 8 > [alias]
9 9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
10 10 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
11 11 > EOF
12 12
13 13
14 14 $ hg init a
15 15 $ cd a
16 16
17 17 $ echo A > A
18 18 $ hg ci -Am A
19 19 adding A
20 20
21 21 $ echo B > B
22 22 $ hg ci -Am B
23 23 adding B
24 24
25 25 $ echo C >> A
26 26 $ hg ci -m C
27 27
28 28 $ hg up -q -C 0
29 29
30 30 $ echo D >> A
31 31 $ hg ci -m D
32 32 created new head
33 33
34 34 $ echo E > E
35 35 $ hg ci -Am E
36 36 adding E
37 37
38 38 $ cd ..
39 39
40 40
41 41 Changes during an interruption - continue:
42 42
43 43 $ hg clone -q -u . a a1
44 44 $ cd a1
45 45
46 46 $ hg tglog
47 47 @ 4: ae36e8e3dfd7 'E'
48 48 |
49 49 o 3: 46b37eabc604 'D'
50 50 |
51 51 | o 2: 965c486023db 'C'
52 52 | |
53 53 | o 1: 27547f69f254 'B'
54 54 |/
55 55 o 0: 4a2df7238c3b 'A'
56 56
57 57 Rebasing B onto E:
58 58
59 59 $ hg rebase -s 1 -d 4
60 60 rebasing 1:27547f69f254 "B"
61 61 rebasing 2:965c486023db "C"
62 62 merging A
63 63 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
64 64 unresolved conflicts (see hg resolve, then hg rebase --continue)
65 65 [1]
66 66
67 67 Force a commit on C during the interruption:
68 68
69 69 $ hg up -q -C 2 --config 'extensions.rebase=!'
70 70
71 71 $ echo 'Extra' > Extra
72 72 $ hg add Extra
73 73 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
74 74
75 75 Force this commit onto secret phase
76 76
77 77 $ hg phase --force --secret 6
78 78
79 79 $ hg tglogp
80 80 @ 6: deb5d2f93d8b secret 'Extra'
81 81 |
82 82 | o 5: 45396c49d53b draft 'B'
83 83 | |
84 84 | o 4: ae36e8e3dfd7 draft 'E'
85 85 | |
86 86 | o 3: 46b37eabc604 draft 'D'
87 87 | |
88 88 o | 2: 965c486023db draft 'C'
89 89 | |
90 90 o | 1: 27547f69f254 draft 'B'
91 91 |/
92 92 o 0: 4a2df7238c3b draft 'A'
93 93
94 94 Resume the rebasing:
95 95
96 96 $ hg rebase --continue
97 97 already rebased 1:27547f69f254 "B" as 45396c49d53b
98 98 rebasing 2:965c486023db "C"
99 99 merging A
100 100 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
101 101 unresolved conflicts (see hg resolve, then hg rebase --continue)
102 102 [1]
103 103
104 104 Solve the conflict and go on:
105 105
106 106 $ echo 'conflict solved' > A
107 107 $ rm A.orig
108 108 $ hg resolve -m A
109 109 (no more unresolved files)
110 110 continue: hg rebase --continue
111 111
112 112 $ hg rebase --continue
113 113 already rebased 1:27547f69f254 "B" as 45396c49d53b
114 114 rebasing 2:965c486023db "C"
115 115 warning: orphaned descendants detected, not stripping 27547f69f254, 965c486023db
116 116
117 117 $ hg tglogp
118 118 o 7: d2d25e26288e draft 'C'
119 119 |
120 120 | o 6: deb5d2f93d8b secret 'Extra'
121 121 | |
122 122 o | 5: 45396c49d53b draft 'B'
123 123 | |
124 124 @ | 4: ae36e8e3dfd7 draft 'E'
125 125 | |
126 126 o | 3: 46b37eabc604 draft 'D'
127 127 | |
128 128 | o 2: 965c486023db draft 'C'
129 129 | |
130 130 | o 1: 27547f69f254 draft 'B'
131 131 |/
132 132 o 0: 4a2df7238c3b draft 'A'
133 133
134 134 $ cd ..
135 135
136 136
137 137 Changes during an interruption - abort:
138 138
139 139 $ hg clone -q -u . a a2
140 140 $ cd a2
141 141
142 142 $ hg tglog
143 143 @ 4: ae36e8e3dfd7 'E'
144 144 |
145 145 o 3: 46b37eabc604 'D'
146 146 |
147 147 | o 2: 965c486023db 'C'
148 148 | |
149 149 | o 1: 27547f69f254 'B'
150 150 |/
151 151 o 0: 4a2df7238c3b 'A'
152 152
153 153 Rebasing B onto E:
154 154
155 155 $ hg rebase -s 1 -d 4
156 156 rebasing 1:27547f69f254 "B"
157 157 rebasing 2:965c486023db "C"
158 158 merging A
159 159 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
160 160 unresolved conflicts (see hg resolve, then hg rebase --continue)
161 161 [1]
162 162
163 163 Force a commit on B' during the interruption:
164 164
165 165 $ hg up -q -C 5 --config 'extensions.rebase=!'
166 166
167 167 $ echo 'Extra' > Extra
168 168 $ hg add Extra
169 169 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
170 170
171 171 $ hg tglog
172 172 @ 6: 402ee3642b59 'Extra'
173 173 |
174 174 o 5: 45396c49d53b 'B'
175 175 |
176 176 o 4: ae36e8e3dfd7 'E'
177 177 |
178 178 o 3: 46b37eabc604 'D'
179 179 |
180 180 | o 2: 965c486023db 'C'
181 181 | |
182 182 | o 1: 27547f69f254 'B'
183 183 |/
184 184 o 0: 4a2df7238c3b 'A'
185 185
186 186 Abort the rebasing:
187 187
188 188 $ hg rebase --abort
189 189 warning: new changesets detected on destination branch, can't strip
190 190 rebase aborted
191 191
192 192 $ hg tglog
193 193 @ 6: 402ee3642b59 'Extra'
194 194 |
195 195 o 5: 45396c49d53b 'B'
196 196 |
197 197 o 4: ae36e8e3dfd7 'E'
198 198 |
199 199 o 3: 46b37eabc604 'D'
200 200 |
201 201 | o 2: 965c486023db 'C'
202 202 | |
203 203 | o 1: 27547f69f254 'B'
204 204 |/
205 205 o 0: 4a2df7238c3b 'A'
206 206
207 207 $ cd ..
208 208
209 209 Changes during an interruption - abort (again):
210 210
211 211 $ hg clone -q -u . a a3
212 212 $ cd a3
213 213
214 214 $ hg tglogp
215 215 @ 4: ae36e8e3dfd7 draft 'E'
216 216 |
217 217 o 3: 46b37eabc604 draft 'D'
218 218 |
219 219 | o 2: 965c486023db draft 'C'
220 220 | |
221 221 | o 1: 27547f69f254 draft 'B'
222 222 |/
223 223 o 0: 4a2df7238c3b draft 'A'
224 224
225 225 Rebasing B onto E:
226 226
227 227 $ hg rebase -s 1 -d 4
228 228 rebasing 1:27547f69f254 "B"
229 229 rebasing 2:965c486023db "C"
230 230 merging A
231 231 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
232 232 unresolved conflicts (see hg resolve, then hg rebase --continue)
233 233 [1]
234 234
235 235 Change phase on B and B'
236 236
237 237 $ hg up -q -C 5 --config 'extensions.rebase=!'
238 238 $ hg phase --public 1
239 239 $ hg phase --public 5
240 240 $ hg phase --secret -f 2
241 241
242 242 $ hg tglogp
243 243 @ 5: 45396c49d53b public 'B'
244 244 |
245 245 o 4: ae36e8e3dfd7 public 'E'
246 246 |
247 247 o 3: 46b37eabc604 public 'D'
248 248 |
249 249 | o 2: 965c486023db secret 'C'
250 250 | |
251 251 | o 1: 27547f69f254 public 'B'
252 252 |/
253 253 o 0: 4a2df7238c3b public 'A'
254 254
255 255 Abort the rebasing:
256 256
257 257 $ hg rebase --abort
258 258 warning: can't clean up public changesets 45396c49d53b
259 259 rebase aborted
260 260
261 261 $ hg tglogp
262 262 @ 5: 45396c49d53b public 'B'
263 263 |
264 264 o 4: ae36e8e3dfd7 public 'E'
265 265 |
266 266 o 3: 46b37eabc604 public 'D'
267 267 |
268 268 | o 2: 965c486023db secret 'C'
269 269 | |
270 270 | o 1: 27547f69f254 public 'B'
271 271 |/
272 272 o 0: 4a2df7238c3b public 'A'
273 273
274 274 Test rebase interrupted by hooks
275 275
276 276 $ hg up 2
277 277 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
278 278 $ echo F > F
279 279 $ hg add F
280 280 $ hg ci -m F
281 281
282 282 $ cd ..
283 283
284 284 (precommit version)
285 285
286 286 $ cp -R a3 hook-precommit
287 287 $ cd hook-precommit
288 288 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.precommit=hg status | grep "M A"'
289 289 rebasing 2:965c486023db "C"
290 290 M A
291 291 rebasing 6:a0b2430ebfb8 "F" (tip)
292 292 abort: precommit hook exited with status 1
293 293 [255]
294 294 $ hg tglogp
295 295 @ 7: 401ccec5e39f secret 'C'
296 296 |
297 297 | @ 6: a0b2430ebfb8 secret 'F'
298 298 | |
299 299 o | 5: 45396c49d53b public 'B'
300 300 | |
301 301 o | 4: ae36e8e3dfd7 public 'E'
302 302 | |
303 303 o | 3: 46b37eabc604 public 'D'
304 304 | |
305 305 | o 2: 965c486023db secret 'C'
306 306 | |
307 307 | o 1: 27547f69f254 public 'B'
308 308 |/
309 309 o 0: 4a2df7238c3b public 'A'
310 310
311 311 $ hg rebase --continue
312 312 already rebased 2:965c486023db "C" as 401ccec5e39f
313 313 rebasing 6:a0b2430ebfb8 "F"
314 314 saved backup bundle to $TESTTMP/hook-precommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
315 315 $ hg tglogp
316 316 @ 6: 6e92a149ac6b secret 'F'
317 317 |
318 318 o 5: 401ccec5e39f secret 'C'
319 319 |
320 320 o 4: 45396c49d53b public 'B'
321 321 |
322 322 o 3: ae36e8e3dfd7 public 'E'
323 323 |
324 324 o 2: 46b37eabc604 public 'D'
325 325 |
326 326 | o 1: 27547f69f254 public 'B'
327 327 |/
328 328 o 0: 4a2df7238c3b public 'A'
329 329
330 330 $ cd ..
331 331
332 332 (pretxncommit version)
333 333
334 334 $ cp -R a3 hook-pretxncommit
335 335 $ cd hook-pretxncommit
336 336 $ hg rebase --source 2 --dest 5 --tool internal:other \
337 337 > --config 'hooks.tonative.pretxncommit=True' --config 'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary: C"'
338 338 rebasing 2:965c486023db "C"
339 339 summary: C
340 340 rebasing 6:a0b2430ebfb8 "F" (tip)
341 341 transaction abort!
342 342 rollback completed
343 343 abort: pretxncommit hook exited with status 1
344 344 [255]
345 345 $ hg tglogp
346 346 @ 7: 401ccec5e39f secret 'C'
347 347 |
348 348 | @ 6: a0b2430ebfb8 secret 'F'
349 349 | |
350 350 o | 5: 45396c49d53b public 'B'
351 351 | |
352 352 o | 4: ae36e8e3dfd7 public 'E'
353 353 | |
354 354 o | 3: 46b37eabc604 public 'D'
355 355 | |
356 356 | o 2: 965c486023db secret 'C'
357 357 | |
358 358 | o 1: 27547f69f254 public 'B'
359 359 |/
360 360 o 0: 4a2df7238c3b public 'A'
361 361
362 362 $ hg rebase --continue
363 363 already rebased 2:965c486023db "C" as 401ccec5e39f
364 364 rebasing 6:a0b2430ebfb8 "F"
365 365 saved backup bundle to $TESTTMP/hook-pretxncommit/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
366 366 $ hg tglogp
367 367 @ 6: 6e92a149ac6b secret 'F'
368 368 |
369 369 o 5: 401ccec5e39f secret 'C'
370 370 |
371 371 o 4: 45396c49d53b public 'B'
372 372 |
373 373 o 3: ae36e8e3dfd7 public 'E'
374 374 |
375 375 o 2: 46b37eabc604 public 'D'
376 376 |
377 377 | o 1: 27547f69f254 public 'B'
378 378 |/
379 379 o 0: 4a2df7238c3b public 'A'
380 380
381 381 $ cd ..
382 382
383 383 (pretxnclose version)
384 384
385 385 $ cp -R a3 hook-pretxnclose
386 386 $ cd hook-pretxnclose
387 387 $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.pretxnclose=hg log -r tip | grep "summary: C"'
388 388 rebasing 2:965c486023db "C"
389 389 summary: C
390 390 rebasing 6:a0b2430ebfb8 "F" (tip)
391 391 transaction abort!
392 392 rollback completed
393 393 abort: pretxnclose hook exited with status 1
394 394 [255]
395 395 $ hg tglogp
396 396 @ 7: 401ccec5e39f secret 'C'
397 397 |
398 398 | @ 6: a0b2430ebfb8 secret 'F'
399 399 | |
400 400 o | 5: 45396c49d53b public 'B'
401 401 | |
402 402 o | 4: ae36e8e3dfd7 public 'E'
403 403 | |
404 404 o | 3: 46b37eabc604 public 'D'
405 405 | |
406 406 | o 2: 965c486023db secret 'C'
407 407 | |
408 408 | o 1: 27547f69f254 public 'B'
409 409 |/
410 410 o 0: 4a2df7238c3b public 'A'
411 411
412 412 $ hg rebase --continue
413 413 already rebased 2:965c486023db "C" as 401ccec5e39f
414 414 rebasing 6:a0b2430ebfb8 "F"
415 415 saved backup bundle to $TESTTMP/hook-pretxnclose/.hg/strip-backup/965c486023db-aa6250e7-rebase.hg
416 416 $ hg tglogp
417 417 @ 6: 6e92a149ac6b secret 'F'
418 418 |
419 419 o 5: 401ccec5e39f secret 'C'
420 420 |
421 421 o 4: 45396c49d53b public 'B'
422 422 |
423 423 o 3: ae36e8e3dfd7 public 'E'
424 424 |
425 425 o 2: 46b37eabc604 public 'D'
426 426 |
427 427 | o 1: 27547f69f254 public 'B'
428 428 |/
429 429 o 0: 4a2df7238c3b public 'A'
430 430
431 431 $ cd ..
432 432
433 433 Make sure merge state is cleaned up after a no-op rebase merge (issue5494)
434 434 $ hg init repo
435 435 $ cd repo
436 436 $ echo a > a
437 437 $ hg commit -qAm base
438 438 $ echo b >> a
439 439 $ hg commit -qm b
440 440 $ hg up '.^'
441 441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 442 $ echo c >> a
443 443 $ hg commit -qm c
444 444 $ hg rebase -s 1 -d 2 --noninteractive
445 445 rebasing 1:fdaca8533b86 "b"
446 446 merging a
447 447 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
448 448 unresolved conflicts (see hg resolve, then hg rebase --continue)
449 449 [1]
450 450 $ echo a > a
451 451 $ echo c >> a
452 452 $ hg resolve --mark a
453 453 (no more unresolved files)
454 454 continue: hg rebase --continue
455 455 $ hg rebase --continue
456 456 rebasing 1:fdaca8533b86 "b"
457 note: rebase of 1:fdaca8533b86 "b" created no changes to commit
457 note: not rebasing 1:fdaca8533b86 "b", its destination already has all its changes
458 458 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
459 459 $ hg resolve --list
460 460 $ test -d .hg/merge
461 461 [1]
462 462 Now try again with --collapse
463 463 $ hg unbundle -q .hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
464 464 $ hg rebase -s 2 -d 1 --noninteractive --collapse
465 465 rebasing 2:fdaca8533b86 "b" (tip)
466 466 merging a
467 467 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
468 468 unresolved conflicts (see hg resolve, then hg rebase --continue)
469 469 [1]
470 470 $ echo a > a
471 471 $ echo c >> a
472 472 $ hg resolve --mark a
473 473 (no more unresolved files)
474 474 continue: hg rebase --continue
475 475 $ hg rebase --continue
476 476 rebasing 2:fdaca8533b86 "b" (tip)
477 477 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
478 478 $ hg resolve --list
479 479 $ test -d .hg/merge
480 480 [1]
@@ -1,189 +1,189 b''
1 1 This emulates the effects of an hg pull --rebase in which the remote repo
2 2 already has one local mq patch
3 3
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [extensions]
6 6 > rebase=
7 7 > mq=
8 8 >
9 9 > [phases]
10 10 > publish=False
11 11 >
12 12 > [alias]
13 13 > tglog = log -G --template "{rev}: {node|short} '{desc}' tags: {tags}\n"
14 14 > EOF
15 15
16 16
17 17 $ hg init a
18 18 $ cd a
19 19 $ hg qinit -c
20 20
21 21 $ echo c1 > c1
22 22 $ hg add c1
23 23 $ hg ci -m C1
24 24
25 25 $ echo r1 > r1
26 26 $ hg add r1
27 27 $ hg ci -m R1
28 28
29 29 $ hg up -q 0
30 30
31 31 $ hg qnew p0.patch -d '1 0'
32 32 $ echo p0 > p0
33 33 $ hg add p0
34 34 $ hg qref -m P0
35 35
36 36 $ hg qnew p1.patch -d '2 0'
37 37 $ echo p1 > p1
38 38 $ hg add p1
39 39 $ hg qref -m P1
40 40
41 41 $ hg export qtip > p1.patch
42 42
43 43 $ hg up -q -C 1
44 44
45 45 $ hg import p1.patch
46 46 applying p1.patch
47 47
48 48 $ rm p1.patch
49 49
50 50 $ hg up -q -C qtip
51 51
52 52 $ hg rebase -v
53 53 rebasing 2:13a46ce44f60 "P0" (p0.patch qbase)
54 54 resolving manifests
55 55 removing p0
56 56 getting r1
57 57 resolving manifests
58 58 getting p0
59 59 committing files:
60 60 p0
61 61 committing manifest
62 62 committing changelog
63 63 rebasing 3:148775c71080 "P1" (p1.patch qtip)
64 64 resolving manifests
65 note: rebase of 3:148775c71080 "P1" (p1.patch qtip) created no changes to commit
65 note: not rebasing 3:148775c71080 "P1" (p1.patch qtip), its destination already has all its changes
66 66 rebase merging completed
67 67 updating mq patch p0.patch to 5:9ecc820b1737
68 68 $TESTTMP/a/.hg/patches/p0.patch
69 69 2 changesets found
70 70 uncompressed size of bundle content:
71 71 348 (changelog)
72 72 324 (manifests)
73 73 129 p0
74 74 129 p1
75 75 saved backup bundle to $TESTTMP/a/.hg/strip-backup/13a46ce44f60-5da6ecfb-rebase.hg
76 76 2 changesets found
77 77 uncompressed size of bundle content:
78 78 403 (changelog)
79 79 324 (manifests)
80 80 129 p0
81 81 129 p1
82 82 adding branch
83 83 adding changesets
84 84 adding manifests
85 85 adding file changes
86 86 added 2 changesets with 2 changes to 2 files
87 87 rebase completed
88 88 1 revisions have been skipped
89 89
90 90 $ hg tglog
91 91 @ 3: 9ecc820b1737 'P0' tags: p0.patch qbase qtip tip
92 92 |
93 93 o 2: 869d8b134a27 'P1' tags: qparent
94 94 |
95 95 o 1: da108f2755df 'R1' tags:
96 96 |
97 97 o 0: cd320d50b341 'C1' tags:
98 98
99 99 $ cd ..
100 100
101 101
102 102 $ hg init b
103 103 $ cd b
104 104 $ hg qinit -c
105 105
106 106 $ for i in r0 r1 r2 r3 r4 r5 r6;
107 107 > do
108 108 > echo $i > $i
109 109 > hg ci -Am $i
110 110 > done
111 111 adding r0
112 112 adding r1
113 113 adding r2
114 114 adding r3
115 115 adding r4
116 116 adding r5
117 117 adding r6
118 118
119 119 $ hg qimport -r 1:tip
120 120
121 121 $ hg up -q 0
122 122
123 123 $ for i in r1 r3 r7 r8;
124 124 > do
125 125 > echo $i > $i
126 126 > hg ci -Am branch2-$i
127 127 > done
128 128 adding r1
129 129 created new head
130 130 adding r3
131 131 adding r7
132 132 adding r8
133 133
134 134 $ echo somethingelse > r4
135 135 $ hg ci -Am branch2-r4
136 136 adding r4
137 137
138 138 $ echo r6 > r6
139 139 $ hg ci -Am branch2-r6
140 140 adding r6
141 141
142 142 $ hg up -q qtip
143 143
144 144 $ HGMERGE=internal:fail hg rebase
145 145 rebasing 1:b4bffa6e4776 "r1" (qbase r1)
146 note: rebase of 1:b4bffa6e4776 "r1" (qbase r1) created no changes to commit
146 note: not rebasing 1:b4bffa6e4776 "r1" (qbase r1), its destination already has all its changes
147 147 rebasing 2:c0fd129beb01 "r2" (r2)
148 148 rebasing 3:6ff5b8feed8e "r3" (r3)
149 note: rebase of 3:6ff5b8feed8e "r3" (r3) created no changes to commit
149 note: not rebasing 3:6ff5b8feed8e "r3" (r3), its destination already has all its changes
150 150 rebasing 4:094320fec554 "r4" (r4)
151 151 unresolved conflicts (see hg resolve, then hg rebase --continue)
152 152 [1]
153 153
154 154 $ HGMERGE=internal:local hg resolve --all
155 155 (no more unresolved files)
156 156 continue: hg rebase --continue
157 157
158 158 $ hg rebase --continue
159 159 already rebased 1:b4bffa6e4776 "r1" (qbase r1) as 057f55ff8f44
160 160 already rebased 2:c0fd129beb01 "r2" (r2) as 1660ab13ce9a
161 161 already rebased 3:6ff5b8feed8e "r3" (r3) as 1660ab13ce9a
162 162 rebasing 4:094320fec554 "r4" (r4)
163 note: rebase of 4:094320fec554 "r4" (r4) created no changes to commit
163 note: not rebasing 4:094320fec554 "r4" (r4), its destination already has all its changes
164 164 rebasing 5:681a378595ba "r5" (r5)
165 165 rebasing 6:512a1f24768b "r6" (qtip r6)
166 note: rebase of 6:512a1f24768b "r6" (qtip r6) created no changes to commit
166 note: not rebasing 6:512a1f24768b "r6" (qtip r6), its destination already has all its changes
167 167 saved backup bundle to $TESTTMP/b/.hg/strip-backup/b4bffa6e4776-b9bfb84d-rebase.hg
168 168
169 169 $ hg tglog
170 170 @ 8: 0b9735ce8f0a 'r5' tags: qtip r5 tip
171 171 |
172 172 o 7: 1660ab13ce9a 'r2' tags: qbase r2
173 173 |
174 174 o 6: 057f55ff8f44 'branch2-r6' tags: qparent
175 175 |
176 176 o 5: 1d7287f8deb1 'branch2-r4' tags:
177 177 |
178 178 o 4: 3c10b9db2bd5 'branch2-r8' tags:
179 179 |
180 180 o 3: b684023158dc 'branch2-r7' tags:
181 181 |
182 182 o 2: d817754b1251 'branch2-r3' tags:
183 183 |
184 184 o 1: 0621a206f8a4 'branch2-r1' tags:
185 185 |
186 186 o 0: 222799e2f90b 'r0' tags:
187 187
188 188
189 189 $ cd ..
@@ -1,360 +1,360 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > mq=
5 5 >
6 6 > [mq]
7 7 > plain=true
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: {node|short} '{desc}' tags: {tags}\n"
11 11 > EOF
12 12
13 13
14 14 $ hg init a
15 15 $ cd a
16 16 $ hg qinit -c
17 17
18 18 $ echo c1 > f
19 19 $ hg add f
20 20 $ hg ci -m C1
21 21
22 22 $ echo r1 > f
23 23 $ hg ci -m R1
24 24
25 25 $ hg up -q 0
26 26
27 27 $ hg qnew f.patch -d '1 0'
28 28 $ echo mq1 > f
29 29 $ hg qref -m P0
30 30
31 31 $ hg qnew f2.patch
32 32 $ echo mq2 > f
33 33 $ hg qref -m P1 -d '2 0'
34 34
35 35 $ hg tglog
36 36 @ 3: 929394423cd3 'P1' tags: f2.patch qtip tip
37 37 |
38 38 o 2: 3504f44bffc0 'P0' tags: f.patch qbase
39 39 |
40 40 | o 1: bac9ed9960d8 'R1' tags:
41 41 |/
42 42 o 0: 36f36ddbca61 'C1' tags: qparent
43 43
44 44
45 45 Rebase - try to rebase on an applied mq patch:
46 46
47 47 $ hg rebase -s 1 -d 3
48 48 abort: cannot rebase onto an applied mq patch
49 49 [255]
50 50
51 51 Rebase - same thing, but mq patch is default dest:
52 52
53 53 $ hg up -q 1
54 54 $ hg rebase
55 55 abort: cannot rebase onto an applied mq patch
56 56 [255]
57 57 $ hg up -q qtip
58 58
59 59 Rebase - generate a conflict:
60 60
61 61 $ hg rebase -s 2 -d 1
62 62 rebasing 2:3504f44bffc0 "P0" (f.patch qbase)
63 63 merging f
64 64 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
65 65 unresolved conflicts (see hg resolve, then hg rebase --continue)
66 66 [1]
67 67
68 68 Fix the 1st conflict:
69 69
70 70 $ echo mq1r1 > f
71 71 $ hg resolve -m f
72 72 (no more unresolved files)
73 73 continue: hg rebase --continue
74 74 $ hg rebase -c
75 75 rebasing 2:3504f44bffc0 "P0" (f.patch qbase)
76 76 rebasing 3:929394423cd3 "P1" (f2.patch qtip tip)
77 77 merging f
78 78 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
79 79 unresolved conflicts (see hg resolve, then hg rebase --continue)
80 80 [1]
81 81
82 82 Fix the 2nd conflict:
83 83
84 84 $ echo mq1r1mq2 > f
85 85 $ hg resolve -m f
86 86 (no more unresolved files)
87 87 continue: hg rebase --continue
88 88 $ hg rebase -c
89 89 already rebased 2:3504f44bffc0 "P0" (f.patch qbase) as ebe9914c0d1c
90 90 rebasing 3:929394423cd3 "P1" (f2.patch qtip)
91 91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3504f44bffc0-30595b40-rebase.hg
92 92
93 93 $ hg tglog
94 94 @ 3: 462012cf340c 'P1' tags: f2.patch qtip tip
95 95 |
96 96 o 2: ebe9914c0d1c 'P0' tags: f.patch qbase
97 97 |
98 98 o 1: bac9ed9960d8 'R1' tags: qparent
99 99 |
100 100 o 0: 36f36ddbca61 'C1' tags:
101 101
102 102 $ hg up -q qbase
103 103
104 104 $ cat f
105 105 mq1r1
106 106
107 107 $ cat .hg/patches/f.patch
108 108 # HG changeset patch
109 109 # User test
110 110 # Date 1 0
111 111 # Thu Jan 01 00:00:01 1970 +0000
112 112 # Node ID ebe9914c0d1c3f60096e952fa4dbb3d377dea3ab
113 113 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
114 114 P0
115 115
116 116 diff -r bac9ed9960d8 -r ebe9914c0d1c f
117 117 --- a/f Thu Jan 01 00:00:00 1970 +0000
118 118 +++ b/f Thu Jan 01 00:00:01 1970 +0000
119 119 @@ -1,1 +1,1 @@
120 120 -r1
121 121 +mq1r1
122 122
123 123 Update to qtip:
124 124
125 125 $ hg up -q qtip
126 126
127 127 $ cat f
128 128 mq1r1mq2
129 129
130 130 $ cat .hg/patches/f2.patch
131 131 # HG changeset patch
132 132 # User test
133 133 # Date 2 0
134 134 # Thu Jan 01 00:00:02 1970 +0000
135 135 # Node ID 462012cf340c97d44d62377c985a423f6bb82f07
136 136 # Parent ebe9914c0d1c3f60096e952fa4dbb3d377dea3ab
137 137 P1
138 138
139 139 diff -r ebe9914c0d1c -r 462012cf340c f
140 140 --- a/f Thu Jan 01 00:00:01 1970 +0000
141 141 +++ b/f Thu Jan 01 00:00:02 1970 +0000
142 142 @@ -1,1 +1,1 @@
143 143 -mq1r1
144 144 +mq1r1mq2
145 145
146 146 Adding one git-style patch and one normal:
147 147
148 148 $ hg qpop -a
149 149 popping f2.patch
150 150 popping f.patch
151 151 patch queue now empty
152 152
153 153 $ rm -fr .hg/patches
154 154 $ hg qinit -c
155 155
156 156 $ hg up -q 0
157 157
158 158 $ hg qnew --git f_git.patch -d '3 0'
159 159 $ echo mq1 > p
160 160 $ hg add p
161 161 $ hg qref --git -m 'P0 (git)'
162 162
163 163 $ hg qnew f.patch -d '4 0'
164 164 $ echo mq2 > p
165 165 $ hg qref -m P1
166 166 $ hg qci -m 'save patch state'
167 167
168 168 $ hg qseries -s
169 169 f_git.patch: P0 (git)
170 170 f.patch: P1
171 171
172 172 $ hg -R .hg/patches manifest
173 173 .hgignore
174 174 f.patch
175 175 f_git.patch
176 176 series
177 177
178 178 $ cat .hg/patches/f_git.patch
179 179 Date: 3 0
180 180
181 181 P0 (git)
182 182
183 183 diff --git a/p b/p
184 184 new file mode 100644
185 185 --- /dev/null
186 186 +++ b/p
187 187 @@ -0,0 +1,1 @@
188 188 +mq1
189 189
190 190 $ cat .hg/patches/f.patch
191 191 Date: 4 0
192 192
193 193 P1
194 194
195 195 diff -r ???????????? p (glob)
196 196 --- a/p ??? ??? ?? ??:??:?? ???? ????? (glob)
197 197 +++ b/p ??? ??? ?? ??:??:?? ???? ????? (glob)
198 198 @@ -1,1 +1,1 @@
199 199 -mq1
200 200 +mq2
201 201
202 202
203 203 Rebase the applied mq patches:
204 204
205 205 $ hg rebase -s 2 -d 1
206 206 rebasing 2:0c587ffcb480 "P0 (git)" (f_git.patch qbase)
207 207 rebasing 3:c7f18665e4bc "P1" (f.patch qtip tip)
208 208 saved backup bundle to $TESTTMP/a/.hg/strip-backup/0c587ffcb480-0ea5695f-rebase.hg
209 209
210 210 $ hg qci -m 'save patch state'
211 211
212 212 $ hg qseries -s
213 213 f_git.patch: P0 (git)
214 214 f.patch: P1
215 215
216 216 $ hg -R .hg/patches manifest
217 217 .hgignore
218 218 f.patch
219 219 f_git.patch
220 220 series
221 221
222 222 $ cat .hg/patches/f_git.patch
223 223 # HG changeset patch
224 224 # User test
225 225 # Date 3 0
226 226 # Thu Jan 01 00:00:03 1970 +0000
227 227 # Node ID 12d9f6a3bbe560dee50c7c454d434add7fb8e837
228 228 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
229 229 P0 (git)
230 230
231 231 diff --git a/p b/p
232 232 new file mode 100644
233 233 --- /dev/null
234 234 +++ b/p
235 235 @@ -0,0 +1,1 @@
236 236 +mq1
237 237
238 238 $ cat .hg/patches/f.patch
239 239 # HG changeset patch
240 240 # User test
241 241 # Date 4 0
242 242 # Thu Jan 01 00:00:04 1970 +0000
243 243 # Node ID c77a2661c64c60d82f63c4f7aefd95b3a948a557
244 244 # Parent 12d9f6a3bbe560dee50c7c454d434add7fb8e837
245 245 P1
246 246
247 247 diff -r 12d9f6a3bbe5 -r c77a2661c64c p
248 248 --- a/p Thu Jan 01 00:00:03 1970 +0000
249 249 +++ b/p Thu Jan 01 00:00:04 1970 +0000
250 250 @@ -1,1 +1,1 @@
251 251 -mq1
252 252 +mq2
253 253
254 254 $ cd ..
255 255
256 256 Rebase with guards
257 257
258 258 $ hg init foo
259 259 $ cd foo
260 260 $ echo a > a
261 261 $ hg ci -Am a
262 262 adding a
263 263
264 264 Create mq repo with guarded patches foo and bar and empty patch:
265 265
266 266 $ hg qinit
267 267 $ echo guarded > guarded
268 268 $ hg add guarded
269 269 $ hg qnew guarded
270 270 $ hg qnew empty-important -m 'important commit message' -d '1 0'
271 271 $ echo bar > bar
272 272 $ hg add bar
273 273 $ hg qnew bar -d '2 0'
274 274 $ echo foo > foo
275 275 $ hg add foo
276 276 $ hg qnew foo
277 277 $ hg qpop -a
278 278 popping foo
279 279 popping bar
280 280 popping empty-important
281 281 popping guarded
282 282 patch queue now empty
283 283 $ hg qguard guarded +guarded
284 284 $ hg qguard bar +baz
285 285 $ hg qguard foo +baz
286 286 $ hg qselect baz
287 287 number of unguarded, unapplied patches has changed from 1 to 3
288 288 $ hg qpush bar
289 289 applying empty-important
290 290 patch empty-important is empty
291 291 applying bar
292 292 now at: bar
293 293
294 294 $ hg qguard -l
295 295 guarded: +guarded
296 296 empty-important: unguarded
297 297 bar: +baz
298 298 foo: +baz
299 299
300 300 $ hg tglog
301 301 @ 2: 4f44b861d38c 'imported patch bar' tags: bar qtip tip
302 302 |
303 303 o 1: 0aaf4c3af7eb 'important commit message' tags: empty-important qbase
304 304 |
305 305 o 0: cb9a9f314b8b 'a' tags: qparent
306 306
307 307 Create new head to rebase bar onto:
308 308
309 309 $ hg up -C 0
310 310 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
311 311 $ echo b > b
312 312 $ hg add b
313 313 $ hg ci -m b
314 314 created new head
315 315 $ hg up -C 2
316 316 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
317 317 $ echo a >> a
318 318 $ hg qref
319 319
320 320 $ hg tglog
321 321 @ 3: d526d4536ed6 '[mq]: bar' tags: bar qtip tip
322 322 |
323 323 | o 2: d2ae7f538514 'b' tags:
324 324 | |
325 325 o | 1: 0aaf4c3af7eb 'important commit message' tags: empty-important qbase
326 326 |/
327 327 o 0: cb9a9f314b8b 'a' tags: qparent
328 328
329 329
330 330 Rebase bar (make sure series order is preserved and empty-important also is
331 331 removed from the series):
332 332
333 333 $ hg qseries
334 334 guarded
335 335 empty-important
336 336 bar
337 337 foo
338 338 $ [ -f .hg/patches/empty-important ]
339 339 $ hg -q rebase -d 2
340 note: rebase of 1:0aaf4c3af7eb "important commit message" (empty-important qbase) created no changes to commit
340 note: not rebasing 1:0aaf4c3af7eb "important commit message" (empty-important qbase), its destination already has all its changes
341 341 $ hg qseries
342 342 guarded
343 343 bar
344 344 foo
345 345 $ [ -f .hg/patches/empty-important ]
346 346 [1]
347 347
348 348 $ hg qguard -l
349 349 guarded: +guarded
350 350 bar: +baz
351 351 foo: +baz
352 352
353 353 $ hg tglog
354 354 @ 2: 477d948bb2af '[mq]: bar' tags: bar qbase qtip tip
355 355 |
356 356 o 1: d2ae7f538514 'b' tags: qparent
357 357 |
358 358 o 0: cb9a9f314b8b 'a' tags:
359 359
360 360 $ cd ..
@@ -1,410 +1,410 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [phases]
6 6 > publish=False
7 7 >
8 8 > [alias]
9 9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
10 10 > EOF
11 11
12 12 $ hg init a
13 13 $ cd a
14 14 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
15 15 adding changesets
16 16 adding manifests
17 17 adding file changes
18 18 added 8 changesets with 7 changes to 7 files (+2 heads)
19 19 new changesets cd010b8cd998:02de42196ebe (8 drafts)
20 20 (run 'hg heads' to see heads, 'hg merge' to merge)
21 21 $ hg up tip
22 22 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 23 $ cd ..
24 24
25 25 $ hg clone -q -u . a a1
26 26
27 27 $ cd a1
28 28
29 29 $ hg update 3
30 30 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
31 31 $ hg branch dev-one
32 32 marked working directory as branch dev-one
33 33 (branches are permanent and global, did you want a bookmark?)
34 34 $ hg ci -m 'dev-one named branch'
35 35
36 36 $ hg update 7
37 37 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
38 38 $ hg branch dev-two
39 39 marked working directory as branch dev-two
40 40
41 41 $ echo x > x
42 42
43 43 $ hg add x
44 44
45 45 $ hg ci -m 'dev-two named branch'
46 46
47 47 $ hg tglog
48 48 @ 9: cb039b7cae8e 'dev-two named branch' dev-two
49 49 |
50 50 | o 8: 643fc9128048 'dev-one named branch' dev-one
51 51 | |
52 52 o | 7: 02de42196ebe 'H'
53 53 | |
54 54 +---o 6: eea13746799a 'G'
55 55 | | |
56 56 o | | 5: 24b6387c8c8c 'F'
57 57 | | |
58 58 +---o 4: 9520eea781bc 'E'
59 59 | |
60 60 | o 3: 32af7686d403 'D'
61 61 | |
62 62 | o 2: 5fddd98957c8 'C'
63 63 | |
64 64 | o 1: 42ccdea3bb16 'B'
65 65 |/
66 66 o 0: cd010b8cd998 'A'
67 67
68 68
69 69 Branch name containing a dash (issue3181)
70 70
71 71 $ hg rebase -b dev-two -d dev-one --keepbranches
72 72 rebasing 5:24b6387c8c8c "F"
73 73 rebasing 6:eea13746799a "G"
74 74 rebasing 7:02de42196ebe "H"
75 75 rebasing 9:cb039b7cae8e "dev-two named branch" (tip)
76 76 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/24b6387c8c8c-24cb8001-rebase.hg
77 77
78 78 $ hg tglog
79 79 @ 9: 9e70cd31750f 'dev-two named branch' dev-two
80 80 |
81 81 o 8: 31d0e4ba75e6 'H'
82 82 |
83 83 | o 7: 4b988a958030 'G'
84 84 |/|
85 85 o | 6: 24de4aff8e28 'F'
86 86 | |
87 87 o | 5: 643fc9128048 'dev-one named branch' dev-one
88 88 | |
89 89 | o 4: 9520eea781bc 'E'
90 90 | |
91 91 o | 3: 32af7686d403 'D'
92 92 | |
93 93 o | 2: 5fddd98957c8 'C'
94 94 | |
95 95 o | 1: 42ccdea3bb16 'B'
96 96 |/
97 97 o 0: cd010b8cd998 'A'
98 98
99 99 $ hg rebase -s dev-one -d 0 --keepbranches
100 100 rebasing 5:643fc9128048 "dev-one named branch"
101 101 rebasing 6:24de4aff8e28 "F"
102 102 rebasing 7:4b988a958030 "G"
103 103 rebasing 8:31d0e4ba75e6 "H"
104 104 rebasing 9:9e70cd31750f "dev-two named branch" (tip)
105 105 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/643fc9128048-c4ee9ef5-rebase.hg
106 106
107 107 $ hg tglog
108 108 @ 9: 59c2e59309fe 'dev-two named branch' dev-two
109 109 |
110 110 o 8: 904590360559 'H'
111 111 |
112 112 | o 7: 1a1e6f72ec38 'G'
113 113 |/|
114 114 o | 6: 42aa3cf0fa7a 'F'
115 115 | |
116 116 o | 5: bc8139ee757c 'dev-one named branch' dev-one
117 117 | |
118 118 | o 4: 9520eea781bc 'E'
119 119 |/
120 120 | o 3: 32af7686d403 'D'
121 121 | |
122 122 | o 2: 5fddd98957c8 'C'
123 123 | |
124 124 | o 1: 42ccdea3bb16 'B'
125 125 |/
126 126 o 0: cd010b8cd998 'A'
127 127
128 128 $ hg update 3
129 129 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
130 130 $ hg branch -f dev-one
131 131 marked working directory as branch dev-one
132 132 $ hg ci -m 'dev-one named branch'
133 133 created new head
134 134
135 135 $ hg tglog
136 136 @ 10: 643fc9128048 'dev-one named branch' dev-one
137 137 |
138 138 | o 9: 59c2e59309fe 'dev-two named branch' dev-two
139 139 | |
140 140 | o 8: 904590360559 'H'
141 141 | |
142 142 | | o 7: 1a1e6f72ec38 'G'
143 143 | |/|
144 144 | o | 6: 42aa3cf0fa7a 'F'
145 145 | | |
146 146 | o | 5: bc8139ee757c 'dev-one named branch' dev-one
147 147 | | |
148 148 | | o 4: 9520eea781bc 'E'
149 149 | |/
150 150 o | 3: 32af7686d403 'D'
151 151 | |
152 152 o | 2: 5fddd98957c8 'C'
153 153 | |
154 154 o | 1: 42ccdea3bb16 'B'
155 155 |/
156 156 o 0: cd010b8cd998 'A'
157 157
158 158 $ hg rebase -b 'max(branch("dev-two"))' -d dev-one --keepbranches
159 159 rebasing 5:bc8139ee757c "dev-one named branch"
160 note: rebase of 5:bc8139ee757c "dev-one named branch" created no changes to commit
160 note: not rebasing 5:bc8139ee757c "dev-one named branch", its destination already has all its changes
161 161 rebasing 6:42aa3cf0fa7a "F"
162 162 rebasing 7:1a1e6f72ec38 "G"
163 163 rebasing 8:904590360559 "H"
164 164 rebasing 9:59c2e59309fe "dev-two named branch"
165 165 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/bc8139ee757c-f11c1080-rebase.hg
166 166
167 167 $ hg tglog
168 168 o 9: 71325f8bc082 'dev-two named branch' dev-two
169 169 |
170 170 o 8: 12b2bc666e20 'H'
171 171 |
172 172 | o 7: 549f007a9f5f 'G'
173 173 |/|
174 174 o | 6: 679f28760620 'F'
175 175 | |
176 176 @ | 5: 643fc9128048 'dev-one named branch' dev-one
177 177 | |
178 178 | o 4: 9520eea781bc 'E'
179 179 | |
180 180 o | 3: 32af7686d403 'D'
181 181 | |
182 182 o | 2: 5fddd98957c8 'C'
183 183 | |
184 184 o | 1: 42ccdea3bb16 'B'
185 185 |/
186 186 o 0: cd010b8cd998 'A'
187 187
188 188 $ hg rebase -s 'max(branch("dev-one"))' -d 0 --keepbranches
189 189 rebasing 5:643fc9128048 "dev-one named branch"
190 190 rebasing 6:679f28760620 "F"
191 191 rebasing 7:549f007a9f5f "G"
192 192 rebasing 8:12b2bc666e20 "H"
193 193 rebasing 9:71325f8bc082 "dev-two named branch" (tip)
194 194 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/643fc9128048-6cdd1a52-rebase.hg
195 195
196 196 $ hg tglog
197 197 o 9: 3944801ae4ea 'dev-two named branch' dev-two
198 198 |
199 199 o 8: 8e279d293175 'H'
200 200 |
201 201 | o 7: aeefee77ab01 'G'
202 202 |/|
203 203 o | 6: e908b85f3729 'F'
204 204 | |
205 205 @ | 5: bc8139ee757c 'dev-one named branch' dev-one
206 206 | |
207 207 | o 4: 9520eea781bc 'E'
208 208 |/
209 209 | o 3: 32af7686d403 'D'
210 210 | |
211 211 | o 2: 5fddd98957c8 'C'
212 212 | |
213 213 | o 1: 42ccdea3bb16 'B'
214 214 |/
215 215 o 0: cd010b8cd998 'A'
216 216
217 217 $ hg up -r 0 > /dev/null
218 218
219 219 Rebasing descendant onto ancestor across different named branches
220 220
221 221 $ hg rebase -s 1 -d 9 --keepbranches
222 222 rebasing 1:42ccdea3bb16 "B"
223 223 rebasing 2:5fddd98957c8 "C"
224 224 rebasing 3:32af7686d403 "D"
225 225 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
226 226
227 227 $ hg tglog
228 228 o 9: e9f862ce8bad 'D'
229 229 |
230 230 o 8: a0d543090fa4 'C'
231 231 |
232 232 o 7: 3bdb949809d9 'B'
233 233 |
234 234 o 6: 3944801ae4ea 'dev-two named branch' dev-two
235 235 |
236 236 o 5: 8e279d293175 'H'
237 237 |
238 238 | o 4: aeefee77ab01 'G'
239 239 |/|
240 240 o | 3: e908b85f3729 'F'
241 241 | |
242 242 o | 2: bc8139ee757c 'dev-one named branch' dev-one
243 243 | |
244 244 | o 1: 9520eea781bc 'E'
245 245 |/
246 246 @ 0: cd010b8cd998 'A'
247 247
248 248 $ hg rebase -s 5 -d 6
249 249 abort: source and destination form a cycle
250 250 [255]
251 251
252 252 $ hg rebase -s 6 -d 5
253 253 rebasing 6:3944801ae4ea "dev-two named branch"
254 254 rebasing 7:3bdb949809d9 "B"
255 255 rebasing 8:a0d543090fa4 "C"
256 256 rebasing 9:e9f862ce8bad "D" (tip)
257 257 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/3944801ae4ea-fb46ed74-rebase.hg
258 258
259 259 $ hg tglog
260 260 o 9: e522577ccdbd 'D'
261 261 |
262 262 o 8: 810110211f50 'C'
263 263 |
264 264 o 7: 160b0930ccc6 'B'
265 265 |
266 266 o 6: c57724c84928 'dev-two named branch'
267 267 |
268 268 o 5: 8e279d293175 'H'
269 269 |
270 270 | o 4: aeefee77ab01 'G'
271 271 |/|
272 272 o | 3: e908b85f3729 'F'
273 273 | |
274 274 o | 2: bc8139ee757c 'dev-one named branch' dev-one
275 275 | |
276 276 | o 1: 9520eea781bc 'E'
277 277 |/
278 278 @ 0: cd010b8cd998 'A'
279 279
280 280
281 281 Reopen branch by rebase
282 282
283 283 $ hg up -qr3
284 284 $ hg branch -q b
285 285 $ hg ci -m 'create b'
286 286 $ hg ci -m 'close b' --close
287 287 $ hg rebase -b 8 -d b
288 288 reopening closed branch head 2b586e70108d
289 289 rebasing 5:8e279d293175 "H"
290 290 rebasing 6:c57724c84928 "dev-two named branch"
291 291 rebasing 7:160b0930ccc6 "B"
292 292 rebasing 8:810110211f50 "C"
293 293 rebasing 9:e522577ccdbd "D"
294 294 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/8e279d293175-b023e27c-rebase.hg
295 295
296 296 $ cd ..
297 297
298 298 Rebase to other head on branch
299 299
300 300 Set up a case:
301 301
302 302 $ hg init case1
303 303 $ cd case1
304 304 $ touch f
305 305 $ hg ci -qAm0
306 306 $ hg branch -q b
307 307 $ echo >> f
308 308 $ hg ci -qAm 'b1'
309 309 $ hg up -qr -2
310 310 $ hg branch -qf b
311 311 $ hg ci -qm 'b2'
312 312 $ hg up -qr -3
313 313 $ hg branch -q c
314 314 $ hg ci -m 'c1'
315 315
316 316 $ hg tglog
317 317 @ 3: c062e3ecd6c6 'c1' c
318 318 |
319 319 | o 2: 792845bb77ee 'b2' b
320 320 |/
321 321 | o 1: 40039acb7ca5 'b1' b
322 322 |/
323 323 o 0: d681519c3ea7 '0'
324 324
325 325 $ hg clone -q . ../case2
326 326
327 327 rebase 'b2' to another lower branch head
328 328
329 329 $ hg up -qr 2
330 330 $ hg rebase
331 331 rebasing 2:792845bb77ee "b2"
332 note: rebase of 2:792845bb77ee "b2" created no changes to commit
332 note: not rebasing 2:792845bb77ee "b2", its destination already has all its changes
333 333 saved backup bundle to $TESTTMP/case1/.hg/strip-backup/792845bb77ee-627120ee-rebase.hg
334 334 $ hg tglog
335 335 o 2: c062e3ecd6c6 'c1' c
336 336 |
337 337 | @ 1: 40039acb7ca5 'b1' b
338 338 |/
339 339 o 0: d681519c3ea7 '0'
340 340
341 341
342 342 rebase 'b1' on top of the tip of the branch ('b2') - ignoring the tip branch ('c1')
343 343
344 344 $ cd ../case2
345 345 $ hg up -qr 1
346 346 $ hg rebase
347 347 rebasing 1:40039acb7ca5 "b1"
348 348 saved backup bundle to $TESTTMP/case2/.hg/strip-backup/40039acb7ca5-342b72d1-rebase.hg
349 349 $ hg tglog
350 350 @ 3: 76abc1c6f8c7 'b1' b
351 351 |
352 352 | o 2: c062e3ecd6c6 'c1' c
353 353 | |
354 354 o | 1: 792845bb77ee 'b2' b
355 355 |/
356 356 o 0: d681519c3ea7 '0'
357 357
358 358
359 359 rebase 'c1' to the branch head 'c2' that is closed
360 360
361 361 $ hg branch -qf c
362 362 $ hg ci -qm 'c2 closed' --close
363 363 $ hg up -qr 2
364 364 $ hg tglog
365 365 _ 4: 8427af5d86f2 'c2 closed' c
366 366 |
367 367 o 3: 76abc1c6f8c7 'b1' b
368 368 |
369 369 | @ 2: c062e3ecd6c6 'c1' c
370 370 | |
371 371 o | 1: 792845bb77ee 'b2' b
372 372 |/
373 373 o 0: d681519c3ea7 '0'
374 374
375 375 $ hg rebase
376 376 abort: branch 'c' has one head - please rebase to an explicit rev
377 377 (run 'hg heads' to see all heads)
378 378 [255]
379 379 $ hg tglog
380 380 _ 4: 8427af5d86f2 'c2 closed' c
381 381 |
382 382 o 3: 76abc1c6f8c7 'b1' b
383 383 |
384 384 | @ 2: c062e3ecd6c6 'c1' c
385 385 | |
386 386 o | 1: 792845bb77ee 'b2' b
387 387 |/
388 388 o 0: d681519c3ea7 '0'
389 389
390 390
391 391 $ hg up -cr 1
392 392 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
393 393 $ hg branch x
394 394 marked working directory as branch x
395 395 $ hg rebase -r 3:: -d .
396 396 rebasing 3:76abc1c6f8c7 "b1"
397 397 rebasing 4:8427af5d86f2 "c2 closed" (tip)
398 note: rebase of 4:8427af5d86f2 "c2 closed" (tip) created no changes to commit
398 note: not rebasing 4:8427af5d86f2 "c2 closed" (tip), its destination already has all its changes
399 399 saved backup bundle to $TESTTMP/case2/.hg/strip-backup/76abc1c6f8c7-cd698d13-rebase.hg
400 400 $ hg tglog
401 401 o 3: 117b0ed08075 'b1' x
402 402 |
403 403 | o 2: c062e3ecd6c6 'c1' c
404 404 | |
405 405 @ | 1: 792845bb77ee 'b2' b
406 406 |/
407 407 o 0: d681519c3ea7 '0'
408 408
409 409
410 410 $ cd ..
@@ -1,426 +1,426 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 > [alias]
6 6 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
7 7 > EOF
8 8
9 9 $ hg init repo
10 10 $ cd repo
11 11
12 12 $ echo A > a
13 13 $ echo >> a
14 14 $ hg ci -Am A
15 15 adding a
16 16
17 17 $ echo B > a
18 18 $ echo >> a
19 19 $ hg ci -m B
20 20
21 21 $ echo C > a
22 22 $ echo >> a
23 23 $ hg ci -m C
24 24
25 25 $ hg up -q -C 0
26 26
27 27 $ echo D >> a
28 28 $ hg ci -Am AD
29 29 created new head
30 30
31 31 $ hg tglog
32 32 @ 3: 3878212183bd 'AD'
33 33 |
34 34 | o 2: 30ae917c0e4f 'C'
35 35 | |
36 36 | o 1: 0f4f7cb4f549 'B'
37 37 |/
38 38 o 0: 1e635d440a73 'A'
39 39
40 40 $ hg rebase -s 1 -d 3
41 41 rebasing 1:0f4f7cb4f549 "B"
42 42 merging a
43 43 rebasing 2:30ae917c0e4f "C"
44 44 merging a
45 45 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0f4f7cb4f549-82b3b163-rebase.hg
46 46
47 47 $ hg tglog
48 48 o 3: 25773bc4b4b0 'C'
49 49 |
50 50 o 2: c09015405f75 'B'
51 51 |
52 52 @ 1: 3878212183bd 'AD'
53 53 |
54 54 o 0: 1e635d440a73 'A'
55 55
56 56
57 57 $ cd ..
58 58
59 59
60 60 Test rebasing of merges with ancestors of the rebase destination - a situation
61 61 that often happens when trying to recover from repeated merging with a mainline
62 62 branch.
63 63
64 64 The test case creates a dev branch that contains a couple of merges from the
65 65 default branch. When rebasing to the default branch, these merges would be
66 66 merges with ancestors on the same branch. The merges _could_ contain some
67 67 interesting conflict resolutions or additional changes in the merge commit, but
68 68 that is mixed up with the actual merge stuff and there is in general no way to
69 69 separate them.
70 70
71 71 Note: The dev branch contains _no_ changes to f-default. It might be unclear
72 72 how rebasing of ancestor merges should be handled, but the current behavior
73 73 with spurious prompts for conflicts in files that didn't change seems very
74 74 wrong.
75 75
76 76 $ hg init ancestor-merge
77 77 $ cd ancestor-merge
78 78
79 79 $ touch f-default
80 80 $ hg ci -Aqm 'default: create f-default'
81 81
82 82 $ hg branch -q dev
83 83 $ hg ci -qm 'dev: create branch'
84 84
85 85 $ echo stuff > f-dev
86 86 $ hg ci -Aqm 'dev: f-dev stuff'
87 87
88 88 $ hg up -q default
89 89 $ echo stuff > f-default
90 90 $ hg ci -m 'default: f-default stuff'
91 91
92 92 $ hg up -q dev
93 93 $ hg merge -q default
94 94 $ hg ci -m 'dev: merge default'
95 95
96 96 $ hg up -q default
97 97 $ hg rm f-default
98 98 $ hg ci -m 'default: remove f-default'
99 99
100 100 $ hg up -q dev
101 101 $ hg merge -q default
102 102 $ hg ci -m 'dev: merge default'
103 103
104 104 $ hg up -q default
105 105 $ echo stuff > f-other
106 106 $ hg ci -Aqm 'default: f-other stuff'
107 107
108 108 $ hg tglog
109 109 @ 7: e08089805d82 'default: f-other stuff'
110 110 |
111 111 | o 6: 9455ee510502 'dev: merge default' dev
112 112 |/|
113 113 o | 5: 462860db70a1 'default: remove f-default'
114 114 | |
115 115 | o 4: 4b019212aaf6 'dev: merge default' dev
116 116 |/|
117 117 o | 3: f157ecfd2b6b 'default: f-default stuff'
118 118 | |
119 119 | o 2: ec2c14fb2984 'dev: f-dev stuff' dev
120 120 | |
121 121 | o 1: 1d1a643d390e 'dev: create branch' dev
122 122 |/
123 123 o 0: e90e8eb90b6f 'default: create f-default'
124 124
125 125 $ hg clone -qU . ../ancestor-merge-2
126 126
127 127 Full rebase all the way back from branching point:
128 128
129 129 $ hg rebase -r 'only(dev,default)' -d default --config ui.interactive=True << EOF
130 130 > c
131 131 > EOF
132 132 rebasing 1:1d1a643d390e "dev: create branch"
133 note: rebase of 1:1d1a643d390e "dev: create branch" created no changes to commit
133 note: not rebasing 1:1d1a643d390e "dev: create branch", its destination already has all its changes
134 134 rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
135 135 rebasing 4:4b019212aaf6 "dev: merge default"
136 136 file 'f-default' was deleted in local [dest] but was modified in other [source].
137 137 What do you want to do?
138 138 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
139 139 rebasing 6:9455ee510502 "dev: merge default"
140 140 saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-43e9e04b-rebase.hg
141 141 $ hg tglog
142 142 o 6: fbc098e72227 'dev: merge default'
143 143 |
144 144 o 5: eda7b7f46f5d 'dev: merge default'
145 145 |
146 146 o 4: 3e075b1c0a40 'dev: f-dev stuff'
147 147 |
148 148 @ 3: e08089805d82 'default: f-other stuff'
149 149 |
150 150 o 2: 462860db70a1 'default: remove f-default'
151 151 |
152 152 o 1: f157ecfd2b6b 'default: f-default stuff'
153 153 |
154 154 o 0: e90e8eb90b6f 'default: create f-default'
155 155
156 156 Grafty cherry picking rebasing:
157 157
158 158 $ cd ../ancestor-merge-2
159 159
160 160 $ hg phase -fdr0:
161 161 $ hg rebase -r 'children(only(dev,default))' -d default --config ui.interactive=True << EOF
162 162 > c
163 163 > EOF
164 164 rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
165 165 rebasing 4:4b019212aaf6 "dev: merge default"
166 166 file 'f-default' was deleted in local [dest] but was modified in other [source].
167 167 What do you want to do?
168 168 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? c
169 169 rebasing 6:9455ee510502 "dev: merge default"
170 170 saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-62d0b222-rebase.hg
171 171 $ hg tglog
172 172 o 7: fbc098e72227 'dev: merge default'
173 173 |
174 174 o 6: eda7b7f46f5d 'dev: merge default'
175 175 |
176 176 o 5: 3e075b1c0a40 'dev: f-dev stuff'
177 177 |
178 178 o 4: e08089805d82 'default: f-other stuff'
179 179 |
180 180 o 3: 462860db70a1 'default: remove f-default'
181 181 |
182 182 o 2: f157ecfd2b6b 'default: f-default stuff'
183 183 |
184 184 | o 1: 1d1a643d390e 'dev: create branch' dev
185 185 |/
186 186 o 0: e90e8eb90b6f 'default: create f-default'
187 187
188 188 $ cd ..
189 189
190 190
191 191 Test order of parents of rebased merged with un-rebased changes as p1.
192 192
193 193 $ hg init parentorder
194 194 $ cd parentorder
195 195 $ touch f
196 196 $ hg ci -Aqm common
197 197 $ touch change
198 198 $ hg ci -Aqm change
199 199 $ touch target
200 200 $ hg ci -Aqm target
201 201 $ hg up -qr 0
202 202 $ touch outside
203 203 $ hg ci -Aqm outside
204 204 $ hg merge -qr 1
205 205 $ hg ci -m 'merge p1 3=outside p2 1=ancestor'
206 206 $ hg par
207 207 changeset: 4:6990226659be
208 208 tag: tip
209 209 parent: 3:f59da8fc0fcf
210 210 parent: 1:dd40c13f7a6f
211 211 user: test
212 212 date: Thu Jan 01 00:00:00 1970 +0000
213 213 summary: merge p1 3=outside p2 1=ancestor
214 214
215 215 $ hg up -qr 1
216 216 $ hg merge -qr 3
217 217 $ hg ci -qm 'merge p1 1=ancestor p2 3=outside'
218 218 $ hg par
219 219 changeset: 5:a57575f79074
220 220 tag: tip
221 221 parent: 1:dd40c13f7a6f
222 222 parent: 3:f59da8fc0fcf
223 223 user: test
224 224 date: Thu Jan 01 00:00:00 1970 +0000
225 225 summary: merge p1 1=ancestor p2 3=outside
226 226
227 227 $ hg tglog
228 228 @ 5: a57575f79074 'merge p1 1=ancestor p2 3=outside'
229 229 |\
230 230 +---o 4: 6990226659be 'merge p1 3=outside p2 1=ancestor'
231 231 | |/
232 232 | o 3: f59da8fc0fcf 'outside'
233 233 | |
234 234 +---o 2: a60552eb93fb 'target'
235 235 | |
236 236 o | 1: dd40c13f7a6f 'change'
237 237 |/
238 238 o 0: 02f0f58d5300 'common'
239 239
240 240 $ hg rebase -r 4 -d 2
241 241 rebasing 4:6990226659be "merge p1 3=outside p2 1=ancestor"
242 242 saved backup bundle to $TESTTMP/parentorder/.hg/strip-backup/6990226659be-4d67a0d3-rebase.hg
243 243 $ hg tip
244 244 changeset: 5:cca50676b1c5
245 245 tag: tip
246 246 parent: 2:a60552eb93fb
247 247 parent: 3:f59da8fc0fcf
248 248 user: test
249 249 date: Thu Jan 01 00:00:00 1970 +0000
250 250 summary: merge p1 3=outside p2 1=ancestor
251 251
252 252 $ hg rebase -r 4 -d 2
253 253 rebasing 4:a57575f79074 "merge p1 1=ancestor p2 3=outside"
254 254 saved backup bundle to $TESTTMP/parentorder/.hg/strip-backup/a57575f79074-385426e5-rebase.hg
255 255 $ hg tip
256 256 changeset: 5:f9daf77ffe76
257 257 tag: tip
258 258 parent: 2:a60552eb93fb
259 259 parent: 3:f59da8fc0fcf
260 260 user: test
261 261 date: Thu Jan 01 00:00:00 1970 +0000
262 262 summary: merge p1 1=ancestor p2 3=outside
263 263
264 264 $ hg tglog
265 265 @ 5: f9daf77ffe76 'merge p1 1=ancestor p2 3=outside'
266 266 |\
267 267 +---o 4: cca50676b1c5 'merge p1 3=outside p2 1=ancestor'
268 268 | |/
269 269 | o 3: f59da8fc0fcf 'outside'
270 270 | |
271 271 o | 2: a60552eb93fb 'target'
272 272 | |
273 273 o | 1: dd40c13f7a6f 'change'
274 274 |/
275 275 o 0: 02f0f58d5300 'common'
276 276
277 277 rebase of merge of ancestors
278 278
279 279 $ hg up -qr 2
280 280 $ hg merge -qr 3
281 281 $ echo 'other change while merging future "rebase ancestors"' > other
282 282 $ hg ci -Aqm 'merge rebase ancestors'
283 283 $ hg rebase -d 5 -v
284 284 rebasing 6:4c5f12f25ebe "merge rebase ancestors" (tip)
285 285 resolving manifests
286 286 removing other
287 287 note: merging f9daf77ffe76+ and 4c5f12f25ebe using bids from ancestors a60552eb93fb and f59da8fc0fcf
288 288
289 289 calculating bids for ancestor a60552eb93fb
290 290 resolving manifests
291 291
292 292 calculating bids for ancestor f59da8fc0fcf
293 293 resolving manifests
294 294
295 295 auction for merging merge bids
296 296 other: consensus for g
297 297 end of auction
298 298
299 299 getting other
300 300 committing files:
301 301 other
302 302 committing manifest
303 303 committing changelog
304 304 rebase merging completed
305 305 1 changesets found
306 306 uncompressed size of bundle content:
307 307 199 (changelog)
308 308 216 (manifests)
309 309 182 other
310 310 saved backup bundle to $TESTTMP/parentorder/.hg/strip-backup/4c5f12f25ebe-f46990e5-rebase.hg
311 311 1 changesets found
312 312 uncompressed size of bundle content:
313 313 254 (changelog)
314 314 167 (manifests)
315 315 182 other
316 316 adding branch
317 317 adding changesets
318 318 adding manifests
319 319 adding file changes
320 320 added 1 changesets with 1 changes to 1 files
321 321 rebase completed
322 322 $ hg tglog
323 323 @ 6: 113755df812b 'merge rebase ancestors'
324 324 |
325 325 o 5: f9daf77ffe76 'merge p1 1=ancestor p2 3=outside'
326 326 |\
327 327 +---o 4: cca50676b1c5 'merge p1 3=outside p2 1=ancestor'
328 328 | |/
329 329 | o 3: f59da8fc0fcf 'outside'
330 330 | |
331 331 o | 2: a60552eb93fb 'target'
332 332 | |
333 333 o | 1: dd40c13f7a6f 'change'
334 334 |/
335 335 o 0: 02f0f58d5300 'common'
336 336
337 337 Due to the limitation of 3-way merge algorithm (1 merge base), rebasing a merge
338 338 may include unwanted content:
339 339
340 340 $ hg init $TESTTMP/dual-merge-base1
341 341 $ cd $TESTTMP/dual-merge-base1
342 342 $ hg debugdrawdag <<'EOS'
343 343 > F
344 344 > /|
345 345 > D E
346 346 > | |
347 347 > B C
348 348 > |/
349 349 > A Z
350 350 > |/
351 351 > R
352 352 > EOS
353 353 $ hg rebase -r D+E+F -d Z
354 354 rebasing 5:5f2c926dfecf "D" (D)
355 355 rebasing 6:b296604d9846 "E" (E)
356 356 rebasing 7:caa9781e507d "F" (F tip)
357 357 abort: rebasing 7:caa9781e507d will include unwanted changes from 4:d6003a550c2c or 3:c1e6b162678d
358 358 [255]
359 359
360 360 The warning does not get printed if there is no unwanted change detected:
361 361
362 362 $ hg init $TESTTMP/dual-merge-base2
363 363 $ cd $TESTTMP/dual-merge-base2
364 364 $ hg debugdrawdag <<'EOS'
365 365 > D
366 366 > /|
367 367 > B C
368 368 > |/
369 369 > A Z
370 370 > |/
371 371 > R
372 372 > EOS
373 373 $ hg rebase -r B+C+D -d Z
374 374 rebasing 3:c1e6b162678d "B" (B)
375 375 rebasing 4:d6003a550c2c "C" (C)
376 376 rebasing 5:c8f78076273e "D" (D tip)
377 377 saved backup bundle to $TESTTMP/dual-merge-base2/.hg/strip-backup/d6003a550c2c-6f1424b6-rebase.hg
378 378 $ hg manifest -r 'desc(D)'
379 379 B
380 380 C
381 381 R
382 382 Z
383 383
384 384 The merge base could be different from old p1 (changed parent becomes new p1):
385 385
386 386 $ hg init $TESTTMP/chosen-merge-base1
387 387 $ cd $TESTTMP/chosen-merge-base1
388 388 $ hg debugdrawdag <<'EOS'
389 389 > F
390 390 > /|
391 391 > D E
392 392 > | |
393 393 > B C Z
394 394 > EOS
395 395 $ hg rebase -r D+F -d Z
396 396 rebasing 3:004dc1679908 "D" (D)
397 397 rebasing 5:4be4cbf6f206 "F" (F tip)
398 398 saved backup bundle to $TESTTMP/chosen-merge-base1/.hg/strip-backup/004dc1679908-06a66a3c-rebase.hg
399 399 $ hg manifest -r 'desc(F)'
400 400 C
401 401 D
402 402 E
403 403 Z
404 404 $ hg log -r `hg log -r 'desc(F)' -T '{p1node}'` -T '{desc}\n'
405 405 D
406 406
407 407 $ hg init $TESTTMP/chosen-merge-base2
408 408 $ cd $TESTTMP/chosen-merge-base2
409 409 $ hg debugdrawdag <<'EOS'
410 410 > F
411 411 > /|
412 412 > D E
413 413 > | |
414 414 > B C Z
415 415 > EOS
416 416 $ hg rebase -r E+F -d Z
417 417 rebasing 4:974e4943c210 "E" (E)
418 418 rebasing 5:4be4cbf6f206 "F" (F tip)
419 419 saved backup bundle to $TESTTMP/chosen-merge-base2/.hg/strip-backup/974e4943c210-b2874da5-rebase.hg
420 420 $ hg manifest -r 'desc(F)'
421 421 B
422 422 D
423 423 E
424 424 Z
425 425 $ hg log -r `hg log -r 'desc(F)' -T '{p1node}'` -T '{desc}\n'
426 426 E
@@ -1,2137 +1,2137 b''
1 1 ==========================
2 2 Test rebase with obsolete
3 3 ==========================
4 4
5 5 Enable obsolete
6 6
7 7 $ cat >> $HGRCPATH << EOF
8 8 > [ui]
9 9 > logtemplate= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
10 10 > [experimental]
11 11 > evolution.createmarkers=True
12 12 > evolution.allowunstable=True
13 13 > [phases]
14 14 > publish=False
15 15 > [extensions]
16 16 > rebase=
17 17 > drawdag=$TESTDIR/drawdag.py
18 18 > strip=
19 19 > EOF
20 20
21 21 Setup rebase canonical repo
22 22
23 23 $ hg init base
24 24 $ cd base
25 25 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
26 26 adding changesets
27 27 adding manifests
28 28 adding file changes
29 29 added 8 changesets with 7 changes to 7 files (+2 heads)
30 30 new changesets cd010b8cd998:02de42196ebe (8 drafts)
31 31 (run 'hg heads' to see heads, 'hg merge' to merge)
32 32 $ hg up tip
33 33 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ hg log -G
35 35 @ 7:02de42196ebe H
36 36 |
37 37 | o 6:eea13746799a G
38 38 |/|
39 39 o | 5:24b6387c8c8c F
40 40 | |
41 41 | o 4:9520eea781bc E
42 42 |/
43 43 | o 3:32af7686d403 D
44 44 | |
45 45 | o 2:5fddd98957c8 C
46 46 | |
47 47 | o 1:42ccdea3bb16 B
48 48 |/
49 49 o 0:cd010b8cd998 A
50 50
51 51 $ cd ..
52 52
53 53 simple rebase
54 54 ---------------------------------
55 55
56 56 $ hg clone base simple
57 57 updating to branch default
58 58 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 59 $ cd simple
60 60 $ hg up 32af7686d403
61 61 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
62 62 $ hg rebase -d eea13746799a
63 63 rebasing 1:42ccdea3bb16 "B"
64 64 rebasing 2:5fddd98957c8 "C"
65 65 rebasing 3:32af7686d403 "D"
66 66 $ hg log -G
67 67 @ 10:8eeb3c33ad33 D
68 68 |
69 69 o 9:2327fea05063 C
70 70 |
71 71 o 8:e4e5be0395b2 B
72 72 |
73 73 | o 7:02de42196ebe H
74 74 | |
75 75 o | 6:eea13746799a G
76 76 |\|
77 77 | o 5:24b6387c8c8c F
78 78 | |
79 79 o | 4:9520eea781bc E
80 80 |/
81 81 o 0:cd010b8cd998 A
82 82
83 83 $ hg log --hidden -G
84 84 @ 10:8eeb3c33ad33 D
85 85 |
86 86 o 9:2327fea05063 C
87 87 |
88 88 o 8:e4e5be0395b2 B
89 89 |
90 90 | o 7:02de42196ebe H
91 91 | |
92 92 o | 6:eea13746799a G
93 93 |\|
94 94 | o 5:24b6387c8c8c F
95 95 | |
96 96 o | 4:9520eea781bc E
97 97 |/
98 98 | x 3:32af7686d403 D (rewritten using rebase as 10:8eeb3c33ad33)
99 99 | |
100 100 | x 2:5fddd98957c8 C (rewritten using rebase as 9:2327fea05063)
101 101 | |
102 102 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:e4e5be0395b2)
103 103 |/
104 104 o 0:cd010b8cd998 A
105 105
106 106 $ hg debugobsolete
107 107 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
108 108 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
109 109 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
110 110
111 111
112 112 $ cd ..
113 113
114 114 empty changeset
115 115 ---------------------------------
116 116
117 117 $ hg clone base empty
118 118 updating to branch default
119 119 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 120 $ cd empty
121 121 $ hg up eea13746799a
122 122 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
123 123
124 124 We make a copy of both the first changeset in the rebased and some other in the
125 125 set.
126 126
127 127 $ hg graft 42ccdea3bb16 32af7686d403
128 128 grafting 1:42ccdea3bb16 "B"
129 129 grafting 3:32af7686d403 "D"
130 130 $ hg rebase -s 42ccdea3bb16 -d .
131 131 rebasing 1:42ccdea3bb16 "B"
132 note: rebase of 1:42ccdea3bb16 "B" created no changes to commit
132 note: not rebasing 1:42ccdea3bb16 "B", its destination already has all its changes
133 133 rebasing 2:5fddd98957c8 "C"
134 134 rebasing 3:32af7686d403 "D"
135 note: rebase of 3:32af7686d403 "D" created no changes to commit
135 note: not rebasing 3:32af7686d403 "D", its destination already has all its changes
136 136 $ hg log -G
137 137 o 10:5ae4c968c6ac C
138 138 |
139 139 @ 9:08483444fef9 D
140 140 |
141 141 o 8:8877864f1edb B
142 142 |
143 143 | o 7:02de42196ebe H
144 144 | |
145 145 o | 6:eea13746799a G
146 146 |\|
147 147 | o 5:24b6387c8c8c F
148 148 | |
149 149 o | 4:9520eea781bc E
150 150 |/
151 151 o 0:cd010b8cd998 A
152 152
153 153 $ hg log --hidden -G
154 154 o 10:5ae4c968c6ac C
155 155 |
156 156 @ 9:08483444fef9 D
157 157 |
158 158 o 8:8877864f1edb B
159 159 |
160 160 | o 7:02de42196ebe H
161 161 | |
162 162 o | 6:eea13746799a G
163 163 |\|
164 164 | o 5:24b6387c8c8c F
165 165 | |
166 166 o | 4:9520eea781bc E
167 167 |/
168 168 | x 3:32af7686d403 D (pruned using rebase)
169 169 | |
170 170 | x 2:5fddd98957c8 C (rewritten using rebase as 10:5ae4c968c6ac)
171 171 | |
172 172 | x 1:42ccdea3bb16 B (pruned using rebase)
173 173 |/
174 174 o 0:cd010b8cd998 A
175 175
176 176 $ hg debugobsolete
177 177 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
178 178 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
179 179 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
180 180
181 181
182 182 More complex case where part of the rebase set were already rebased
183 183
184 184 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
185 185 rebasing 9:08483444fef9 "D"
186 186 1 new orphan changesets
187 187 $ hg debugobsolete
188 188 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
189 189 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
190 190 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
191 191 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
192 192 $ hg log -G
193 193 @ 11:4596109a6a43 D
194 194 |
195 195 | * 10:5ae4c968c6ac C
196 196 | |
197 197 | x 9:08483444fef9 D (rewritten using rebase as 11:4596109a6a43)
198 198 | |
199 199 | o 8:8877864f1edb B
200 200 | |
201 201 o | 7:02de42196ebe H
202 202 | |
203 203 | o 6:eea13746799a G
204 204 |/|
205 205 o | 5:24b6387c8c8c F
206 206 | |
207 207 | o 4:9520eea781bc E
208 208 |/
209 209 o 0:cd010b8cd998 A
210 210
211 211 $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
212 212 rebasing 8:8877864f1edb "B"
213 213 note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D" (tip)
214 214 rebasing 10:5ae4c968c6ac "C"
215 215 $ hg debugobsolete
216 216 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
217 217 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
218 218 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {5fddd98957c8a54a4d436dfe1da9d87f21a1b97b} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
219 219 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
220 220 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
221 221 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
222 222 $ hg log --rev 'contentdivergent()'
223 223 $ hg log -G
224 224 o 13:98f6af4ee953 C
225 225 |
226 226 o 12:462a34d07e59 B
227 227 |
228 228 @ 11:4596109a6a43 D
229 229 |
230 230 o 7:02de42196ebe H
231 231 |
232 232 | o 6:eea13746799a G
233 233 |/|
234 234 o | 5:24b6387c8c8c F
235 235 | |
236 236 | o 4:9520eea781bc E
237 237 |/
238 238 o 0:cd010b8cd998 A
239 239
240 240 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
241 241 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
242 242 phase: draft
243 243 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
244 244 parent: -1:0000000000000000000000000000000000000000
245 245 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
246 246 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
247 247 date: Sat Apr 30 15:24:48 2011 +0200
248 248 files+: D
249 249 extra: branch=default
250 250 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
251 251 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
252 252 description:
253 253 D
254 254
255 255
256 256 $ hg up -qr 'desc(G)'
257 257 $ hg graft 4596109a6a4328c398bde3a4a3b6737cfade3003
258 258 grafting 11:4596109a6a43 "D"
259 259 $ hg up -qr 'desc(E)'
260 260 $ hg rebase -s tip -d .
261 261 rebasing 14:9e36056a46e3 "D" (tip)
262 262 $ hg log --style default --debug -r tip
263 263 changeset: 15:627d4614809036ba22b9e7cb31638ddc06ab99ab
264 264 tag: tip
265 265 phase: draft
266 266 parent: 4:9520eea781bcca16c1e15acc0ba14335a0e8e5ba
267 267 parent: -1:0000000000000000000000000000000000000000
268 268 manifest: 15:648e8ede73ae3e497d093d3a4c8fcc2daa864f42
269 269 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
270 270 date: Sat Apr 30 15:24:48 2011 +0200
271 271 files+: D
272 272 extra: branch=default
273 273 extra: intermediate-source=4596109a6a4328c398bde3a4a3b6737cfade3003
274 274 extra: rebase_source=9e36056a46e37c9776168c7375734eebc70e294f
275 275 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
276 276 description:
277 277 D
278 278
279 279
280 280 Start rebase from a commit that is obsolete but not hidden only because it's
281 281 a working copy parent. We should be moved back to the starting commit as usual
282 282 even though it is hidden (until we're moved there).
283 283
284 284 $ hg --hidden up -qr 'first(hidden())'
285 285 updated to hidden changeset 42ccdea3bb16
286 286 (hidden revision '42ccdea3bb16' is pruned)
287 287 $ hg rebase --rev 13 --dest 15
288 288 rebasing 13:98f6af4ee953 "C"
289 289 $ hg log -G
290 290 o 16:294a2b93eb4d C
291 291 |
292 292 o 15:627d46148090 D
293 293 |
294 294 | o 12:462a34d07e59 B
295 295 | |
296 296 | o 11:4596109a6a43 D
297 297 | |
298 298 | o 7:02de42196ebe H
299 299 | |
300 300 +---o 6:eea13746799a G
301 301 | |/
302 302 | o 5:24b6387c8c8c F
303 303 | |
304 304 o | 4:9520eea781bc E
305 305 |/
306 306 | @ 1:42ccdea3bb16 B (pruned using rebase)
307 307 |/
308 308 o 0:cd010b8cd998 A
309 309
310 310
311 311 $ cd ..
312 312
313 313 collapse rebase
314 314 ---------------------------------
315 315
316 316 $ hg clone base collapse
317 317 updating to branch default
318 318 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 319 $ cd collapse
320 320 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
321 321 rebasing 1:42ccdea3bb16 "B"
322 322 rebasing 2:5fddd98957c8 "C"
323 323 rebasing 3:32af7686d403 "D"
324 324 $ hg log -G
325 325 o 8:4dc2197e807b Collapsed revision
326 326 |
327 327 | @ 7:02de42196ebe H
328 328 | |
329 329 o | 6:eea13746799a G
330 330 |\|
331 331 | o 5:24b6387c8c8c F
332 332 | |
333 333 o | 4:9520eea781bc E
334 334 |/
335 335 o 0:cd010b8cd998 A
336 336
337 337 $ hg log --hidden -G
338 338 o 8:4dc2197e807b Collapsed revision
339 339 |
340 340 | @ 7:02de42196ebe H
341 341 | |
342 342 o | 6:eea13746799a G
343 343 |\|
344 344 | o 5:24b6387c8c8c F
345 345 | |
346 346 o | 4:9520eea781bc E
347 347 |/
348 348 | x 3:32af7686d403 D (rewritten using rebase as 8:4dc2197e807b)
349 349 | |
350 350 | x 2:5fddd98957c8 C (rewritten using rebase as 8:4dc2197e807b)
351 351 | |
352 352 | x 1:42ccdea3bb16 B (rewritten using rebase as 8:4dc2197e807b)
353 353 |/
354 354 o 0:cd010b8cd998 A
355 355
356 356 $ hg id --debug -r tip
357 357 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
358 358 $ hg debugobsolete
359 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 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 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 363 $ cd ..
364 364
365 365 Rebase set has hidden descendants
366 366 ---------------------------------
367 367
368 368 We rebase a changeset which has hidden descendants. Hidden changesets must not
369 369 be rebased.
370 370
371 371 $ hg clone base hidden
372 372 updating to branch default
373 373 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 374 $ cd hidden
375 375 $ hg log -G
376 376 @ 7:02de42196ebe H
377 377 |
378 378 | o 6:eea13746799a G
379 379 |/|
380 380 o | 5:24b6387c8c8c F
381 381 | |
382 382 | o 4:9520eea781bc E
383 383 |/
384 384 | o 3:32af7686d403 D
385 385 | |
386 386 | o 2:5fddd98957c8 C
387 387 | |
388 388 | o 1:42ccdea3bb16 B
389 389 |/
390 390 o 0:cd010b8cd998 A
391 391
392 392 $ hg rebase -s 5fddd98957c8 -d eea13746799a
393 393 rebasing 2:5fddd98957c8 "C"
394 394 rebasing 3:32af7686d403 "D"
395 395 $ hg log -G
396 396 o 9:cf44d2f5a9f4 D
397 397 |
398 398 o 8:e273c5e7d2d2 C
399 399 |
400 400 | @ 7:02de42196ebe H
401 401 | |
402 402 o | 6:eea13746799a G
403 403 |\|
404 404 | o 5:24b6387c8c8c F
405 405 | |
406 406 o | 4:9520eea781bc E
407 407 |/
408 408 | o 1:42ccdea3bb16 B
409 409 |/
410 410 o 0:cd010b8cd998 A
411 411
412 412 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
413 413 rebasing 1:42ccdea3bb16 "B"
414 414 $ hg log -G
415 415 o 10:7c6027df6a99 B
416 416 |
417 417 | o 9:cf44d2f5a9f4 D
418 418 | |
419 419 | o 8:e273c5e7d2d2 C
420 420 | |
421 421 @ | 7:02de42196ebe H
422 422 | |
423 423 | o 6:eea13746799a G
424 424 |/|
425 425 o | 5:24b6387c8c8c F
426 426 | |
427 427 | o 4:9520eea781bc E
428 428 |/
429 429 o 0:cd010b8cd998 A
430 430
431 431 $ hg log --hidden -G
432 432 o 10:7c6027df6a99 B
433 433 |
434 434 | o 9:cf44d2f5a9f4 D
435 435 | |
436 436 | o 8:e273c5e7d2d2 C
437 437 | |
438 438 @ | 7:02de42196ebe H
439 439 | |
440 440 | o 6:eea13746799a G
441 441 |/|
442 442 o | 5:24b6387c8c8c F
443 443 | |
444 444 | o 4:9520eea781bc E
445 445 |/
446 446 | x 3:32af7686d403 D (rewritten using rebase as 9:cf44d2f5a9f4)
447 447 | |
448 448 | x 2:5fddd98957c8 C (rewritten using rebase as 8:e273c5e7d2d2)
449 449 | |
450 450 | x 1:42ccdea3bb16 B (rewritten using rebase as 10:7c6027df6a99)
451 451 |/
452 452 o 0:cd010b8cd998 A
453 453
454 454 $ hg debugobsolete
455 455 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
456 456 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
457 457 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
458 458
459 459 Test that rewriting leaving instability behind is allowed
460 460 ---------------------------------------------------------------------
461 461
462 462 $ hg log -r 'children(8)'
463 463 9:cf44d2f5a9f4 D (no-eol)
464 464 $ hg rebase -r 8
465 465 rebasing 8:e273c5e7d2d2 "C"
466 466 1 new orphan changesets
467 467 $ hg log -G
468 468 o 11:0d8f238b634c C
469 469 |
470 470 o 10:7c6027df6a99 B
471 471 |
472 472 | * 9:cf44d2f5a9f4 D
473 473 | |
474 474 | x 8:e273c5e7d2d2 C (rewritten using rebase as 11:0d8f238b634c)
475 475 | |
476 476 @ | 7:02de42196ebe H
477 477 | |
478 478 | o 6:eea13746799a G
479 479 |/|
480 480 o | 5:24b6387c8c8c F
481 481 | |
482 482 | o 4:9520eea781bc E
483 483 |/
484 484 o 0:cd010b8cd998 A
485 485
486 486 $ cd ..
487 487 $ cp -R hidden stabilize
488 488 $ cd stabilize
489 489 $ hg rebase --auto-orphans '0::' -d 10
490 490 abort: --auto-orphans is incompatible with --dest
491 491 [255]
492 492 $ hg rebase --auto-orphans '0::'
493 493 rebasing 9:cf44d2f5a9f4 "D"
494 494 $ hg log -G
495 495 o 12:7e3935feaa68 D
496 496 |
497 497 o 11:0d8f238b634c C
498 498 |
499 499 o 10:7c6027df6a99 B
500 500 |
501 501 @ 7:02de42196ebe H
502 502 |
503 503 | o 6:eea13746799a G
504 504 |/|
505 505 o | 5:24b6387c8c8c F
506 506 | |
507 507 | o 4:9520eea781bc E
508 508 |/
509 509 o 0:cd010b8cd998 A
510 510
511 511
512 512 $ cd ../hidden
513 513 $ rm -r ../stabilize
514 514
515 515 Test multiple root handling
516 516 ------------------------------------
517 517
518 518 $ hg rebase --dest 4 --rev '7+11+9'
519 519 rebasing 9:cf44d2f5a9f4 "D"
520 520 rebasing 7:02de42196ebe "H"
521 521 rebasing 11:0d8f238b634c "C" (tip)
522 522 $ hg log -G
523 523 o 14:1e8370e38cca C
524 524 |
525 525 @ 13:bfe264faf697 H
526 526 |
527 527 | o 12:102b4c1d889b D
528 528 |/
529 529 | * 10:7c6027df6a99 B
530 530 | |
531 531 | x 7:02de42196ebe H (rewritten using rebase as 13:bfe264faf697)
532 532 | |
533 533 +---o 6:eea13746799a G
534 534 | |/
535 535 | o 5:24b6387c8c8c F
536 536 | |
537 537 o | 4:9520eea781bc E
538 538 |/
539 539 o 0:cd010b8cd998 A
540 540
541 541 $ cd ..
542 542
543 543 Detach both parents
544 544
545 545 $ hg init double-detach
546 546 $ cd double-detach
547 547
548 548 $ hg debugdrawdag <<EOF
549 549 > F
550 550 > /|
551 551 > C E
552 552 > | |
553 553 > B D G
554 554 > \|/
555 555 > A
556 556 > EOF
557 557
558 558 $ hg rebase -d G -r 'B + D + F'
559 559 rebasing 1:112478962961 "B" (B)
560 560 rebasing 2:b18e25de2cf5 "D" (D)
561 561 rebasing 6:f15c3adaf214 "F" (F tip)
562 562 abort: cannot rebase 6:f15c3adaf214 without moving at least one of its parents
563 563 [255]
564 564
565 565 $ cd ..
566 566
567 567 test on rebase dropping a merge
568 568
569 569 (setup)
570 570
571 571 $ hg init dropmerge
572 572 $ cd dropmerge
573 573 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
574 574 adding changesets
575 575 adding manifests
576 576 adding file changes
577 577 added 8 changesets with 7 changes to 7 files (+2 heads)
578 578 new changesets cd010b8cd998:02de42196ebe (8 drafts)
579 579 (run 'hg heads' to see heads, 'hg merge' to merge)
580 580 $ hg up 3
581 581 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 582 $ hg merge 7
583 583 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 584 (branch merge, don't forget to commit)
585 585 $ hg ci -m 'M'
586 586 $ echo I > I
587 587 $ hg add I
588 588 $ hg ci -m I
589 589 $ hg log -G
590 590 @ 9:4bde274eefcf I
591 591 |
592 592 o 8:53a6a128b2b7 M
593 593 |\
594 594 | o 7:02de42196ebe H
595 595 | |
596 596 | | o 6:eea13746799a G
597 597 | |/|
598 598 | o | 5:24b6387c8c8c F
599 599 | | |
600 600 | | o 4:9520eea781bc E
601 601 | |/
602 602 o | 3:32af7686d403 D
603 603 | |
604 604 o | 2:5fddd98957c8 C
605 605 | |
606 606 o | 1:42ccdea3bb16 B
607 607 |/
608 608 o 0:cd010b8cd998 A
609 609
610 610 (actual test)
611 611
612 612 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
613 613 rebasing 3:32af7686d403 "D"
614 614 rebasing 7:02de42196ebe "H"
615 615 rebasing 9:4bde274eefcf "I" (tip)
616 616 1 new orphan changesets
617 617 $ hg log -G
618 618 @ 12:acd174b7ab39 I
619 619 |
620 620 o 11:6c11a6218c97 H
621 621 |
622 622 | o 10:b5313c85b22e D
623 623 |/
624 624 | * 8:53a6a128b2b7 M
625 625 | |\
626 626 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
627 627 | | |
628 628 o---+ 6:eea13746799a G
629 629 | | |
630 630 | | o 5:24b6387c8c8c F
631 631 | | |
632 632 o---+ 4:9520eea781bc E
633 633 / /
634 634 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
635 635 | |
636 636 o | 2:5fddd98957c8 C
637 637 | |
638 638 o | 1:42ccdea3bb16 B
639 639 |/
640 640 o 0:cd010b8cd998 A
641 641
642 642
643 643 Test hidden changesets in the rebase set (issue4504)
644 644
645 645 $ hg up --hidden 9
646 646 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
647 647 updated to hidden changeset 4bde274eefcf
648 648 (hidden revision '4bde274eefcf' was rewritten as: acd174b7ab39)
649 649 $ echo J > J
650 650 $ hg add J
651 651 $ hg commit -m J
652 652 1 new orphan changesets
653 653 $ hg debugobsolete `hg log --rev . -T '{node}'`
654 654 obsoleted 1 changesets
655 655
656 656 $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
657 657 rebasing 9:4bde274eefcf "I"
658 658 rebasing 13:06edfc82198f "J" (tip)
659 659 2 new content-divergent changesets
660 660 $ hg log -G
661 661 @ 15:5ae8a643467b J
662 662 |
663 663 * 14:9ad579b4a5de I
664 664 |
665 665 | * 12:acd174b7ab39 I
666 666 | |
667 667 | o 11:6c11a6218c97 H
668 668 | |
669 669 o | 10:b5313c85b22e D
670 670 |/
671 671 | * 8:53a6a128b2b7 M
672 672 | |\
673 673 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
674 674 | | |
675 675 o---+ 6:eea13746799a G
676 676 | | |
677 677 | | o 5:24b6387c8c8c F
678 678 | | |
679 679 o---+ 4:9520eea781bc E
680 680 / /
681 681 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
682 682 | |
683 683 o | 2:5fddd98957c8 C
684 684 | |
685 685 o | 1:42ccdea3bb16 B
686 686 |/
687 687 o 0:cd010b8cd998 A
688 688
689 689 $ hg up 14 -C
690 690 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
691 691 $ echo "K" > K
692 692 $ hg add K
693 693 $ hg commit --amend -m "K"
694 694 1 new orphan changesets
695 695 $ echo "L" > L
696 696 $ hg add L
697 697 $ hg commit -m "L"
698 698 $ hg up '.^'
699 699 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
700 700 $ echo "M" > M
701 701 $ hg add M
702 702 $ hg commit --amend -m "M"
703 703 1 new orphan changesets
704 704 $ hg log -G
705 705 @ 18:bfaedf8eb73b M
706 706 |
707 707 | * 17:97219452e4bd L
708 708 | |
709 709 | x 16:fc37a630c901 K (rewritten using amend as 18:bfaedf8eb73b)
710 710 |/
711 711 | * 15:5ae8a643467b J
712 712 | |
713 713 | x 14:9ad579b4a5de I (rewritten using amend as 16:fc37a630c901)
714 714 |/
715 715 | * 12:acd174b7ab39 I
716 716 | |
717 717 | o 11:6c11a6218c97 H
718 718 | |
719 719 o | 10:b5313c85b22e D
720 720 |/
721 721 | * 8:53a6a128b2b7 M
722 722 | |\
723 723 | | x 7:02de42196ebe H (rewritten using rebase as 11:6c11a6218c97)
724 724 | | |
725 725 o---+ 6:eea13746799a G
726 726 | | |
727 727 | | o 5:24b6387c8c8c F
728 728 | | |
729 729 o---+ 4:9520eea781bc E
730 730 / /
731 731 x | 3:32af7686d403 D (rewritten using rebase as 10:b5313c85b22e)
732 732 | |
733 733 o | 2:5fddd98957c8 C
734 734 | |
735 735 o | 1:42ccdea3bb16 B
736 736 |/
737 737 o 0:cd010b8cd998 A
738 738
739 739 $ hg rebase -s 14 -d 17 --config experimental.rebaseskipobsolete=True
740 740 note: not rebasing 14:9ad579b4a5de "I", already in destination as 16:fc37a630c901 "K"
741 741 rebasing 15:5ae8a643467b "J"
742 742 1 new orphan changesets
743 743
744 744 $ cd ..
745 745
746 746 Skip obsolete changeset even with multiple hops
747 747 -----------------------------------------------
748 748
749 749 setup
750 750
751 751 $ hg init obsskip
752 752 $ cd obsskip
753 753 $ cat << EOF >> .hg/hgrc
754 754 > [experimental]
755 755 > rebaseskipobsolete = True
756 756 > [extensions]
757 757 > strip =
758 758 > EOF
759 759 $ echo A > A
760 760 $ hg add A
761 761 $ hg commit -m A
762 762 $ echo B > B
763 763 $ hg add B
764 764 $ hg commit -m B0
765 765 $ hg commit --amend -m B1
766 766 $ hg commit --amend -m B2
767 767 $ hg up --hidden 'desc(B0)'
768 768 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
769 769 updated to hidden changeset a8b11f55fb19
770 770 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
771 771 $ echo C > C
772 772 $ hg add C
773 773 $ hg commit -m C
774 774 1 new orphan changesets
775 775 $ hg log -G
776 776 @ 4:212cb178bcbb C
777 777 |
778 778 | o 3:261e70097290 B2
779 779 | |
780 780 x | 1:a8b11f55fb19 B0 (rewritten using amend as 3:261e70097290)
781 781 |/
782 782 o 0:4a2df7238c3b A
783 783
784 784
785 785 Rebase finds its way in a chain of marker
786 786
787 787 $ hg rebase -d 'desc(B2)'
788 788 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
789 789 rebasing 4:212cb178bcbb "C" (tip)
790 790
791 791 Even when the chain include missing node
792 792
793 793 $ hg up --hidden 'desc(B0)'
794 794 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
795 795 updated to hidden changeset a8b11f55fb19
796 796 (hidden revision 'a8b11f55fb19' was rewritten as: 261e70097290)
797 797 $ echo D > D
798 798 $ hg add D
799 799 $ hg commit -m D
800 800 1 new orphan changesets
801 801 $ hg --hidden strip -r 'desc(B1)'
802 802 saved backup bundle to $TESTTMP/obsskip/.hg/strip-backup/86f6414ccda7-b1c452ee-backup.hg
803 803 1 new orphan changesets
804 804 $ hg log -G
805 805 @ 5:1a79b7535141 D
806 806 |
807 807 | o 4:ff2c4d47b71d C
808 808 | |
809 809 | o 2:261e70097290 B2
810 810 | |
811 811 x | 1:a8b11f55fb19 B0 (rewritten using amend as 2:261e70097290)
812 812 |/
813 813 o 0:4a2df7238c3b A
814 814
815 815
816 816 $ hg rebase -d 'desc(B2)'
817 817 note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
818 818 rebasing 5:1a79b7535141 "D" (tip)
819 819 $ hg up 4
820 820 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
821 821 $ echo "O" > O
822 822 $ hg add O
823 823 $ hg commit -m O
824 824 $ echo "P" > P
825 825 $ hg add P
826 826 $ hg commit -m P
827 827 $ hg log -G
828 828 @ 8:8d47583e023f P
829 829 |
830 830 o 7:360bbaa7d3ce O
831 831 |
832 832 | o 6:9c48361117de D
833 833 | |
834 834 o | 4:ff2c4d47b71d C
835 835 |/
836 836 o 2:261e70097290 B2
837 837 |
838 838 o 0:4a2df7238c3b A
839 839
840 840 $ hg debugobsolete `hg log -r 7 -T '{node}\n'` --config experimental.evolution=true
841 841 obsoleted 1 changesets
842 842 1 new orphan changesets
843 843 $ hg rebase -d 6 -r "4::"
844 844 rebasing 4:ff2c4d47b71d "C"
845 845 note: not rebasing 7:360bbaa7d3ce "O", it has no successor
846 846 rebasing 8:8d47583e023f "P" (tip)
847 847
848 848 If all the changeset to be rebased are obsolete and present in the destination, we
849 849 should display a friendly error message
850 850
851 851 $ hg log -G
852 852 @ 10:121d9e3bc4c6 P
853 853 |
854 854 o 9:4be60e099a77 C
855 855 |
856 856 o 6:9c48361117de D
857 857 |
858 858 o 2:261e70097290 B2
859 859 |
860 860 o 0:4a2df7238c3b A
861 861
862 862
863 863 $ hg up 9
864 864 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
865 865 $ echo "non-relevant change" > nonrelevant
866 866 $ hg add nonrelevant
867 867 $ hg commit -m nonrelevant
868 868 created new head
869 869 $ hg debugobsolete `hg log -r 11 -T '{node}\n'` --config experimental.evolution=true
870 870 obsoleted 1 changesets
871 871 $ hg log -G
872 872 @ 11:f44da1f4954c nonrelevant (pruned)
873 873 |
874 874 | o 10:121d9e3bc4c6 P
875 875 |/
876 876 o 9:4be60e099a77 C
877 877 |
878 878 o 6:9c48361117de D
879 879 |
880 880 o 2:261e70097290 B2
881 881 |
882 882 o 0:4a2df7238c3b A
883 883
884 884 $ hg rebase -r . -d 10
885 885 note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
886 886
887 887 If a rebase is going to create divergence, it should abort
888 888
889 889 $ hg log -G
890 890 @ 10:121d9e3bc4c6 P
891 891 |
892 892 o 9:4be60e099a77 C
893 893 |
894 894 o 6:9c48361117de D
895 895 |
896 896 o 2:261e70097290 B2
897 897 |
898 898 o 0:4a2df7238c3b A
899 899
900 900
901 901 $ hg up 9
902 902 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
903 903 $ echo "john" > doe
904 904 $ hg add doe
905 905 $ hg commit -m "john doe"
906 906 created new head
907 907 $ hg up 10
908 908 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
909 909 $ echo "foo" > bar
910 910 $ hg add bar
911 911 $ hg commit --amend -m "10'"
912 912 $ hg up 10 --hidden
913 913 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
914 914 updated to hidden changeset 121d9e3bc4c6
915 915 (hidden revision '121d9e3bc4c6' was rewritten as: 77d874d096a2)
916 916 $ echo "bar" > foo
917 917 $ hg add foo
918 918 $ hg commit -m "bar foo"
919 919 1 new orphan changesets
920 920 $ hg log -G
921 921 @ 14:73568ab6879d bar foo
922 922 |
923 923 | o 13:77d874d096a2 10'
924 924 | |
925 925 | | o 12:3eb461388009 john doe
926 926 | |/
927 927 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
928 928 |/
929 929 o 9:4be60e099a77 C
930 930 |
931 931 o 6:9c48361117de D
932 932 |
933 933 o 2:261e70097290 B2
934 934 |
935 935 o 0:4a2df7238c3b A
936 936
937 937 $ hg summary
938 938 parent: 14:73568ab6879d tip (orphan)
939 939 bar foo
940 940 branch: default
941 941 commit: (clean)
942 942 update: 2 new changesets, 3 branch heads (merge)
943 943 phases: 8 draft
944 944 orphan: 1 changesets
945 945 $ hg rebase -s 10 -d 12
946 946 abort: this rebase will cause divergences from: 121d9e3bc4c6
947 947 (to force the rebase please set experimental.evolution.allowdivergence=True)
948 948 [255]
949 949 $ hg log -G
950 950 @ 14:73568ab6879d bar foo
951 951 |
952 952 | o 13:77d874d096a2 10'
953 953 | |
954 954 | | o 12:3eb461388009 john doe
955 955 | |/
956 956 x | 10:121d9e3bc4c6 P (rewritten using amend as 13:77d874d096a2)
957 957 |/
958 958 o 9:4be60e099a77 C
959 959 |
960 960 o 6:9c48361117de D
961 961 |
962 962 o 2:261e70097290 B2
963 963 |
964 964 o 0:4a2df7238c3b A
965 965
966 966 With experimental.evolution.allowdivergence=True, rebase can create divergence
967 967
968 968 $ hg rebase -s 10 -d 12 --config experimental.evolution.allowdivergence=True
969 969 rebasing 10:121d9e3bc4c6 "P"
970 970 rebasing 14:73568ab6879d "bar foo" (tip)
971 971 2 new content-divergent changesets
972 972 $ hg summary
973 973 parent: 16:61bd55f69bc4 tip
974 974 bar foo
975 975 branch: default
976 976 commit: (clean)
977 977 update: 1 new changesets, 2 branch heads (merge)
978 978 phases: 8 draft
979 979 content-divergent: 2 changesets
980 980
981 981 rebase --continue + skipped rev because their successors are in destination
982 982 we make a change in trunk and work on conflicting changes to make rebase abort.
983 983
984 984 $ hg log -G -r 16::
985 985 @ 16:61bd55f69bc4 bar foo
986 986 |
987 987 ~
988 988
989 989 Create the two changes in trunk
990 990 $ printf "a" > willconflict
991 991 $ hg add willconflict
992 992 $ hg commit -m "willconflict first version"
993 993
994 994 $ printf "dummy" > C
995 995 $ hg commit -m "dummy change successor"
996 996
997 997 Create the changes that we will rebase
998 998 $ hg update -C 16 -q
999 999 $ printf "b" > willconflict
1000 1000 $ hg add willconflict
1001 1001 $ hg commit -m "willconflict second version"
1002 1002 created new head
1003 1003 $ printf "dummy" > K
1004 1004 $ hg add K
1005 1005 $ hg commit -m "dummy change"
1006 1006 $ printf "dummy" > L
1007 1007 $ hg add L
1008 1008 $ hg commit -m "dummy change"
1009 1009 $ hg debugobsolete `hg log -r ".^" -T '{node}'` `hg log -r 18 -T '{node}'` --config experimental.evolution=true
1010 1010 obsoleted 1 changesets
1011 1011 1 new orphan changesets
1012 1012
1013 1013 $ hg log -G -r 16::
1014 1014 @ 21:7bdc8a87673d dummy change
1015 1015 |
1016 1016 x 20:8b31da3c4919 dummy change (rewritten as 18:601db7a18f51)
1017 1017 |
1018 1018 o 19:b82fb57ea638 willconflict second version
1019 1019 |
1020 1020 | o 18:601db7a18f51 dummy change successor
1021 1021 | |
1022 1022 | o 17:357ddf1602d5 willconflict first version
1023 1023 |/
1024 1024 o 16:61bd55f69bc4 bar foo
1025 1025 |
1026 1026 ~
1027 1027 $ hg rebase -r ".^^ + .^ + ." -d 18
1028 1028 rebasing 19:b82fb57ea638 "willconflict second version"
1029 1029 merging willconflict
1030 1030 warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
1031 1031 unresolved conflicts (see hg resolve, then hg rebase --continue)
1032 1032 [1]
1033 1033
1034 1034 $ hg resolve --mark willconflict
1035 1035 (no more unresolved files)
1036 1036 continue: hg rebase --continue
1037 1037 $ hg rebase --continue
1038 1038 rebasing 19:b82fb57ea638 "willconflict second version"
1039 1039 note: not rebasing 20:8b31da3c4919 "dummy change", already in destination as 18:601db7a18f51 "dummy change successor"
1040 1040 rebasing 21:7bdc8a87673d "dummy change" (tip)
1041 1041 $ cd ..
1042 1042
1043 1043 Divergence cases due to obsolete changesets
1044 1044 -------------------------------------------
1045 1045
1046 1046 We should ignore branches with unstable changesets when they are based on an
1047 1047 obsolete changeset which successor is in rebase set.
1048 1048
1049 1049 $ hg init divergence
1050 1050 $ cd divergence
1051 1051 $ cat >> .hg/hgrc << EOF
1052 1052 > [extensions]
1053 1053 > strip =
1054 1054 > [alias]
1055 1055 > strip = strip --no-backup --quiet
1056 1056 > [templates]
1057 1057 > instabilities = '{rev}:{node|short} {desc|firstline}{if(instabilities," ({instabilities})")}\n'
1058 1058 > EOF
1059 1059
1060 1060 $ hg debugdrawdag <<EOF
1061 1061 > e f
1062 1062 > | |
1063 1063 > d' d # replace: d -> d'
1064 1064 > \ /
1065 1065 > c
1066 1066 > |
1067 1067 > x b
1068 1068 > \|
1069 1069 > a
1070 1070 > EOF
1071 1071 1 new orphan changesets
1072 1072 $ hg log -G -r 'a'::
1073 1073 * 7:1143e9adc121 f
1074 1074 |
1075 1075 | o 6:d60ebfa0f1cb e
1076 1076 | |
1077 1077 | o 5:027ad6c5830d d'
1078 1078 | |
1079 1079 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1080 1080 |/
1081 1081 o 3:a82ac2b38757 c
1082 1082 |
1083 1083 | o 2:630d7c95eff7 x
1084 1084 | |
1085 1085 o | 1:488e1b7e7341 b
1086 1086 |/
1087 1087 o 0:b173517d0057 a
1088 1088
1089 1089
1090 1090 Changeset d and its descendants are excluded to avoid divergence of d, which
1091 1091 would occur because the successor of d (d') is also in rebaseset. As a
1092 1092 consequence f (descendant of d) is left behind.
1093 1093
1094 1094 $ hg rebase -b 'e' -d 'x'
1095 1095 rebasing 1:488e1b7e7341 "b" (b)
1096 1096 rebasing 3:a82ac2b38757 "c" (c)
1097 1097 rebasing 5:027ad6c5830d "d'" (d')
1098 1098 rebasing 6:d60ebfa0f1cb "e" (e)
1099 1099 note: not rebasing 4:76be324c128b "d" (d) and its descendants as this would cause divergence
1100 1100 $ hg log -G -r 'a'::
1101 1101 o 11:eb6d63fc4ed5 e
1102 1102 |
1103 1103 o 10:44d8c724a70c d'
1104 1104 |
1105 1105 o 9:d008e6b4d3fd c
1106 1106 |
1107 1107 o 8:67e8f4a16c49 b
1108 1108 |
1109 1109 | * 7:1143e9adc121 f
1110 1110 | |
1111 1111 | | x 6:d60ebfa0f1cb e (rewritten using rebase as 11:eb6d63fc4ed5)
1112 1112 | | |
1113 1113 | | x 5:027ad6c5830d d' (rewritten using rebase as 10:44d8c724a70c)
1114 1114 | | |
1115 1115 | x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1116 1116 | |/
1117 1117 | x 3:a82ac2b38757 c (rewritten using rebase as 9:d008e6b4d3fd)
1118 1118 | |
1119 1119 o | 2:630d7c95eff7 x
1120 1120 | |
1121 1121 | x 1:488e1b7e7341 b (rewritten using rebase as 8:67e8f4a16c49)
1122 1122 |/
1123 1123 o 0:b173517d0057 a
1124 1124
1125 1125 $ hg strip -r 8:
1126 1126 $ hg log -G -r 'a'::
1127 1127 * 7:1143e9adc121 f
1128 1128 |
1129 1129 | o 6:d60ebfa0f1cb e
1130 1130 | |
1131 1131 | o 5:027ad6c5830d d'
1132 1132 | |
1133 1133 x | 4:76be324c128b d (rewritten using replace as 5:027ad6c5830d)
1134 1134 |/
1135 1135 o 3:a82ac2b38757 c
1136 1136 |
1137 1137 | o 2:630d7c95eff7 x
1138 1138 | |
1139 1139 o | 1:488e1b7e7341 b
1140 1140 |/
1141 1141 o 0:b173517d0057 a
1142 1142
1143 1143
1144 1144 If the rebase set has an obsolete (d) with a successor (d') outside the rebase
1145 1145 set and none in destination, we still get the divergence warning.
1146 1146 By allowing divergence, we can perform the rebase.
1147 1147
1148 1148 $ hg rebase -r 'c'::'f' -d 'x'
1149 1149 abort: this rebase will cause divergences from: 76be324c128b
1150 1150 (to force the rebase please set experimental.evolution.allowdivergence=True)
1151 1151 [255]
1152 1152 $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
1153 1153 rebasing 3:a82ac2b38757 "c" (c)
1154 1154 rebasing 4:76be324c128b "d" (d)
1155 1155 rebasing 7:1143e9adc121 "f" (f tip)
1156 1156 1 new orphan changesets
1157 1157 2 new content-divergent changesets
1158 1158 $ hg log -G -r 'a':: -T instabilities
1159 1159 o 10:e1744ea07510 f
1160 1160 |
1161 1161 * 9:e2b36ea9a0a0 d (content-divergent)
1162 1162 |
1163 1163 o 8:6a0376de376e c
1164 1164 |
1165 1165 | x 7:1143e9adc121 f
1166 1166 | |
1167 1167 | | * 6:d60ebfa0f1cb e (orphan)
1168 1168 | | |
1169 1169 | | * 5:027ad6c5830d d' (orphan content-divergent)
1170 1170 | | |
1171 1171 | x | 4:76be324c128b d
1172 1172 | |/
1173 1173 | x 3:a82ac2b38757 c
1174 1174 | |
1175 1175 o | 2:630d7c95eff7 x
1176 1176 | |
1177 1177 | o 1:488e1b7e7341 b
1178 1178 |/
1179 1179 o 0:b173517d0057 a
1180 1180
1181 1181 $ hg strip -r 8:
1182 1182
1183 1183 (Not skipping obsoletes means that divergence is allowed.)
1184 1184
1185 1185 $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
1186 1186 rebasing 3:a82ac2b38757 "c" (c)
1187 1187 rebasing 4:76be324c128b "d" (d)
1188 1188 rebasing 7:1143e9adc121 "f" (f tip)
1189 1189 1 new orphan changesets
1190 1190 2 new content-divergent changesets
1191 1191
1192 1192 $ hg strip -r 0:
1193 1193
1194 1194 Similar test on a more complex graph
1195 1195
1196 1196 $ hg debugdrawdag <<EOF
1197 1197 > g
1198 1198 > |
1199 1199 > f e
1200 1200 > | |
1201 1201 > e' d # replace: e -> e'
1202 1202 > \ /
1203 1203 > c
1204 1204 > |
1205 1205 > x b
1206 1206 > \|
1207 1207 > a
1208 1208 > EOF
1209 1209 1 new orphan changesets
1210 1210 $ hg log -G -r 'a':
1211 1211 * 8:2876ce66c6eb g
1212 1212 |
1213 1213 | o 7:3ffec603ab53 f
1214 1214 | |
1215 1215 x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1216 1216 | |
1217 1217 | o 5:63324dc512ea e'
1218 1218 | |
1219 1219 o | 4:76be324c128b d
1220 1220 |/
1221 1221 o 3:a82ac2b38757 c
1222 1222 |
1223 1223 | o 2:630d7c95eff7 x
1224 1224 | |
1225 1225 o | 1:488e1b7e7341 b
1226 1226 |/
1227 1227 o 0:b173517d0057 a
1228 1228
1229 1229 $ hg rebase -b 'f' -d 'x'
1230 1230 rebasing 1:488e1b7e7341 "b" (b)
1231 1231 rebasing 3:a82ac2b38757 "c" (c)
1232 1232 rebasing 5:63324dc512ea "e'" (e')
1233 1233 rebasing 7:3ffec603ab53 "f" (f)
1234 1234 rebasing 4:76be324c128b "d" (d)
1235 1235 note: not rebasing 6:e36fae928aec "e" (e) and its descendants as this would cause divergence
1236 1236 $ hg log -G -r 'a':
1237 1237 o 13:a1707a5b7c2c d
1238 1238 |
1239 1239 | o 12:ef6251596616 f
1240 1240 | |
1241 1241 | o 11:b6f172e64af9 e'
1242 1242 |/
1243 1243 o 10:d008e6b4d3fd c
1244 1244 |
1245 1245 o 9:67e8f4a16c49 b
1246 1246 |
1247 1247 | * 8:2876ce66c6eb g
1248 1248 | |
1249 1249 | | x 7:3ffec603ab53 f (rewritten using rebase as 12:ef6251596616)
1250 1250 | | |
1251 1251 | x | 6:e36fae928aec e (rewritten using replace as 5:63324dc512ea)
1252 1252 | | |
1253 1253 | | x 5:63324dc512ea e' (rewritten using rebase as 11:b6f172e64af9)
1254 1254 | | |
1255 1255 | x | 4:76be324c128b d (rewritten using rebase as 13:a1707a5b7c2c)
1256 1256 | |/
1257 1257 | x 3:a82ac2b38757 c (rewritten using rebase as 10:d008e6b4d3fd)
1258 1258 | |
1259 1259 o | 2:630d7c95eff7 x
1260 1260 | |
1261 1261 | x 1:488e1b7e7341 b (rewritten using rebase as 9:67e8f4a16c49)
1262 1262 |/
1263 1263 o 0:b173517d0057 a
1264 1264
1265 1265
1266 1266 issue5782
1267 1267 $ hg strip -r 0:
1268 1268 $ hg debugdrawdag <<EOF
1269 1269 > d
1270 1270 > |
1271 1271 > c1 c # replace: c -> c1
1272 1272 > \ /
1273 1273 > b
1274 1274 > |
1275 1275 > a
1276 1276 > EOF
1277 1277 1 new orphan changesets
1278 1278 $ hg debugobsolete `hg log -T "{node}" --hidden -r 'desc("c1")'`
1279 1279 obsoleted 1 changesets
1280 1280 $ hg log -G -r 'a': --hidden
1281 1281 * 4:76be324c128b d
1282 1282 |
1283 1283 | x 3:ef8a456de8fa c1 (pruned)
1284 1284 | |
1285 1285 x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa)
1286 1286 |/
1287 1287 o 1:488e1b7e7341 b
1288 1288 |
1289 1289 o 0:b173517d0057 a
1290 1290
1291 1291 $ hg rebase -d 0 -r 2
1292 1292 rebasing 2:a82ac2b38757 "c" (c)
1293 1293 $ hg log -G -r 'a': --hidden
1294 1294 o 5:69ad416a4a26 c
1295 1295 |
1296 1296 | * 4:76be324c128b d
1297 1297 | |
1298 1298 | | x 3:ef8a456de8fa c1 (pruned)
1299 1299 | | |
1300 1300 | x | 2:a82ac2b38757 c (rewritten using replace as 3:ef8a456de8fa rewritten using rebase as 5:69ad416a4a26)
1301 1301 | |/
1302 1302 | o 1:488e1b7e7341 b
1303 1303 |/
1304 1304 o 0:b173517d0057 a
1305 1305
1306 1306 $ cd ..
1307 1307
1308 1308 Rebase merge where successor of one parent is equal to destination (issue5198)
1309 1309
1310 1310 $ hg init p1-succ-is-dest
1311 1311 $ cd p1-succ-is-dest
1312 1312
1313 1313 $ hg debugdrawdag <<EOF
1314 1314 > F
1315 1315 > /|
1316 1316 > E D B # replace: D -> B
1317 1317 > \|/
1318 1318 > A
1319 1319 > EOF
1320 1320 1 new orphan changesets
1321 1321
1322 1322 $ hg rebase -d B -s D
1323 1323 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1324 1324 rebasing 4:66f1a38021c9 "F" (F tip)
1325 1325 $ hg log -G
1326 1326 o 5:50e9d60b99c6 F
1327 1327 |\
1328 1328 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:50e9d60b99c6)
1329 1329 | |/|
1330 1330 | o | 3:7fb047a69f22 E
1331 1331 | | |
1332 1332 | | x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1333 1333 | |/
1334 1334 o | 1:112478962961 B
1335 1335 |/
1336 1336 o 0:426bada5c675 A
1337 1337
1338 1338 $ cd ..
1339 1339
1340 1340 Rebase merge where successor of other parent is equal to destination
1341 1341
1342 1342 $ hg init p2-succ-is-dest
1343 1343 $ cd p2-succ-is-dest
1344 1344
1345 1345 $ hg debugdrawdag <<EOF
1346 1346 > F
1347 1347 > /|
1348 1348 > E D B # replace: E -> B
1349 1349 > \|/
1350 1350 > A
1351 1351 > EOF
1352 1352 1 new orphan changesets
1353 1353
1354 1354 $ hg rebase -d B -s E
1355 1355 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1356 1356 rebasing 4:66f1a38021c9 "F" (F tip)
1357 1357 $ hg log -G
1358 1358 o 5:aae1787dacee F
1359 1359 |\
1360 1360 | | x 4:66f1a38021c9 F (rewritten using rebase as 5:aae1787dacee)
1361 1361 | |/|
1362 1362 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1363 1363 | | |
1364 1364 | o | 2:b18e25de2cf5 D
1365 1365 | |/
1366 1366 o / 1:112478962961 B
1367 1367 |/
1368 1368 o 0:426bada5c675 A
1369 1369
1370 1370 $ cd ..
1371 1371
1372 1372 Rebase merge where successor of one parent is ancestor of destination
1373 1373
1374 1374 $ hg init p1-succ-in-dest
1375 1375 $ cd p1-succ-in-dest
1376 1376
1377 1377 $ hg debugdrawdag <<EOF
1378 1378 > F C
1379 1379 > /| |
1380 1380 > E D B # replace: D -> B
1381 1381 > \|/
1382 1382 > A
1383 1383 > EOF
1384 1384 1 new orphan changesets
1385 1385
1386 1386 $ hg rebase -d C -s D
1387 1387 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1388 1388 rebasing 5:66f1a38021c9 "F" (F tip)
1389 1389
1390 1390 $ hg log -G
1391 1391 o 6:0913febf6439 F
1392 1392 |\
1393 1393 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:0913febf6439)
1394 1394 | | |
1395 1395 | o | 4:26805aba1e60 C
1396 1396 | | |
1397 1397 o | | 3:7fb047a69f22 E
1398 1398 | | |
1399 1399 +---x 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1400 1400 | |
1401 1401 | o 1:112478962961 B
1402 1402 |/
1403 1403 o 0:426bada5c675 A
1404 1404
1405 1405 $ cd ..
1406 1406
1407 1407 Rebase merge where successor of other parent is ancestor of destination
1408 1408
1409 1409 $ hg init p2-succ-in-dest
1410 1410 $ cd p2-succ-in-dest
1411 1411
1412 1412 $ hg debugdrawdag <<EOF
1413 1413 > F C
1414 1414 > /| |
1415 1415 > E D B # replace: E -> B
1416 1416 > \|/
1417 1417 > A
1418 1418 > EOF
1419 1419 1 new orphan changesets
1420 1420
1421 1421 $ hg rebase -d C -s E
1422 1422 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1423 1423 rebasing 5:66f1a38021c9 "F" (F tip)
1424 1424 $ hg log -G
1425 1425 o 6:c6ab0cc6d220 F
1426 1426 |\
1427 1427 +---x 5:66f1a38021c9 F (rewritten using rebase as 6:c6ab0cc6d220)
1428 1428 | | |
1429 1429 | o | 4:26805aba1e60 C
1430 1430 | | |
1431 1431 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1432 1432 | | |
1433 1433 o---+ 2:b18e25de2cf5 D
1434 1434 / /
1435 1435 o / 1:112478962961 B
1436 1436 |/
1437 1437 o 0:426bada5c675 A
1438 1438
1439 1439 $ cd ..
1440 1440
1441 1441 Rebase merge where successor of one parent is ancestor of destination
1442 1442
1443 1443 $ hg init p1-succ-in-dest-b
1444 1444 $ cd p1-succ-in-dest-b
1445 1445
1446 1446 $ hg debugdrawdag <<EOF
1447 1447 > F C
1448 1448 > /| |
1449 1449 > E D B # replace: E -> B
1450 1450 > \|/
1451 1451 > A
1452 1452 > EOF
1453 1453 1 new orphan changesets
1454 1454
1455 1455 $ hg rebase -d C -b F
1456 1456 rebasing 2:b18e25de2cf5 "D" (D)
1457 1457 note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
1458 1458 rebasing 5:66f1a38021c9 "F" (F tip)
1459 note: rebase of 5:66f1a38021c9 "F" (F tip) created no changes to commit
1459 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1460 1460 $ hg log -G
1461 1461 o 6:8f47515dda15 D
1462 1462 |
1463 1463 | x 5:66f1a38021c9 F (pruned using rebase)
1464 1464 | |\
1465 1465 o | | 4:26805aba1e60 C
1466 1466 | | |
1467 1467 | | x 3:7fb047a69f22 E (rewritten using replace as 1:112478962961)
1468 1468 | | |
1469 1469 | x | 2:b18e25de2cf5 D (rewritten using rebase as 6:8f47515dda15)
1470 1470 | |/
1471 1471 o / 1:112478962961 B
1472 1472 |/
1473 1473 o 0:426bada5c675 A
1474 1474
1475 1475 $ cd ..
1476 1476
1477 1477 Rebase merge where successor of other parent is ancestor of destination
1478 1478
1479 1479 $ hg init p2-succ-in-dest-b
1480 1480 $ cd p2-succ-in-dest-b
1481 1481
1482 1482 $ hg debugdrawdag <<EOF
1483 1483 > F C
1484 1484 > /| |
1485 1485 > E D B # replace: D -> B
1486 1486 > \|/
1487 1487 > A
1488 1488 > EOF
1489 1489 1 new orphan changesets
1490 1490
1491 1491 $ hg rebase -d C -b F
1492 1492 note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
1493 1493 rebasing 3:7fb047a69f22 "E" (E)
1494 1494 rebasing 5:66f1a38021c9 "F" (F tip)
1495 note: rebase of 5:66f1a38021c9 "F" (F tip) created no changes to commit
1495 note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
1496 1496
1497 1497 $ hg log -G
1498 1498 o 6:533690786a86 E
1499 1499 |
1500 1500 | x 5:66f1a38021c9 F (pruned using rebase)
1501 1501 | |\
1502 1502 o | | 4:26805aba1e60 C
1503 1503 | | |
1504 1504 | | x 3:7fb047a69f22 E (rewritten using rebase as 6:533690786a86)
1505 1505 | | |
1506 1506 | x | 2:b18e25de2cf5 D (rewritten using replace as 1:112478962961)
1507 1507 | |/
1508 1508 o / 1:112478962961 B
1509 1509 |/
1510 1510 o 0:426bada5c675 A
1511 1511
1512 1512 $ cd ..
1513 1513
1514 1514 Rebase merge where extinct node has successor that is not an ancestor of
1515 1515 destination
1516 1516
1517 1517 $ hg init extinct-with-succ-not-in-dest
1518 1518 $ cd extinct-with-succ-not-in-dest
1519 1519
1520 1520 $ hg debugdrawdag <<EOF
1521 1521 > E C # replace: C -> E
1522 1522 > | |
1523 1523 > D B
1524 1524 > |/
1525 1525 > A
1526 1526 > EOF
1527 1527
1528 1528 $ hg rebase -d D -s B
1529 1529 rebasing 1:112478962961 "B" (B)
1530 1530 note: not rebasing 3:26805aba1e60 "C" (C) and its descendants as this would cause divergence
1531 1531
1532 1532 $ cd ..
1533 1533
1534 1534 $ hg init p2-succ-in-dest-c
1535 1535 $ cd p2-succ-in-dest-c
1536 1536
1537 1537 The scenario here was that B::D were developed on default. B was queued on
1538 1538 stable, but amended before being push to hg-committed. C was queued on default,
1539 1539 along with unrelated J.
1540 1540
1541 1541 $ hg debugdrawdag <<EOF
1542 1542 > J
1543 1543 > |
1544 1544 > F
1545 1545 > |
1546 1546 > E
1547 1547 > | D
1548 1548 > | |
1549 1549 > | C # replace: C -> F
1550 1550 > | | H I # replace: B -> H -> I
1551 1551 > | B |/
1552 1552 > |/ G
1553 1553 > A
1554 1554 > EOF
1555 1555 1 new orphan changesets
1556 1556
1557 1557 This strip seems to be the key to avoid an early divergence warning.
1558 1558 $ hg --config extensions.strip= --hidden strip -qr H
1559 1559 1 new orphan changesets
1560 1560
1561 1561 $ hg rebase -b 'desc("D")' -d 'desc("J")'
1562 1562 abort: this rebase will cause divergences from: 112478962961
1563 1563 (to force the rebase please set experimental.evolution.allowdivergence=True)
1564 1564 [255]
1565 1565
1566 1566 Rebase merge where both parents have successors in destination
1567 1567
1568 1568 $ hg init p12-succ-in-dest
1569 1569 $ cd p12-succ-in-dest
1570 1570 $ hg debugdrawdag <<'EOS'
1571 1571 > E F
1572 1572 > /| /| # replace: A -> C
1573 1573 > A B C D # replace: B -> D
1574 1574 > | |
1575 1575 > X Y
1576 1576 > EOS
1577 1577 1 new orphan changesets
1578 1578 $ hg rebase -r A+B+E -d F
1579 1579 note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" (C)
1580 1580 note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" (D)
1581 1581 rebasing 7:dac5d11c5a7d "E" (E tip)
1582 1582 abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
1583 1583 [255]
1584 1584 $ cd ..
1585 1585
1586 1586 Rebase a non-clean merge. One parent has successor in destination, the other
1587 1587 parent moves as requested.
1588 1588
1589 1589 $ hg init p1-succ-p2-move
1590 1590 $ cd p1-succ-p2-move
1591 1591 $ hg debugdrawdag <<'EOS'
1592 1592 > D Z
1593 1593 > /| | # replace: A -> C
1594 1594 > A B C # D/D = D
1595 1595 > EOS
1596 1596 1 new orphan changesets
1597 1597 $ hg rebase -r A+B+D -d Z
1598 1598 note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" (C)
1599 1599 rebasing 1:fc2b737bb2e5 "B" (B)
1600 1600 rebasing 3:b8ed089c80ad "D" (D)
1601 1601
1602 1602 $ rm .hg/localtags
1603 1603 $ hg log -G
1604 1604 o 6:e4f78693cc88 D
1605 1605 |
1606 1606 o 5:76840d832e98 B
1607 1607 |
1608 1608 o 4:50e41c1f3950 Z
1609 1609 |
1610 1610 o 2:96cc3511f894 C
1611 1611
1612 1612 $ hg files -r tip
1613 1613 B
1614 1614 C
1615 1615 D
1616 1616 Z
1617 1617
1618 1618 $ cd ..
1619 1619
1620 1620 $ hg init p1-move-p2-succ
1621 1621 $ cd p1-move-p2-succ
1622 1622 $ hg debugdrawdag <<'EOS'
1623 1623 > D Z
1624 1624 > /| | # replace: B -> C
1625 1625 > A B C # D/D = D
1626 1626 > EOS
1627 1627 1 new orphan changesets
1628 1628 $ hg rebase -r B+A+D -d Z
1629 1629 rebasing 0:426bada5c675 "A" (A)
1630 1630 note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" (C)
1631 1631 rebasing 3:b8ed089c80ad "D" (D)
1632 1632
1633 1633 $ rm .hg/localtags
1634 1634 $ hg log -G
1635 1635 o 6:1b355ed94d82 D
1636 1636 |
1637 1637 o 5:a81a74d764a6 A
1638 1638 |
1639 1639 o 4:50e41c1f3950 Z
1640 1640 |
1641 1641 o 2:96cc3511f894 C
1642 1642
1643 1643 $ hg files -r tip
1644 1644 A
1645 1645 C
1646 1646 D
1647 1647 Z
1648 1648
1649 1649 $ cd ..
1650 1650
1651 1651 Test that bookmark is moved and working dir is updated when all changesets have
1652 1652 equivalents in destination
1653 1653 $ hg init rbsrepo && cd rbsrepo
1654 1654 $ echo "[experimental]" > .hg/hgrc
1655 1655 $ echo "evolution=true" >> .hg/hgrc
1656 1656 $ echo "rebaseskipobsolete=on" >> .hg/hgrc
1657 1657 $ echo root > root && hg ci -Am root
1658 1658 adding root
1659 1659 $ echo a > a && hg ci -Am a
1660 1660 adding a
1661 1661 $ hg up 0
1662 1662 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1663 1663 $ echo b > b && hg ci -Am b
1664 1664 adding b
1665 1665 created new head
1666 1666 $ hg rebase -r 2 -d 1
1667 1667 rebasing 2:1e9a3c00cbe9 "b" (tip)
1668 1668 $ hg log -r . # working dir is at rev 3 (successor of 2)
1669 1669 3:be1832deae9a b (no-eol)
1670 1670 $ hg book -r 2 mybook --hidden # rev 2 has a bookmark on it now
1671 1671 bookmarking hidden changeset 1e9a3c00cbe9
1672 1672 (hidden revision '1e9a3c00cbe9' was rewritten as: be1832deae9a)
1673 1673 $ hg up 2 && hg log -r . # working dir is at rev 2 again
1674 1674 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1675 1675 2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
1676 1676 $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
1677 1677 note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b" (tip)
1678 1678 Check that working directory and bookmark was updated to rev 3 although rev 2
1679 1679 was skipped
1680 1680 $ hg log -r .
1681 1681 3:be1832deae9a b (no-eol)
1682 1682 $ hg bookmarks
1683 1683 mybook 3:be1832deae9a
1684 1684 $ hg debugobsolete --rev tip
1685 1685 1e9a3c00cbe90d236ac05ef61efcc5e40b7412bc be1832deae9ac531caa7438b8dcf6055a122cd8e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
1686 1686
1687 1687 Obsoleted working parent and bookmark could be moved if an ancestor of working
1688 1688 parent gets moved:
1689 1689
1690 1690 $ hg init $TESTTMP/ancestor-wd-move
1691 1691 $ cd $TESTTMP/ancestor-wd-move
1692 1692 $ hg debugdrawdag <<'EOS'
1693 1693 > E D1 # rebase: D1 -> D2
1694 1694 > | |
1695 1695 > | C
1696 1696 > D2 |
1697 1697 > | B
1698 1698 > |/
1699 1699 > A
1700 1700 > EOS
1701 1701 $ hg update D1 -q
1702 1702 $ hg bookmark book -i
1703 1703 $ hg rebase -r B+D1 -d E
1704 1704 rebasing 1:112478962961 "B" (B)
1705 1705 note: not rebasing 5:15ecf15e0114 "D1" (book D1 tip), already in destination as 2:0807738e0be9 "D2" (D2)
1706 1706 1 new orphan changesets
1707 1707 $ hg log -G -T '{desc} {bookmarks}'
1708 1708 @ B book
1709 1709 |
1710 1710 | x D1
1711 1711 | |
1712 1712 o | E
1713 1713 | |
1714 1714 | * C
1715 1715 | |
1716 1716 o | D2
1717 1717 | |
1718 1718 | x B
1719 1719 |/
1720 1720 o A
1721 1721
1722 1722 Rebasing a merge with one of its parent having a hidden successor
1723 1723
1724 1724 $ hg init $TESTTMP/merge-p1-hidden-successor
1725 1725 $ cd $TESTTMP/merge-p1-hidden-successor
1726 1726
1727 1727 $ hg debugdrawdag <<'EOS'
1728 1728 > E
1729 1729 > |
1730 1730 > B3 B2 # amend: B1 -> B2 -> B3
1731 1731 > |/ # B2 is hidden
1732 1732 > | D
1733 1733 > | |\
1734 1734 > | B1 C
1735 1735 > |/
1736 1736 > A
1737 1737 > EOS
1738 1738 1 new orphan changesets
1739 1739
1740 1740 $ eval `hg tags -T '{tag}={node}\n'`
1741 1741 $ rm .hg/localtags
1742 1742
1743 1743 $ hg rebase -r $D -d $E
1744 1744 rebasing 5:9e62094e4d94 "D"
1745 1745
1746 1746 $ hg log -G
1747 1747 o 7:a699d059adcf D
1748 1748 |\
1749 1749 | o 6:ecc93090a95c E
1750 1750 | |
1751 1751 | o 4:0dc878468a23 B3
1752 1752 | |
1753 1753 o | 1:96cc3511f894 C
1754 1754 /
1755 1755 o 0:426bada5c675 A
1756 1756
1757 1757 For some reasons (--hidden, rebaseskipobsolete=0, directaccess, etc.),
1758 1758 rebasestate may contain hidden hashes. "rebase --abort" should work regardless.
1759 1759
1760 1760 $ hg init $TESTTMP/hidden-state1
1761 1761 $ cd $TESTTMP/hidden-state1
1762 1762 $ cat >> .hg/hgrc <<EOF
1763 1763 > [experimental]
1764 1764 > rebaseskipobsolete=0
1765 1765 > EOF
1766 1766
1767 1767 $ hg debugdrawdag <<'EOS'
1768 1768 > C
1769 1769 > |
1770 1770 > D B # prune: B, C
1771 1771 > |/ # B/D=B
1772 1772 > A
1773 1773 > EOS
1774 1774
1775 1775 $ eval `hg tags -T '{tag}={node}\n'`
1776 1776 $ rm .hg/localtags
1777 1777
1778 1778 $ hg update -q $C --hidden
1779 1779 updated to hidden changeset 7829726be4dc
1780 1780 (hidden revision '7829726be4dc' is pruned)
1781 1781 $ hg rebase -s $B -d $D
1782 1782 rebasing 1:2ec65233581b "B"
1783 1783 merging D
1784 1784 warning: conflicts while merging D! (edit, then use 'hg resolve --mark')
1785 1785 unresolved conflicts (see hg resolve, then hg rebase --continue)
1786 1786 [1]
1787 1787
1788 1788 $ cp -R . $TESTTMP/hidden-state2
1789 1789
1790 1790 $ hg log -G
1791 1791 @ 2:b18e25de2cf5 D
1792 1792 |
1793 1793 | @ 1:2ec65233581b B (pruned using prune)
1794 1794 |/
1795 1795 o 0:426bada5c675 A
1796 1796
1797 1797 $ hg summary
1798 1798 parent: 2:b18e25de2cf5 tip
1799 1799 D
1800 1800 parent: 1:2ec65233581b (obsolete)
1801 1801 B
1802 1802 branch: default
1803 1803 commit: 2 modified, 1 unknown, 1 unresolved (merge)
1804 1804 update: (current)
1805 1805 phases: 3 draft
1806 1806 rebase: 0 rebased, 2 remaining (rebase --continue)
1807 1807
1808 1808 $ hg rebase --abort
1809 1809 rebase aborted
1810 1810
1811 1811 Also test --continue for the above case
1812 1812
1813 1813 $ cd $TESTTMP/hidden-state2
1814 1814 $ hg resolve -m
1815 1815 (no more unresolved files)
1816 1816 continue: hg rebase --continue
1817 1817 $ hg rebase --continue
1818 1818 rebasing 1:2ec65233581b "B"
1819 1819 rebasing 3:7829726be4dc "C" (tip)
1820 1820 $ hg log -G
1821 1821 @ 5:1964d5d5b547 C
1822 1822 |
1823 1823 o 4:68deb90c12a2 B
1824 1824 |
1825 1825 o 2:b18e25de2cf5 D
1826 1826 |
1827 1827 o 0:426bada5c675 A
1828 1828
1829 1829 ====================
1830 1830 Test --stop option |
1831 1831 ====================
1832 1832 $ cd ..
1833 1833 $ hg init rbstop
1834 1834 $ cd rbstop
1835 1835 $ echo a>a
1836 1836 $ hg ci -Aqma
1837 1837 $ echo b>b
1838 1838 $ hg ci -Aqmb
1839 1839 $ echo c>c
1840 1840 $ hg ci -Aqmc
1841 1841 $ echo d>d
1842 1842 $ hg ci -Aqmd
1843 1843 $ hg up 0 -q
1844 1844 $ echo f>f
1845 1845 $ hg ci -Aqmf
1846 1846 $ echo D>d
1847 1847 $ hg ci -Aqm "conflict with d"
1848 1848 $ hg up 3 -q
1849 1849 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1850 1850 o 5:00bfc9898aeb test
1851 1851 | conflict with d
1852 1852 |
1853 1853 o 4:dafd40200f93 test
1854 1854 | f
1855 1855 |
1856 1856 | @ 3:055a42cdd887 test
1857 1857 | | d
1858 1858 | |
1859 1859 | o 2:177f92b77385 test
1860 1860 | | c
1861 1861 | |
1862 1862 | o 1:d2ae7f538514 test
1863 1863 |/ b
1864 1864 |
1865 1865 o 0:cb9a9f314b8b test
1866 1866 a
1867 1867
1868 1868 $ hg rebase -s 1 -d 5
1869 1869 rebasing 1:d2ae7f538514 "b"
1870 1870 rebasing 2:177f92b77385 "c"
1871 1871 rebasing 3:055a42cdd887 "d"
1872 1872 merging d
1873 1873 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1874 1874 unresolved conflicts (see hg resolve, then hg rebase --continue)
1875 1875 [1]
1876 1876 $ hg rebase --stop
1877 1877 1 new orphan changesets
1878 1878 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1879 1879 o 7:7fffad344617 test
1880 1880 | c
1881 1881 |
1882 1882 o 6:b15528633407 test
1883 1883 | b
1884 1884 |
1885 1885 o 5:00bfc9898aeb test
1886 1886 | conflict with d
1887 1887 |
1888 1888 o 4:dafd40200f93 test
1889 1889 | f
1890 1890 |
1891 1891 | @ 3:055a42cdd887 test
1892 1892 | | d
1893 1893 | |
1894 1894 | x 2:177f92b77385 test
1895 1895 | | c
1896 1896 | |
1897 1897 | x 1:d2ae7f538514 test
1898 1898 |/ b
1899 1899 |
1900 1900 o 0:cb9a9f314b8b test
1901 1901 a
1902 1902
1903 1903 Test it aborts if unstable csets is not allowed:
1904 1904 ===============================================
1905 1905 $ cat >> $HGRCPATH << EOF
1906 1906 > [experimental]
1907 1907 > evolution.allowunstable=False
1908 1908 > EOF
1909 1909
1910 1910 $ hg strip 6 --no-backup -q
1911 1911 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1912 1912 o 5:00bfc9898aeb test
1913 1913 | conflict with d
1914 1914 |
1915 1915 o 4:dafd40200f93 test
1916 1916 | f
1917 1917 |
1918 1918 | @ 3:055a42cdd887 test
1919 1919 | | d
1920 1920 | |
1921 1921 | o 2:177f92b77385 test
1922 1922 | | c
1923 1923 | |
1924 1924 | o 1:d2ae7f538514 test
1925 1925 |/ b
1926 1926 |
1927 1927 o 0:cb9a9f314b8b test
1928 1928 a
1929 1929
1930 1930 $ hg rebase -s 1 -d 5
1931 1931 rebasing 1:d2ae7f538514 "b"
1932 1932 rebasing 2:177f92b77385 "c"
1933 1933 rebasing 3:055a42cdd887 "d"
1934 1934 merging d
1935 1935 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1936 1936 unresolved conflicts (see hg resolve, then hg rebase --continue)
1937 1937 [1]
1938 1938 $ hg rebase --stop
1939 1939 abort: cannot remove original changesets with unrebased descendants
1940 1940 (either enable obsmarkers to allow unstable revisions or use --keep to keep original changesets)
1941 1941 [255]
1942 1942 $ hg rebase --abort
1943 1943 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1944 1944 rebase aborted
1945 1945
1946 1946 Test --stop when --keep is passed:
1947 1947 ==================================
1948 1948 $ hg rebase -s 1 -d 5 --keep
1949 1949 rebasing 1:d2ae7f538514 "b"
1950 1950 rebasing 2:177f92b77385 "c"
1951 1951 rebasing 3:055a42cdd887 "d"
1952 1952 merging d
1953 1953 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1954 1954 unresolved conflicts (see hg resolve, then hg rebase --continue)
1955 1955 [1]
1956 1956 $ hg rebase --stop
1957 1957 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1958 1958 o 7:7fffad344617 test
1959 1959 | c
1960 1960 |
1961 1961 o 6:b15528633407 test
1962 1962 | b
1963 1963 |
1964 1964 o 5:00bfc9898aeb test
1965 1965 | conflict with d
1966 1966 |
1967 1967 o 4:dafd40200f93 test
1968 1968 | f
1969 1969 |
1970 1970 | @ 3:055a42cdd887 test
1971 1971 | | d
1972 1972 | |
1973 1973 | o 2:177f92b77385 test
1974 1974 | | c
1975 1975 | |
1976 1976 | o 1:d2ae7f538514 test
1977 1977 |/ b
1978 1978 |
1979 1979 o 0:cb9a9f314b8b test
1980 1980 a
1981 1981
1982 1982 Test --stop aborts when --collapse was passed:
1983 1983 =============================================
1984 1984 $ cat >> $HGRCPATH << EOF
1985 1985 > [experimental]
1986 1986 > evolution.allowunstable=True
1987 1987 > EOF
1988 1988
1989 1989 $ hg strip 6
1990 1990 saved backup bundle to $TESTTMP/rbstop/.hg/strip-backup/b15528633407-6eb72b6f-backup.hg
1991 1991 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
1992 1992 o 5:00bfc9898aeb test
1993 1993 | conflict with d
1994 1994 |
1995 1995 o 4:dafd40200f93 test
1996 1996 | f
1997 1997 |
1998 1998 | @ 3:055a42cdd887 test
1999 1999 | | d
2000 2000 | |
2001 2001 | o 2:177f92b77385 test
2002 2002 | | c
2003 2003 | |
2004 2004 | o 1:d2ae7f538514 test
2005 2005 |/ b
2006 2006 |
2007 2007 o 0:cb9a9f314b8b test
2008 2008 a
2009 2009
2010 2010 $ hg rebase -s 1 -d 5 --collapse -m "collapsed b c d"
2011 2011 rebasing 1:d2ae7f538514 "b"
2012 2012 rebasing 2:177f92b77385 "c"
2013 2013 rebasing 3:055a42cdd887 "d"
2014 2014 merging d
2015 2015 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2016 2016 unresolved conflicts (see hg resolve, then hg rebase --continue)
2017 2017 [1]
2018 2018 $ hg rebase --stop
2019 2019 abort: cannot stop in --collapse session
2020 2020 [255]
2021 2021 $ hg rebase --abort
2022 2022 rebase aborted
2023 2023 $ hg diff
2024 2024 $ hg log -G --template "{rev}:{short(node)} {person(author)}\n{firstline(desc)} {topic}\n\n"
2025 2025 o 5:00bfc9898aeb test
2026 2026 | conflict with d
2027 2027 |
2028 2028 o 4:dafd40200f93 test
2029 2029 | f
2030 2030 |
2031 2031 | @ 3:055a42cdd887 test
2032 2032 | | d
2033 2033 | |
2034 2034 | o 2:177f92b77385 test
2035 2035 | | c
2036 2036 | |
2037 2037 | o 1:d2ae7f538514 test
2038 2038 |/ b
2039 2039 |
2040 2040 o 0:cb9a9f314b8b test
2041 2041 a
2042 2042
2043 2043 Test --stop raise errors with conflicting options:
2044 2044 =================================================
2045 2045 $ hg rebase -s 3 -d 5
2046 2046 rebasing 3:055a42cdd887 "d"
2047 2047 merging d
2048 2048 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2049 2049 unresolved conflicts (see hg resolve, then hg rebase --continue)
2050 2050 [1]
2051 2051 $ hg rebase --stop --dry-run
2052 2052 abort: cannot specify both --dry-run and --stop
2053 2053 [255]
2054 2054
2055 2055 $ hg rebase -s 3 -d 5
2056 2056 abort: rebase in progress
2057 2057 (use 'hg rebase --continue' or 'hg rebase --abort')
2058 2058 [255]
2059 2059 $ hg rebase --stop --continue
2060 2060 abort: cannot use --stop with --continue
2061 2061 [255]
2062 2062
2063 2063 Test --stop moves bookmarks of original revisions to new rebased nodes:
2064 2064 ======================================================================
2065 2065 $ cd ..
2066 2066 $ hg init repo
2067 2067 $ cd repo
2068 2068
2069 2069 $ echo a > a
2070 2070 $ hg ci -Am A
2071 2071 adding a
2072 2072
2073 2073 $ echo b > b
2074 2074 $ hg ci -Am B
2075 2075 adding b
2076 2076 $ hg book X
2077 2077 $ hg book Y
2078 2078
2079 2079 $ echo c > c
2080 2080 $ hg ci -Am C
2081 2081 adding c
2082 2082 $ hg book Z
2083 2083
2084 2084 $ echo d > d
2085 2085 $ hg ci -Am D
2086 2086 adding d
2087 2087
2088 2088 $ hg up 0 -q
2089 2089 $ echo e > e
2090 2090 $ hg ci -Am E
2091 2091 adding e
2092 2092 created new head
2093 2093
2094 2094 $ echo doubt > d
2095 2095 $ hg ci -Am "conflict with d"
2096 2096 adding d
2097 2097
2098 2098 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2099 2099 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2100 2100 |
2101 2101 o 4: 9c1e55f411b6 'E' bookmarks:
2102 2102 |
2103 2103 | o 3: 67a385d4e6f2 'D' bookmarks: Z
2104 2104 | |
2105 2105 | o 2: 49cb3485fa0c 'C' bookmarks: Y
2106 2106 | |
2107 2107 | o 1: 6c81ed0049f8 'B' bookmarks: X
2108 2108 |/
2109 2109 o 0: 1994f17a630e 'A' bookmarks:
2110 2110
2111 2111 $ hg rebase -s 1 -d 5
2112 2112 rebasing 1:6c81ed0049f8 "B" (X)
2113 2113 rebasing 2:49cb3485fa0c "C" (Y)
2114 2114 rebasing 3:67a385d4e6f2 "D" (Z)
2115 2115 merging d
2116 2116 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
2117 2117 unresolved conflicts (see hg resolve, then hg rebase --continue)
2118 2118 [1]
2119 2119 $ hg rebase --stop
2120 2120 1 new orphan changesets
2121 2121 $ hg log -GT "{rev}: {node|short} '{desc}' bookmarks: {bookmarks}\n"
2122 2122 o 7: 9c86c650b686 'C' bookmarks: Y
2123 2123 |
2124 2124 o 6: 9b87b54e5fd8 'B' bookmarks: X
2125 2125 |
2126 2126 @ 5: 39adf30bc1be 'conflict with d' bookmarks:
2127 2127 |
2128 2128 o 4: 9c1e55f411b6 'E' bookmarks:
2129 2129 |
2130 2130 | * 3: 67a385d4e6f2 'D' bookmarks: Z
2131 2131 | |
2132 2132 | x 2: 49cb3485fa0c 'C' bookmarks:
2133 2133 | |
2134 2134 | x 1: 6c81ed0049f8 'B' bookmarks:
2135 2135 |/
2136 2136 o 0: 1994f17a630e 'A' bookmarks:
2137 2137
@@ -1,521 +1,521 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 >
5 5 > [phases]
6 6 > publish=False
7 7 >
8 8 > [alias]
9 9 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
10 10 > EOF
11 11
12 12
13 13 $ hg init a
14 14 $ cd a
15 15 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 16 adding changesets
17 17 adding manifests
18 18 adding file changes
19 19 added 8 changesets with 7 changes to 7 files (+2 heads)
20 20 new changesets cd010b8cd998:02de42196ebe (8 drafts)
21 21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 22 $ hg up tip
23 23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 24
25 25 $ echo I > I
26 26 $ hg ci -AmI
27 27 adding I
28 28
29 29 $ hg tglog
30 30 @ 8: e7ec4e813ba6 'I'
31 31 |
32 32 o 7: 02de42196ebe 'H'
33 33 |
34 34 | o 6: eea13746799a 'G'
35 35 |/|
36 36 o | 5: 24b6387c8c8c 'F'
37 37 | |
38 38 | o 4: 9520eea781bc 'E'
39 39 |/
40 40 | o 3: 32af7686d403 'D'
41 41 | |
42 42 | o 2: 5fddd98957c8 'C'
43 43 | |
44 44 | o 1: 42ccdea3bb16 'B'
45 45 |/
46 46 o 0: cd010b8cd998 'A'
47 47
48 48 $ cd ..
49 49
50 50 Version with only two heads (to allow default destination to work)
51 51
52 52 $ hg clone -q -u . a a2heads -r 3 -r 8
53 53
54 54 These fail:
55 55
56 56 $ hg clone -q -u . a a0
57 57 $ cd a0
58 58
59 59 $ hg rebase -s 8 -d 7
60 60 nothing to rebase
61 61 [1]
62 62
63 63 $ hg rebase --continue --abort
64 64 abort: cannot use --abort with --continue
65 65 [255]
66 66
67 67 $ hg rebase --continue --collapse
68 68 abort: cannot use collapse with continue or abort
69 69 [255]
70 70
71 71 $ hg rebase --continue --dest 4
72 72 abort: abort and continue do not allow specifying revisions
73 73 [255]
74 74
75 75 $ hg rebase --base 5 --source 4
76 76 abort: cannot specify both a source and a base
77 77 [255]
78 78
79 79 $ hg rebase --rev 5 --source 4
80 80 abort: cannot specify both a revision and a source
81 81 [255]
82 82 $ hg rebase --base 5 --rev 4
83 83 abort: cannot specify both a revision and a base
84 84 [255]
85 85
86 86 $ hg rebase --base 6
87 87 abort: branch 'default' has 3 heads - please rebase to an explicit rev
88 88 (run 'hg heads .' to see heads)
89 89 [255]
90 90
91 91 $ hg rebase --rev '1 & !1' --dest 8
92 92 empty "rev" revision set - nothing to rebase
93 93 [1]
94 94
95 95 $ hg rebase --source '1 & !1' --dest 8
96 96 empty "source" revision set - nothing to rebase
97 97 [1]
98 98
99 99 $ hg rebase --base '1 & !1' --dest 8
100 100 empty "base" revision set - can't compute rebase set
101 101 [1]
102 102
103 103 $ hg rebase --dest 8
104 104 nothing to rebase - working directory parent is also destination
105 105 [1]
106 106
107 107 $ hg rebase -b . --dest 8
108 108 nothing to rebase - e7ec4e813ba6 is both "base" and destination
109 109 [1]
110 110
111 111 $ hg up -q 7
112 112
113 113 $ hg rebase --dest 8 --traceback
114 114 nothing to rebase - working directory parent is already an ancestor of destination e7ec4e813ba6
115 115 [1]
116 116
117 117 $ hg rebase --dest 8 -b.
118 118 nothing to rebase - "base" 02de42196ebe is already an ancestor of destination e7ec4e813ba6
119 119 [1]
120 120
121 121 $ hg rebase --dest '1 & !1'
122 122 abort: empty revision set
123 123 [255]
124 124
125 125 These work:
126 126
127 127 Rebase with no arguments (from 3 onto 8):
128 128
129 129 $ cd ..
130 130 $ hg clone -q -u . a2heads a1
131 131 $ cd a1
132 132 $ hg up -q -C 3
133 133
134 134 $ hg rebase
135 135 rebasing 1:42ccdea3bb16 "B"
136 136 rebasing 2:5fddd98957c8 "C"
137 137 rebasing 3:32af7686d403 "D"
138 138 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
139 139
140 140 $ hg tglog
141 141 @ 6: ed65089c18f8 'D'
142 142 |
143 143 o 5: 7621bf1a2f17 'C'
144 144 |
145 145 o 4: 9430a62369c6 'B'
146 146 |
147 147 o 3: e7ec4e813ba6 'I'
148 148 |
149 149 o 2: 02de42196ebe 'H'
150 150 |
151 151 o 1: 24b6387c8c8c 'F'
152 152 |
153 153 o 0: cd010b8cd998 'A'
154 154
155 155 Try to rollback after a rebase (fail):
156 156
157 157 $ hg rollback
158 158 no rollback information available
159 159 [1]
160 160
161 161 $ cd ..
162 162
163 163 Rebase with base == '.' => same as no arguments (from 3 onto 8):
164 164
165 165 $ hg clone -q -u 3 a2heads a2
166 166 $ cd a2
167 167
168 168 $ hg rebase --base .
169 169 rebasing 1:42ccdea3bb16 "B"
170 170 rebasing 2:5fddd98957c8 "C"
171 171 rebasing 3:32af7686d403 "D"
172 172 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
173 173
174 174 $ hg tglog
175 175 @ 6: ed65089c18f8 'D'
176 176 |
177 177 o 5: 7621bf1a2f17 'C'
178 178 |
179 179 o 4: 9430a62369c6 'B'
180 180 |
181 181 o 3: e7ec4e813ba6 'I'
182 182 |
183 183 o 2: 02de42196ebe 'H'
184 184 |
185 185 o 1: 24b6387c8c8c 'F'
186 186 |
187 187 o 0: cd010b8cd998 'A'
188 188
189 189 $ cd ..
190 190
191 191
192 192 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
193 193
194 194 $ hg clone -q -u 3 a a3
195 195 $ cd a3
196 196
197 197 $ hg rebase --dest 'branch(.)'
198 198 rebasing 1:42ccdea3bb16 "B"
199 199 rebasing 2:5fddd98957c8 "C"
200 200 rebasing 3:32af7686d403 "D"
201 201 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
202 202
203 203 $ hg tglog
204 204 @ 8: ed65089c18f8 'D'
205 205 |
206 206 o 7: 7621bf1a2f17 'C'
207 207 |
208 208 o 6: 9430a62369c6 'B'
209 209 |
210 210 o 5: e7ec4e813ba6 'I'
211 211 |
212 212 o 4: 02de42196ebe 'H'
213 213 |
214 214 | o 3: eea13746799a 'G'
215 215 |/|
216 216 o | 2: 24b6387c8c8c 'F'
217 217 | |
218 218 | o 1: 9520eea781bc 'E'
219 219 |/
220 220 o 0: cd010b8cd998 'A'
221 221
222 222 $ cd ..
223 223
224 224
225 225 Specify only source (from 2 onto 8):
226 226
227 227 $ hg clone -q -u . a2heads a4
228 228 $ cd a4
229 229
230 230 $ hg rebase --source 'desc("C")'
231 231 rebasing 2:5fddd98957c8 "C"
232 232 rebasing 3:32af7686d403 "D"
233 233 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
234 234
235 235 $ hg tglog
236 236 o 6: 7726e9fd58f7 'D'
237 237 |
238 238 o 5: 72c8333623d0 'C'
239 239 |
240 240 @ 4: e7ec4e813ba6 'I'
241 241 |
242 242 o 3: 02de42196ebe 'H'
243 243 |
244 244 o 2: 24b6387c8c8c 'F'
245 245 |
246 246 | o 1: 42ccdea3bb16 'B'
247 247 |/
248 248 o 0: cd010b8cd998 'A'
249 249
250 250 $ cd ..
251 251
252 252
253 253 Specify only dest (from 3 onto 6):
254 254
255 255 $ hg clone -q -u 3 a a5
256 256 $ cd a5
257 257
258 258 $ hg rebase --dest 6
259 259 rebasing 1:42ccdea3bb16 "B"
260 260 rebasing 2:5fddd98957c8 "C"
261 261 rebasing 3:32af7686d403 "D"
262 262 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
263 263
264 264 $ hg tglog
265 265 @ 8: 8eeb3c33ad33 'D'
266 266 |
267 267 o 7: 2327fea05063 'C'
268 268 |
269 269 o 6: e4e5be0395b2 'B'
270 270 |
271 271 | o 5: e7ec4e813ba6 'I'
272 272 | |
273 273 | o 4: 02de42196ebe 'H'
274 274 | |
275 275 o | 3: eea13746799a 'G'
276 276 |\|
277 277 | o 2: 24b6387c8c8c 'F'
278 278 | |
279 279 o | 1: 9520eea781bc 'E'
280 280 |/
281 281 o 0: cd010b8cd998 'A'
282 282
283 283 $ cd ..
284 284
285 285
286 286 Specify only base (from 1 onto 8):
287 287
288 288 $ hg clone -q -u . a2heads a6
289 289 $ cd a6
290 290
291 291 $ hg rebase --base 'desc("D")'
292 292 rebasing 1:42ccdea3bb16 "B"
293 293 rebasing 2:5fddd98957c8 "C"
294 294 rebasing 3:32af7686d403 "D"
295 295 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
296 296
297 297 $ hg tglog
298 298 o 6: ed65089c18f8 'D'
299 299 |
300 300 o 5: 7621bf1a2f17 'C'
301 301 |
302 302 o 4: 9430a62369c6 'B'
303 303 |
304 304 @ 3: e7ec4e813ba6 'I'
305 305 |
306 306 o 2: 02de42196ebe 'H'
307 307 |
308 308 o 1: 24b6387c8c8c 'F'
309 309 |
310 310 o 0: cd010b8cd998 'A'
311 311
312 312 $ cd ..
313 313
314 314
315 315 Specify source and dest (from 2 onto 7):
316 316
317 317 $ hg clone -q -u . a a7
318 318 $ cd a7
319 319
320 320 $ hg rebase --source 2 --dest 7
321 321 rebasing 2:5fddd98957c8 "C"
322 322 rebasing 3:32af7686d403 "D"
323 323 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
324 324
325 325 $ hg tglog
326 326 o 8: 668acadedd30 'D'
327 327 |
328 328 o 7: 09eb682ba906 'C'
329 329 |
330 330 | @ 6: e7ec4e813ba6 'I'
331 331 |/
332 332 o 5: 02de42196ebe 'H'
333 333 |
334 334 | o 4: eea13746799a 'G'
335 335 |/|
336 336 o | 3: 24b6387c8c8c 'F'
337 337 | |
338 338 | o 2: 9520eea781bc 'E'
339 339 |/
340 340 | o 1: 42ccdea3bb16 'B'
341 341 |/
342 342 o 0: cd010b8cd998 'A'
343 343
344 344 $ cd ..
345 345
346 346
347 347 Specify base and dest (from 1 onto 7):
348 348
349 349 $ hg clone -q -u . a a8
350 350 $ cd a8
351 351
352 352 $ hg rebase --base 3 --dest 7
353 353 rebasing 1:42ccdea3bb16 "B"
354 354 rebasing 2:5fddd98957c8 "C"
355 355 rebasing 3:32af7686d403 "D"
356 356 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/42ccdea3bb16-3cb021d3-rebase.hg
357 357
358 358 $ hg tglog
359 359 o 8: 287cc92ba5a4 'D'
360 360 |
361 361 o 7: 6824f610a250 'C'
362 362 |
363 363 o 6: 7c6027df6a99 'B'
364 364 |
365 365 | @ 5: e7ec4e813ba6 'I'
366 366 |/
367 367 o 4: 02de42196ebe 'H'
368 368 |
369 369 | o 3: eea13746799a 'G'
370 370 |/|
371 371 o | 2: 24b6387c8c8c 'F'
372 372 | |
373 373 | o 1: 9520eea781bc 'E'
374 374 |/
375 375 o 0: cd010b8cd998 'A'
376 376
377 377 $ cd ..
378 378
379 379
380 380 Specify only revs (from 2 onto 8)
381 381
382 382 $ hg clone -q -u . a2heads a9
383 383 $ cd a9
384 384
385 385 $ hg rebase --rev 'desc("C")::'
386 386 rebasing 2:5fddd98957c8 "C"
387 387 rebasing 3:32af7686d403 "D"
388 388 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
389 389
390 390 $ hg tglog
391 391 o 6: 7726e9fd58f7 'D'
392 392 |
393 393 o 5: 72c8333623d0 'C'
394 394 |
395 395 @ 4: e7ec4e813ba6 'I'
396 396 |
397 397 o 3: 02de42196ebe 'H'
398 398 |
399 399 o 2: 24b6387c8c8c 'F'
400 400 |
401 401 | o 1: 42ccdea3bb16 'B'
402 402 |/
403 403 o 0: cd010b8cd998 'A'
404 404
405 405 $ cd ..
406 406
407 407 Rebasing both a single revision and a merge in one command
408 408
409 409 $ hg clone -q -u . a aX
410 410 $ cd aX
411 411 $ hg rebase -r 3 -r 6 --dest 8
412 412 rebasing 3:32af7686d403 "D"
413 413 rebasing 6:eea13746799a "G"
414 414 saved backup bundle to $TESTTMP/aX/.hg/strip-backup/eea13746799a-ad273fd6-rebase.hg
415 415 $ cd ..
416 416
417 417 Test --tool parameter:
418 418
419 419 $ hg init b
420 420 $ cd b
421 421
422 422 $ echo c1 > c1
423 423 $ hg ci -Am c1
424 424 adding c1
425 425
426 426 $ echo c2 > c2
427 427 $ hg ci -Am c2
428 428 adding c2
429 429
430 430 $ hg up -q 0
431 431 $ echo c2b > c2
432 432 $ hg ci -Am c2b
433 433 adding c2
434 434 created new head
435 435
436 436 $ cd ..
437 437
438 438 $ hg clone -q -u . b b1
439 439 $ cd b1
440 440
441 441 $ hg rebase -s 2 -d 1 --tool internal:local
442 442 rebasing 2:e4e3f3546619 "c2b" (tip)
443 note: rebase of 2:e4e3f3546619 "c2b" (tip) created no changes to commit
443 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
444 444 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
445 445
446 446 $ hg cat c2
447 447 c2
448 448
449 449 $ cd ..
450 450
451 451
452 452 $ hg clone -q -u . b b2
453 453 $ cd b2
454 454
455 455 $ hg rebase -s 2 -d 1 --tool internal:other
456 456 rebasing 2:e4e3f3546619 "c2b" (tip)
457 457 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
458 458
459 459 $ hg cat c2
460 460 c2b
461 461
462 462 $ cd ..
463 463
464 464
465 465 $ hg clone -q -u . b b3
466 466 $ cd b3
467 467
468 468 $ hg rebase -s 2 -d 1 --tool internal:fail
469 469 rebasing 2:e4e3f3546619 "c2b" (tip)
470 470 unresolved conflicts (see hg resolve, then hg rebase --continue)
471 471 [1]
472 472
473 473 $ hg summary
474 474 parent: 1:56daeba07f4b
475 475 c2
476 476 parent: 2:e4e3f3546619 tip
477 477 c2b
478 478 branch: default
479 479 commit: 1 modified, 1 unresolved (merge)
480 480 update: (current)
481 481 phases: 3 draft
482 482 rebase: 0 rebased, 1 remaining (rebase --continue)
483 483
484 484 $ hg resolve -l
485 485 U c2
486 486
487 487 $ hg resolve -m c2
488 488 (no more unresolved files)
489 489 continue: hg rebase --continue
490 490 $ hg graft --continue
491 491 abort: no graft in progress
492 492 (continue: hg rebase --continue)
493 493 [255]
494 494 $ hg rebase -c --tool internal:fail
495 495 rebasing 2:e4e3f3546619 "c2b" (tip)
496 note: rebase of 2:e4e3f3546619 "c2b" (tip) created no changes to commit
496 note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
497 497 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
498 498
499 499 $ hg rebase -i
500 500 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
501 501 [255]
502 502
503 503 $ hg rebase --interactive
504 504 abort: interactive history editing is supported by the 'histedit' extension (see "hg --config extensions.histedit= help -e histedit")
505 505 [255]
506 506
507 507 $ cd ..
508 508
509 509 No common ancestor
510 510
511 511 $ hg init separaterepo
512 512 $ cd separaterepo
513 513 $ touch a
514 514 $ hg commit -Aqm a
515 515 $ hg up -q null
516 516 $ touch b
517 517 $ hg commit -Aqm b
518 518 $ hg rebase -d 0
519 519 nothing to rebase from d7486e00c6f1 to 3903775176ed
520 520 [1]
521 521 $ cd ..
@@ -1,984 +1,984 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
11 11 > EOF
12 12
13 13
14 14 $ hg init a
15 15 $ cd a
16 16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 17 adding changesets
18 18 adding manifests
19 19 adding file changes
20 20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 21 new changesets cd010b8cd998:02de42196ebe (8 drafts)
22 22 (run 'hg heads' to see heads, 'hg merge' to merge)
23 23 $ hg up tip
24 24 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 25 $ cd ..
26 26
27 27
28 28 Rebasing
29 29 D onto H - simple rebase:
30 30 (this also tests that editor is invoked if '--edit' is specified, and that we
31 31 can abort or warn for colliding untracked files)
32 32
33 33 $ hg clone -q -u . a a1
34 34 $ cd a1
35 35
36 36 $ hg tglog
37 37 @ 7: 02de42196ebe 'H'
38 38 |
39 39 | o 6: eea13746799a 'G'
40 40 |/|
41 41 o | 5: 24b6387c8c8c 'F'
42 42 | |
43 43 | o 4: 9520eea781bc 'E'
44 44 |/
45 45 | o 3: 32af7686d403 'D'
46 46 | |
47 47 | o 2: 5fddd98957c8 'C'
48 48 | |
49 49 | o 1: 42ccdea3bb16 'B'
50 50 |/
51 51 o 0: cd010b8cd998 'A'
52 52
53 53
54 54 $ hg status --rev "3^1" --rev 3
55 55 A D
56 56 $ echo collide > D
57 57 $ HGEDITOR=cat hg rebase -s 3 -d 7 --edit --config merge.checkunknown=warn
58 58 rebasing 3:32af7686d403 "D"
59 59 D: replacing untracked file
60 60 D
61 61
62 62
63 63 HG: Enter commit message. Lines beginning with 'HG:' are removed.
64 64 HG: Leave message empty to abort commit.
65 65 HG: --
66 66 HG: user: Nicolas Dumazet <nicdumz.commits@gmail.com>
67 67 HG: branch 'default'
68 68 HG: added D
69 69 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/32af7686d403-6f7dface-rebase.hg
70 70 $ cat D.orig
71 71 collide
72 72 $ rm D.orig
73 73
74 74 $ hg tglog
75 75 o 7: 1619f02ff7dd 'D'
76 76 |
77 77 @ 6: 02de42196ebe 'H'
78 78 |
79 79 | o 5: eea13746799a 'G'
80 80 |/|
81 81 o | 4: 24b6387c8c8c 'F'
82 82 | |
83 83 | o 3: 9520eea781bc 'E'
84 84 |/
85 85 | o 2: 5fddd98957c8 'C'
86 86 | |
87 87 | o 1: 42ccdea3bb16 'B'
88 88 |/
89 89 o 0: cd010b8cd998 'A'
90 90
91 91 $ cd ..
92 92
93 93
94 94 D onto F - intermediate point:
95 95 (this also tests that editor is not invoked if '--edit' is not specified, and
96 96 that we can ignore for colliding untracked files)
97 97
98 98 $ hg clone -q -u . a a2
99 99 $ cd a2
100 100 $ echo collide > D
101 101
102 102 $ HGEDITOR=cat hg rebase -s 3 -d 5 --config merge.checkunknown=ignore
103 103 rebasing 3:32af7686d403 "D"
104 104 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/32af7686d403-6f7dface-rebase.hg
105 105 $ cat D.orig
106 106 collide
107 107 $ rm D.orig
108 108
109 109 $ hg tglog
110 110 o 7: 2107530e74ab 'D'
111 111 |
112 112 | @ 6: 02de42196ebe 'H'
113 113 |/
114 114 | o 5: eea13746799a 'G'
115 115 |/|
116 116 o | 4: 24b6387c8c8c 'F'
117 117 | |
118 118 | o 3: 9520eea781bc 'E'
119 119 |/
120 120 | o 2: 5fddd98957c8 'C'
121 121 | |
122 122 | o 1: 42ccdea3bb16 'B'
123 123 |/
124 124 o 0: cd010b8cd998 'A'
125 125
126 126 $ cd ..
127 127
128 128
129 129 E onto H - skip of G:
130 130 (this also tests that we can overwrite untracked files and don't create backups
131 131 if they have the same contents)
132 132
133 133 $ hg clone -q -u . a a3
134 134 $ cd a3
135 135 $ hg cat -r 4 E | tee E
136 136 E
137 137
138 138 $ hg rebase -s 4 -d 7
139 139 rebasing 4:9520eea781bc "E"
140 140 rebasing 6:eea13746799a "G"
141 note: rebase of 6:eea13746799a "G" created no changes to commit
141 note: not rebasing 6:eea13746799a "G", its destination already has all its changes
142 142 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/9520eea781bc-fcd8edd4-rebase.hg
143 143 $ f E.orig
144 144 E.orig: file not found
145 145
146 146 $ hg tglog
147 147 o 6: 9f8b8ec77260 'E'
148 148 |
149 149 @ 5: 02de42196ebe 'H'
150 150 |
151 151 o 4: 24b6387c8c8c 'F'
152 152 |
153 153 | o 3: 32af7686d403 'D'
154 154 | |
155 155 | o 2: 5fddd98957c8 'C'
156 156 | |
157 157 | o 1: 42ccdea3bb16 'B'
158 158 |/
159 159 o 0: cd010b8cd998 'A'
160 160
161 161 $ cd ..
162 162
163 163
164 164 F onto E - rebase of a branching point (skip G):
165 165
166 166 $ hg clone -q -u . a a4
167 167 $ cd a4
168 168
169 169 $ hg rebase -s 5 -d 4
170 170 rebasing 5:24b6387c8c8c "F"
171 171 rebasing 6:eea13746799a "G"
172 note: rebase of 6:eea13746799a "G" created no changes to commit
172 note: not rebasing 6:eea13746799a "G", its destination already has all its changes
173 173 rebasing 7:02de42196ebe "H" (tip)
174 174 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
175 175
176 176 $ hg tglog
177 177 @ 6: e9240aeaa6ad 'H'
178 178 |
179 179 o 5: 5d0ccadb6e3e 'F'
180 180 |
181 181 o 4: 9520eea781bc 'E'
182 182 |
183 183 | o 3: 32af7686d403 'D'
184 184 | |
185 185 | o 2: 5fddd98957c8 'C'
186 186 | |
187 187 | o 1: 42ccdea3bb16 'B'
188 188 |/
189 189 o 0: cd010b8cd998 'A'
190 190
191 191 $ cd ..
192 192
193 193
194 194 G onto H - merged revision having a parent in ancestors of target:
195 195
196 196 $ hg clone -q -u . a a5
197 197 $ cd a5
198 198
199 199 $ hg rebase -s 6 -d 7
200 200 rebasing 6:eea13746799a "G"
201 201 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/eea13746799a-883828ed-rebase.hg
202 202
203 203 $ hg tglog
204 204 o 7: 397834907a90 'G'
205 205 |\
206 206 | @ 6: 02de42196ebe 'H'
207 207 | |
208 208 | o 5: 24b6387c8c8c 'F'
209 209 | |
210 210 o | 4: 9520eea781bc 'E'
211 211 |/
212 212 | o 3: 32af7686d403 'D'
213 213 | |
214 214 | o 2: 5fddd98957c8 'C'
215 215 | |
216 216 | o 1: 42ccdea3bb16 'B'
217 217 |/
218 218 o 0: cd010b8cd998 'A'
219 219
220 220 $ cd ..
221 221
222 222
223 223 F onto B - G maintains E as parent:
224 224
225 225 $ hg clone -q -u . a a6
226 226 $ cd a6
227 227
228 228 $ hg rebase -s 5 -d 1
229 229 rebasing 5:24b6387c8c8c "F"
230 230 rebasing 6:eea13746799a "G"
231 231 rebasing 7:02de42196ebe "H" (tip)
232 232 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
233 233
234 234 $ hg tglog
235 235 @ 7: c87be72f9641 'H'
236 236 |
237 237 | o 6: 17badd73d4f1 'G'
238 238 |/|
239 239 o | 5: 74fb9ed646c4 'F'
240 240 | |
241 241 | o 4: 9520eea781bc 'E'
242 242 | |
243 243 | | o 3: 32af7686d403 'D'
244 244 | | |
245 245 +---o 2: 5fddd98957c8 'C'
246 246 | |
247 247 o | 1: 42ccdea3bb16 'B'
248 248 |/
249 249 o 0: cd010b8cd998 'A'
250 250
251 251 $ cd ..
252 252
253 253
254 254 These will fail (using --source):
255 255
256 256 G onto F - rebase onto an ancestor:
257 257
258 258 $ hg clone -q -u . a a7
259 259 $ cd a7
260 260
261 261 $ hg rebase -s 6 -d 5
262 262 nothing to rebase
263 263 [1]
264 264
265 265 F onto G - rebase onto a descendant:
266 266
267 267 $ hg rebase -s 5 -d 6
268 268 abort: source and destination form a cycle
269 269 [255]
270 270
271 271 G onto B - merge revision with both parents not in ancestors of target:
272 272
273 273 $ hg rebase -s 6 -d 1
274 274 rebasing 6:eea13746799a "G"
275 275 abort: cannot rebase 6:eea13746799a without moving at least one of its parents
276 276 [255]
277 277 $ hg rebase --abort
278 278 rebase aborted
279 279
280 280 These will abort gracefully (using --base):
281 281
282 282 G onto G - rebase onto same changeset:
283 283
284 284 $ hg rebase -b 6 -d 6
285 285 nothing to rebase - eea13746799a is both "base" and destination
286 286 [1]
287 287
288 288 G onto F - rebase onto an ancestor:
289 289
290 290 $ hg rebase -b 6 -d 5
291 291 nothing to rebase
292 292 [1]
293 293
294 294 F onto G - rebase onto a descendant:
295 295
296 296 $ hg rebase -b 5 -d 6
297 297 nothing to rebase - "base" 24b6387c8c8c is already an ancestor of destination eea13746799a
298 298 [1]
299 299
300 300 C onto A - rebase onto an ancestor:
301 301
302 302 $ hg rebase -d 0 -s 2
303 303 rebasing 2:5fddd98957c8 "C"
304 304 rebasing 3:32af7686d403 "D"
305 305 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-f9244fa1-rebase.hg
306 306 $ hg tglog
307 307 o 7: c9659aac0000 'D'
308 308 |
309 309 o 6: e1c4361dd923 'C'
310 310 |
311 311 | @ 5: 02de42196ebe 'H'
312 312 | |
313 313 | | o 4: eea13746799a 'G'
314 314 | |/|
315 315 | o | 3: 24b6387c8c8c 'F'
316 316 |/ /
317 317 | o 2: 9520eea781bc 'E'
318 318 |/
319 319 | o 1: 42ccdea3bb16 'B'
320 320 |/
321 321 o 0: cd010b8cd998 'A'
322 322
323 323
324 324 Check rebasing public changeset
325 325
326 326 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
327 327 $ hg rebase -d 0 -b 6
328 328 nothing to rebase
329 329 [1]
330 330 $ hg rebase -d 5 -b 6
331 331 abort: can't rebase public changeset e1c4361dd923
332 332 (see 'hg help phases' for details)
333 333 [255]
334 334 $ hg rebase -d 5 -r '1 + (6::)'
335 335 abort: can't rebase public changeset e1c4361dd923
336 336 (see 'hg help phases' for details)
337 337 [255]
338 338
339 339 $ hg rebase -d 5 -b 6 --keep
340 340 rebasing 6:e1c4361dd923 "C"
341 341 rebasing 7:c9659aac0000 "D" (tip)
342 342
343 343 Check rebasing mutable changeset
344 344 Source phase greater or equal to destination phase: new changeset get the phase of source:
345 345 $ hg id -n
346 346 5
347 347 $ hg rebase -s9 -d0
348 348 rebasing 9:2b23e52411f4 "D" (tip)
349 349 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-f942decf-rebase.hg
350 350 $ hg id -n # check we updated back to parent
351 351 5
352 352 $ hg log --template "{phase}\n" -r 9
353 353 draft
354 354 $ hg rebase -s9 -d1
355 355 rebasing 9:2cb10d0cfc6c "D" (tip)
356 356 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-ddb0f256-rebase.hg
357 357 $ hg log --template "{phase}\n" -r 9
358 358 draft
359 359 $ hg phase --force --secret 9
360 360 $ hg rebase -s9 -d0
361 361 rebasing 9:c5b12b67163a "D" (tip)
362 362 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-4e372053-rebase.hg
363 363 $ hg log --template "{phase}\n" -r 9
364 364 secret
365 365 $ hg rebase -s9 -d1
366 366 rebasing 9:2a0524f868ac "D" (tip)
367 367 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-cefd8574-rebase.hg
368 368 $ hg log --template "{phase}\n" -r 9
369 369 secret
370 370 Source phase lower than destination phase: new changeset get the phase of destination:
371 371 $ hg rebase -s8 -d9
372 372 rebasing 8:6d4f22462821 "C"
373 373 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-3441f70b-rebase.hg
374 374 $ hg log --template "{phase}\n" -r 'rev(9)'
375 375 secret
376 376
377 377 $ cd ..
378 378
379 379 Check that temporary bundle doesn't lose phase when not using generaldelta
380 380
381 381 $ hg --config format.usegeneraldelta=no init issue5678
382 382 $ cd issue5678
383 383 $ grep generaldelta .hg/requires
384 384 [1]
385 385 $ echo a > a
386 386 $ hg ci -Aqm a
387 387 $ echo b > b
388 388 $ hg ci -Aqm b
389 389 $ hg co -q '.^'
390 390 $ echo c > c
391 391 $ hg ci -Aqm c
392 392 $ hg phase --public
393 393 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
394 394 @ 2:d36c public c
395 395 |
396 396 | o 1:d2ae draft b
397 397 |/
398 398 o 0:cb9a public a
399 399
400 400 $ hg rebase -s 1 -d 2
401 401 rebasing 1:d2ae7f538514 "b"
402 402 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/d2ae7f538514-2953539b-rebase.hg
403 403 $ hg log -G -T '{rev}:{node|shortest} {phase} {desc}\n'
404 404 o 2:c882 draft b
405 405 |
406 406 @ 1:d36c public c
407 407 |
408 408 o 0:cb9a public a
409 409
410 410 $ cd ..
411 411
412 412 Test for revset
413 413
414 414 We need a bit different graph
415 415 All destination are B
416 416
417 417 $ hg init ah
418 418 $ cd ah
419 419 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
420 420 adding changesets
421 421 adding manifests
422 422 adding file changes
423 423 added 9 changesets with 9 changes to 9 files (+2 heads)
424 424 new changesets 9ae2ed22e576:479ddb54a924 (9 drafts)
425 425 (run 'hg heads' to see heads, 'hg merge' to merge)
426 426 $ hg tglog
427 427 o 8: 479ddb54a924 'I'
428 428 |
429 429 o 7: 72434a4e60b0 'H'
430 430 |
431 431 o 6: 3d8a618087a7 'G'
432 432 |
433 433 | o 5: 41bfcc75ed73 'F'
434 434 | |
435 435 | o 4: c01897464e7f 'E'
436 436 |/
437 437 o 3: ffd453c31098 'D'
438 438 |
439 439 o 2: c9e50f6cdc55 'C'
440 440 |
441 441 | o 1: 8fd0f7e49f53 'B'
442 442 |/
443 443 o 0: 9ae2ed22e576 'A'
444 444
445 445 $ cd ..
446 446
447 447
448 448 Simple case with keep:
449 449
450 450 Source on have two descendant heads but ask for one
451 451
452 452 $ hg clone -q -u . ah ah1
453 453 $ cd ah1
454 454 $ hg rebase -r '2::8' -d 1
455 455 abort: can't remove original changesets with unrebased descendants
456 456 (use --keep to keep original changesets)
457 457 [255]
458 458 $ hg rebase -r '2::8' -d 1 -k
459 459 rebasing 2:c9e50f6cdc55 "C"
460 460 rebasing 3:ffd453c31098 "D"
461 461 rebasing 6:3d8a618087a7 "G"
462 462 rebasing 7:72434a4e60b0 "H"
463 463 rebasing 8:479ddb54a924 "I" (tip)
464 464 $ hg tglog
465 465 o 13: 9bf1d9358a90 'I'
466 466 |
467 467 o 12: 274623a778d4 'H'
468 468 |
469 469 o 11: ab8c8617c8e8 'G'
470 470 |
471 471 o 10: c8cbf59f70da 'D'
472 472 |
473 473 o 9: 563e4faab485 'C'
474 474 |
475 475 | o 8: 479ddb54a924 'I'
476 476 | |
477 477 | o 7: 72434a4e60b0 'H'
478 478 | |
479 479 | o 6: 3d8a618087a7 'G'
480 480 | |
481 481 | | o 5: 41bfcc75ed73 'F'
482 482 | | |
483 483 | | o 4: c01897464e7f 'E'
484 484 | |/
485 485 | o 3: ffd453c31098 'D'
486 486 | |
487 487 | o 2: c9e50f6cdc55 'C'
488 488 | |
489 489 o | 1: 8fd0f7e49f53 'B'
490 490 |/
491 491 o 0: 9ae2ed22e576 'A'
492 492
493 493
494 494 $ cd ..
495 495
496 496 Base on have one descendant heads we ask for but common ancestor have two
497 497
498 498 $ hg clone -q -u . ah ah2
499 499 $ cd ah2
500 500 $ hg rebase -r '3::8' -d 1
501 501 abort: can't remove original changesets with unrebased descendants
502 502 (use --keep to keep original changesets)
503 503 [255]
504 504 $ hg rebase -r '3::8' -d 1 --keep
505 505 rebasing 3:ffd453c31098 "D"
506 506 rebasing 6:3d8a618087a7 "G"
507 507 rebasing 7:72434a4e60b0 "H"
508 508 rebasing 8:479ddb54a924 "I" (tip)
509 509 $ hg tglog
510 510 o 12: 9d7da0053b1c 'I'
511 511 |
512 512 o 11: 8fbd00952cbc 'H'
513 513 |
514 514 o 10: 51d434a615ee 'G'
515 515 |
516 516 o 9: a9c125634b0b 'D'
517 517 |
518 518 | o 8: 479ddb54a924 'I'
519 519 | |
520 520 | o 7: 72434a4e60b0 'H'
521 521 | |
522 522 | o 6: 3d8a618087a7 'G'
523 523 | |
524 524 | | o 5: 41bfcc75ed73 'F'
525 525 | | |
526 526 | | o 4: c01897464e7f 'E'
527 527 | |/
528 528 | o 3: ffd453c31098 'D'
529 529 | |
530 530 | o 2: c9e50f6cdc55 'C'
531 531 | |
532 532 o | 1: 8fd0f7e49f53 'B'
533 533 |/
534 534 o 0: 9ae2ed22e576 'A'
535 535
536 536
537 537 $ cd ..
538 538
539 539 rebase subset
540 540
541 541 $ hg clone -q -u . ah ah3
542 542 $ cd ah3
543 543 $ hg rebase -r '3::7' -d 1
544 544 abort: can't remove original changesets with unrebased descendants
545 545 (use --keep to keep original changesets)
546 546 [255]
547 547 $ hg rebase -r '3::7' -d 1 --keep
548 548 rebasing 3:ffd453c31098 "D"
549 549 rebasing 6:3d8a618087a7 "G"
550 550 rebasing 7:72434a4e60b0 "H"
551 551 $ hg tglog
552 552 o 11: 8fbd00952cbc 'H'
553 553 |
554 554 o 10: 51d434a615ee 'G'
555 555 |
556 556 o 9: a9c125634b0b 'D'
557 557 |
558 558 | o 8: 479ddb54a924 'I'
559 559 | |
560 560 | o 7: 72434a4e60b0 'H'
561 561 | |
562 562 | o 6: 3d8a618087a7 'G'
563 563 | |
564 564 | | o 5: 41bfcc75ed73 'F'
565 565 | | |
566 566 | | o 4: c01897464e7f 'E'
567 567 | |/
568 568 | o 3: ffd453c31098 'D'
569 569 | |
570 570 | o 2: c9e50f6cdc55 'C'
571 571 | |
572 572 o | 1: 8fd0f7e49f53 'B'
573 573 |/
574 574 o 0: 9ae2ed22e576 'A'
575 575
576 576
577 577 $ cd ..
578 578
579 579 rebase subset with multiple head
580 580
581 581 $ hg clone -q -u . ah ah4
582 582 $ cd ah4
583 583 $ hg rebase -r '3::(7+5)' -d 1
584 584 abort: can't remove original changesets with unrebased descendants
585 585 (use --keep to keep original changesets)
586 586 [255]
587 587 $ hg rebase -r '3::(7+5)' -d 1 --keep
588 588 rebasing 3:ffd453c31098 "D"
589 589 rebasing 4:c01897464e7f "E"
590 590 rebasing 5:41bfcc75ed73 "F"
591 591 rebasing 6:3d8a618087a7 "G"
592 592 rebasing 7:72434a4e60b0 "H"
593 593 $ hg tglog
594 594 o 13: 8fbd00952cbc 'H'
595 595 |
596 596 o 12: 51d434a615ee 'G'
597 597 |
598 598 | o 11: df23d8bda0b7 'F'
599 599 | |
600 600 | o 10: 47b7889448ff 'E'
601 601 |/
602 602 o 9: a9c125634b0b 'D'
603 603 |
604 604 | o 8: 479ddb54a924 'I'
605 605 | |
606 606 | o 7: 72434a4e60b0 'H'
607 607 | |
608 608 | o 6: 3d8a618087a7 'G'
609 609 | |
610 610 | | o 5: 41bfcc75ed73 'F'
611 611 | | |
612 612 | | o 4: c01897464e7f 'E'
613 613 | |/
614 614 | o 3: ffd453c31098 'D'
615 615 | |
616 616 | o 2: c9e50f6cdc55 'C'
617 617 | |
618 618 o | 1: 8fd0f7e49f53 'B'
619 619 |/
620 620 o 0: 9ae2ed22e576 'A'
621 621
622 622
623 623 $ cd ..
624 624
625 625 More advanced tests
626 626
627 627 rebase on ancestor with revset
628 628
629 629 $ hg clone -q -u . ah ah5
630 630 $ cd ah5
631 631 $ hg rebase -r '6::' -d 2
632 632 rebasing 6:3d8a618087a7 "G"
633 633 rebasing 7:72434a4e60b0 "H"
634 634 rebasing 8:479ddb54a924 "I" (tip)
635 635 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-b4f73f31-rebase.hg
636 636 $ hg tglog
637 637 o 8: fcb52e68a694 'I'
638 638 |
639 639 o 7: 77bd65cd7600 'H'
640 640 |
641 641 o 6: 12d0e738fb18 'G'
642 642 |
643 643 | o 5: 41bfcc75ed73 'F'
644 644 | |
645 645 | o 4: c01897464e7f 'E'
646 646 | |
647 647 | o 3: ffd453c31098 'D'
648 648 |/
649 649 o 2: c9e50f6cdc55 'C'
650 650 |
651 651 | o 1: 8fd0f7e49f53 'B'
652 652 |/
653 653 o 0: 9ae2ed22e576 'A'
654 654
655 655 $ cd ..
656 656
657 657
658 658 rebase with multiple root.
659 659 We rebase E and G on B
660 660 We would expect heads are I, F if it was supported
661 661
662 662 $ hg clone -q -u . ah ah6
663 663 $ cd ah6
664 664 $ hg rebase -r '(4+6)::' -d 1
665 665 rebasing 4:c01897464e7f "E"
666 666 rebasing 5:41bfcc75ed73 "F"
667 667 rebasing 6:3d8a618087a7 "G"
668 668 rebasing 7:72434a4e60b0 "H"
669 669 rebasing 8:479ddb54a924 "I" (tip)
670 670 saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-aae93a24-rebase.hg
671 671 $ hg tglog
672 672 o 8: 9136df9a87cf 'I'
673 673 |
674 674 o 7: 23e8f30da832 'H'
675 675 |
676 676 o 6: b0efe8534e8b 'G'
677 677 |
678 678 | o 5: 6eb5b496ab79 'F'
679 679 | |
680 680 | o 4: d15eade9b0b1 'E'
681 681 |/
682 682 | o 3: ffd453c31098 'D'
683 683 | |
684 684 | o 2: c9e50f6cdc55 'C'
685 685 | |
686 686 o | 1: 8fd0f7e49f53 'B'
687 687 |/
688 688 o 0: 9ae2ed22e576 'A'
689 689
690 690 $ cd ..
691 691
692 692 More complex rebase with multiple roots
693 693 each root have a different common ancestor with the destination and this is a detach
694 694
695 695 (setup)
696 696
697 697 $ hg clone -q -u . a a8
698 698 $ cd a8
699 699 $ echo I > I
700 700 $ hg add I
701 701 $ hg commit -m I
702 702 $ hg up 4
703 703 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
704 704 $ echo I > J
705 705 $ hg add J
706 706 $ hg commit -m J
707 707 created new head
708 708 $ echo I > K
709 709 $ hg add K
710 710 $ hg commit -m K
711 711 $ hg tglog
712 712 @ 10: 23a4ace37988 'K'
713 713 |
714 714 o 9: 1301922eeb0c 'J'
715 715 |
716 716 | o 8: e7ec4e813ba6 'I'
717 717 | |
718 718 | o 7: 02de42196ebe 'H'
719 719 | |
720 720 +---o 6: eea13746799a 'G'
721 721 | |/
722 722 | o 5: 24b6387c8c8c 'F'
723 723 | |
724 724 o | 4: 9520eea781bc 'E'
725 725 |/
726 726 | o 3: 32af7686d403 'D'
727 727 | |
728 728 | o 2: 5fddd98957c8 'C'
729 729 | |
730 730 | o 1: 42ccdea3bb16 'B'
731 731 |/
732 732 o 0: cd010b8cd998 'A'
733 733
734 734 (actual test)
735 735
736 736 $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
737 737 rebasing 8:e7ec4e813ba6 "I"
738 738 rebasing 10:23a4ace37988 "K" (tip)
739 739 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-b06984b3-rebase.hg
740 740 $ hg log --rev 'children(desc(G))'
741 741 changeset: 9:adb617877056
742 742 parent: 6:eea13746799a
743 743 user: test
744 744 date: Thu Jan 01 00:00:00 1970 +0000
745 745 summary: I
746 746
747 747 changeset: 10:882431a34a0e
748 748 tag: tip
749 749 parent: 6:eea13746799a
750 750 user: test
751 751 date: Thu Jan 01 00:00:00 1970 +0000
752 752 summary: K
753 753
754 754 $ hg tglog
755 755 @ 10: 882431a34a0e 'K'
756 756 |
757 757 | o 9: adb617877056 'I'
758 758 |/
759 759 | o 8: 1301922eeb0c 'J'
760 760 | |
761 761 | | o 7: 02de42196ebe 'H'
762 762 | | |
763 763 o---+ 6: eea13746799a 'G'
764 764 |/ /
765 765 | o 5: 24b6387c8c8c 'F'
766 766 | |
767 767 o | 4: 9520eea781bc 'E'
768 768 |/
769 769 | o 3: 32af7686d403 'D'
770 770 | |
771 771 | o 2: 5fddd98957c8 'C'
772 772 | |
773 773 | o 1: 42ccdea3bb16 'B'
774 774 |/
775 775 o 0: cd010b8cd998 'A'
776 776
777 777
778 778 Test that rebase is not confused by $CWD disappearing during rebase (issue4121)
779 779
780 780 $ cd ..
781 781 $ hg init cwd-vanish
782 782 $ cd cwd-vanish
783 783 $ touch initial-file
784 784 $ hg add initial-file
785 785 $ hg commit -m 'initial commit'
786 786 $ touch dest-file
787 787 $ hg add dest-file
788 788 $ hg commit -m 'dest commit'
789 789 $ hg up 0
790 790 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
791 791 $ touch other-file
792 792 $ hg add other-file
793 793 $ hg commit -m 'first source commit'
794 794 created new head
795 795 $ mkdir subdir
796 796 $ cd subdir
797 797 $ touch subfile
798 798 $ hg add subfile
799 799 $ hg commit -m 'second source with subdir'
800 800
801 801 $ hg rebase -b . -d 1 --traceback
802 802 rebasing 2:779a07b1b7a0 "first source commit"
803 803 current directory was removed (rmcwd !)
804 804 (consider changing to repo root: $TESTTMP/cwd-vanish) (rmcwd !)
805 805 rebasing 3:a7d6f3a00bf3 "second source with subdir" (tip)
806 806 saved backup bundle to $TESTTMP/cwd-vanish/.hg/strip-backup/779a07b1b7a0-853e0073-rebase.hg
807 807
808 808 Get back to the root of cwd-vanish. Note that even though `cd ..`
809 809 works on most systems, it does not work on FreeBSD 10, so we use an
810 810 absolute path to get back to the repository.
811 811 $ cd $TESTTMP
812 812
813 813 Test that rebase is done in topo order (issue5370)
814 814
815 815 $ hg init order
816 816 $ cd order
817 817 $ touch a && hg add a && hg ci -m A
818 818 $ touch b && hg add b && hg ci -m B
819 819 $ touch c && hg add c && hg ci -m C
820 820 $ hg up 1
821 821 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
822 822 $ touch d && hg add d && hg ci -m D
823 823 created new head
824 824 $ hg up 2
825 825 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
826 826 $ touch e && hg add e && hg ci -m E
827 827 $ hg up 3
828 828 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
829 829 $ touch f && hg add f && hg ci -m F
830 830 $ hg up 0
831 831 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
832 832 $ touch g && hg add g && hg ci -m G
833 833 created new head
834 834
835 835 $ hg tglog
836 836 @ 6: 124bb27b6f28 'G'
837 837 |
838 838 | o 5: 412b391de760 'F'
839 839 | |
840 840 | | o 4: 82ae8dc7a9b7 'E'
841 841 | | |
842 842 | o | 3: ab709c9f7171 'D'
843 843 | | |
844 844 | | o 2: d84f5cfaaf14 'C'
845 845 | |/
846 846 | o 1: 76035bbd54bd 'B'
847 847 |/
848 848 o 0: 216878401574 'A'
849 849
850 850
851 851 $ hg rebase -s 1 -d 6
852 852 rebasing 1:76035bbd54bd "B"
853 853 rebasing 2:d84f5cfaaf14 "C"
854 854 rebasing 4:82ae8dc7a9b7 "E"
855 855 rebasing 3:ab709c9f7171 "D"
856 856 rebasing 5:412b391de760 "F"
857 857 saved backup bundle to $TESTTMP/order/.hg/strip-backup/76035bbd54bd-e341bc99-rebase.hg
858 858
859 859 $ hg tglog
860 860 o 6: 31884cfb735e 'F'
861 861 |
862 862 o 5: 6d89fa5b0909 'D'
863 863 |
864 864 | o 4: de64d97c697b 'E'
865 865 | |
866 866 | o 3: b18e4d2d0aa1 'C'
867 867 |/
868 868 o 2: 0983daf9ff6a 'B'
869 869 |
870 870 @ 1: 124bb27b6f28 'G'
871 871 |
872 872 o 0: 216878401574 'A'
873 873
874 874
875 875 Test experimental revset
876 876 ========================
877 877
878 878 $ cd ../cwd-vanish
879 879
880 880 Make the repo a bit more interesting
881 881
882 882 $ hg up 1
883 883 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
884 884 $ echo aaa > aaa
885 885 $ hg add aaa
886 886 $ hg commit -m aaa
887 887 created new head
888 888 $ hg log -G
889 889 @ changeset: 4:5f7bc9025ed2
890 890 | tag: tip
891 891 | parent: 1:58d79cc1cf43
892 892 | user: test
893 893 | date: Thu Jan 01 00:00:00 1970 +0000
894 894 | summary: aaa
895 895 |
896 896 | o changeset: 3:1910d5ff34ea
897 897 | | user: test
898 898 | | date: Thu Jan 01 00:00:00 1970 +0000
899 899 | | summary: second source with subdir
900 900 | |
901 901 | o changeset: 2:82901330b6ef
902 902 |/ user: test
903 903 | date: Thu Jan 01 00:00:00 1970 +0000
904 904 | summary: first source commit
905 905 |
906 906 o changeset: 1:58d79cc1cf43
907 907 | user: test
908 908 | date: Thu Jan 01 00:00:00 1970 +0000
909 909 | summary: dest commit
910 910 |
911 911 o changeset: 0:e94b687f7da3
912 912 user: test
913 913 date: Thu Jan 01 00:00:00 1970 +0000
914 914 summary: initial commit
915 915
916 916
917 917 Testing from lower head
918 918
919 919 $ hg up 3
920 920 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
921 921 $ hg log -r '_destrebase()'
922 922 changeset: 4:5f7bc9025ed2
923 923 tag: tip
924 924 parent: 1:58d79cc1cf43
925 925 user: test
926 926 date: Thu Jan 01 00:00:00 1970 +0000
927 927 summary: aaa
928 928
929 929
930 930 Testing from upper head
931 931
932 932 $ hg log -r '_destrebase(4)'
933 933 changeset: 3:1910d5ff34ea
934 934 user: test
935 935 date: Thu Jan 01 00:00:00 1970 +0000
936 936 summary: second source with subdir
937 937
938 938 $ hg up 4
939 939 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
940 940 $ hg log -r '_destrebase()'
941 941 changeset: 3:1910d5ff34ea
942 942 user: test
943 943 date: Thu Jan 01 00:00:00 1970 +0000
944 944 summary: second source with subdir
945 945
946 946 Testing rebase being called inside another transaction
947 947
948 948 $ cd $TESTTMP
949 949 $ hg init tr-state
950 950 $ cd tr-state
951 951 $ cat > $TESTTMP/wraprebase.py <<EOF
952 952 > from __future__ import absolute_import
953 953 > from mercurial import extensions
954 954 > def _rebase(orig, ui, repo, *args, **kwargs):
955 955 > with repo.wlock():
956 956 > with repo.lock():
957 957 > with repo.transaction(b'wrappedrebase'):
958 958 > return orig(ui, repo, *args, **kwargs)
959 959 > def wraprebase(loaded):
960 960 > assert loaded
961 961 > rebasemod = extensions.find(b'rebase')
962 962 > extensions.wrapcommand(rebasemod.cmdtable, b'rebase', _rebase)
963 963 > def extsetup(ui):
964 964 > extensions.afterloaded(b'rebase', wraprebase)
965 965 > EOF
966 966
967 967 $ cat >> .hg/hgrc <<EOF
968 968 > [extensions]
969 969 > wraprebase=$TESTTMP/wraprebase.py
970 970 > [experimental]
971 971 > evolution=true
972 972 > EOF
973 973
974 974 $ hg debugdrawdag <<'EOS'
975 975 > B C
976 976 > |/
977 977 > A
978 978 > EOS
979 979
980 980 $ hg rebase -s C -d B
981 981 rebasing 2:dc0947a82db8 "C" (C tip)
982 982
983 983 $ [ -f .hg/rebasestate ] && echo 'WRONG: rebasestate should not exist'
984 984 [1]
@@ -1,194 +1,194 b''
1 1 #require no-windows
2 2
3 3 # Tests for the complicated linknode logic in remotefilelog.py::ancestormap()
4 4
5 5 $ . "$TESTDIR/remotefilelog-library.sh"
6 6
7 7 $ hg init master
8 8 $ cd master
9 9 $ cat >> .hg/hgrc <<EOF
10 10 > [remotefilelog]
11 11 > server=True
12 12 > serverexpiration=-1
13 13 > EOF
14 14 $ echo x > x
15 15 $ hg commit -qAm x
16 16 $ cd ..
17 17
18 18 $ hgcloneshallow ssh://user@dummy/master shallow -q
19 19 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s (glob)
20 20
21 21 # Rebase produces correct log -f linknodes
22 22
23 23 $ cd shallow
24 24 $ echo y > y
25 25 $ hg commit -qAm y
26 26 $ hg up 0
27 27 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
28 28 $ echo x >> x
29 29 $ hg commit -qAm xx
30 30 $ hg log -f x --template "{node|short}\n"
31 31 0632994590a8
32 32 b292c1e3311f
33 33
34 34 $ hg rebase -d 1
35 35 rebasing 2:0632994590a8 "xx" (tip)
36 36 saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/0632994590a8-0bc786d8-rebase.hg (glob)
37 37 $ hg log -f x --template "{node|short}\n"
38 38 81deab2073bc
39 39 b292c1e3311f
40 40
41 41 # Rebase back, log -f still works
42 42
43 43 $ hg rebase -d 0 -r 2
44 44 rebasing 2:81deab2073bc "xx" (tip)
45 45 saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/81deab2073bc-80cb4fda-rebase.hg (glob)
46 46 $ hg log -f x --template "{node|short}\n"
47 47 b3fca10fb42d
48 48 b292c1e3311f
49 49
50 50 $ hg rebase -d 1 -r 2
51 51 rebasing 2:b3fca10fb42d "xx" (tip)
52 52 saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/b3fca10fb42d-da73a0c7-rebase.hg (glob)
53 53
54 54 $ cd ..
55 55
56 56 # Reset repos
57 57 $ clearcache
58 58
59 59 $ rm -rf master
60 60 $ rm -rf shallow
61 61 $ hg init master
62 62 $ cd master
63 63 $ cat >> .hg/hgrc <<EOF
64 64 > [remotefilelog]
65 65 > server=True
66 66 > serverexpiration=-1
67 67 > EOF
68 68 $ echo x > x
69 69 $ hg commit -qAm x
70 70 $ cd ..
71 71
72 72 $ hgcloneshallow ssh://user@dummy/master shallow -q
73 73 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s (glob)
74 74
75 75 # Rebase stack onto landed commit
76 76
77 77 $ cd master
78 78 $ echo x >> x
79 79 $ hg commit -Aqm xx
80 80
81 81 $ cd ../shallow
82 82 $ echo x >> x
83 83 $ hg commit -Aqm xx2
84 84 $ echo y >> x
85 85 $ hg commit -Aqm xxy
86 86
87 87 $ hg pull -q
88 88 $ hg rebase -d tip
89 89 rebasing 1:4549721d828f "xx2"
90 note: rebase of 1:4549721d828f "xx2" created no changes to commit
90 note: not rebasing 1:4549721d828f "xx2", its destination already has all its changes
91 91 rebasing 2:5ef6d97e851c "xxy"
92 92 saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/4549721d828f-b084e33c-rebase.hg (glob)
93 93 $ hg log -f x --template '{node|short}\n'
94 94 4ae8e31c85ef
95 95 0632994590a8
96 96 b292c1e3311f
97 97
98 98 $ cd ..
99 99
100 100 # system cache has invalid linknode, but .hg/store/data has valid
101 101
102 102 $ cd shallow
103 103 $ hg strip -r 1 -q
104 104 $ rm -rf .hg/store/data/*
105 105 $ echo x >> x
106 106 $ hg commit -Aqm xx_local
107 107 $ hg log -f x --template '{rev}:{node|short}\n'
108 108 1:21847713771d
109 109 0:b292c1e3311f
110 110
111 111 $ cd ..
112 112 $ rm -rf shallow
113 113
114 114 /* Local linknode is invalid; remote linknode is valid (formerly slow case) */
115 115
116 116 $ hgcloneshallow ssh://user@dummy/master shallow -q
117 117 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over * (glob)
118 118 $ cd shallow
119 119 $ echo x >> x
120 120 $ hg commit -Aqm xx2
121 121 $ cd ../master
122 122 $ echo y >> y
123 123 $ hg commit -Aqm yy2
124 124 $ echo x >> x
125 125 $ hg commit -Aqm xx2-fake-rebased
126 126 $ echo y >> y
127 127 $ hg commit -Aqm yy3
128 128 $ cd ../shallow
129 129 $ hg pull --config remotefilelog.debug=True
130 130 pulling from ssh://user@dummy/master
131 131 searching for changes
132 132 adding changesets
133 133 adding manifests
134 134 adding file changes
135 135 added 3 changesets with 0 changes to 0 files (+1 heads)
136 136 new changesets 01979f9404f8:7200df4e0aca
137 137 (run 'hg heads' to see heads, 'hg merge' to merge)
138 138 $ hg update tip -q
139 139 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s (glob)
140 140 $ echo x > x
141 141 $ hg commit -qAm xx3
142 142
143 143 # At this point, the linknode points to c1254e70bad1 instead of 32e6611f6149
144 144 $ hg log -G -T '{node|short} {desc} {phase} {files}\n'
145 145 @ a5957b6bf0bd xx3 draft x
146 146 |
147 147 o 7200df4e0aca yy3 public y
148 148 |
149 149 o 32e6611f6149 xx2-fake-rebased public x
150 150 |
151 151 o 01979f9404f8 yy2 public y
152 152 |
153 153 | o c1254e70bad1 xx2 draft x
154 154 |/
155 155 o 0632994590a8 xx public x
156 156 |
157 157 o b292c1e3311f x public x
158 158
159 159 # Check the contents of the local blob for incorrect linknode
160 160 $ hg debugremotefilelog .hg/store/data/11f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
161 161 size: 6 bytes
162 162 path: .hg/store/data/11f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
163 163 key: d4a3ed9310e5
164 164
165 165 node => p1 p2 linknode copyfrom
166 166 d4a3ed9310e5 => aee31534993a 000000000000 c1254e70bad1
167 167 aee31534993a => 1406e7411862 000000000000 0632994590a8
168 168 1406e7411862 => 000000000000 000000000000 b292c1e3311f
169 169
170 170 # Verify that we do a fetch on the first log (remote blob fetch for linkrev fix)
171 171 $ hg log -f x -T '{node|short} {desc} {phase} {files}\n'
172 172 a5957b6bf0bd xx3 draft x
173 173 32e6611f6149 xx2-fake-rebased public x
174 174 0632994590a8 xx public x
175 175 b292c1e3311f x public x
176 176 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s (glob)
177 177
178 178 # But not after that
179 179 $ hg log -f x -T '{node|short} {desc} {phase} {files}\n'
180 180 a5957b6bf0bd xx3 draft x
181 181 32e6611f6149 xx2-fake-rebased public x
182 182 0632994590a8 xx public x
183 183 b292c1e3311f x public x
184 184
185 185 # Check the contents of the remote blob for correct linknode
186 186 $ hg debugremotefilelog $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
187 187 size: 6 bytes
188 188 path: $TESTTMP/hgcache/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/d4a3ed9310e5bd9887e3bf779da5077efab28216
189 189 key: d4a3ed9310e5
190 190
191 191 node => p1 p2 linknode copyfrom
192 192 d4a3ed9310e5 => aee31534993a 000000000000 32e6611f6149
193 193 aee31534993a => 1406e7411862 000000000000 0632994590a8
194 194 1406e7411862 => 000000000000 000000000000 b292c1e3311f
General Comments 0
You need to be logged in to leave comments. Login now