##// END OF EJS Templates
rebase: preserve working directory parent (BC)...
Pierre-Yves David -
r19925:9c78ed39 default
parent child Browse files
Show More
@@ -1,864 +1,871 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 http://mercurial.selenic.com/wiki/RebaseExtension
15 15 '''
16 16
17 17 from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
18 18 from mercurial import extensions, patch, scmutil, phases, obsolete, error
19 19 from mercurial.commands import templateopts
20 20 from mercurial.node import nullrev
21 21 from mercurial.lock import release
22 22 from mercurial.i18n import _
23 23 import os, errno
24 24
25 25 nullmerge = -2
26 26 revignored = -3
27 27
28 28 cmdtable = {}
29 29 command = cmdutil.command(cmdtable)
30 30 testedwith = 'internal'
31 31
32 32 def _savegraft(ctx, extra):
33 33 s = ctx.extra().get('source', None)
34 34 if s is not None:
35 35 extra['source'] = s
36 36
37 37 def _savebranch(ctx, extra):
38 38 extra['branch'] = ctx.branch()
39 39
40 40 def _makeextrafn(copiers):
41 41 """make an extrafn out of the given copy-functions.
42 42
43 43 A copy function takes a context and an extra dict, and mutates the
44 44 extra dict as needed based on the given context.
45 45 """
46 46 def extrafn(ctx, extra):
47 47 for c in copiers:
48 48 c(ctx, extra)
49 49 return extrafn
50 50
51 51 @command('rebase',
52 52 [('s', 'source', '',
53 53 _('rebase from the specified changeset'), _('REV')),
54 54 ('b', 'base', '',
55 55 _('rebase from the base of the specified changeset '
56 56 '(up to greatest common ancestor of base and dest)'),
57 57 _('REV')),
58 58 ('r', 'rev', [],
59 59 _('rebase these revisions'),
60 60 _('REV')),
61 61 ('d', 'dest', '',
62 62 _('rebase onto the specified changeset'), _('REV')),
63 63 ('', 'collapse', False, _('collapse the rebased changesets')),
64 64 ('m', 'message', '',
65 65 _('use text as collapse commit message'), _('TEXT')),
66 66 ('e', 'edit', False, _('invoke editor on commit messages')),
67 67 ('l', 'logfile', '',
68 68 _('read collapse commit message from file'), _('FILE')),
69 69 ('', 'keep', False, _('keep original changesets')),
70 70 ('', 'keepbranches', False, _('keep original branch names')),
71 71 ('D', 'detach', False, _('(DEPRECATED)')),
72 72 ('t', 'tool', '', _('specify merge tool')),
73 73 ('c', 'continue', False, _('continue an interrupted rebase')),
74 74 ('a', 'abort', False, _('abort an interrupted rebase'))] +
75 75 templateopts,
76 76 _('[-s REV | -b REV] [-d REV] [OPTION]'))
77 77 def rebase(ui, repo, **opts):
78 78 """move changeset (and descendants) to a different branch
79 79
80 80 Rebase uses repeated merging to graft changesets from one part of
81 81 history (the source) onto another (the destination). This can be
82 82 useful for linearizing *local* changes relative to a master
83 83 development tree.
84 84
85 85 You should not rebase changesets that have already been shared
86 86 with others. Doing so will force everybody else to perform the
87 87 same rebase or they will end up with duplicated changesets after
88 88 pulling in your rebased changesets.
89 89
90 90 In its default configuration, Mercurial will prevent you from
91 91 rebasing published changes. See :hg:`help phases` for details.
92 92
93 93 If you don't specify a destination changeset (``-d/--dest``),
94 94 rebase uses the current branch tip as the destination. (The
95 95 destination changeset is not modified by rebasing, but new
96 96 changesets are added as its descendants.)
97 97
98 98 You can specify which changesets to rebase in two ways: as a
99 99 "source" changeset or as a "base" changeset. Both are shorthand
100 100 for a topologically related set of changesets (the "source
101 101 branch"). If you specify source (``-s/--source``), rebase will
102 102 rebase that changeset and all of its descendants onto dest. If you
103 103 specify base (``-b/--base``), rebase will select ancestors of base
104 104 back to but not including the common ancestor with dest. Thus,
105 105 ``-b`` is less precise but more convenient than ``-s``: you can
106 106 specify any changeset in the source branch, and rebase will select
107 107 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
108 108 uses the parent of the working directory as the base.
109 109
110 110 For advanced usage, a third way is available through the ``--rev``
111 111 option. It allows you to specify an arbitrary set of changesets to
112 112 rebase. Descendants of revs you specify with this option are not
113 113 automatically included in the rebase.
114 114
115 115 By default, rebase recreates the changesets in the source branch
116 116 as descendants of dest and then destroys the originals. Use
117 117 ``--keep`` to preserve the original source changesets. Some
118 118 changesets in the source branch (e.g. merges from the destination
119 119 branch) may be dropped if they no longer contribute any change.
120 120
121 121 One result of the rules for selecting the destination changeset
122 122 and source branch is that, unlike ``merge``, rebase will do
123 123 nothing if you are at the branch tip of a named branch
124 124 with two heads. You need to explicitly specify source and/or
125 125 destination (or ``update`` to the other head, if it's the head of
126 126 the intended source branch).
127 127
128 128 If a rebase is interrupted to manually resolve a merge, it can be
129 129 continued with --continue/-c or aborted with --abort/-a.
130 130
131 131 Returns 0 on success, 1 if nothing to rebase.
132 132 """
133 133 originalwd = target = None
134 134 activebookmark = None
135 135 external = nullrev
136 136 state = {}
137 137 skipped = set()
138 138 targetancestors = set()
139 139
140 140 editor = None
141 141 if opts.get('edit'):
142 142 editor = cmdutil.commitforceeditor
143 143
144 144 lock = wlock = None
145 145 try:
146 146 wlock = repo.wlock()
147 147 lock = repo.lock()
148 148
149 149 # Validate input and define rebasing points
150 150 destf = opts.get('dest', None)
151 151 srcf = opts.get('source', None)
152 152 basef = opts.get('base', None)
153 153 revf = opts.get('rev', [])
154 154 contf = opts.get('continue')
155 155 abortf = opts.get('abort')
156 156 collapsef = opts.get('collapse', False)
157 157 collapsemsg = cmdutil.logmessage(ui, opts)
158 158 e = opts.get('extrafn') # internal, used by e.g. hgsubversion
159 159 extrafns = [_savegraft]
160 160 if e:
161 161 extrafns = [e]
162 162 keepf = opts.get('keep', False)
163 163 keepbranchesf = opts.get('keepbranches', False)
164 164 # keepopen is not meant for use on the command line, but by
165 165 # other extensions
166 166 keepopen = opts.get('keepopen', False)
167 167
168 168 if collapsemsg and not collapsef:
169 169 raise util.Abort(
170 170 _('message can only be specified with collapse'))
171 171
172 172 if contf or abortf:
173 173 if contf and abortf:
174 174 raise util.Abort(_('cannot use both abort and continue'))
175 175 if collapsef:
176 176 raise util.Abort(
177 177 _('cannot use collapse with continue or abort'))
178 178 if srcf or basef or destf:
179 179 raise util.Abort(
180 180 _('abort and continue do not allow specifying revisions'))
181 181 if opts.get('tool', False):
182 182 ui.warn(_('tool option will be ignored\n'))
183 183
184 184 try:
185 185 (originalwd, target, state, skipped, collapsef, keepf,
186 186 keepbranchesf, external, activebookmark) = restorestatus(repo)
187 187 except error.RepoLookupError:
188 188 if abortf:
189 189 clearstatus(repo)
190 190 repo.ui.warn(_('rebase aborted (no revision is removed,'
191 191 ' only broken state is cleared)\n'))
192 192 return 0
193 193 else:
194 194 msg = _('cannot continue inconsistent rebase')
195 195 hint = _('use "hg rebase --abort" to clear borken state')
196 196 raise util.Abort(msg, hint=hint)
197 197 if abortf:
198 198 return abort(repo, originalwd, target, state)
199 199 else:
200 200 if srcf and basef:
201 201 raise util.Abort(_('cannot specify both a '
202 202 'source and a base'))
203 203 if revf and basef:
204 204 raise util.Abort(_('cannot specify both a '
205 205 'revision and a base'))
206 206 if revf and srcf:
207 207 raise util.Abort(_('cannot specify both a '
208 208 'revision and a source'))
209 209
210 210 cmdutil.checkunfinished(repo)
211 211 cmdutil.bailifchanged(repo)
212 212
213 213 if not destf:
214 214 # Destination defaults to the latest revision in the
215 215 # current branch
216 216 branch = repo[None].branch()
217 217 dest = repo[branch]
218 218 else:
219 219 dest = scmutil.revsingle(repo, destf)
220 220
221 221 if revf:
222 222 rebaseset = scmutil.revrange(repo, revf)
223 223 elif srcf:
224 224 src = scmutil.revrange(repo, [srcf])
225 225 rebaseset = repo.revs('(%ld)::', src)
226 226 else:
227 227 base = scmutil.revrange(repo, [basef or '.'])
228 228 rebaseset = repo.revs(
229 229 '(children(ancestor(%ld, %d)) and ::(%ld))::',
230 230 base, dest, base)
231 231 if rebaseset:
232 232 root = min(rebaseset)
233 233 else:
234 234 root = None
235 235
236 236 if not rebaseset:
237 237 repo.ui.debug('base is ancestor of destination\n')
238 238 result = None
239 239 elif (not (keepf or obsolete._enabled)
240 240 and repo.revs('first(children(%ld) - %ld)',
241 241 rebaseset, rebaseset)):
242 242 raise util.Abort(
243 243 _("can't remove original changesets with"
244 244 " unrebased descendants"),
245 245 hint=_('use --keep to keep original changesets'))
246 246 else:
247 247 result = buildstate(repo, dest, rebaseset, collapsef)
248 248
249 249 if not result:
250 250 # Empty state built, nothing to rebase
251 251 ui.status(_('nothing to rebase\n'))
252 252 return 1
253 253 elif not keepf and not repo[root].mutable():
254 254 raise util.Abort(_("can't rebase immutable changeset %s")
255 255 % repo[root],
256 256 hint=_('see hg help phases for details'))
257 257 else:
258 258 originalwd, target, state = result
259 259 if collapsef:
260 260 targetancestors = repo.changelog.ancestors([target],
261 261 inclusive=True)
262 262 external = checkexternal(repo, state, targetancestors)
263 263
264 264 if keepbranchesf:
265 265 # insert _savebranch at the start of extrafns so if
266 266 # there's a user-provided extrafn it can clobber branch if
267 267 # desired
268 268 extrafns.insert(0, _savebranch)
269 269 if collapsef:
270 270 branches = set()
271 271 for rev in state:
272 272 branches.add(repo[rev].branch())
273 273 if len(branches) > 1:
274 274 raise util.Abort(_('cannot collapse multiple named '
275 275 'branches'))
276 276
277 277
278 278 # Rebase
279 279 if not targetancestors:
280 280 targetancestors = repo.changelog.ancestors([target], inclusive=True)
281 281
282 282 # Keep track of the current bookmarks in order to reset them later
283 283 currentbookmarks = repo._bookmarks.copy()
284 284 activebookmark = activebookmark or repo._bookmarkcurrent
285 285 if activebookmark:
286 286 bookmarks.unsetcurrent(repo)
287 287
288 288 extrafn = _makeextrafn(extrafns)
289 289
290 290 sortedstate = sorted(state)
291 291 total = len(sortedstate)
292 292 pos = 0
293 293 for rev in sortedstate:
294 294 pos += 1
295 295 if state[rev] == -1:
296 296 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
297 297 _('changesets'), total)
298 298 p1, p2 = defineparents(repo, rev, target, state,
299 299 targetancestors)
300 300 storestatus(repo, originalwd, target, state, collapsef, keepf,
301 301 keepbranchesf, external, activebookmark)
302 302 if len(repo.parents()) == 2:
303 303 repo.ui.debug('resuming interrupted rebase\n')
304 304 else:
305 305 try:
306 306 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
307 307 stats = rebasenode(repo, rev, p1, state, collapsef)
308 308 if stats and stats[3] > 0:
309 309 raise error.InterventionRequired(
310 310 _('unresolved conflicts (see hg '
311 311 'resolve, then hg rebase --continue)'))
312 312 finally:
313 313 ui.setconfig('ui', 'forcemerge', '')
314 314 cmdutil.duplicatecopies(repo, rev, target)
315 315 if not collapsef:
316 316 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
317 317 editor=editor)
318 318 else:
319 319 # Skip commit if we are collapsing
320 320 repo.setparents(repo[p1].node())
321 321 newrev = None
322 322 # Update the state
323 323 if newrev is not None:
324 324 state[rev] = repo[newrev].rev()
325 325 else:
326 326 if not collapsef:
327 327 ui.note(_('no changes, revision %d skipped\n') % rev)
328 328 ui.debug('next revision set to %s\n' % p1)
329 329 skipped.add(rev)
330 330 state[rev] = p1
331 331
332 332 ui.progress(_('rebasing'), None)
333 333 ui.note(_('rebase merging completed\n'))
334 334
335 335 if collapsef and not keepopen:
336 336 p1, p2 = defineparents(repo, min(state), target,
337 337 state, targetancestors)
338 338 if collapsemsg:
339 339 commitmsg = collapsemsg
340 340 else:
341 341 commitmsg = 'Collapsed revision'
342 342 for rebased in state:
343 343 if rebased not in skipped and state[rebased] > nullmerge:
344 344 commitmsg += '\n* %s' % repo[rebased].description()
345 345 commitmsg = ui.edit(commitmsg, repo.ui.username())
346 346 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
347 347 extrafn=extrafn, editor=editor)
348 348
349 349 if 'qtip' in repo.tags():
350 350 updatemq(repo, state, skipped, **opts)
351 351
352 352 if currentbookmarks:
353 353 # Nodeids are needed to reset bookmarks
354 354 nstate = {}
355 355 for k, v in state.iteritems():
356 356 if v > nullmerge:
357 357 nstate[repo[k].node()] = repo[v].node()
358 358 # XXX this is the same as dest.node() for the non-continue path --
359 359 # this should probably be cleaned up
360 360 targetnode = repo[target].node()
361 361
362 # restore original working directory
363 # (we do this before stripping)
364 newwd = state.get(originalwd, originalwd)
365 if newwd not in [c.rev() for c in repo[None].parents()]:
366 ui.note(_("update back to initial working directory parent\n"))
367 hg.updaterepo(repo, newwd, False)
368
362 369 if not keepf:
363 370 collapsedas = None
364 371 if collapsef:
365 372 collapsedas = newrev
366 373 clearrebased(ui, repo, state, skipped, collapsedas)
367 374
368 375 if currentbookmarks:
369 376 updatebookmarks(repo, targetnode, nstate, currentbookmarks)
370 377
371 378 clearstatus(repo)
372 379 ui.note(_("rebase completed\n"))
373 380 util.unlinkpath(repo.sjoin('undo'), ignoremissing=True)
374 381 if skipped:
375 382 ui.note(_("%d revisions have been skipped\n") % len(skipped))
376 383
377 384 if (activebookmark and
378 385 repo['tip'].node() == repo._bookmarks[activebookmark]):
379 386 bookmarks.setcurrent(repo, activebookmark)
380 387
381 388 finally:
382 389 release(lock, wlock)
383 390
384 391 def checkexternal(repo, state, targetancestors):
385 392 """Check whether one or more external revisions need to be taken in
386 393 consideration. In the latter case, abort.
387 394 """
388 395 external = nullrev
389 396 source = min(state)
390 397 for rev in state:
391 398 if rev == source:
392 399 continue
393 400 # Check externals and fail if there are more than one
394 401 for p in repo[rev].parents():
395 402 if (p.rev() not in state
396 403 and p.rev() not in targetancestors):
397 404 if external != nullrev:
398 405 raise util.Abort(_('unable to collapse, there is more '
399 406 'than one external parent'))
400 407 external = p.rev()
401 408 return external
402 409
403 410 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
404 411 'Commit the changes and store useful information in extra'
405 412 try:
406 413 repo.setparents(repo[p1].node(), repo[p2].node())
407 414 ctx = repo[rev]
408 415 if commitmsg is None:
409 416 commitmsg = ctx.description()
410 417 extra = {'rebase_source': ctx.hex()}
411 418 if extrafn:
412 419 extrafn(ctx, extra)
413 420 # Commit might fail if unresolved files exist
414 421 newrev = repo.commit(text=commitmsg, user=ctx.user(),
415 422 date=ctx.date(), extra=extra, editor=editor)
416 423 repo.dirstate.setbranch(repo[newrev].branch())
417 424 targetphase = max(ctx.phase(), phases.draft)
418 425 # retractboundary doesn't overwrite upper phase inherited from parent
419 426 newnode = repo[newrev].node()
420 427 if newnode:
421 428 phases.retractboundary(repo, targetphase, [newnode])
422 429 return newrev
423 430 except util.Abort:
424 431 # Invalidate the previous setparents
425 432 repo.dirstate.invalidate()
426 433 raise
427 434
428 435 def rebasenode(repo, rev, p1, state, collapse):
429 436 'Rebase a single revision'
430 437 # Merge phase
431 438 # Update to target and merge it with local
432 439 if repo['.'].rev() != repo[p1].rev():
433 440 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
434 441 merge.update(repo, p1, False, True, False)
435 442 else:
436 443 repo.ui.debug(" already in target\n")
437 444 repo.dirstate.write()
438 445 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
439 446 base = None
440 447 if repo[rev].rev() != repo[min(state)].rev():
441 448 base = repo[rev].p1().node()
442 449 # When collapsing in-place, the parent is the common ancestor, we
443 450 # have to allow merging with it.
444 451 return merge.update(repo, rev, True, True, False, base, collapse)
445 452
446 453 def nearestrebased(repo, rev, state):
447 454 """return the nearest ancestors of rev in the rebase result"""
448 455 rebased = [r for r in state if state[r] > nullmerge]
449 456 candidates = repo.revs('max(%ld and (::%d))', rebased, rev)
450 457 if candidates:
451 458 return state[candidates[0]]
452 459 else:
453 460 return None
454 461
455 462 def defineparents(repo, rev, target, state, targetancestors):
456 463 'Return the new parent relationship of the revision that will be rebased'
457 464 parents = repo[rev].parents()
458 465 p1 = p2 = nullrev
459 466
460 467 P1n = parents[0].rev()
461 468 if P1n in targetancestors:
462 469 p1 = target
463 470 elif P1n in state:
464 471 if state[P1n] == nullmerge:
465 472 p1 = target
466 473 elif state[P1n] == revignored:
467 474 p1 = nearestrebased(repo, P1n, state)
468 475 if p1 is None:
469 476 p1 = target
470 477 else:
471 478 p1 = state[P1n]
472 479 else: # P1n external
473 480 p1 = target
474 481 p2 = P1n
475 482
476 483 if len(parents) == 2 and parents[1].rev() not in targetancestors:
477 484 P2n = parents[1].rev()
478 485 # interesting second parent
479 486 if P2n in state:
480 487 if p1 == target: # P1n in targetancestors or external
481 488 p1 = state[P2n]
482 489 elif state[P2n] == revignored:
483 490 p2 = nearestrebased(repo, P2n, state)
484 491 if p2 is None:
485 492 # no ancestors rebased yet, detach
486 493 p2 = target
487 494 else:
488 495 p2 = state[P2n]
489 496 else: # P2n external
490 497 if p2 != nullrev: # P1n external too => rev is a merged revision
491 498 raise util.Abort(_('cannot use revision %d as base, result '
492 499 'would have 3 parents') % rev)
493 500 p2 = P2n
494 501 repo.ui.debug(" future parents are %d and %d\n" %
495 502 (repo[p1].rev(), repo[p2].rev()))
496 503 return p1, p2
497 504
498 505 def isagitpatch(repo, patchname):
499 506 'Return true if the given patch is in git format'
500 507 mqpatch = os.path.join(repo.mq.path, patchname)
501 508 for line in patch.linereader(file(mqpatch, 'rb')):
502 509 if line.startswith('diff --git'):
503 510 return True
504 511 return False
505 512
506 513 def updatemq(repo, state, skipped, **opts):
507 514 'Update rebased mq patches - finalize and then import them'
508 515 mqrebase = {}
509 516 mq = repo.mq
510 517 original_series = mq.fullseries[:]
511 518 skippedpatches = set()
512 519
513 520 for p in mq.applied:
514 521 rev = repo[p.node].rev()
515 522 if rev in state:
516 523 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
517 524 (rev, p.name))
518 525 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
519 526 else:
520 527 # Applied but not rebased, not sure this should happen
521 528 skippedpatches.add(p.name)
522 529
523 530 if mqrebase:
524 531 mq.finish(repo, mqrebase.keys())
525 532
526 533 # We must start import from the newest revision
527 534 for rev in sorted(mqrebase, reverse=True):
528 535 if rev not in skipped:
529 536 name, isgit = mqrebase[rev]
530 537 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
531 538 mq.qimport(repo, (), patchname=name, git=isgit,
532 539 rev=[str(state[rev])])
533 540 else:
534 541 # Rebased and skipped
535 542 skippedpatches.add(mqrebase[rev][0])
536 543
537 544 # Patches were either applied and rebased and imported in
538 545 # order, applied and removed or unapplied. Discard the removed
539 546 # ones while preserving the original series order and guards.
540 547 newseries = [s for s in original_series
541 548 if mq.guard_re.split(s, 1)[0] not in skippedpatches]
542 549 mq.fullseries[:] = newseries
543 550 mq.seriesdirty = True
544 551 mq.savedirty()
545 552
546 553 def updatebookmarks(repo, targetnode, nstate, originalbookmarks):
547 554 'Move bookmarks to their correct changesets, and delete divergent ones'
548 555 marks = repo._bookmarks
549 556 for k, v in originalbookmarks.iteritems():
550 557 if v in nstate:
551 558 # update the bookmarks for revs that have moved
552 559 marks[k] = nstate[v]
553 560 bookmarks.deletedivergent(repo, [targetnode], k)
554 561
555 562 marks.write()
556 563
557 564 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
558 565 external, activebookmark):
559 566 'Store the current status to allow recovery'
560 567 f = repo.opener("rebasestate", "w")
561 568 f.write(repo[originalwd].hex() + '\n')
562 569 f.write(repo[target].hex() + '\n')
563 570 f.write(repo[external].hex() + '\n')
564 571 f.write('%d\n' % int(collapse))
565 572 f.write('%d\n' % int(keep))
566 573 f.write('%d\n' % int(keepbranches))
567 574 f.write('%s\n' % (activebookmark or ''))
568 575 for d, v in state.iteritems():
569 576 oldrev = repo[d].hex()
570 577 if v > nullmerge:
571 578 newrev = repo[v].hex()
572 579 else:
573 580 newrev = v
574 581 f.write("%s:%s\n" % (oldrev, newrev))
575 582 f.close()
576 583 repo.ui.debug('rebase status stored\n')
577 584
578 585 def clearstatus(repo):
579 586 'Remove the status files'
580 587 util.unlinkpath(repo.join("rebasestate"), ignoremissing=True)
581 588
582 589 def restorestatus(repo):
583 590 'Restore a previously stored status'
584 591 try:
585 592 target = None
586 593 collapse = False
587 594 external = nullrev
588 595 activebookmark = None
589 596 state = {}
590 597 f = repo.opener("rebasestate")
591 598 for i, l in enumerate(f.read().splitlines()):
592 599 if i == 0:
593 600 originalwd = repo[l].rev()
594 601 elif i == 1:
595 602 target = repo[l].rev()
596 603 elif i == 2:
597 604 external = repo[l].rev()
598 605 elif i == 3:
599 606 collapse = bool(int(l))
600 607 elif i == 4:
601 608 keep = bool(int(l))
602 609 elif i == 5:
603 610 keepbranches = bool(int(l))
604 611 elif i == 6 and not (len(l) == 81 and ':' in l):
605 612 # line 6 is a recent addition, so for backwards compatibility
606 613 # check that the line doesn't look like the oldrev:newrev lines
607 614 activebookmark = l
608 615 else:
609 616 oldrev, newrev = l.split(':')
610 617 if newrev in (str(nullmerge), str(revignored)):
611 618 state[repo[oldrev].rev()] = int(newrev)
612 619 else:
613 620 state[repo[oldrev].rev()] = repo[newrev].rev()
614 621 skipped = set()
615 622 # recompute the set of skipped revs
616 623 if not collapse:
617 624 seen = set([target])
618 625 for old, new in sorted(state.items()):
619 626 if new != nullrev and new in seen:
620 627 skipped.add(old)
621 628 seen.add(new)
622 629 repo.ui.debug('computed skipped revs: %s\n' % skipped)
623 630 repo.ui.debug('rebase status resumed\n')
624 631 return (originalwd, target, state, skipped,
625 632 collapse, keep, keepbranches, external, activebookmark)
626 633 except IOError, err:
627 634 if err.errno != errno.ENOENT:
628 635 raise
629 636 raise util.Abort(_('no rebase in progress'))
630 637
631 638 def inrebase(repo, originalwd, state):
632 639 '''check whether the workdir is in an interrupted rebase'''
633 640 parents = [p.rev() for p in repo.parents()]
634 641 if originalwd in parents:
635 642 return True
636 643
637 644 for newrev in state.itervalues():
638 645 if newrev in parents:
639 646 return True
640 647
641 648 return False
642 649
643 650 def abort(repo, originalwd, target, state):
644 651 'Restore the repository to its original state'
645 652 dstates = [s for s in state.values() if s != nullrev]
646 653 immutable = [d for d in dstates if not repo[d].mutable()]
647 654 cleanup = True
648 655 if immutable:
649 656 repo.ui.warn(_("warning: can't clean up immutable changesets %s\n")
650 657 % ', '.join(str(repo[r]) for r in immutable),
651 658 hint=_('see hg help phases for details'))
652 659 cleanup = False
653 660
654 661 descendants = set()
655 662 if dstates:
656 663 descendants = set(repo.changelog.descendants(dstates))
657 664 if descendants - set(dstates):
658 665 repo.ui.warn(_("warning: new changesets detected on target branch, "
659 666 "can't strip\n"))
660 667 cleanup = False
661 668
662 669 if cleanup:
663 670 # Update away from the rebase if necessary
664 671 if inrebase(repo, originalwd, state):
665 672 merge.update(repo, repo[originalwd].rev(), False, True, False)
666 673
667 674 # Strip from the first rebased revision
668 675 rebased = filter(lambda x: x > -1 and x != target, state.values())
669 676 if rebased:
670 677 strippoints = [c.node() for c in repo.set('roots(%ld)', rebased)]
671 678 # no backup of rebased cset versions needed
672 679 repair.strip(repo.ui, repo, strippoints)
673 680
674 681 clearstatus(repo)
675 682 repo.ui.warn(_('rebase aborted\n'))
676 683 return 0
677 684
678 685 def buildstate(repo, dest, rebaseset, collapse):
679 686 '''Define which revisions are going to be rebased and where
680 687
681 688 repo: repo
682 689 dest: context
683 690 rebaseset: set of rev
684 691 '''
685 692
686 693 # This check isn't strictly necessary, since mq detects commits over an
687 694 # applied patch. But it prevents messing up the working directory when
688 695 # a partially completed rebase is blocked by mq.
689 696 if 'qtip' in repo.tags() and (dest.node() in
690 697 [s.node for s in repo.mq.applied]):
691 698 raise util.Abort(_('cannot rebase onto an applied mq patch'))
692 699
693 700 roots = list(repo.set('roots(%ld)', rebaseset))
694 701 if not roots:
695 702 raise util.Abort(_('no matching revisions'))
696 703 roots.sort()
697 704 state = {}
698 705 detachset = set()
699 706 for root in roots:
700 707 commonbase = root.ancestor(dest)
701 708 if commonbase == root:
702 709 raise util.Abort(_('source is ancestor of destination'))
703 710 if commonbase == dest:
704 711 samebranch = root.branch() == dest.branch()
705 712 if not collapse and samebranch and root in dest.children():
706 713 repo.ui.debug('source is a child of destination\n')
707 714 return None
708 715
709 716 repo.ui.debug('rebase onto %d starting from %s\n' % (dest, roots))
710 717 state.update(dict.fromkeys(rebaseset, nullrev))
711 718 # Rebase tries to turn <dest> into a parent of <root> while
712 719 # preserving the number of parents of rebased changesets:
713 720 #
714 721 # - A changeset with a single parent will always be rebased as a
715 722 # changeset with a single parent.
716 723 #
717 724 # - A merge will be rebased as merge unless its parents are both
718 725 # ancestors of <dest> or are themselves in the rebased set and
719 726 # pruned while rebased.
720 727 #
721 728 # If one parent of <root> is an ancestor of <dest>, the rebased
722 729 # version of this parent will be <dest>. This is always true with
723 730 # --base option.
724 731 #
725 732 # Otherwise, we need to *replace* the original parents with
726 733 # <dest>. This "detaches" the rebased set from its former location
727 734 # and rebases it onto <dest>. Changes introduced by ancestors of
728 735 # <root> not common with <dest> (the detachset, marked as
729 736 # nullmerge) are "removed" from the rebased changesets.
730 737 #
731 738 # - If <root> has a single parent, set it to <dest>.
732 739 #
733 740 # - If <root> is a merge, we cannot decide which parent to
734 741 # replace, the rebase operation is not clearly defined.
735 742 #
736 743 # The table below sums up this behavior:
737 744 #
738 745 # +------------------+----------------------+-------------------------+
739 746 # | | one parent | merge |
740 747 # +------------------+----------------------+-------------------------+
741 748 # | parent in | new parent is <dest> | parents in ::<dest> are |
742 749 # | ::<dest> | | remapped to <dest> |
743 750 # +------------------+----------------------+-------------------------+
744 751 # | unrelated source | new parent is <dest> | ambiguous, abort |
745 752 # +------------------+----------------------+-------------------------+
746 753 #
747 754 # The actual abort is handled by `defineparents`
748 755 if len(root.parents()) <= 1:
749 756 # ancestors of <root> not ancestors of <dest>
750 757 detachset.update(repo.changelog.findmissingrevs([commonbase.rev()],
751 758 [root.rev()]))
752 759 for r in detachset:
753 760 if r not in state:
754 761 state[r] = nullmerge
755 762 if len(roots) > 1:
756 763 # If we have multiple roots, we may have "hole" in the rebase set.
757 764 # Rebase roots that descend from those "hole" should not be detached as
758 765 # other root are. We use the special `revignored` to inform rebase that
759 766 # the revision should be ignored but that `defineparents` should search
760 767 # a rebase destination that make sense regarding rebased topology.
761 768 rebasedomain = set(repo.revs('%ld::%ld', rebaseset, rebaseset))
762 769 for ignored in set(rebasedomain) - set(rebaseset):
763 770 state[ignored] = revignored
764 771 return repo['.'].rev(), dest.rev(), state
765 772
766 773 def clearrebased(ui, repo, state, skipped, collapsedas=None):
767 774 """dispose of rebased revision at the end of the rebase
768 775
769 776 If `collapsedas` is not None, the rebase was a collapse whose result if the
770 777 `collapsedas` node."""
771 778 if obsolete._enabled:
772 779 markers = []
773 780 for rev, newrev in sorted(state.items()):
774 781 if newrev >= 0:
775 782 if rev in skipped:
776 783 succs = ()
777 784 elif collapsedas is not None:
778 785 succs = (repo[collapsedas],)
779 786 else:
780 787 succs = (repo[newrev],)
781 788 markers.append((repo[rev], succs))
782 789 if markers:
783 790 obsolete.createmarkers(repo, markers)
784 791 else:
785 792 rebased = [rev for rev in state if state[rev] > nullmerge]
786 793 if rebased:
787 794 stripped = []
788 795 for root in repo.set('roots(%ld)', rebased):
789 796 if set(repo.changelog.descendants([root.rev()])) - set(state):
790 797 ui.warn(_("warning: new changesets detected "
791 798 "on source branch, not stripping\n"))
792 799 else:
793 800 stripped.append(root.node())
794 801 if stripped:
795 802 # backup the old csets by default
796 803 repair.strip(ui, repo, stripped, "all")
797 804
798 805
799 806 def pullrebase(orig, ui, repo, *args, **opts):
800 807 'Call rebase after pull if the latter has been invoked with --rebase'
801 808 if opts.get('rebase'):
802 809 if opts.get('update'):
803 810 del opts['update']
804 811 ui.debug('--update and --rebase are not compatible, ignoring '
805 812 'the update flag\n')
806 813
807 814 movemarkfrom = repo['.'].node()
808 815 revsprepull = len(repo)
809 816 origpostincoming = commands.postincoming
810 817 def _dummy(*args, **kwargs):
811 818 pass
812 819 commands.postincoming = _dummy
813 820 try:
814 821 orig(ui, repo, *args, **opts)
815 822 finally:
816 823 commands.postincoming = origpostincoming
817 824 revspostpull = len(repo)
818 825 if revspostpull > revsprepull:
819 826 # --rev option from pull conflict with rebase own --rev
820 827 # dropping it
821 828 if 'rev' in opts:
822 829 del opts['rev']
823 830 rebase(ui, repo, **opts)
824 831 branch = repo[None].branch()
825 832 dest = repo[branch].rev()
826 833 if dest != repo['.'].rev():
827 834 # there was nothing to rebase we force an update
828 835 hg.update(repo, dest)
829 836 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
830 837 ui.status(_("updating bookmark %s\n")
831 838 % repo._bookmarkcurrent)
832 839 else:
833 840 if opts.get('tool'):
834 841 raise util.Abort(_('--tool can only be used with --rebase'))
835 842 orig(ui, repo, *args, **opts)
836 843
837 844 def summaryhook(ui, repo):
838 845 if not os.path.exists(repo.join('rebasestate')):
839 846 return
840 847 try:
841 848 state = restorestatus(repo)[2]
842 849 except error.RepoLookupError:
843 850 # i18n: column positioning for "hg summary"
844 851 msg = _('rebase: (use "hg rebase --abort" to clear broken state)\n')
845 852 ui.write(msg)
846 853 return
847 854 numrebased = len([i for i in state.itervalues() if i != -1])
848 855 # i18n: column positioning for "hg summary"
849 856 ui.write(_('rebase: %s, %s (rebase --continue)\n') %
850 857 (ui.label(_('%d rebased'), 'rebase.rebased') % numrebased,
851 858 ui.label(_('%d remaining'), 'rebase.remaining') %
852 859 (len(state) - numrebased)))
853 860
854 861 def uisetup(ui):
855 862 'Replace pull with a decorator to provide --rebase option'
856 863 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
857 864 entry[1].append(('', 'rebase', None,
858 865 _("rebase working directory to branch head")))
859 866 entry[1].append(('t', 'tool', '',
860 867 _("specify merge tool for rebase")))
861 868 cmdutil.summaryhooks.add('rebase', summaryhook)
862 869 cmdutil.unfinishedstates.append(
863 870 ['rebasestate', False, False, _('rebase in progress'),
864 871 _("use 'hg rebase --continue' or 'hg rebase --abort'")])
@@ -1,176 +1,176 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
11 11 > EOF
12 12
13 13 Create a repo with several bookmarks
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 $ hg book 'X'
25 25 $ hg book 'Y'
26 26
27 27 $ echo c > c
28 28 $ hg ci -Am C
29 29 adding c
30 30 $ hg book 'Z'
31 31
32 32 $ hg up -q 0
33 33
34 34 $ echo d > d
35 35 $ hg ci -Am D
36 36 adding d
37 37 created new head
38 38
39 39 $ hg book W
40 40
41 41 $ hg tglog
42 42 @ 3: 'D' bookmarks: W
43 43 |
44 44 | o 2: 'C' bookmarks: Y Z
45 45 | |
46 46 | o 1: 'B' bookmarks: X
47 47 |/
48 48 o 0: 'A' bookmarks:
49 49
50 50
51 51 Move only rebased bookmarks
52 52
53 53 $ cd ..
54 54 $ hg clone -q a a1
55 55
56 56 $ cd a1
57 57 $ hg up -q Z
58 58
59 59 Test deleting divergent bookmarks from dest (issue3685)
60 60
61 61 $ hg book -r 3 Z@diverge
62 62
63 63 ... and also test that bookmarks not on dest or not being moved aren't deleted
64 64
65 65 $ hg book -r 3 X@diverge
66 66 $ hg book -r 0 Y@diverge
67 67
68 68 $ hg tglog
69 69 o 3: 'D' bookmarks: W X@diverge Z@diverge
70 70 |
71 71 | @ 2: 'C' bookmarks: Y Z
72 72 | |
73 73 | o 1: 'B' bookmarks: X
74 74 |/
75 75 o 0: 'A' bookmarks: Y@diverge
76 76
77 77 $ hg rebase -s Y -d 3
78 78 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
79 79
80 80 $ hg tglog
81 81 @ 3: 'C' bookmarks: Y Z
82 82 |
83 83 o 2: 'D' bookmarks: W X@diverge
84 84 |
85 85 | o 1: 'B' bookmarks: X
86 86 |/
87 87 o 0: 'A' bookmarks: Y@diverge
88 88
89 89 Keep bookmarks to the correct rebased changeset
90 90
91 91 $ cd ..
92 92 $ hg clone -q a a2
93 93
94 94 $ cd a2
95 95 $ hg up -q Z
96 96
97 97 $ hg rebase -s 1 -d 3
98 98 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
99 99
100 100 $ hg tglog
101 101 @ 3: 'C' bookmarks: Y Z
102 102 |
103 103 o 2: 'B' bookmarks: X
104 104 |
105 105 o 1: 'D' bookmarks: W
106 106 |
107 107 o 0: 'A' bookmarks:
108 108
109 109
110 110 Keep active bookmark on the correct changeset
111 111
112 112 $ cd ..
113 113 $ hg clone -q a a3
114 114
115 115 $ cd a3
116 116 $ hg up -q X
117 117
118 118 $ hg rebase -d W
119 119 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
120 120
121 121 $ hg tglog
122 @ 3: 'C' bookmarks: Y Z
122 o 3: 'C' bookmarks: Y Z
123 123 |
124 o 2: 'B' bookmarks: X
124 @ 2: 'B' bookmarks: X
125 125 |
126 126 o 1: 'D' bookmarks: W
127 127 |
128 128 o 0: 'A' bookmarks:
129 129
130 130 rebase --continue with bookmarks present (issue3802)
131 131
132 132 $ hg up 2
133 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
134 134 $ echo 'C' > c
135 135 $ hg add c
136 136 $ hg ci -m 'other C'
137 137 created new head
138 138 $ hg up 3
139 139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 140 $ hg rebase
141 141 merging c
142 142 warning: conflicts during merge.
143 143 merging c incomplete! (edit conflicts, then use 'hg resolve --mark')
144 144 unresolved conflicts (see hg resolve, then hg rebase --continue)
145 145 [1]
146 146 $ echo 'c' > c
147 147 $ hg resolve --mark c
148 148 $ hg rebase --continue
149 149 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/3d5fa227f4b5-backup.hg (glob)
150 150 $ hg tglog
151 151 @ 4: 'C' bookmarks: Y Z
152 152 |
153 153 o 3: 'other C' bookmarks:
154 154 |
155 155 o 2: 'B' bookmarks: X
156 156 |
157 157 o 1: 'D' bookmarks: W
158 158 |
159 159 o 0: 'A' bookmarks:
160 160
161 161
162 162 ensure that bookmarks given the names of revset functions can be used
163 163 as --rev arguments (issue3950)
164 164
165 165 $ hg update -q 3
166 166 $ echo bimble > bimble
167 167 $ hg add bimble
168 168 $ hg commit -q -m 'bisect'
169 169 $ echo e >> bimble
170 170 $ hg ci -m bisect2
171 171 $ echo e >> bimble
172 172 $ hg ci -m bisect3
173 173 $ hg book bisect
174 174 $ hg update -q Y
175 175 $ hg rebase -r '"bisect"^^::"bisect"^' -r bisect -d Z
176 176 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/345c90f326a4-backup.hg (glob)
@@ -1,475 +1,475 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 > mq=
6 6 >
7 7 > [phases]
8 8 > publish=False
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
12 12 > theads = heads --template "{rev}: '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 $ hg init a
16 16 $ cd a
17 17
18 18 $ echo a > a
19 19 $ hg ci -Am A
20 20 adding a
21 21
22 22 $ hg branch branch1
23 23 marked working directory as branch branch1
24 24 (branches are permanent and global, did you want a bookmark?)
25 25 $ hg ci -m 'branch1'
26 26
27 27 $ echo b > b
28 28 $ hg ci -Am B
29 29 adding b
30 30
31 31 $ hg up -q 0
32 32
33 33 $ hg branch branch2
34 34 marked working directory as branch branch2
35 35 (branches are permanent and global, did you want a bookmark?)
36 36 $ hg ci -m 'branch2'
37 37
38 38 $ echo c > C
39 39 $ hg ci -Am C
40 40 adding C
41 41
42 42 $ hg up -q 2
43 43
44 44 $ hg branch -f branch2
45 45 marked working directory as branch branch2
46 46 (branches are permanent and global, did you want a bookmark?)
47 47 $ echo d > d
48 48 $ hg ci -Am D
49 49 adding d
50 50 created new head
51 51
52 52 $ echo e > e
53 53 $ hg ci -Am E
54 54 adding e
55 55
56 56 $ hg update default
57 57 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
58 58
59 59 $ hg branch branch3
60 60 marked working directory as branch branch3
61 61 (branches are permanent and global, did you want a bookmark?)
62 62 $ hg ci -m 'branch3'
63 63
64 64 $ echo f > f
65 65 $ hg ci -Am F
66 66 adding f
67 67
68 68 $ cd ..
69 69
70 70
71 71 Rebase part of branch2 (5-6) onto branch3 (8):
72 72
73 73 $ hg clone -q -u . a a1
74 74 $ cd a1
75 75
76 76 $ hg tglog
77 77 @ 8: 'F' branch3
78 78 |
79 79 o 7: 'branch3' branch3
80 80 |
81 81 | o 6: 'E' branch2
82 82 | |
83 83 | o 5: 'D' branch2
84 84 | |
85 85 | | o 4: 'C' branch2
86 86 | | |
87 87 +---o 3: 'branch2' branch2
88 88 | |
89 89 | o 2: 'B' branch1
90 90 | |
91 91 | o 1: 'branch1' branch1
92 92 |/
93 93 o 0: 'A'
94 94
95 95 $ hg branches
96 96 branch3 8:4666b71e8e32
97 97 branch2 6:5097051d331d
98 98 branch1 2:0a03079c47fd (inactive)
99 99 default 0:1994f17a630e (inactive)
100 100
101 101 $ hg theads
102 102 8: 'F' branch3
103 103 6: 'E' branch2
104 104 4: 'C' branch2
105 105 2: 'B' branch1
106 106 0: 'A'
107 107
108 108 $ hg rebase -s 5 -d 8
109 109 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
110 110
111 111 $ hg branches
112 112 branch3 8:466cdfb14b62
113 113 branch2 4:e4fdb121d036
114 114 branch1 2:0a03079c47fd
115 115 default 0:1994f17a630e (inactive)
116 116
117 117 $ hg theads
118 118 8: 'E' branch3
119 119 4: 'C' branch2
120 120 2: 'B' branch1
121 121 0: 'A'
122 122
123 123 $ hg tglog
124 @ 8: 'E' branch3
124 o 8: 'E' branch3
125 125 |
126 126 o 7: 'D' branch3
127 127 |
128 o 6: 'F' branch3
128 @ 6: 'F' branch3
129 129 |
130 130 o 5: 'branch3' branch3
131 131 |
132 132 | o 4: 'C' branch2
133 133 | |
134 134 | o 3: 'branch2' branch2
135 135 |/
136 136 | o 2: 'B' branch1
137 137 | |
138 138 | o 1: 'branch1' branch1
139 139 |/
140 140 o 0: 'A'
141 141
142 142 $ cd ..
143 143
144 144
145 145 Rebase head of branch3 (8) onto branch2 (6):
146 146
147 147 $ hg clone -q -u . a a2
148 148 $ cd a2
149 149
150 150 $ hg tglog
151 151 @ 8: 'F' branch3
152 152 |
153 153 o 7: 'branch3' branch3
154 154 |
155 155 | o 6: 'E' branch2
156 156 | |
157 157 | o 5: 'D' branch2
158 158 | |
159 159 | | o 4: 'C' branch2
160 160 | | |
161 161 +---o 3: 'branch2' branch2
162 162 | |
163 163 | o 2: 'B' branch1
164 164 | |
165 165 | o 1: 'branch1' branch1
166 166 |/
167 167 o 0: 'A'
168 168
169 169 $ hg rebase -s 8 -d 6
170 170 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
171 171
172 172 $ hg branches
173 173 branch2 8:6b4bdc1b5ac0
174 174 branch3 7:653b9feb4616
175 175 branch1 2:0a03079c47fd (inactive)
176 176 default 0:1994f17a630e (inactive)
177 177
178 178 $ hg theads
179 179 8: 'F' branch2
180 180 7: 'branch3' branch3
181 181 4: 'C' branch2
182 182 2: 'B' branch1
183 183 0: 'A'
184 184
185 185 $ hg tglog
186 186 @ 8: 'F' branch2
187 187 |
188 188 | o 7: 'branch3' branch3
189 189 | |
190 190 o | 6: 'E' branch2
191 191 | |
192 192 o | 5: 'D' branch2
193 193 | |
194 194 | | o 4: 'C' branch2
195 195 | | |
196 196 | | o 3: 'branch2' branch2
197 197 | |/
198 198 o | 2: 'B' branch1
199 199 | |
200 200 o | 1: 'branch1' branch1
201 201 |/
202 202 o 0: 'A'
203 203
204 204 $ hg verify -q
205 205
206 206 $ cd ..
207 207
208 208
209 209 Rebase entire branch3 (7-8) onto branch2 (6):
210 210
211 211 $ hg clone -q -u . a a3
212 212 $ cd a3
213 213
214 214 $ hg tglog
215 215 @ 8: 'F' branch3
216 216 |
217 217 o 7: 'branch3' branch3
218 218 |
219 219 | o 6: 'E' branch2
220 220 | |
221 221 | o 5: 'D' branch2
222 222 | |
223 223 | | o 4: 'C' branch2
224 224 | | |
225 225 +---o 3: 'branch2' branch2
226 226 | |
227 227 | o 2: 'B' branch1
228 228 | |
229 229 | o 1: 'branch1' branch1
230 230 |/
231 231 o 0: 'A'
232 232
233 233 $ hg rebase -s 7 -d 6
234 234 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
235 235
236 236 $ hg branches
237 237 branch2 7:6b4bdc1b5ac0
238 238 branch1 2:0a03079c47fd (inactive)
239 239 default 0:1994f17a630e (inactive)
240 240
241 241 $ hg theads
242 242 7: 'F' branch2
243 243 4: 'C' branch2
244 244 2: 'B' branch1
245 245 0: 'A'
246 246
247 247 $ hg tglog
248 248 @ 7: 'F' branch2
249 249 |
250 250 o 6: 'E' branch2
251 251 |
252 252 o 5: 'D' branch2
253 253 |
254 254 | o 4: 'C' branch2
255 255 | |
256 256 | o 3: 'branch2' branch2
257 257 | |
258 258 o | 2: 'B' branch1
259 259 | |
260 260 o | 1: 'branch1' branch1
261 261 |/
262 262 o 0: 'A'
263 263
264 264 $ hg verify -q
265 265
266 266 Stripping multiple branches in one go bypasses the fast-case code to
267 267 update the branch cache.
268 268
269 269 $ hg strip 2
270 270 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
271 271 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
272 272
273 273 $ hg tglog
274 274 o 3: 'C' branch2
275 275 |
276 276 o 2: 'branch2' branch2
277 277 |
278 278 | @ 1: 'branch1' branch1
279 279 |/
280 280 o 0: 'A'
281 281
282 282
283 283 $ hg branches
284 284 branch2 3:e4fdb121d036
285 285 branch1 1:63379ac49655
286 286 default 0:1994f17a630e (inactive)
287 287
288 288 $ hg theads
289 289 3: 'C' branch2
290 290 1: 'branch1' branch1
291 291 0: 'A'
292 292
293 293 Fast path branchcache code should not be invoked if branches stripped is not
294 294 the same as branches remaining.
295 295
296 296 $ hg init b
297 297 $ cd b
298 298
299 299 $ hg branch branch1
300 300 marked working directory as branch branch1
301 301 (branches are permanent and global, did you want a bookmark?)
302 302 $ hg ci -m 'branch1'
303 303
304 304 $ hg branch branch2
305 305 marked working directory as branch branch2
306 306 (branches are permanent and global, did you want a bookmark?)
307 307 $ hg ci -m 'branch2'
308 308
309 309 $ hg branch -f branch1
310 310 marked working directory as branch branch1
311 311 (branches are permanent and global, did you want a bookmark?)
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/*-backup.hg (glob)
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/*-backup.hg (glob)
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/*-backup.hg (glob)
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 $ hg rebase --dest 7 --source 5
475 475 saved backup bundle to $TESTTMP/a3/c4/.hg/strip-backup/*-backup.hg (glob)
@@ -1,150 +1,150 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}:{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 add A
19 19 $ hg ci -m A
20 20
21 21 $ echo 'B' > B
22 22 $ hg add B
23 23 $ hg ci -m 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 add E
36 36 $ hg ci -m E
37 37
38 38 $ hg up -q -C 0
39 39
40 40 $ hg branch 'notdefault'
41 41 marked working directory as branch notdefault
42 42 (branches are permanent and global, did you want a bookmark?)
43 43 $ echo F >> A
44 44 $ hg ci -m F
45 45
46 46 $ cd ..
47 47
48 48
49 49 Rebasing B onto E - check keep: and phases
50 50
51 51 $ hg clone -q -u . a a1
52 52 $ cd a1
53 53 $ hg phase --force --secret 2
54 54
55 55 $ hg tglog
56 56 @ 5:draft 'F' notdefault
57 57 |
58 58 | o 4:draft 'E'
59 59 | |
60 60 | o 3:draft 'D'
61 61 |/
62 62 | o 2:secret 'C'
63 63 | |
64 64 | o 1:draft 'B'
65 65 |/
66 66 o 0:draft 'A'
67 67
68 68 $ hg rebase -s 1 -d 4 --keep
69 69 merging A
70 70 warning: conflicts during merge.
71 71 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
72 72 unresolved conflicts (see hg resolve, then hg rebase --continue)
73 73 [1]
74 74
75 75 Solve the conflict and go on:
76 76
77 77 $ echo 'conflict solved' > A
78 78 $ rm A.orig
79 79 $ hg resolve -m A
80 80 $ hg rebase --continue
81 81
82 82 $ hg tglog
83 @ 7:secret 'C'
83 o 7:secret 'C'
84 84 |
85 85 o 6:draft 'B'
86 86 |
87 | o 5:draft 'F' notdefault
87 | @ 5:draft 'F' notdefault
88 88 | |
89 89 o | 4:draft 'E'
90 90 | |
91 91 o | 3:draft 'D'
92 92 |/
93 93 | o 2:secret 'C'
94 94 | |
95 95 | o 1:draft 'B'
96 96 |/
97 97 o 0:draft 'A'
98 98
99 99 $ cd ..
100 100
101 101
102 102 Rebase F onto E - check keepbranches:
103 103
104 104 $ hg clone -q -u . a a2
105 105 $ cd a2
106 106 $ hg phase --force --secret 2
107 107
108 108 $ hg tglog
109 109 @ 5:draft 'F' notdefault
110 110 |
111 111 | o 4:draft 'E'
112 112 | |
113 113 | o 3:draft 'D'
114 114 |/
115 115 | o 2:secret 'C'
116 116 | |
117 117 | o 1:draft 'B'
118 118 |/
119 119 o 0:draft 'A'
120 120
121 121 $ hg rebase -s 5 -d 4 --keepbranches
122 122 merging A
123 123 warning: conflicts during merge.
124 124 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
125 125 unresolved conflicts (see hg resolve, then hg rebase --continue)
126 126 [1]
127 127
128 128 Solve the conflict and go on:
129 129
130 130 $ echo 'conflict solved' > A
131 131 $ rm A.orig
132 132 $ hg resolve -m A
133 133 $ hg rebase --continue
134 134 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
135 135
136 136 $ hg tglog
137 137 @ 5:draft 'F' notdefault
138 138 |
139 139 o 4:draft 'E'
140 140 |
141 141 o 3:draft 'D'
142 142 |
143 143 | o 2:secret 'C'
144 144 | |
145 145 | o 1:draft 'B'
146 146 |/
147 147 o 0:draft 'A'
148 148
149 149
150 150 $ cd ..
@@ -1,751 +1,751 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 > mq=
6 6 >
7 7 > [phases]
8 8 > publish=False
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
12 12 > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 Create repo a:
16 16
17 17 $ hg init a
18 18 $ cd a
19 19 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
20 20 adding changesets
21 21 adding manifests
22 22 adding file changes
23 23 added 8 changesets with 7 changes to 7 files (+2 heads)
24 24 (run 'hg heads' to see heads, 'hg merge' to merge)
25 25 $ hg up tip
26 26 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 27
28 28 $ hg tglog
29 29 @ 7: 'H'
30 30 |
31 31 | o 6: 'G'
32 32 |/|
33 33 o | 5: 'F'
34 34 | |
35 35 | o 4: 'E'
36 36 |/
37 37 | o 3: 'D'
38 38 | |
39 39 | o 2: 'C'
40 40 | |
41 41 | o 1: 'B'
42 42 |/
43 43 o 0: 'A'
44 44
45 45 $ cd ..
46 46
47 47
48 48 Rebasing B onto H and collapsing changesets with different phases:
49 49
50 50
51 51 $ hg clone -q -u 3 a a1
52 52 $ cd a1
53 53
54 54 $ hg phase --force --secret 3
55 55
56 56 $ hg rebase --collapse --keepbranches
57 57 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
58 58
59 59 $ hg tglogp
60 @ 5:secret 'Collapsed revision
60 o 5:secret 'Collapsed revision
61 61 | * B
62 62 | * C
63 63 | * D'
64 o 4:draft 'H'
64 @ 4:draft 'H'
65 65 |
66 66 | o 3:draft 'G'
67 67 |/|
68 68 o | 2:draft 'F'
69 69 | |
70 70 | o 1:draft 'E'
71 71 |/
72 72 o 0:draft 'A'
73 73
74 74 $ hg manifest --rev tip
75 75 A
76 76 B
77 77 C
78 78 D
79 79 F
80 80 H
81 81
82 82 $ cd ..
83 83
84 84
85 85 Rebasing E onto H:
86 86
87 87 $ hg clone -q -u . a a2
88 88 $ cd a2
89 89
90 90 $ hg phase --force --secret 6
91 91 $ hg rebase --source 4 --collapse
92 92 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
93 93
94 94 $ hg tglog
95 @ 6: 'Collapsed revision
95 o 6: 'Collapsed revision
96 96 | * E
97 97 | * G'
98 o 5: 'H'
98 @ 5: 'H'
99 99 |
100 100 o 4: 'F'
101 101 |
102 102 | o 3: 'D'
103 103 | |
104 104 | o 2: 'C'
105 105 | |
106 106 | o 1: 'B'
107 107 |/
108 108 o 0: 'A'
109 109
110 110 $ hg manifest --rev tip
111 111 A
112 112 E
113 113 F
114 114 H
115 115
116 116 $ cd ..
117 117
118 118 Rebasing G onto H with custom message:
119 119
120 120 $ hg clone -q -u . a a3
121 121 $ cd a3
122 122
123 123 $ hg rebase --base 6 -m 'custom message'
124 124 abort: message can only be specified with collapse
125 125 [255]
126 126
127 127 $ hg rebase --source 4 --collapse -m 'custom message'
128 128 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
129 129
130 130 $ hg tglog
131 @ 6: 'custom message'
131 o 6: 'custom message'
132 132 |
133 o 5: 'H'
133 @ 5: 'H'
134 134 |
135 135 o 4: 'F'
136 136 |
137 137 | o 3: 'D'
138 138 | |
139 139 | o 2: 'C'
140 140 | |
141 141 | o 1: 'B'
142 142 |/
143 143 o 0: 'A'
144 144
145 145 $ hg manifest --rev tip
146 146 A
147 147 E
148 148 F
149 149 H
150 150
151 151 $ cd ..
152 152
153 153 Create repo b:
154 154
155 155 $ hg init b
156 156 $ cd b
157 157
158 158 $ echo A > A
159 159 $ hg ci -Am A
160 160 adding A
161 161 $ echo B > B
162 162 $ hg ci -Am B
163 163 adding B
164 164
165 165 $ hg up -q 0
166 166
167 167 $ echo C > C
168 168 $ hg ci -Am C
169 169 adding C
170 170 created new head
171 171
172 172 $ hg merge
173 173 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 174 (branch merge, don't forget to commit)
175 175
176 176 $ echo D > D
177 177 $ hg ci -Am D
178 178 adding D
179 179
180 180 $ hg up -q 1
181 181
182 182 $ echo E > E
183 183 $ hg ci -Am E
184 184 adding E
185 185 created new head
186 186
187 187 $ echo F > F
188 188 $ hg ci -Am F
189 189 adding F
190 190
191 191 $ hg merge
192 192 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 (branch merge, don't forget to commit)
194 194 $ hg ci -m G
195 195
196 196 $ hg up -q 0
197 197
198 198 $ echo H > H
199 199 $ hg ci -Am H
200 200 adding H
201 201 created new head
202 202
203 203 $ hg tglog
204 204 @ 7: 'H'
205 205 |
206 206 | o 6: 'G'
207 207 | |\
208 208 | | o 5: 'F'
209 209 | | |
210 210 | | o 4: 'E'
211 211 | | |
212 212 | o | 3: 'D'
213 213 | |\|
214 214 | o | 2: 'C'
215 215 |/ /
216 216 | o 1: 'B'
217 217 |/
218 218 o 0: 'A'
219 219
220 220 $ cd ..
221 221
222 222
223 223 Rebase and collapse - more than one external (fail):
224 224
225 225 $ hg clone -q -u . b b1
226 226 $ cd b1
227 227
228 228 $ hg rebase -s 2 --collapse
229 229 abort: unable to collapse, there is more than one external parent
230 230 [255]
231 231
232 232 Rebase and collapse - E onto H:
233 233
234 234 $ hg rebase -s 4 --collapse # root (4) is not a merge
235 235 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
236 236
237 237 $ hg tglog
238 @ 5: 'Collapsed revision
238 o 5: 'Collapsed revision
239 239 |\ * E
240 240 | | * F
241 241 | | * G'
242 | o 4: 'H'
242 | @ 4: 'H'
243 243 | |
244 244 o | 3: 'D'
245 245 |\ \
246 246 | o | 2: 'C'
247 247 | |/
248 248 o / 1: 'B'
249 249 |/
250 250 o 0: 'A'
251 251
252 252 $ hg manifest --rev tip
253 253 A
254 254 C
255 255 D
256 256 E
257 257 F
258 258 H
259 259
260 260 $ cd ..
261 261
262 262
263 263
264 264
265 265 Test that branchheads cache is updated correctly when doing a strip in which
266 266 the parent of the ancestor node to be stripped does not become a head and also,
267 267 the parent of a node that is a child of the node stripped becomes a head (node
268 268 3). The code is now much simpler and we could just test a simpler scenario
269 269 We keep it the test this way in case new complexity is injected.
270 270
271 271 $ hg clone -q -u . b b2
272 272 $ cd b2
273 273
274 274 $ hg heads --template="{rev}:{node} {branch}\n"
275 275 7:c65502d4178782309ce0574c5ae6ee9485a9bafa default
276 276 6:c772a8b2dc17629cec88a19d09c926c4814b12c7 default
277 277
278 278 $ cat $TESTTMP/b2/.hg/cache/branchheads-served
279 279 c65502d4178782309ce0574c5ae6ee9485a9bafa 7
280 280 c772a8b2dc17629cec88a19d09c926c4814b12c7 default
281 281 c65502d4178782309ce0574c5ae6ee9485a9bafa default
282 282
283 283 $ hg strip 4
284 284 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/8a5212ebc852-backup.hg (glob)
285 285
286 286 $ cat $TESTTMP/b2/.hg/cache/branchheads-served
287 287 c65502d4178782309ce0574c5ae6ee9485a9bafa 4
288 288 2870ad076e541e714f3c2bc32826b5c6a6e5b040 default
289 289 c65502d4178782309ce0574c5ae6ee9485a9bafa default
290 290
291 291 $ hg heads --template="{rev}:{node} {branch}\n"
292 292 4:c65502d4178782309ce0574c5ae6ee9485a9bafa default
293 293 3:2870ad076e541e714f3c2bc32826b5c6a6e5b040 default
294 294
295 295 $ cd ..
296 296
297 297
298 298
299 299
300 300
301 301
302 302 Create repo c:
303 303
304 304 $ hg init c
305 305 $ cd c
306 306
307 307 $ echo A > A
308 308 $ hg ci -Am A
309 309 adding A
310 310 $ echo B > B
311 311 $ hg ci -Am B
312 312 adding B
313 313
314 314 $ hg up -q 0
315 315
316 316 $ echo C > C
317 317 $ hg ci -Am C
318 318 adding C
319 319 created new head
320 320
321 321 $ hg merge
322 322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 323 (branch merge, don't forget to commit)
324 324
325 325 $ echo D > D
326 326 $ hg ci -Am D
327 327 adding D
328 328
329 329 $ hg up -q 1
330 330
331 331 $ echo E > E
332 332 $ hg ci -Am E
333 333 adding E
334 334 created new head
335 335 $ echo F > E
336 336 $ hg ci -m 'F'
337 337
338 338 $ echo G > G
339 339 $ hg ci -Am G
340 340 adding G
341 341
342 342 $ hg merge
343 343 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
344 344 (branch merge, don't forget to commit)
345 345
346 346 $ hg ci -m H
347 347
348 348 $ hg up -q 0
349 349
350 350 $ echo I > I
351 351 $ hg ci -Am I
352 352 adding I
353 353 created new head
354 354
355 355 $ hg tglog
356 356 @ 8: 'I'
357 357 |
358 358 | o 7: 'H'
359 359 | |\
360 360 | | o 6: 'G'
361 361 | | |
362 362 | | o 5: 'F'
363 363 | | |
364 364 | | o 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 $ cd ..
375 375
376 376
377 377 Rebase and collapse - E onto I:
378 378
379 379 $ hg clone -q -u . c c1
380 380 $ cd c1
381 381
382 382 $ hg rebase -s 4 --collapse # root (4) is not a merge
383 383 merging E
384 384 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
385 385
386 386 $ hg tglog
387 @ 5: 'Collapsed revision
387 o 5: 'Collapsed revision
388 388 |\ * E
389 389 | | * F
390 390 | | * G
391 391 | | * H'
392 | o 4: 'I'
392 | @ 4: 'I'
393 393 | |
394 394 o | 3: 'D'
395 395 |\ \
396 396 | o | 2: 'C'
397 397 | |/
398 398 o / 1: 'B'
399 399 |/
400 400 o 0: 'A'
401 401
402 402 $ hg manifest --rev tip
403 403 A
404 404 C
405 405 D
406 406 E
407 407 G
408 408 I
409 409
410 410 $ hg up tip -q
411 411 $ cat E
412 412 F
413 413
414 414 $ cd ..
415 415
416 416
417 417 Create repo d:
418 418
419 419 $ hg init d
420 420 $ cd d
421 421
422 422 $ echo A > A
423 423 $ hg ci -Am A
424 424 adding A
425 425 $ echo B > B
426 426 $ hg ci -Am B
427 427 adding B
428 428 $ echo C > C
429 429 $ hg ci -Am C
430 430 adding C
431 431
432 432 $ hg up -q 1
433 433
434 434 $ echo D > D
435 435 $ hg ci -Am D
436 436 adding D
437 437 created new head
438 438 $ hg merge
439 439 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
440 440 (branch merge, don't forget to commit)
441 441
442 442 $ hg ci -m E
443 443
444 444 $ hg up -q 0
445 445
446 446 $ echo F > F
447 447 $ hg ci -Am F
448 448 adding F
449 449 created new head
450 450
451 451 $ hg tglog
452 452 @ 5: 'F'
453 453 |
454 454 | o 4: 'E'
455 455 | |\
456 456 | | o 3: 'D'
457 457 | | |
458 458 | o | 2: 'C'
459 459 | |/
460 460 | o 1: 'B'
461 461 |/
462 462 o 0: 'A'
463 463
464 464 $ cd ..
465 465
466 466
467 467 Rebase and collapse - B onto F:
468 468
469 469 $ hg clone -q -u . d d1
470 470 $ cd d1
471 471
472 472 $ hg rebase -s 1 --collapse
473 473 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
474 474
475 475 $ hg tglog
476 @ 2: 'Collapsed revision
476 o 2: 'Collapsed revision
477 477 | * B
478 478 | * C
479 479 | * D
480 480 | * E'
481 o 1: 'F'
481 @ 1: 'F'
482 482 |
483 483 o 0: 'A'
484 484
485 485 $ hg manifest --rev tip
486 486 A
487 487 B
488 488 C
489 489 D
490 490 F
491 491
492 492 Interactions between collapse and keepbranches
493 493 $ cd ..
494 494 $ hg init e
495 495 $ cd e
496 496 $ echo 'a' > a
497 497 $ hg ci -Am 'A'
498 498 adding a
499 499
500 500 $ hg branch 'one'
501 501 marked working directory as branch one
502 502 (branches are permanent and global, did you want a bookmark?)
503 503 $ echo 'b' > b
504 504 $ hg ci -Am 'B'
505 505 adding b
506 506
507 507 $ hg branch 'two'
508 508 marked working directory as branch two
509 509 (branches are permanent and global, did you want a bookmark?)
510 510 $ echo 'c' > c
511 511 $ hg ci -Am 'C'
512 512 adding c
513 513
514 514 $ hg up -q 0
515 515 $ echo 'd' > d
516 516 $ hg ci -Am 'D'
517 517 adding d
518 518
519 519 $ hg tglog
520 520 @ 3: 'D'
521 521 |
522 522 | o 2: 'C' two
523 523 | |
524 524 | o 1: 'B' one
525 525 |/
526 526 o 0: 'A'
527 527
528 528 $ hg rebase --keepbranches --collapse -s 1 -d 3
529 529 abort: cannot collapse multiple named branches
530 530 [255]
531 531
532 532 $ repeatchange() {
533 533 > hg checkout $1
534 534 > hg cp d z
535 535 > echo blah >> z
536 536 > hg commit -Am "$2" --user "$3"
537 537 > }
538 538 $ repeatchange 3 "E" "user1"
539 539 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
540 540 $ repeatchange 3 "E" "user2"
541 541 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
542 542 created new head
543 543 $ hg tglog
544 544 @ 5: 'E'
545 545 |
546 546 | o 4: 'E'
547 547 |/
548 548 o 3: 'D'
549 549 |
550 550 | o 2: 'C' two
551 551 | |
552 552 | o 1: 'B' one
553 553 |/
554 554 o 0: 'A'
555 555
556 556 $ hg rebase -s 5 -d 4
557 557 saved backup bundle to $TESTTMP/e/.hg/strip-backup/*-backup.hg (glob)
558 558 $ hg tglog
559 559 @ 4: 'E'
560 560 |
561 561 o 3: 'D'
562 562 |
563 563 | o 2: 'C' two
564 564 | |
565 565 | o 1: 'B' one
566 566 |/
567 567 o 0: 'A'
568 568
569 569 $ hg export tip
570 570 # HG changeset patch
571 571 # User user1
572 572 # Date 0 0
573 573 # Thu Jan 01 00:00:00 1970 +0000
574 574 # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213
575 575 # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09
576 576 E
577 577
578 578 diff -r 41acb9dca9eb -r f338eb3c2c7c z
579 579 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
580 580 +++ b/z Thu Jan 01 00:00:00 1970 +0000
581 581 @@ -0,0 +1,2 @@
582 582 +d
583 583 +blah
584 584
585 585 $ cd ..
586 586
587 587 Rebase, collapse and copies
588 588
589 589 $ hg init copies
590 590 $ cd copies
591 591 $ hg unbundle "$TESTDIR/bundles/renames.hg"
592 592 adding changesets
593 593 adding manifests
594 594 adding file changes
595 595 added 4 changesets with 11 changes to 7 files (+1 heads)
596 596 (run 'hg heads' to see heads, 'hg merge' to merge)
597 597 $ hg up -q tip
598 598 $ hg tglog
599 599 @ 3: 'move2'
600 600 |
601 601 o 2: 'move1'
602 602 |
603 603 | o 1: 'change'
604 604 |/
605 605 o 0: 'add'
606 606
607 607 $ hg rebase --collapse -d 1
608 608 merging a and d to d
609 609 merging b and e to e
610 610 merging c and f to f
611 611 merging e and g to g
612 612 merging f and c to c
613 613 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
614 614 $ hg st
615 615 $ hg st --copies --change tip
616 616 A d
617 617 a
618 618 A g
619 619 b
620 620 R b
621 621 $ hg up tip -q
622 622 $ cat c
623 623 c
624 624 c
625 625 $ cat d
626 626 a
627 627 a
628 628 $ cat g
629 629 b
630 630 b
631 631 $ hg log -r . --template "{file_copies}\n"
632 632 d (a)g (b)
633 633
634 634 Test collapsing a middle revision in-place
635 635
636 636 $ hg tglog
637 637 @ 2: 'Collapsed revision
638 638 | * move1
639 639 | * move2'
640 640 o 1: 'change'
641 641 |
642 642 o 0: 'add'
643 643
644 644 $ hg rebase --collapse -r 1 -d 0
645 645 abort: can't remove original changesets with unrebased descendants
646 646 (use --keep to keep original changesets)
647 647 [255]
648 648
649 649 Test collapsing in place
650 650
651 651 $ hg rebase --collapse -b . -d 0
652 652 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
653 653 $ hg st --change tip --copies
654 654 M a
655 655 M c
656 656 A d
657 657 a
658 658 A g
659 659 b
660 660 R b
661 661 $ hg up tip -q
662 662 $ cat a
663 663 a
664 664 a
665 665 $ cat c
666 666 c
667 667 c
668 668 $ cat d
669 669 a
670 670 a
671 671 $ cat g
672 672 b
673 673 b
674 674 $ cd ..
675 675
676 676
677 677 Test stripping a revision with another child
678 678
679 679 $ hg init f
680 680 $ cd f
681 681
682 682 $ echo A > A
683 683 $ hg ci -Am A
684 684 adding A
685 685 $ echo B > B
686 686 $ hg ci -Am B
687 687 adding B
688 688
689 689 $ hg up -q 0
690 690
691 691 $ echo C > C
692 692 $ hg ci -Am C
693 693 adding C
694 694 created new head
695 695
696 696 $ hg tglog
697 697 @ 2: 'C'
698 698 |
699 699 | o 1: 'B'
700 700 |/
701 701 o 0: 'A'
702 702
703 703
704 704
705 705 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
706 706 2:c5cefa58fd557f84b72b87f970135984337acbc5 default: C
707 707 1:27547f69f25460a52fff66ad004e58da7ad3fb56 default: B
708 708
709 709 $ hg strip 2
710 710 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
711 711 saved backup bundle to $TESTTMP/f/.hg/strip-backup/*-backup.hg (glob)
712 712
713 713 $ hg tglog
714 714 o 1: 'B'
715 715 |
716 716 @ 0: 'A'
717 717
718 718
719 719
720 720 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
721 721 1:27547f69f25460a52fff66ad004e58da7ad3fb56 default: B
722 722
723 723 $ cd ..
724 724
725 725 Test collapsing changes that add then remove a file
726 726
727 727 $ hg init collapseaddremove
728 728 $ cd collapseaddremove
729 729
730 730 $ touch base
731 731 $ hg commit -Am base
732 732 adding base
733 733 $ touch a
734 734 $ hg commit -Am a
735 735 adding a
736 736 $ hg rm a
737 737 $ touch b
738 738 $ hg commit -Am b
739 739 adding b
740 740 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
741 741 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/*-backup.hg (glob)
742 742 $ hg tglog
743 @ 1: 'collapsed'
743 o 1: 'collapsed'
744 744 |
745 o 0: 'base'
745 @ 0: 'base'
746 746
747 747 $ hg manifest --rev tip
748 748 b
749 749 base
750 750
751 751 $ cd ..
@@ -1,398 +1,398 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
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 > 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 (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 $ cd ..
26 26
27 27
28 28 Rebasing D onto H detaching from C:
29 29
30 30 $ hg clone -q -u . a a1
31 31 $ cd a1
32 32
33 33 $ hg tglog
34 34 @ 7: 'H'
35 35 |
36 36 | o 6: 'G'
37 37 |/|
38 38 o | 5: 'F'
39 39 | |
40 40 | o 4: 'E'
41 41 |/
42 42 | o 3: 'D'
43 43 | |
44 44 | o 2: 'C'
45 45 | |
46 46 | o 1: 'B'
47 47 |/
48 48 o 0: 'A'
49 49
50 50 $ hg phase --force --secret 3
51 51 $ hg rebase -s 3 -d 7
52 52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
53 53
54 54 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
55 @ 7:secret 'D'
55 o 7:secret 'D'
56 56 |
57 o 6:draft 'H'
57 @ 6:draft 'H'
58 58 |
59 59 | o 5:draft 'G'
60 60 |/|
61 61 o | 4:draft 'F'
62 62 | |
63 63 | o 3:draft 'E'
64 64 |/
65 65 | o 2:draft 'C'
66 66 | |
67 67 | o 1:draft 'B'
68 68 |/
69 69 o 0:draft 'A'
70 70
71 71 $ hg manifest --rev tip
72 72 A
73 73 D
74 74 F
75 75 H
76 76
77 77 $ cd ..
78 78
79 79
80 80 Rebasing C onto H detaching from B:
81 81
82 82 $ hg clone -q -u . a a2
83 83 $ cd a2
84 84
85 85 $ hg tglog
86 86 @ 7: 'H'
87 87 |
88 88 | o 6: 'G'
89 89 |/|
90 90 o | 5: 'F'
91 91 | |
92 92 | o 4: 'E'
93 93 |/
94 94 | o 3: 'D'
95 95 | |
96 96 | o 2: 'C'
97 97 | |
98 98 | o 1: 'B'
99 99 |/
100 100 o 0: 'A'
101 101
102 102 $ hg rebase -s 2 -d 7
103 103 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
104 104
105 105 $ hg tglog
106 @ 7: 'D'
106 o 7: 'D'
107 107 |
108 108 o 6: 'C'
109 109 |
110 o 5: 'H'
110 @ 5: 'H'
111 111 |
112 112 | o 4: 'G'
113 113 |/|
114 114 o | 3: 'F'
115 115 | |
116 116 | o 2: 'E'
117 117 |/
118 118 | o 1: 'B'
119 119 |/
120 120 o 0: 'A'
121 121
122 122 $ hg manifest --rev tip
123 123 A
124 124 C
125 125 D
126 126 F
127 127 H
128 128
129 129 $ cd ..
130 130
131 131
132 132 Rebasing B onto H using detach (same as not using it):
133 133
134 134 $ hg clone -q -u . a a3
135 135 $ cd a3
136 136
137 137 $ hg tglog
138 138 @ 7: 'H'
139 139 |
140 140 | o 6: 'G'
141 141 |/|
142 142 o | 5: 'F'
143 143 | |
144 144 | o 4: 'E'
145 145 |/
146 146 | o 3: 'D'
147 147 | |
148 148 | o 2: 'C'
149 149 | |
150 150 | o 1: 'B'
151 151 |/
152 152 o 0: 'A'
153 153
154 154 $ hg rebase -s 1 -d 7
155 155 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
156 156
157 157 $ hg tglog
158 @ 7: 'D'
158 o 7: 'D'
159 159 |
160 160 o 6: 'C'
161 161 |
162 162 o 5: 'B'
163 163 |
164 o 4: 'H'
164 @ 4: 'H'
165 165 |
166 166 | o 3: 'G'
167 167 |/|
168 168 o | 2: 'F'
169 169 | |
170 170 | o 1: 'E'
171 171 |/
172 172 o 0: 'A'
173 173
174 174 $ hg manifest --rev tip
175 175 A
176 176 B
177 177 C
178 178 D
179 179 F
180 180 H
181 181
182 182 $ cd ..
183 183
184 184
185 185 Rebasing C onto H detaching from B and collapsing:
186 186
187 187 $ hg clone -q -u . a a4
188 188 $ cd a4
189 189 $ hg phase --force --secret 3
190 190
191 191 $ hg tglog
192 192 @ 7: 'H'
193 193 |
194 194 | o 6: 'G'
195 195 |/|
196 196 o | 5: 'F'
197 197 | |
198 198 | o 4: 'E'
199 199 |/
200 200 | o 3: 'D'
201 201 | |
202 202 | o 2: 'C'
203 203 | |
204 204 | o 1: 'B'
205 205 |/
206 206 o 0: 'A'
207 207
208 208 $ hg rebase --collapse -s 2 -d 7
209 209 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
210 210
211 211 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
212 @ 6:secret 'Collapsed revision
212 o 6:secret 'Collapsed revision
213 213 | * C
214 214 | * D'
215 o 5:draft 'H'
215 @ 5:draft 'H'
216 216 |
217 217 | o 4:draft 'G'
218 218 |/|
219 219 o | 3:draft 'F'
220 220 | |
221 221 | o 2:draft 'E'
222 222 |/
223 223 | o 1:draft 'B'
224 224 |/
225 225 o 0:draft 'A'
226 226
227 227 $ hg manifest --rev tip
228 228 A
229 229 C
230 230 D
231 231 F
232 232 H
233 233
234 234 $ cd ..
235 235
236 236 Rebasing across null as ancestor
237 237 $ hg clone -q -U a a5
238 238
239 239 $ cd a5
240 240
241 241 $ echo x > x
242 242
243 243 $ hg add x
244 244
245 245 $ hg ci -m "extra branch"
246 246 created new head
247 247
248 248 $ hg tglog
249 249 @ 8: 'extra branch'
250 250
251 251 o 7: 'H'
252 252 |
253 253 | o 6: 'G'
254 254 |/|
255 255 o | 5: 'F'
256 256 | |
257 257 | o 4: 'E'
258 258 |/
259 259 | o 3: 'D'
260 260 | |
261 261 | o 2: 'C'
262 262 | |
263 263 | o 1: 'B'
264 264 |/
265 265 o 0: 'A'
266 266
267 267 $ hg rebase -s 1 -d tip
268 268 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
269 269
270 270 $ hg tglog
271 @ 8: 'D'
271 o 8: 'D'
272 272 |
273 273 o 7: 'C'
274 274 |
275 275 o 6: 'B'
276 276 |
277 o 5: 'extra branch'
277 @ 5: 'extra branch'
278 278
279 279 o 4: 'H'
280 280 |
281 281 | o 3: 'G'
282 282 |/|
283 283 o | 2: 'F'
284 284 | |
285 285 | o 1: 'E'
286 286 |/
287 287 o 0: 'A'
288 288
289 289
290 290 $ hg rebase -d 5 -s 7
291 291 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
292 292 $ hg tglog
293 @ 8: 'D'
293 o 8: 'D'
294 294 |
295 295 o 7: 'C'
296 296 |
297 297 | o 6: 'B'
298 298 |/
299 o 5: 'extra branch'
299 @ 5: 'extra branch'
300 300
301 301 o 4: 'H'
302 302 |
303 303 | o 3: 'G'
304 304 |/|
305 305 o | 2: 'F'
306 306 | |
307 307 | o 1: 'E'
308 308 |/
309 309 o 0: 'A'
310 310
311 311 $ cd ..
312 312
313 313 Verify that target is not selected as external rev (issue3085)
314 314
315 315 $ hg clone -q -U a a6
316 316 $ cd a6
317 317 $ hg up -q 6
318 318
319 319 $ echo "I" >> E
320 320 $ hg ci -m "I"
321 321 $ hg merge 7
322 322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 323 (branch merge, don't forget to commit)
324 324 $ hg ci -m "Merge"
325 325 $ echo "J" >> F
326 326 $ hg ci -m "J"
327 327
328 328 $ hg rebase -s 8 -d 7 --collapse --config ui.merge=internal:other
329 329 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
330 330
331 331 $ hg tglog
332 @ 8: 'Collapsed revision
332 o 8: 'Collapsed revision
333 333 | * I
334 334 | * Merge
335 335 | * J'
336 o 7: 'H'
336 @ 7: 'H'
337 337 |
338 338 | o 6: 'G'
339 339 |/|
340 340 o | 5: 'F'
341 341 | |
342 342 | o 4: 'E'
343 343 |/
344 344 | o 3: 'D'
345 345 | |
346 346 | o 2: 'C'
347 347 | |
348 348 | o 1: 'B'
349 349 |/
350 350 o 0: 'A'
351 351
352 352
353 353 $ hg log --rev tip
354 354 changeset: 8:9472f4b1d736
355 355 tag: tip
356 356 user: test
357 357 date: Thu Jan 01 00:00:00 1970 +0000
358 358 summary: Collapsed revision
359 359
360 360
361 361 $ cd ..
362 362
363 363 Ensure --continue restores a correct state (issue3046) and phase:
364 364 $ hg clone -q a a7
365 365 $ cd a7
366 366 $ hg up -q 3
367 367 $ echo 'H2' > H
368 368 $ hg ci -A -m 'H2'
369 369 adding H
370 370 $ hg phase --force --secret 8
371 371 $ hg rebase -s 8 -d 7 --config ui.merge=internal:fail
372 372 merging H
373 373 warning: conflicts during merge.
374 374 merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
375 375 unresolved conflicts (see hg resolve, then hg rebase --continue)
376 376 [1]
377 377 $ hg resolve --all -t internal:local
378 378 $ hg rebase -c
379 379 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
380 380 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
381 381 @ 7:draft 'H'
382 382 |
383 383 | o 6:draft 'G'
384 384 |/|
385 385 o | 5:draft 'F'
386 386 | |
387 387 | o 4:draft 'E'
388 388 |/
389 389 | o 3:draft 'D'
390 390 | |
391 391 | o 2:draft 'C'
392 392 | |
393 393 | o 1:draft 'B'
394 394 |/
395 395 o 0:draft 'A'
396 396
397 397
398 398 $ cd ..
@@ -1,267 +1,267 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
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 > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
12 12 > EOF
13 13
14 14
15 15 $ hg init a
16 16 $ cd a
17 17
18 18 $ echo A > A
19 19 $ hg ci -Am A
20 20 adding A
21 21
22 22 $ echo B > B
23 23 $ hg ci -Am B
24 24 adding B
25 25
26 26 $ echo C >> A
27 27 $ hg ci -m C
28 28
29 29 $ hg up -q -C 0
30 30
31 31 $ echo D >> A
32 32 $ hg ci -m D
33 33 created new head
34 34
35 35 $ echo E > E
36 36 $ hg ci -Am E
37 37 adding E
38 38
39 39 $ cd ..
40 40
41 41
42 42 Changes during an interruption - continue:
43 43
44 44 $ hg clone -q -u . a a1
45 45 $ cd a1
46 46
47 47 $ hg tglog
48 48 @ 4: 'E'
49 49 |
50 50 o 3: 'D'
51 51 |
52 52 | o 2: 'C'
53 53 | |
54 54 | o 1: 'B'
55 55 |/
56 56 o 0: 'A'
57 57
58 58 Rebasing B onto E:
59 59
60 60 $ hg rebase -s 1 -d 4
61 61 merging A
62 62 warning: conflicts during merge.
63 63 merging A incomplete! (edit conflicts, 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:secret 'Extra'
81 81 |
82 82 | o 5:draft 'B'
83 83 | |
84 84 | o 4:draft 'E'
85 85 | |
86 86 | o 3:draft 'D'
87 87 | |
88 88 o | 2:draft 'C'
89 89 | |
90 90 o | 1:draft 'B'
91 91 |/
92 92 o 0:draft 'A'
93 93
94 94 Resume the rebasing:
95 95
96 96 $ hg rebase --continue
97 97 merging A
98 98 warning: conflicts during merge.
99 99 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
100 100 unresolved conflicts (see hg resolve, then hg rebase --continue)
101 101 [1]
102 102
103 103 Solve the conflict and go on:
104 104
105 105 $ echo 'conflict solved' > A
106 106 $ rm A.orig
107 107 $ hg resolve -m A
108 108
109 109 $ hg rebase --continue
110 110 warning: new changesets detected on source branch, not stripping
111 111
112 112 $ hg tglogp
113 @ 7:draft 'C'
113 o 7:draft 'C'
114 114 |
115 115 | o 6:secret 'Extra'
116 116 | |
117 117 o | 5:draft 'B'
118 118 | |
119 o | 4:draft 'E'
119 @ | 4:draft 'E'
120 120 | |
121 121 o | 3:draft 'D'
122 122 | |
123 123 | o 2:draft 'C'
124 124 | |
125 125 | o 1:draft 'B'
126 126 |/
127 127 o 0:draft 'A'
128 128
129 129 $ cd ..
130 130
131 131
132 132 Changes during an interruption - abort:
133 133
134 134 $ hg clone -q -u . a a2
135 135 $ cd a2
136 136
137 137 $ hg tglog
138 138 @ 4: 'E'
139 139 |
140 140 o 3: 'D'
141 141 |
142 142 | o 2: 'C'
143 143 | |
144 144 | o 1: 'B'
145 145 |/
146 146 o 0: 'A'
147 147
148 148 Rebasing B onto E:
149 149
150 150 $ hg rebase -s 1 -d 4
151 151 merging A
152 152 warning: conflicts during merge.
153 153 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
154 154 unresolved conflicts (see hg resolve, then hg rebase --continue)
155 155 [1]
156 156
157 157 Force a commit on B' during the interruption:
158 158
159 159 $ hg up -q -C 5 --config 'extensions.rebase=!'
160 160
161 161 $ echo 'Extra' > Extra
162 162 $ hg add Extra
163 163 $ hg ci -m 'Extra' --config 'extensions.rebase=!'
164 164
165 165 $ hg tglog
166 166 @ 6: 'Extra'
167 167 |
168 168 o 5: 'B'
169 169 |
170 170 o 4: 'E'
171 171 |
172 172 o 3: 'D'
173 173 |
174 174 | o 2: 'C'
175 175 | |
176 176 | o 1: 'B'
177 177 |/
178 178 o 0: 'A'
179 179
180 180 Abort the rebasing:
181 181
182 182 $ hg rebase --abort
183 183 warning: new changesets detected on target branch, can't strip
184 184 rebase aborted
185 185
186 186 $ hg tglog
187 187 @ 6: 'Extra'
188 188 |
189 189 o 5: 'B'
190 190 |
191 191 o 4: 'E'
192 192 |
193 193 o 3: 'D'
194 194 |
195 195 | o 2: 'C'
196 196 | |
197 197 | o 1: 'B'
198 198 |/
199 199 o 0: 'A'
200 200
201 201 $ cd ..
202 202
203 203 Changes during an interruption - abort (again):
204 204
205 205 $ hg clone -q -u . a a3
206 206 $ cd a3
207 207
208 208 $ hg tglogp
209 209 @ 4:draft 'E'
210 210 |
211 211 o 3:draft 'D'
212 212 |
213 213 | o 2:draft 'C'
214 214 | |
215 215 | o 1:draft 'B'
216 216 |/
217 217 o 0:draft 'A'
218 218
219 219 Rebasing B onto E:
220 220
221 221 $ hg rebase -s 1 -d 4
222 222 merging A
223 223 warning: conflicts during merge.
224 224 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
225 225 unresolved conflicts (see hg resolve, then hg rebase --continue)
226 226 [1]
227 227
228 228 Change phase on B and B'
229 229
230 230 $ hg up -q -C 5 --config 'extensions.rebase=!'
231 231 $ hg phase --public 1
232 232 $ hg phase --public 5
233 233 $ hg phase --secret -f 2
234 234
235 235 $ hg tglogp
236 236 @ 5:public 'B'
237 237 |
238 238 o 4:public 'E'
239 239 |
240 240 o 3:public 'D'
241 241 |
242 242 | o 2:secret 'C'
243 243 | |
244 244 | o 1:public 'B'
245 245 |/
246 246 o 0:public 'A'
247 247
248 248 Abort the rebasing:
249 249
250 250 $ hg rebase --abort
251 251 warning: can't clean up immutable changesets 45396c49d53b
252 252 rebase aborted
253 253
254 254 $ hg tglogp
255 255 @ 5:public 'B'
256 256 |
257 257 o 4:public 'E'
258 258 |
259 259 o 3:public 'D'
260 260 |
261 261 | o 2:secret 'C'
262 262 | |
263 263 | o 1:public 'B'
264 264 |/
265 265 o 0:public 'A'
266 266
267 267 $ cd ..
@@ -1,243 +1,243 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
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 > EOF
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 (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 (branches are permanent and global, did you want a bookmark?)
41 41
42 42 $ echo x > x
43 43
44 44 $ hg add x
45 45
46 46 $ hg ci -m 'dev-two named branch'
47 47
48 48 $ hg tglog
49 49 @ 9: 'dev-two named branch' dev-two
50 50 |
51 51 | o 8: 'dev-one named branch' dev-one
52 52 | |
53 53 o | 7: 'H'
54 54 | |
55 55 +---o 6: 'G'
56 56 | | |
57 57 o | | 5: 'F'
58 58 | | |
59 59 +---o 4: 'E'
60 60 | |
61 61 | o 3: 'D'
62 62 | |
63 63 | o 2: 'C'
64 64 | |
65 65 | o 1: 'B'
66 66 |/
67 67 o 0: 'A'
68 68
69 69
70 70 Branch name containing a dash (issue3181)
71 71
72 72 $ hg rebase -b dev-two -d dev-one --keepbranches
73 73 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
74 74
75 75 $ hg tglog
76 76 @ 9: 'dev-two named branch' dev-two
77 77 |
78 78 o 8: 'H'
79 79 |
80 80 | o 7: 'G'
81 81 |/|
82 82 o | 6: 'F'
83 83 | |
84 84 o | 5: 'dev-one named branch' dev-one
85 85 | |
86 86 | o 4: 'E'
87 87 | |
88 88 o | 3: 'D'
89 89 | |
90 90 o | 2: 'C'
91 91 | |
92 92 o | 1: 'B'
93 93 |/
94 94 o 0: 'A'
95 95
96 96 $ hg rebase -s dev-one -d 0 --keepbranches
97 97 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
98 98
99 99 $ hg tglog
100 100 @ 8: 'dev-two named branch' dev-two
101 101 |
102 102 o 7: 'H'
103 103 |
104 104 | o 6: 'G'
105 105 |/|
106 106 o | 5: 'F'
107 107 | |
108 108 | o 4: 'E'
109 109 |/
110 110 | o 3: 'D'
111 111 | |
112 112 | o 2: 'C'
113 113 | |
114 114 | o 1: 'B'
115 115 |/
116 116 o 0: 'A'
117 117
118 118 $ hg update 3
119 119 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
120 120 $ hg branch dev-one
121 121 marked working directory as branch dev-one
122 122 (branches are permanent and global, did you want a bookmark?)
123 123 $ hg ci -m 'dev-one named branch'
124 124
125 125 $ hg tglog
126 126 @ 9: 'dev-one named branch' dev-one
127 127 |
128 128 | o 8: 'dev-two named branch' dev-two
129 129 | |
130 130 | o 7: 'H'
131 131 | |
132 132 | | o 6: 'G'
133 133 | |/|
134 134 | o | 5: 'F'
135 135 | | |
136 136 | | o 4: 'E'
137 137 | |/
138 138 o | 3: 'D'
139 139 | |
140 140 o | 2: 'C'
141 141 | |
142 142 o | 1: 'B'
143 143 |/
144 144 o 0: 'A'
145 145
146 146 $ hg rebase -b 'max(branch("dev-two"))' -d dev-one --keepbranches
147 147 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
148 148
149 149 $ hg tglog
150 @ 9: 'dev-two named branch' dev-two
150 o 9: 'dev-two named branch' dev-two
151 151 |
152 152 o 8: 'H'
153 153 |
154 154 | o 7: 'G'
155 155 |/|
156 156 o | 6: 'F'
157 157 | |
158 o | 5: 'dev-one named branch' dev-one
158 @ | 5: 'dev-one named branch' dev-one
159 159 | |
160 160 | o 4: 'E'
161 161 | |
162 162 o | 3: 'D'
163 163 | |
164 164 o | 2: 'C'
165 165 | |
166 166 o | 1: 'B'
167 167 |/
168 168 o 0: 'A'
169 169
170 170 $ hg rebase -s 'max(branch("dev-one"))' -d 0 --keepbranches
171 171 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
172 172
173 173 $ hg tglog
174 @ 8: 'dev-two named branch' dev-two
174 o 8: 'dev-two named branch' dev-two
175 175 |
176 176 o 7: 'H'
177 177 |
178 178 | o 6: 'G'
179 179 |/|
180 180 o | 5: 'F'
181 181 | |
182 182 | o 4: 'E'
183 183 |/
184 184 | o 3: 'D'
185 185 | |
186 186 | o 2: 'C'
187 187 | |
188 188 | o 1: 'B'
189 189 |/
190 o 0: 'A'
190 @ 0: 'A'
191 191
192 192
193 193 Rebasing descendant onto ancestor across different named branches
194 194
195 195 $ hg rebase -s 1 -d 8 --keepbranches
196 196 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
197 197
198 198 $ hg tglog
199 @ 8: 'D'
199 o 8: 'D'
200 200 |
201 201 o 7: 'C'
202 202 |
203 203 o 6: 'B'
204 204 |
205 205 o 5: 'dev-two named branch' dev-two
206 206 |
207 207 o 4: 'H'
208 208 |
209 209 | o 3: 'G'
210 210 |/|
211 211 o | 2: 'F'
212 212 | |
213 213 | o 1: 'E'
214 214 |/
215 o 0: 'A'
215 @ 0: 'A'
216 216
217 217 $ hg rebase -s 4 -d 5
218 218 abort: source is ancestor of destination
219 219 [255]
220 220
221 221 $ hg rebase -s 5 -d 4
222 222 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
223 223
224 224 $ hg tglog
225 @ 8: 'D'
225 o 8: 'D'
226 226 |
227 227 o 7: 'C'
228 228 |
229 229 o 6: 'B'
230 230 |
231 231 o 5: 'dev-two named branch'
232 232 |
233 233 o 4: 'H'
234 234 |
235 235 | o 3: 'G'
236 236 |/|
237 237 o | 2: 'F'
238 238 | |
239 239 | o 1: 'E'
240 240 |/
241 o 0: 'A'
241 @ 0: 'A'
242 242
243 243 $ cd ..
@@ -1,56 +1,56 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [alias]
7 7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 8 > EOF
9 9
10 10 $ hg init repo
11 11 $ cd repo
12 12
13 13 $ echo A > a
14 14 $ echo >> a
15 15 $ hg ci -Am A
16 16 adding a
17 17
18 18 $ echo B > a
19 19 $ echo >> a
20 20 $ hg ci -m B
21 21
22 22 $ echo C > a
23 23 $ echo >> a
24 24 $ hg ci -m C
25 25
26 26 $ hg up -q -C 0
27 27
28 28 $ echo D >> a
29 29 $ hg ci -Am AD
30 30 created new head
31 31
32 32 $ hg tglog
33 33 @ 3: 'AD'
34 34 |
35 35 | o 2: 'C'
36 36 | |
37 37 | o 1: 'B'
38 38 |/
39 39 o 0: 'A'
40 40
41 41 $ hg rebase -s 1 -d 3
42 42 merging a
43 43 merging a
44 44 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-backup.hg (glob)
45 45
46 46 $ hg tglog
47 @ 3: 'C'
47 o 3: 'C'
48 48 |
49 49 o 2: 'B'
50 50 |
51 o 1: 'AD'
51 @ 1: 'AD'
52 52 |
53 53 o 0: 'A'
54 54
55 55
56 56 $ cd ..
@@ -1,473 +1,473 b''
1 1 ==========================
2 2 Test rebase with obsolete
3 3 ==========================
4 4
5 5 Enable obsolete
6 6
7 7 $ cat > ${TESTTMP}/obs.py << EOF
8 8 > import mercurial.obsolete
9 9 > mercurial.obsolete._enabled = True
10 10 > EOF
11 11 $ cat >> $HGRCPATH << EOF
12 12 > [ui]
13 13 > logtemplate= {rev}:{node|short} {desc|firstline}
14 14 > [phases]
15 15 > publish=False
16 16 > [extensions]'
17 17 > rebase=
18 18 >
19 19 > obs=${TESTTMP}/obs.py
20 20 > EOF
21 21
22 22 Setup rebase canonical repo
23 23
24 24 $ hg init base
25 25 $ cd base
26 26 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
27 27 adding changesets
28 28 adding manifests
29 29 adding file changes
30 30 added 8 changesets with 7 changes to 7 files (+2 heads)
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 $ hg log -G
64 64 @ 10:8eeb3c33ad33 D
65 65 |
66 66 o 9:2327fea05063 C
67 67 |
68 68 o 8:e4e5be0395b2 B
69 69 |
70 70 | o 7:02de42196ebe H
71 71 | |
72 72 o | 6:eea13746799a G
73 73 |\|
74 74 | o 5:24b6387c8c8c F
75 75 | |
76 76 o | 4:9520eea781bc E
77 77 |/
78 78 o 0:cd010b8cd998 A
79 79
80 80 $ hg log --hidden -G
81 81 @ 10:8eeb3c33ad33 D
82 82 |
83 83 o 9:2327fea05063 C
84 84 |
85 85 o 8:e4e5be0395b2 B
86 86 |
87 87 | o 7:02de42196ebe H
88 88 | |
89 89 o | 6:eea13746799a G
90 90 |\|
91 91 | o 5:24b6387c8c8c F
92 92 | |
93 93 o | 4:9520eea781bc E
94 94 |/
95 95 | x 3:32af7686d403 D
96 96 | |
97 97 | x 2:5fddd98957c8 C
98 98 | |
99 99 | x 1:42ccdea3bb16 B
100 100 |/
101 101 o 0:cd010b8cd998 A
102 102
103 103 $ hg debugobsolete
104 104 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 {'date': '*', 'user': 'test'} (glob)
105 105 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 {'date': '*', 'user': 'test'} (glob)
106 106 32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 {'date': '*', 'user': 'test'} (glob)
107 107
108 108
109 109 $ cd ..
110 110
111 111 empty changeset
112 112 ---------------------------------
113 113
114 114 $ hg clone base empty
115 115 updating to branch default
116 116 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 117 $ cd empty
118 118 $ hg up eea13746799a
119 119 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
120 120
121 121 We make a copy of both the first changeset in the rebased and some other in the
122 122 set.
123 123
124 124 $ hg graft 42ccdea3bb16 32af7686d403
125 125 grafting revision 1
126 126 grafting revision 3
127 127 $ hg rebase -s 42ccdea3bb16 -d .
128 128 $ hg log -G
129 @ 10:5ae4c968c6ac C
129 o 10:5ae4c968c6ac C
130 130 |
131 o 9:08483444fef9 D
131 @ 9:08483444fef9 D
132 132 |
133 133 o 8:8877864f1edb B
134 134 |
135 135 | o 7:02de42196ebe H
136 136 | |
137 137 o | 6:eea13746799a G
138 138 |\|
139 139 | o 5:24b6387c8c8c F
140 140 | |
141 141 o | 4:9520eea781bc E
142 142 |/
143 143 o 0:cd010b8cd998 A
144 144
145 145 $ hg log --hidden -G
146 @ 10:5ae4c968c6ac C
146 o 10:5ae4c968c6ac C
147 147 |
148 o 9:08483444fef9 D
148 @ 9:08483444fef9 D
149 149 |
150 150 o 8:8877864f1edb B
151 151 |
152 152 | o 7:02de42196ebe H
153 153 | |
154 154 o | 6:eea13746799a G
155 155 |\|
156 156 | o 5:24b6387c8c8c F
157 157 | |
158 158 o | 4:9520eea781bc E
159 159 |/
160 160 | x 3:32af7686d403 D
161 161 | |
162 162 | x 2:5fddd98957c8 C
163 163 | |
164 164 | x 1:42ccdea3bb16 B
165 165 |/
166 166 o 0:cd010b8cd998 A
167 167
168 168 $ hg debugobsolete
169 169 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '*', 'user': 'test'} (glob)
170 170 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
171 171 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '*', 'user': 'test'} (glob)
172 172
173 173
174 174 More complex case were part of the rebase set were already rebased
175 175
176 176 $ hg rebase --rev 'desc(D)' --dest 'desc(H)'
177 177 $ hg debugobsolete
178 178 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '*', 'user': 'test'} (glob)
179 179 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
180 180 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '*', 'user': 'test'} (glob)
181 181 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 {'date': '* *', 'user': 'test'} (glob)
182 182 $ hg log -G
183 183 @ 11:4596109a6a43 D
184 184 |
185 185 | o 10:5ae4c968c6ac C
186 186 | |
187 187 | x 9:08483444fef9 D
188 188 | |
189 189 | o 8:8877864f1edb B
190 190 | |
191 191 o | 7:02de42196ebe H
192 192 | |
193 193 | o 6:eea13746799a G
194 194 |/|
195 195 o | 5:24b6387c8c8c F
196 196 | |
197 197 | o 4:9520eea781bc E
198 198 |/
199 199 o 0:cd010b8cd998 A
200 200
201 201 $ hg rebase --source 'desc(B)' --dest 'tip'
202 202 $ hg debugobsolete
203 203 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {'date': '* *', 'user': 'test'} (glob)
204 204 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '* *', 'user': 'test'} (glob)
205 205 32af7686d403cf45b5d95f2d70cebea587ac806a 0 {'date': '* *', 'user': 'test'} (glob)
206 206 08483444fef91d6224f6655ee586a65d263ad34c 4596109a6a4328c398bde3a4a3b6737cfade3003 0 {'date': '* *', 'user': 'test'} (glob)
207 207 8877864f1edb05d0e07dc4ba77b67a80a7b86672 462a34d07e599b87ea08676a449373fe4e2e1347 0 {'date': '* *', 'user': 'test'} (glob)
208 208 08483444fef91d6224f6655ee586a65d263ad34c 0 {'date': '* *', 'user': 'test'} (glob)
209 209 5ae4c968c6aca831df823664e706c9d4aa34473d 98f6af4ee9539e14da4465128f894c274900b6e5 0 {'date': '* *', 'user': 'test'} (glob)
210 210 $ hg log --rev 'divergent()'
211 211 $ hg log -G
212 @ 13:98f6af4ee953 C
212 o 13:98f6af4ee953 C
213 213 |
214 214 o 12:462a34d07e59 B
215 215 |
216 o 11:4596109a6a43 D
216 @ 11:4596109a6a43 D
217 217 |
218 218 o 7:02de42196ebe H
219 219 |
220 220 | o 6:eea13746799a G
221 221 |/|
222 222 o | 5:24b6387c8c8c F
223 223 | |
224 224 | o 4:9520eea781bc E
225 225 |/
226 226 o 0:cd010b8cd998 A
227 227
228 228 $ hg log --style default --debug -r 4596109a6a4328c398bde3a4a3b6737cfade3003
229 229 changeset: 11:4596109a6a4328c398bde3a4a3b6737cfade3003
230 230 phase: draft
231 231 parent: 7:02de42196ebee42ef284b6780a87cdc96e8eaab6
232 232 parent: -1:0000000000000000000000000000000000000000
233 233 manifest: 11:a91006e3a02f1edf631f7018e6e5684cf27dd905
234 234 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
235 235 date: Sat Apr 30 15:24:48 2011 +0200
236 236 files+: D
237 237 extra: branch=default
238 238 extra: rebase_source=08483444fef91d6224f6655ee586a65d263ad34c
239 239 extra: source=32af7686d403cf45b5d95f2d70cebea587ac806a
240 240 description:
241 241 D
242 242
243 243
244 244 $ cd ..
245 245
246 246 collapse rebase
247 247 ---------------------------------
248 248
249 249 $ hg clone base collapse
250 250 updating to branch default
251 251 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 252 $ cd collapse
253 253 $ hg rebase -s 42ccdea3bb16 -d eea13746799a --collapse
254 254 $ hg log -G
255 @ 8:4dc2197e807b Collapsed revision
255 o 8:4dc2197e807b Collapsed revision
256 256 |
257 | o 7:02de42196ebe H
257 | @ 7:02de42196ebe H
258 258 | |
259 259 o | 6:eea13746799a G
260 260 |\|
261 261 | o 5:24b6387c8c8c F
262 262 | |
263 263 o | 4:9520eea781bc E
264 264 |/
265 265 o 0:cd010b8cd998 A
266 266
267 267 $ hg log --hidden -G
268 @ 8:4dc2197e807b Collapsed revision
268 o 8:4dc2197e807b Collapsed revision
269 269 |
270 | o 7:02de42196ebe H
270 | @ 7:02de42196ebe H
271 271 | |
272 272 o | 6:eea13746799a G
273 273 |\|
274 274 | o 5:24b6387c8c8c F
275 275 | |
276 276 o | 4:9520eea781bc E
277 277 |/
278 278 | x 3:32af7686d403 D
279 279 | |
280 280 | x 2:5fddd98957c8 C
281 281 | |
282 282 | x 1:42ccdea3bb16 B
283 283 |/
284 284 o 0:cd010b8cd998 A
285 285
286 286 $ hg id --debug -r tip
287 287 4dc2197e807bae9817f09905b50ab288be2dbbcf tip
288 288 $ hg debugobsolete
289 289 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
290 290 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
291 291 32af7686d403cf45b5d95f2d70cebea587ac806a 4dc2197e807bae9817f09905b50ab288be2dbbcf 0 {'date': '*', 'user': 'test'} (glob)
292 292
293 293 $ cd ..
294 294
295 295 Rebase set has hidden descendants
296 296 ---------------------------------
297 297
298 298 We rebase a changeset which has a hidden changeset. The hidden changeset must
299 299 not be rebased.
300 300
301 301 $ hg clone base hidden
302 302 updating to branch default
303 303 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 304 $ cd hidden
305 305 $ hg rebase -s 5fddd98957c8 -d eea13746799a
306 306 $ hg rebase -s 42ccdea3bb16 -d 02de42196ebe
307 307 $ hg log -G
308 @ 10:7c6027df6a99 B
308 o 10:7c6027df6a99 B
309 309 |
310 310 | o 9:cf44d2f5a9f4 D
311 311 | |
312 312 | o 8:e273c5e7d2d2 C
313 313 | |
314 o | 7:02de42196ebe H
314 @ | 7:02de42196ebe H
315 315 | |
316 316 | o 6:eea13746799a G
317 317 |/|
318 318 o | 5:24b6387c8c8c F
319 319 | |
320 320 | o 4:9520eea781bc E
321 321 |/
322 322 o 0:cd010b8cd998 A
323 323
324 324 $ hg log --hidden -G
325 @ 10:7c6027df6a99 B
325 o 10:7c6027df6a99 B
326 326 |
327 327 | o 9:cf44d2f5a9f4 D
328 328 | |
329 329 | o 8:e273c5e7d2d2 C
330 330 | |
331 o | 7:02de42196ebe H
331 @ | 7:02de42196ebe H
332 332 | |
333 333 | o 6:eea13746799a G
334 334 |/|
335 335 o | 5:24b6387c8c8c F
336 336 | |
337 337 | o 4:9520eea781bc E
338 338 |/
339 339 | x 3:32af7686d403 D
340 340 | |
341 341 | x 2:5fddd98957c8 C
342 342 | |
343 343 | x 1:42ccdea3bb16 B
344 344 |/
345 345 o 0:cd010b8cd998 A
346 346
347 347 $ hg debugobsolete
348 348 5fddd98957c8a54a4d436dfe1da9d87f21a1b97b e273c5e7d2d29df783dce9f9eaa3ac4adc69c15d 0 {'date': '*', 'user': 'test'} (glob)
349 349 32af7686d403cf45b5d95f2d70cebea587ac806a cf44d2f5a9f4297a62be94cbdd3dff7c7dc54258 0 {'date': '*', 'user': 'test'} (glob)
350 350 42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 7c6027df6a99d93f461868e5433f63bde20b6dfb 0 {'date': '*', 'user': 'test'} (glob)
351 351
352 352 Test that rewriting leaving instability behind is allowed
353 353 ---------------------------------------------------------------------
354 354
355 355 $ hg log -r 'children(8)'
356 356 9:cf44d2f5a9f4 D (no-eol)
357 357 $ hg rebase -r 8
358 358 $ hg log -G
359 @ 11:0d8f238b634c C
359 o 11:0d8f238b634c C
360 360 |
361 361 o 10:7c6027df6a99 B
362 362 |
363 363 | o 9:cf44d2f5a9f4 D
364 364 | |
365 365 | x 8:e273c5e7d2d2 C
366 366 | |
367 o | 7:02de42196ebe H
367 @ | 7:02de42196ebe H
368 368 | |
369 369 | o 6:eea13746799a G
370 370 |/|
371 371 o | 5:24b6387c8c8c F
372 372 | |
373 373 | o 4:9520eea781bc E
374 374 |/
375 375 o 0:cd010b8cd998 A
376 376
377 377
378 378
379 379 Test multiple root handling
380 380 ------------------------------------
381 381
382 382 $ hg rebase --dest 4 --rev '7+11+9'
383 383 $ hg log -G
384 @ 14:1e8370e38cca C
384 o 14:1e8370e38cca C
385 385 |
386 386 | o 13:102b4c1d889b D
387 387 | |
388 o | 12:bfe264faf697 H
388 @ | 12:bfe264faf697 H
389 389 |/
390 390 | o 10:7c6027df6a99 B
391 391 | |
392 392 | x 7:02de42196ebe H
393 393 | |
394 394 +---o 6:eea13746799a G
395 395 | |/
396 396 | o 5:24b6387c8c8c F
397 397 | |
398 398 o | 4:9520eea781bc E
399 399 |/
400 400 o 0:cd010b8cd998 A
401 401
402 402 $ cd ..
403 403
404 404 test on rebase dropping a merge
405 405
406 406 (setup)
407 407
408 408 $ hg init dropmerge
409 409 $ cd dropmerge
410 410 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
411 411 adding changesets
412 412 adding manifests
413 413 adding file changes
414 414 added 8 changesets with 7 changes to 7 files (+2 heads)
415 415 (run 'hg heads' to see heads, 'hg merge' to merge)
416 416 $ hg up 3
417 417 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
418 418 $ hg merge 7
419 419 2 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 'M'
422 422 $ echo I > I
423 423 $ hg add I
424 424 $ hg ci -m I
425 425 $ hg log -G
426 426 @ 9:4bde274eefcf I
427 427 |
428 428 o 8:53a6a128b2b7 M
429 429 |\
430 430 | o 7:02de42196ebe H
431 431 | |
432 432 | | o 6:eea13746799a G
433 433 | |/|
434 434 | o | 5:24b6387c8c8c F
435 435 | | |
436 436 | | o 4:9520eea781bc E
437 437 | |/
438 438 o | 3:32af7686d403 D
439 439 | |
440 440 o | 2:5fddd98957c8 C
441 441 | |
442 442 o | 1:42ccdea3bb16 B
443 443 |/
444 444 o 0:cd010b8cd998 A
445 445
446 446 (actual test)
447 447
448 448 $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
449 449 $ hg log -G
450 450 @ 12:acd174b7ab39 I
451 451 |
452 452 o 11:6c11a6218c97 H
453 453 |
454 454 | o 10:b5313c85b22e D
455 455 |/
456 456 | o 8:53a6a128b2b7 M
457 457 | |\
458 458 | | x 7:02de42196ebe H
459 459 | | |
460 460 o---+ 6:eea13746799a G
461 461 | | |
462 462 | | o 5:24b6387c8c8c F
463 463 | | |
464 464 o---+ 4:9520eea781bc E
465 465 / /
466 466 x | 3:32af7686d403 D
467 467 | |
468 468 o | 2:5fddd98957c8 C
469 469 | |
470 470 o | 1:42ccdea3bb16 B
471 471 |/
472 472 o 0:cd010b8cd998 A
473 473
@@ -1,440 +1,440 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
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 > 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 (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: 'I'
31 31 |
32 32 o 7: 'H'
33 33 |
34 34 | o 6: 'G'
35 35 |/|
36 36 o | 5: 'F'
37 37 | |
38 38 | o 4: 'E'
39 39 |/
40 40 | o 3: 'D'
41 41 | |
42 42 | o 2: 'C'
43 43 | |
44 44 | o 1: 'B'
45 45 |/
46 46 o 0: 'A'
47 47
48 48 $ cd ..
49 49
50 50
51 51 These fail:
52 52
53 53 $ hg clone -q -u . a a1
54 54 $ cd a1
55 55
56 56 $ hg rebase -s 8 -d 7
57 57 nothing to rebase
58 58 [1]
59 59
60 60 $ hg rebase --continue --abort
61 61 abort: cannot use both abort and continue
62 62 [255]
63 63
64 64 $ hg rebase --continue --collapse
65 65 abort: cannot use collapse with continue or abort
66 66 [255]
67 67
68 68 $ hg rebase --continue --dest 4
69 69 abort: abort and continue do not allow specifying revisions
70 70 [255]
71 71
72 72 $ hg rebase --base 5 --source 4
73 73 abort: cannot specify both a source and a base
74 74 [255]
75 75
76 76 $ hg rebase --rev 5 --source 4
77 77 abort: cannot specify both a revision and a source
78 78 [255]
79 79 $ hg rebase --base 5 --rev 4
80 80 abort: cannot specify both a revision and a base
81 81 [255]
82 82
83 83 $ hg rebase
84 84 nothing to rebase
85 85 [1]
86 86
87 87 $ hg up -q 7
88 88
89 89 $ hg rebase --traceback
90 90 nothing to rebase
91 91 [1]
92 92
93 93
94 94 These work:
95 95
96 96 Rebase with no arguments (from 3 onto 8):
97 97
98 98 $ hg up -q -C 3
99 99
100 100 $ hg rebase
101 101 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
102 102
103 103 $ hg tglog
104 104 @ 8: 'D'
105 105 |
106 106 o 7: 'C'
107 107 |
108 108 o 6: 'B'
109 109 |
110 110 o 5: 'I'
111 111 |
112 112 o 4: 'H'
113 113 |
114 114 | o 3: 'G'
115 115 |/|
116 116 o | 2: 'F'
117 117 | |
118 118 | o 1: 'E'
119 119 |/
120 120 o 0: 'A'
121 121
122 122 Try to rollback after a rebase (fail):
123 123
124 124 $ hg rollback
125 125 no rollback information available
126 126 [1]
127 127
128 128 $ cd ..
129 129
130 130
131 131 Rebase with base == '.' => same as no arguments (from 3 onto 8):
132 132
133 133 $ hg clone -q -u 3 a a2
134 134 $ cd a2
135 135
136 136 $ hg rebase --base .
137 137 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
138 138
139 139 $ hg tglog
140 140 @ 8: 'D'
141 141 |
142 142 o 7: 'C'
143 143 |
144 144 o 6: 'B'
145 145 |
146 146 o 5: 'I'
147 147 |
148 148 o 4: 'H'
149 149 |
150 150 | o 3: 'G'
151 151 |/|
152 152 o | 2: 'F'
153 153 | |
154 154 | o 1: 'E'
155 155 |/
156 156 o 0: 'A'
157 157
158 158 $ cd ..
159 159
160 160
161 161 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
162 162
163 163 $ hg clone -q -u 3 a a3
164 164 $ cd a3
165 165
166 166 $ hg rebase --dest 'branch(.)'
167 167 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
168 168
169 169 $ hg tglog
170 170 @ 8: 'D'
171 171 |
172 172 o 7: 'C'
173 173 |
174 174 o 6: 'B'
175 175 |
176 176 o 5: 'I'
177 177 |
178 178 o 4: 'H'
179 179 |
180 180 | o 3: 'G'
181 181 |/|
182 182 o | 2: 'F'
183 183 | |
184 184 | o 1: 'E'
185 185 |/
186 186 o 0: 'A'
187 187
188 188 $ cd ..
189 189
190 190
191 191 Specify only source (from 2 onto 8):
192 192
193 193 $ hg clone -q -u . a a4
194 194 $ cd a4
195 195
196 196 $ hg rebase --source 'desc("C")'
197 197 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
198 198
199 199 $ hg tglog
200 @ 8: 'D'
200 o 8: 'D'
201 201 |
202 202 o 7: 'C'
203 203 |
204 o 6: 'I'
204 @ 6: 'I'
205 205 |
206 206 o 5: 'H'
207 207 |
208 208 | o 4: 'G'
209 209 |/|
210 210 o | 3: 'F'
211 211 | |
212 212 | o 2: 'E'
213 213 |/
214 214 | o 1: 'B'
215 215 |/
216 216 o 0: 'A'
217 217
218 218 $ cd ..
219 219
220 220
221 221 Specify only dest (from 3 onto 6):
222 222
223 223 $ hg clone -q -u 3 a a5
224 224 $ cd a5
225 225
226 226 $ hg rebase --dest 6
227 227 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
228 228
229 229 $ hg tglog
230 230 @ 8: 'D'
231 231 |
232 232 o 7: 'C'
233 233 |
234 234 o 6: 'B'
235 235 |
236 236 | o 5: 'I'
237 237 | |
238 238 | o 4: 'H'
239 239 | |
240 240 o | 3: 'G'
241 241 |\|
242 242 | o 2: 'F'
243 243 | |
244 244 o | 1: 'E'
245 245 |/
246 246 o 0: 'A'
247 247
248 248 $ cd ..
249 249
250 250
251 251 Specify only base (from 1 onto 8):
252 252
253 253 $ hg clone -q -u . a a6
254 254 $ cd a6
255 255
256 256 $ hg rebase --base 'desc("D")'
257 257 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
258 258
259 259 $ hg tglog
260 @ 8: 'D'
260 o 8: 'D'
261 261 |
262 262 o 7: 'C'
263 263 |
264 264 o 6: 'B'
265 265 |
266 o 5: 'I'
266 @ 5: 'I'
267 267 |
268 268 o 4: 'H'
269 269 |
270 270 | o 3: 'G'
271 271 |/|
272 272 o | 2: 'F'
273 273 | |
274 274 | o 1: 'E'
275 275 |/
276 276 o 0: 'A'
277 277
278 278 $ cd ..
279 279
280 280
281 281 Specify source and dest (from 2 onto 7):
282 282
283 283 $ hg clone -q -u . a a7
284 284 $ cd a7
285 285
286 286 $ hg rebase --source 2 --dest 7
287 287 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
288 288
289 289 $ hg tglog
290 @ 8: 'D'
290 o 8: 'D'
291 291 |
292 292 o 7: 'C'
293 293 |
294 | o 6: 'I'
294 | @ 6: 'I'
295 295 |/
296 296 o 5: 'H'
297 297 |
298 298 | o 4: 'G'
299 299 |/|
300 300 o | 3: 'F'
301 301 | |
302 302 | o 2: 'E'
303 303 |/
304 304 | o 1: 'B'
305 305 |/
306 306 o 0: 'A'
307 307
308 308 $ cd ..
309 309
310 310
311 311 Specify base and dest (from 1 onto 7):
312 312
313 313 $ hg clone -q -u . a a8
314 314 $ cd a8
315 315
316 316 $ hg rebase --base 3 --dest 7
317 317 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
318 318
319 319 $ hg tglog
320 @ 8: 'D'
320 o 8: 'D'
321 321 |
322 322 o 7: 'C'
323 323 |
324 324 o 6: 'B'
325 325 |
326 | o 5: 'I'
326 | @ 5: 'I'
327 327 |/
328 328 o 4: 'H'
329 329 |
330 330 | o 3: 'G'
331 331 |/|
332 332 o | 2: 'F'
333 333 | |
334 334 | o 1: 'E'
335 335 |/
336 336 o 0: 'A'
337 337
338 338 $ cd ..
339 339
340 340
341 341 Specify only revs (from 2 onto 8)
342 342
343 343 $ hg clone -q -u . a a9
344 344 $ cd a9
345 345
346 346 $ hg rebase --rev 'desc("C")::'
347 347 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/*-backup.hg (glob)
348 348
349 349 $ hg tglog
350 @ 8: 'D'
350 o 8: 'D'
351 351 |
352 352 o 7: 'C'
353 353 |
354 o 6: 'I'
354 @ 6: 'I'
355 355 |
356 356 o 5: 'H'
357 357 |
358 358 | o 4: 'G'
359 359 |/|
360 360 o | 3: 'F'
361 361 | |
362 362 | o 2: 'E'
363 363 |/
364 364 | o 1: 'B'
365 365 |/
366 366 o 0: 'A'
367 367
368 368 $ cd ..
369 369
370 370 Test --tool parameter:
371 371
372 372 $ hg init b
373 373 $ cd b
374 374
375 375 $ echo c1 > c1
376 376 $ hg ci -Am c1
377 377 adding c1
378 378
379 379 $ echo c2 > c2
380 380 $ hg ci -Am c2
381 381 adding c2
382 382
383 383 $ hg up -q 0
384 384 $ echo c2b > c2
385 385 $ hg ci -Am c2b
386 386 adding c2
387 387 created new head
388 388
389 389 $ cd ..
390 390
391 391 $ hg clone -q -u . b b1
392 392 $ cd b1
393 393
394 394 $ hg rebase -s 2 -d 1 --tool internal:local
395 395 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
396 396
397 397 $ hg cat c2
398 398 c2
399 399
400 400 $ cd ..
401 401
402 402
403 403 $ hg clone -q -u . b b2
404 404 $ cd b2
405 405
406 406 $ hg rebase -s 2 -d 1 --tool internal:other
407 407 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
408 408
409 409 $ hg cat c2
410 410 c2b
411 411
412 412 $ cd ..
413 413
414 414
415 415 $ hg clone -q -u . b b3
416 416 $ cd b3
417 417
418 418 $ hg rebase -s 2 -d 1 --tool internal:fail
419 419 unresolved conflicts (see hg resolve, then hg rebase --continue)
420 420 [1]
421 421
422 422 $ hg summary
423 423 parent: 1:56daeba07f4b
424 424 c2
425 425 parent: 2:e4e3f3546619 tip
426 426 c2b
427 427 branch: default
428 428 commit: 1 modified, 1 unresolved (merge)
429 429 update: (current)
430 430 rebase: 0 rebased, 1 remaining (rebase --continue)
431 431
432 432 $ hg resolve -l
433 433 U c2
434 434
435 435 $ hg resolve -m c2
436 436 $ hg rebase -c --tool internal:fail
437 437 tool option will be ignored
438 438 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
439 439
440 440 $ cd ..
@@ -1,652 +1,652 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
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 > 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 (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 $ cd ..
25 25
26 26
27 27 Rebasing
28 28 D onto H - simple rebase:
29 29
30 30 $ hg clone -q -u . a a1
31 31 $ cd a1
32 32
33 33 $ hg tglog
34 34 @ 7: 'H'
35 35 |
36 36 | o 6: 'G'
37 37 |/|
38 38 o | 5: 'F'
39 39 | |
40 40 | o 4: 'E'
41 41 |/
42 42 | o 3: 'D'
43 43 | |
44 44 | o 2: 'C'
45 45 | |
46 46 | o 1: 'B'
47 47 |/
48 48 o 0: 'A'
49 49
50 50
51 51 $ hg rebase -s 3 -d 7
52 52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
53 53
54 54 $ hg tglog
55 @ 7: 'D'
55 o 7: 'D'
56 56 |
57 o 6: 'H'
57 @ 6: 'H'
58 58 |
59 59 | o 5: 'G'
60 60 |/|
61 61 o | 4: 'F'
62 62 | |
63 63 | o 3: 'E'
64 64 |/
65 65 | o 2: 'C'
66 66 | |
67 67 | o 1: 'B'
68 68 |/
69 69 o 0: 'A'
70 70
71 71 $ cd ..
72 72
73 73
74 74 D onto F - intermediate point:
75 75
76 76 $ hg clone -q -u . a a2
77 77 $ cd a2
78 78
79 79 $ hg rebase -s 3 -d 5
80 80 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
81 81
82 82 $ hg tglog
83 @ 7: 'D'
83 o 7: 'D'
84 84 |
85 | o 6: 'H'
85 | @ 6: 'H'
86 86 |/
87 87 | o 5: 'G'
88 88 |/|
89 89 o | 4: 'F'
90 90 | |
91 91 | o 3: 'E'
92 92 |/
93 93 | o 2: 'C'
94 94 | |
95 95 | o 1: 'B'
96 96 |/
97 97 o 0: 'A'
98 98
99 99 $ cd ..
100 100
101 101
102 102 E onto H - skip of G:
103 103
104 104 $ hg clone -q -u . a a3
105 105 $ cd a3
106 106
107 107 $ hg rebase -s 4 -d 7
108 108 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
109 109
110 110 $ hg tglog
111 @ 6: 'E'
111 o 6: 'E'
112 112 |
113 o 5: 'H'
113 @ 5: 'H'
114 114 |
115 115 o 4: 'F'
116 116 |
117 117 | o 3: 'D'
118 118 | |
119 119 | o 2: 'C'
120 120 | |
121 121 | o 1: 'B'
122 122 |/
123 123 o 0: 'A'
124 124
125 125 $ cd ..
126 126
127 127
128 128 F onto E - rebase of a branching point (skip G):
129 129
130 130 $ hg clone -q -u . a a4
131 131 $ cd a4
132 132
133 133 $ hg rebase -s 5 -d 4
134 134 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
135 135
136 136 $ hg tglog
137 137 @ 6: 'H'
138 138 |
139 139 o 5: 'F'
140 140 |
141 141 o 4: 'E'
142 142 |
143 143 | o 3: 'D'
144 144 | |
145 145 | o 2: 'C'
146 146 | |
147 147 | o 1: 'B'
148 148 |/
149 149 o 0: 'A'
150 150
151 151 $ cd ..
152 152
153 153
154 154 G onto H - merged revision having a parent in ancestors of target:
155 155
156 156 $ hg clone -q -u . a a5
157 157 $ cd a5
158 158
159 159 $ hg rebase -s 6 -d 7
160 160 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
161 161
162 162 $ hg tglog
163 @ 7: 'G'
163 o 7: 'G'
164 164 |\
165 | o 6: 'H'
165 | @ 6: 'H'
166 166 | |
167 167 | o 5: 'F'
168 168 | |
169 169 o | 4: 'E'
170 170 |/
171 171 | o 3: 'D'
172 172 | |
173 173 | o 2: 'C'
174 174 | |
175 175 | o 1: 'B'
176 176 |/
177 177 o 0: 'A'
178 178
179 179 $ cd ..
180 180
181 181
182 182 F onto B - G maintains E as parent:
183 183
184 184 $ hg clone -q -u . a a6
185 185 $ cd a6
186 186
187 187 $ hg rebase -s 5 -d 1
188 188 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
189 189
190 190 $ hg tglog
191 191 @ 7: 'H'
192 192 |
193 193 | o 6: 'G'
194 194 |/|
195 195 o | 5: 'F'
196 196 | |
197 197 | o 4: 'E'
198 198 | |
199 199 | | o 3: 'D'
200 200 | | |
201 201 +---o 2: 'C'
202 202 | |
203 203 o | 1: 'B'
204 204 |/
205 205 o 0: 'A'
206 206
207 207 $ cd ..
208 208
209 209
210 210 These will fail (using --source):
211 211
212 212 G onto F - rebase onto an ancestor:
213 213
214 214 $ hg clone -q -u . a a7
215 215 $ cd a7
216 216
217 217 $ hg rebase -s 6 -d 5
218 218 nothing to rebase
219 219 [1]
220 220
221 221 F onto G - rebase onto a descendant:
222 222
223 223 $ hg rebase -s 5 -d 6
224 224 abort: source is ancestor of destination
225 225 [255]
226 226
227 227 G onto B - merge revision with both parents not in ancestors of target:
228 228
229 229 $ hg rebase -s 6 -d 1
230 230 abort: cannot use revision 6 as base, result would have 3 parents
231 231 [255]
232 232
233 233
234 234 These will abort gracefully (using --base):
235 235
236 236 G onto G - rebase onto same changeset:
237 237
238 238 $ hg rebase -b 6 -d 6
239 239 nothing to rebase
240 240 [1]
241 241
242 242 G onto F - rebase onto an ancestor:
243 243
244 244 $ hg rebase -b 6 -d 5
245 245 nothing to rebase
246 246 [1]
247 247
248 248 F onto G - rebase onto a descendant:
249 249
250 250 $ hg rebase -b 5 -d 6
251 251 nothing to rebase
252 252 [1]
253 253
254 254 C onto A - rebase onto an ancestor:
255 255
256 256 $ hg rebase -d 0 -s 2
257 257 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
258 258 $ hg tglog
259 @ 7: 'D'
259 o 7: 'D'
260 260 |
261 261 o 6: 'C'
262 262 |
263 | o 5: 'H'
263 | @ 5: 'H'
264 264 | |
265 265 | | o 4: 'G'
266 266 | |/|
267 267 | o | 3: 'F'
268 268 |/ /
269 269 | o 2: 'E'
270 270 |/
271 271 | o 1: 'B'
272 272 |/
273 273 o 0: 'A'
274 274
275 275
276 276 Check rebasing public changeset
277 277
278 278 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
279 279 $ hg rebase -d 0 -b 6
280 280 nothing to rebase
281 281 [1]
282 282 $ hg rebase -d 5 -b 6
283 283 abort: can't rebase immutable changeset e1c4361dd923
284 284 (see hg help phases for details)
285 285 [255]
286 286
287 287 $ hg rebase -d 5 -b 6 --keep
288 288
289 289 Check rebasing mutable changeset
290 290 Source phase greater or equal to destination phase: new changeset get the phase of source:
291 291 $ hg rebase -s9 -d0
292 292 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-backup.hg (glob)
293 293 $ hg log --template "{phase}\n" -r 9
294 294 draft
295 295 $ hg rebase -s9 -d1
296 296 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-backup.hg (glob)
297 297 $ hg log --template "{phase}\n" -r 9
298 298 draft
299 299 $ hg phase --force --secret 9
300 300 $ hg rebase -s9 -d0
301 301 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-backup.hg (glob)
302 302 $ hg log --template "{phase}\n" -r 9
303 303 secret
304 304 $ hg rebase -s9 -d1
305 305 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-backup.hg (glob)
306 306 $ hg log --template "{phase}\n" -r 9
307 307 secret
308 308 Source phase lower than destination phase: new changeset get the phase of destination:
309 309 $ hg rebase -s8 -d9
310 310 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-backup.hg (glob)
311 311 $ hg log --template "{phase}\n" -r 'rev(9)'
312 312 secret
313 313
314 314 $ cd ..
315 315
316 316 Test for revset
317 317
318 318 We need a bit different graph
319 319 All destination are B
320 320
321 321 $ hg init ah
322 322 $ cd ah
323 323 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
324 324 adding changesets
325 325 adding manifests
326 326 adding file changes
327 327 added 9 changesets with 9 changes to 9 files (+2 heads)
328 328 (run 'hg heads' to see heads, 'hg merge' to merge)
329 329 $ hg tglog
330 330 o 8: 'I'
331 331 |
332 332 o 7: 'H'
333 333 |
334 334 o 6: 'G'
335 335 |
336 336 | o 5: 'F'
337 337 | |
338 338 | o 4: 'E'
339 339 |/
340 340 o 3: 'D'
341 341 |
342 342 o 2: 'C'
343 343 |
344 344 | o 1: 'B'
345 345 |/
346 346 o 0: 'A'
347 347
348 348 $ cd ..
349 349
350 350
351 351 Simple case with keep:
352 352
353 353 Source on have two descendant heads but ask for one
354 354
355 355 $ hg clone -q -u . ah ah1
356 356 $ cd ah1
357 357 $ hg rebase -r '2::8' -d 1
358 358 abort: can't remove original changesets with unrebased descendants
359 359 (use --keep to keep original changesets)
360 360 [255]
361 361 $ hg rebase -r '2::8' -d 1 --keep
362 362 $ hg tglog
363 @ 13: 'I'
363 o 13: 'I'
364 364 |
365 365 o 12: 'H'
366 366 |
367 367 o 11: 'G'
368 368 |
369 369 o 10: 'D'
370 370 |
371 371 o 9: 'C'
372 372 |
373 373 | o 8: 'I'
374 374 | |
375 375 | o 7: 'H'
376 376 | |
377 377 | o 6: 'G'
378 378 | |
379 379 | | o 5: 'F'
380 380 | | |
381 381 | | o 4: 'E'
382 382 | |/
383 383 | o 3: 'D'
384 384 | |
385 385 | o 2: 'C'
386 386 | |
387 387 o | 1: 'B'
388 388 |/
389 389 o 0: 'A'
390 390
391 391
392 392 $ cd ..
393 393
394 394 Base on have one descendant heads we ask for but common ancestor have two
395 395
396 396 $ hg clone -q -u . ah ah2
397 397 $ cd ah2
398 398 $ hg rebase -r '3::8' -d 1
399 399 abort: can't remove original changesets with unrebased descendants
400 400 (use --keep to keep original changesets)
401 401 [255]
402 402 $ hg rebase -r '3::8' -d 1 --keep
403 403 $ hg tglog
404 @ 12: 'I'
404 o 12: 'I'
405 405 |
406 406 o 11: 'H'
407 407 |
408 408 o 10: 'G'
409 409 |
410 410 o 9: 'D'
411 411 |
412 412 | o 8: 'I'
413 413 | |
414 414 | o 7: 'H'
415 415 | |
416 416 | o 6: 'G'
417 417 | |
418 418 | | o 5: 'F'
419 419 | | |
420 420 | | o 4: 'E'
421 421 | |/
422 422 | o 3: 'D'
423 423 | |
424 424 | o 2: 'C'
425 425 | |
426 426 o | 1: 'B'
427 427 |/
428 428 o 0: 'A'
429 429
430 430
431 431 $ cd ..
432 432
433 433 rebase subset
434 434
435 435 $ hg clone -q -u . ah ah3
436 436 $ cd ah3
437 437 $ hg rebase -r '3::7' -d 1
438 438 abort: can't remove original changesets with unrebased descendants
439 439 (use --keep to keep original changesets)
440 440 [255]
441 441 $ hg rebase -r '3::7' -d 1 --keep
442 442 $ hg tglog
443 @ 11: 'H'
443 o 11: 'H'
444 444 |
445 445 o 10: 'G'
446 446 |
447 447 o 9: 'D'
448 448 |
449 449 | o 8: 'I'
450 450 | |
451 451 | o 7: 'H'
452 452 | |
453 453 | o 6: 'G'
454 454 | |
455 455 | | o 5: 'F'
456 456 | | |
457 457 | | o 4: 'E'
458 458 | |/
459 459 | o 3: 'D'
460 460 | |
461 461 | o 2: 'C'
462 462 | |
463 463 o | 1: 'B'
464 464 |/
465 465 o 0: 'A'
466 466
467 467
468 468 $ cd ..
469 469
470 470 rebase subset with multiple head
471 471
472 472 $ hg clone -q -u . ah ah4
473 473 $ cd ah4
474 474 $ hg rebase -r '3::(7+5)' -d 1
475 475 abort: can't remove original changesets with unrebased descendants
476 476 (use --keep to keep original changesets)
477 477 [255]
478 478 $ hg rebase -r '3::(7+5)' -d 1 --keep
479 479 $ hg tglog
480 @ 13: 'H'
480 o 13: 'H'
481 481 |
482 482 o 12: 'G'
483 483 |
484 484 | o 11: 'F'
485 485 | |
486 486 | o 10: 'E'
487 487 |/
488 488 o 9: 'D'
489 489 |
490 490 | o 8: 'I'
491 491 | |
492 492 | o 7: 'H'
493 493 | |
494 494 | o 6: 'G'
495 495 | |
496 496 | | o 5: 'F'
497 497 | | |
498 498 | | o 4: 'E'
499 499 | |/
500 500 | o 3: 'D'
501 501 | |
502 502 | o 2: 'C'
503 503 | |
504 504 o | 1: 'B'
505 505 |/
506 506 o 0: 'A'
507 507
508 508
509 509 $ cd ..
510 510
511 511 More advanced tests
512 512
513 513 rebase on ancestor with revset
514 514
515 515 $ hg clone -q -u . ah ah5
516 516 $ cd ah5
517 517 $ hg rebase -r '6::' -d 2
518 518 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
519 519 $ hg tglog
520 @ 8: 'I'
520 o 8: 'I'
521 521 |
522 522 o 7: 'H'
523 523 |
524 524 o 6: 'G'
525 525 |
526 526 | o 5: 'F'
527 527 | |
528 528 | o 4: 'E'
529 529 | |
530 530 | o 3: 'D'
531 531 |/
532 532 o 2: 'C'
533 533 |
534 534 | o 1: 'B'
535 535 |/
536 536 o 0: 'A'
537 537
538 538 $ cd ..
539 539
540 540
541 541 rebase with multiple root.
542 542 We rebase E and G on B
543 543 We would expect heads are I, F if it was supported
544 544
545 545 $ hg clone -q -u . ah ah6
546 546 $ cd ah6
547 547 $ hg rebase -r '(4+6)::' -d 1
548 548 saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
549 549 $ hg tglog
550 @ 8: 'I'
550 o 8: 'I'
551 551 |
552 552 o 7: 'H'
553 553 |
554 554 o 6: 'G'
555 555 |
556 556 | o 5: 'F'
557 557 | |
558 558 | o 4: 'E'
559 559 |/
560 560 | o 3: 'D'
561 561 | |
562 562 | o 2: 'C'
563 563 | |
564 564 o | 1: 'B'
565 565 |/
566 566 o 0: 'A'
567 567
568 568 $ cd ..
569 569
570 570 More complex rebase with multiple roots
571 571 each root have a different common ancestor with the destination and this is a detach
572 572
573 573 (setup)
574 574
575 575 $ hg clone -q -u . a a8
576 576 $ cd a8
577 577 $ echo I > I
578 578 $ hg add I
579 579 $ hg commit -m I
580 580 $ hg up 4
581 581 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
582 582 $ echo I > J
583 583 $ hg add J
584 584 $ hg commit -m J
585 585 created new head
586 586 $ echo I > K
587 587 $ hg add K
588 588 $ hg commit -m K
589 589 $ hg tglog
590 590 @ 10: 'K'
591 591 |
592 592 o 9: 'J'
593 593 |
594 594 | o 8: 'I'
595 595 | |
596 596 | o 7: 'H'
597 597 | |
598 598 +---o 6: 'G'
599 599 | |/
600 600 | o 5: 'F'
601 601 | |
602 602 o | 4: 'E'
603 603 |/
604 604 | o 3: 'D'
605 605 | |
606 606 | o 2: 'C'
607 607 | |
608 608 | o 1: 'B'
609 609 |/
610 610 o 0: 'A'
611 611
612 612 (actual test)
613 613
614 614 $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
615 615 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-backup.hg (glob)
616 616 $ hg log --rev 'children(desc(G))'
617 617 changeset: 9:adb617877056
618 618 parent: 6:eea13746799a
619 619 user: test
620 620 date: Thu Jan 01 00:00:00 1970 +0000
621 621 summary: I
622 622
623 623 changeset: 10:882431a34a0e
624 624 tag: tip
625 625 parent: 6:eea13746799a
626 626 user: test
627 627 date: Thu Jan 01 00:00:00 1970 +0000
628 628 summary: K
629 629
630 630 $ hg tglog
631 631 @ 10: 'K'
632 632 |
633 633 | o 9: 'I'
634 634 |/
635 635 | o 8: 'J'
636 636 | |
637 637 | | o 7: 'H'
638 638 | | |
639 639 o---+ 6: 'G'
640 640 |/ /
641 641 | o 5: 'F'
642 642 | |
643 643 o | 4: 'E'
644 644 |/
645 645 | o 3: 'D'
646 646 | |
647 647 | o 2: 'C'
648 648 | |
649 649 | o 1: 'B'
650 650 |/
651 651 o 0: 'A'
652 652
General Comments 0
You need to be logged in to leave comments. Login now