##// END OF EJS Templates
Fix up rebase's handling of strip backups
Matt Mackall -
r11201:34023f2c default
parent child Browse files
Show More
@@ -1,556 +1,558 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, error
18 18 from mercurial import extensions, ancestor, copies, patch
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
27 27 def rebase(ui, repo, **opts):
28 28 """move changeset (and descendants) to a different branch
29 29
30 30 Rebase uses repeated merging to graft changesets from one part of
31 31 history (the source) onto another (the destination). This can be
32 32 useful for linearizing *local* changes relative to a master
33 33 development tree.
34 34
35 35 You should not rebase changesets that have already been shared
36 36 with others. Doing so will force everybody else to perform the
37 37 same rebase or they will end up with duplicated changesets after
38 38 pulling in your rebased changesets.
39 39
40 40 If you don't specify a destination changeset (``-d/--dest``),
41 41 rebase uses the tipmost head of the current named branch as the
42 42 destination. (The destination changeset is not modified by
43 43 rebasing, but new changesets are added as its descendants.)
44 44
45 45 You can specify which changesets to rebase in two ways: as a
46 46 "source" changeset or as a "base" changeset. Both are shorthand
47 47 for a topologically related set of changesets (the "source
48 48 branch"). If you specify source (``-s/--source``), rebase will
49 49 rebase that changeset and all of its descendants onto dest. If you
50 50 specify base (``-b/--base``), rebase will select ancestors of base
51 51 back to but not including the common ancestor with dest. Thus,
52 52 ``-b`` is less precise but more convenient than ``-s``: you can
53 53 specify any changeset in the source branch, and rebase will select
54 54 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
55 55 uses the parent of the working directory as the base.
56 56
57 57 By default, rebase recreates the changesets in the source branch
58 58 as descendants of dest and then destroys the originals. Use
59 59 ``--keep`` to preserve the original source changesets. Some
60 60 changesets in the source branch (e.g. merges from the destination
61 61 branch) may be dropped if they no longer contribute any change.
62 62
63 63 One result of the rules for selecting the destination changeset
64 64 and source branch is that, unlike ``merge``, rebase will do
65 65 nothing if you are at the latest (tipmost) head of a named branch
66 66 with two heads. You need to explicitly specify source and/or
67 67 destination (or ``update`` to the other head, if it's the head of
68 68 the intended source branch).
69 69
70 70 If a rebase is interrupted to manually resolve a merge, it can be
71 71 continued with --continue/-c or aborted with --abort/-a.
72 72 """
73 73 originalwd = target = None
74 74 external = nullrev
75 75 state = {}
76 76 skipped = set()
77 77 targetancestors = set()
78 78
79 79 lock = wlock = None
80 80 try:
81 81 lock = repo.lock()
82 82 wlock = repo.wlock()
83 83
84 84 # Validate input and define rebasing points
85 85 destf = opts.get('dest', None)
86 86 srcf = opts.get('source', None)
87 87 basef = opts.get('base', None)
88 88 contf = opts.get('continue')
89 89 abortf = opts.get('abort')
90 90 collapsef = opts.get('collapse', False)
91 91 extrafn = opts.get('extrafn')
92 92 keepf = opts.get('keep', False)
93 93 keepbranchesf = opts.get('keepbranches', False)
94 94 detachf = opts.get('detach', False)
95 95 # keepopen is not meant for use on the command line, but by
96 96 # other extensions
97 97 keepopen = opts.get('keepopen', False)
98 98
99 99 if contf or abortf:
100 100 if contf and abortf:
101 101 raise error.ParseError('rebase',
102 102 _('cannot use both abort and continue'))
103 103 if collapsef:
104 104 raise error.ParseError(
105 105 'rebase', _('cannot use collapse with continue or abort'))
106 106
107 107 if detachf:
108 108 raise error.ParseError(
109 109 'rebase', _('cannot use detach with continue or abort'))
110 110
111 111 if srcf or basef or destf:
112 112 raise error.ParseError('rebase',
113 113 _('abort and continue do not allow specifying revisions'))
114 114
115 115 (originalwd, target, state, collapsef, keepf,
116 116 keepbranchesf, external) = restorestatus(repo)
117 117 if abortf:
118 118 abort(repo, originalwd, target, state)
119 119 return
120 120 else:
121 121 if srcf and basef:
122 122 raise error.ParseError('rebase', _('cannot specify both a '
123 123 'revision and a base'))
124 124 if detachf:
125 125 if not srcf:
126 126 raise error.ParseError(
127 127 'rebase', _('detach requires a revision to be specified'))
128 128 if basef:
129 129 raise error.ParseError(
130 130 'rebase', _('cannot specify a base with detach'))
131 131
132 132 cmdutil.bail_if_changed(repo)
133 133 result = buildstate(repo, destf, srcf, basef, detachf)
134 134 if not result:
135 135 # Empty state built, nothing to rebase
136 136 ui.status(_('nothing to rebase\n'))
137 137 return
138 138 else:
139 139 originalwd, target, state = result
140 140 if collapsef:
141 141 targetancestors = set(repo.changelog.ancestors(target))
142 142 external = checkexternal(repo, state, targetancestors)
143 143
144 144 if keepbranchesf:
145 145 if extrafn:
146 146 raise error.ParseError(
147 147 'rebase', _('cannot use both keepbranches and extrafn'))
148 148 def extrafn(ctx, extra):
149 149 extra['branch'] = ctx.branch()
150 150
151 151 # Rebase
152 152 if not targetancestors:
153 153 targetancestors = set(repo.changelog.ancestors(target))
154 154 targetancestors.add(target)
155 155
156 156 for rev in sorted(state):
157 157 if state[rev] == -1:
158 158 ui.debug("rebasing %d:%s\n" % (rev, repo[rev]))
159 159 storestatus(repo, originalwd, target, state, collapsef, keepf,
160 160 keepbranchesf, external)
161 161 p1, p2 = defineparents(repo, rev, target, state,
162 162 targetancestors)
163 163 if len(repo.parents()) == 2:
164 164 repo.ui.debug('resuming interrupted rebase\n')
165 165 else:
166 166 stats = rebasenode(repo, rev, p1, p2, state)
167 167 if stats and stats[3] > 0:
168 168 raise util.Abort(_('fix unresolved conflicts with hg '
169 169 'resolve then run hg rebase --continue'))
170 170 updatedirstate(repo, rev, target, p2)
171 171 if not collapsef:
172 172 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
173 173 else:
174 174 # Skip commit if we are collapsing
175 175 repo.dirstate.setparents(repo[p1].node())
176 176 newrev = None
177 177 # Update the state
178 178 if newrev is not None:
179 179 state[rev] = repo[newrev].rev()
180 180 else:
181 181 if not collapsef:
182 182 ui.note(_('no changes, revision %d skipped\n') % rev)
183 183 ui.debug('next revision set to %s\n' % p1)
184 184 skipped.add(rev)
185 185 state[rev] = p1
186 186
187 187 ui.note(_('rebase merging completed\n'))
188 188
189 189 if collapsef and not keepopen:
190 190 p1, p2 = defineparents(repo, min(state), target,
191 191 state, targetancestors)
192 192 commitmsg = 'Collapsed revision'
193 193 for rebased in state:
194 194 if rebased not in skipped and state[rebased] != nullmerge:
195 195 commitmsg += '\n* %s' % repo[rebased].description()
196 196 commitmsg = ui.edit(commitmsg, repo.ui.username())
197 197 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
198 198 extrafn=extrafn)
199 199
200 200 if 'qtip' in repo.tags():
201 201 updatemq(repo, state, skipped, **opts)
202 202
203 203 if not keepf:
204 204 # Remove no more useful revisions
205 205 rebased = [rev for rev in state if state[rev] != nullmerge]
206 206 if rebased:
207 207 if set(repo.changelog.descendants(min(rebased))) - set(state):
208 208 ui.warn(_("warning: new changesets detected "
209 209 "on source branch, not stripping\n"))
210 210 else:
211 repair.strip(ui, repo, repo[min(rebased)].node(), "strip")
211 # backup the old csets by default
212 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
212 213
213 214 clearstatus(repo)
214 215 ui.status(_("rebase completed\n"))
215 216 if os.path.exists(repo.sjoin('undo')):
216 217 util.unlink(repo.sjoin('undo'))
217 218 if skipped:
218 219 ui.note(_("%d revisions have been skipped\n") % len(skipped))
219 220 finally:
220 221 release(lock, wlock)
221 222
222 223 def rebasemerge(repo, rev, first=False):
223 224 'return the correct ancestor'
224 225 oldancestor = ancestor.ancestor
225 226
226 227 def newancestor(a, b, pfunc):
227 228 if b == rev:
228 229 return repo[rev].parents()[0].rev()
229 230 return oldancestor(a, b, pfunc)
230 231
231 232 if not first:
232 233 ancestor.ancestor = newancestor
233 234 else:
234 235 repo.ui.debug("first revision, do not change ancestor\n")
235 236 try:
236 237 stats = merge.update(repo, rev, True, True, False)
237 238 return stats
238 239 finally:
239 240 ancestor.ancestor = oldancestor
240 241
241 242 def checkexternal(repo, state, targetancestors):
242 243 """Check whether one or more external revisions need to be taken in
243 244 consideration. In the latter case, abort.
244 245 """
245 246 external = nullrev
246 247 source = min(state)
247 248 for rev in state:
248 249 if rev == source:
249 250 continue
250 251 # Check externals and fail if there are more than one
251 252 for p in repo[rev].parents():
252 253 if (p.rev() not in state
253 254 and p.rev() not in targetancestors):
254 255 if external != nullrev:
255 256 raise util.Abort(_('unable to collapse, there is more '
256 257 'than one external parent'))
257 258 external = p.rev()
258 259 return external
259 260
260 261 def updatedirstate(repo, rev, p1, p2):
261 262 """Keep track of renamed files in the revision that is going to be rebased
262 263 """
263 264 # Here we simulate the copies and renames in the source changeset
264 265 cop, diver = copies.copies(repo, repo[rev], repo[p1], repo[p2], True)
265 266 m1 = repo[rev].manifest()
266 267 m2 = repo[p1].manifest()
267 268 for k, v in cop.iteritems():
268 269 if k in m1:
269 270 if v in m1 or v in m2:
270 271 repo.dirstate.copy(v, k)
271 272 if v in m2 and v not in m1:
272 273 repo.dirstate.remove(v)
273 274
274 275 def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
275 276 'Commit the changes and store useful information in extra'
276 277 try:
277 278 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
278 279 if commitmsg is None:
279 280 commitmsg = repo[rev].description()
280 281 ctx = repo[rev]
281 282 extra = {'rebase_source': ctx.hex()}
282 283 if extrafn:
283 284 extrafn(ctx, extra)
284 285 # Commit might fail if unresolved files exist
285 286 newrev = repo.commit(text=commitmsg, user=ctx.user(),
286 287 date=ctx.date(), extra=extra)
287 288 repo.dirstate.setbranch(repo[newrev].branch())
288 289 return newrev
289 290 except util.Abort:
290 291 # Invalidate the previous setparents
291 292 repo.dirstate.invalidate()
292 293 raise
293 294
294 295 def rebasenode(repo, rev, p1, p2, state):
295 296 'Rebase a single revision'
296 297 # Merge phase
297 298 # Update to target and merge it with local
298 299 if repo['.'].rev() != repo[p1].rev():
299 300 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
300 301 merge.update(repo, p1, False, True, False)
301 302 else:
302 303 repo.ui.debug(" already in target\n")
303 304 repo.dirstate.write()
304 305 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
305 306 first = repo[rev].rev() == repo[min(state)].rev()
306 307 stats = rebasemerge(repo, rev, first)
307 308 return stats
308 309
309 310 def defineparents(repo, rev, target, state, targetancestors):
310 311 'Return the new parent relationship of the revision that will be rebased'
311 312 parents = repo[rev].parents()
312 313 p1 = p2 = nullrev
313 314
314 315 P1n = parents[0].rev()
315 316 if P1n in targetancestors:
316 317 p1 = target
317 318 elif P1n in state:
318 319 if state[P1n] == nullmerge:
319 320 p1 = target
320 321 else:
321 322 p1 = state[P1n]
322 323 else: # P1n external
323 324 p1 = target
324 325 p2 = P1n
325 326
326 327 if len(parents) == 2 and parents[1].rev() not in targetancestors:
327 328 P2n = parents[1].rev()
328 329 # interesting second parent
329 330 if P2n in state:
330 331 if p1 == target: # P1n in targetancestors or external
331 332 p1 = state[P2n]
332 333 else:
333 334 p2 = state[P2n]
334 335 else: # P2n external
335 336 if p2 != nullrev: # P1n external too => rev is a merged revision
336 337 raise util.Abort(_('cannot use revision %d as base, result '
337 338 'would have 3 parents') % rev)
338 339 p2 = P2n
339 340 repo.ui.debug(" future parents are %d and %d\n" %
340 341 (repo[p1].rev(), repo[p2].rev()))
341 342 return p1, p2
342 343
343 344 def isagitpatch(repo, patchname):
344 345 'Return true if the given patch is in git format'
345 346 mqpatch = os.path.join(repo.mq.path, patchname)
346 347 for line in patch.linereader(file(mqpatch, 'rb')):
347 348 if line.startswith('diff --git'):
348 349 return True
349 350 return False
350 351
351 352 def updatemq(repo, state, skipped, **opts):
352 353 'Update rebased mq patches - finalize and then import them'
353 354 mqrebase = {}
354 355 for p in repo.mq.applied:
355 356 if repo[p.node].rev() in state:
356 357 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
357 358 (repo[p.node].rev(), p.name))
358 359 mqrebase[repo[p.node].rev()] = (p.name, isagitpatch(repo, p.name))
359 360
360 361 if mqrebase:
361 362 repo.mq.finish(repo, mqrebase.keys())
362 363
363 364 # We must start import from the newest revision
364 365 for rev in sorted(mqrebase, reverse=True):
365 366 if rev not in skipped:
366 367 repo.ui.debug('import mq patch %d (%s)\n'
367 368 % (state[rev], mqrebase[rev][0]))
368 369 repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
369 370 git=mqrebase[rev][1],rev=[str(state[rev])])
370 371 repo.mq.save_dirty()
371 372
372 373 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
373 374 external):
374 375 'Store the current status to allow recovery'
375 376 f = repo.opener("rebasestate", "w")
376 377 f.write(repo[originalwd].hex() + '\n')
377 378 f.write(repo[target].hex() + '\n')
378 379 f.write(repo[external].hex() + '\n')
379 380 f.write('%d\n' % int(collapse))
380 381 f.write('%d\n' % int(keep))
381 382 f.write('%d\n' % int(keepbranches))
382 383 for d, v in state.iteritems():
383 384 oldrev = repo[d].hex()
384 385 newrev = repo[v].hex()
385 386 f.write("%s:%s\n" % (oldrev, newrev))
386 387 f.close()
387 388 repo.ui.debug('rebase status stored\n')
388 389
389 390 def clearstatus(repo):
390 391 'Remove the status files'
391 392 if os.path.exists(repo.join("rebasestate")):
392 393 util.unlink(repo.join("rebasestate"))
393 394
394 395 def restorestatus(repo):
395 396 'Restore a previously stored status'
396 397 try:
397 398 target = None
398 399 collapse = False
399 400 external = nullrev
400 401 state = {}
401 402 f = repo.opener("rebasestate")
402 403 for i, l in enumerate(f.read().splitlines()):
403 404 if i == 0:
404 405 originalwd = repo[l].rev()
405 406 elif i == 1:
406 407 target = repo[l].rev()
407 408 elif i == 2:
408 409 external = repo[l].rev()
409 410 elif i == 3:
410 411 collapse = bool(int(l))
411 412 elif i == 4:
412 413 keep = bool(int(l))
413 414 elif i == 5:
414 415 keepbranches = bool(int(l))
415 416 else:
416 417 oldrev, newrev = l.split(':')
417 418 state[repo[oldrev].rev()] = repo[newrev].rev()
418 419 repo.ui.debug('rebase status resumed\n')
419 420 return originalwd, target, state, collapse, keep, keepbranches, external
420 421 except IOError, err:
421 422 if err.errno != errno.ENOENT:
422 423 raise
423 424 raise util.Abort(_('no rebase in progress'))
424 425
425 426 def abort(repo, originalwd, target, state):
426 427 'Restore the repository to its original state'
427 428 if set(repo.changelog.descendants(target)) - set(state.values()):
428 429 repo.ui.warn(_("warning: new changesets detected on target branch, "
429 430 "not stripping\n"))
430 431 else:
431 432 # Strip from the first rebased revision
432 433 merge.update(repo, repo[originalwd].rev(), False, True, False)
433 434 rebased = filter(lambda x: x > -1, state.values())
434 435 if rebased:
435 436 strippoint = min(rebased)
436 repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
437 # no backup of rebased cset versions needed
438 repair.strip(repo.ui, repo, repo[strippoint].node())
437 439 clearstatus(repo)
438 440 repo.ui.status(_('rebase aborted\n'))
439 441
440 442 def buildstate(repo, dest, src, base, detach):
441 443 'Define which revisions are going to be rebased and where'
442 444 targetancestors = set()
443 445 detachset = set()
444 446
445 447 if not dest:
446 448 # Destination defaults to the latest revision in the current branch
447 449 branch = repo[None].branch()
448 450 dest = repo[branch].rev()
449 451 else:
450 452 dest = repo[dest].rev()
451 453
452 454 # This check isn't strictly necessary, since mq detects commits over an
453 455 # applied patch. But it prevents messing up the working directory when
454 456 # a partially completed rebase is blocked by mq.
455 457 if 'qtip' in repo.tags() and (repo[dest].node() in
456 458 [s.node for s in repo.mq.applied]):
457 459 raise util.Abort(_('cannot rebase onto an applied mq patch'))
458 460
459 461 if src:
460 462 commonbase = repo[src].ancestor(repo[dest])
461 463 if commonbase == repo[src]:
462 464 raise util.Abort(_('source is ancestor of destination'))
463 465 if commonbase == repo[dest]:
464 466 raise util.Abort(_('source is descendant of destination'))
465 467 source = repo[src].rev()
466 468 if detach:
467 469 # We need to keep track of source's ancestors up to the common base
468 470 srcancestors = set(repo.changelog.ancestors(source))
469 471 baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
470 472 detachset = srcancestors - baseancestors
471 473 detachset.remove(commonbase.rev())
472 474 else:
473 475 if base:
474 476 cwd = repo[base].rev()
475 477 else:
476 478 cwd = repo['.'].rev()
477 479
478 480 if cwd == dest:
479 481 repo.ui.debug('source and destination are the same\n')
480 482 return None
481 483
482 484 targetancestors = set(repo.changelog.ancestors(dest))
483 485 if cwd in targetancestors:
484 486 repo.ui.debug('source is ancestor of destination\n')
485 487 return None
486 488
487 489 cwdancestors = set(repo.changelog.ancestors(cwd))
488 490 if dest in cwdancestors:
489 491 repo.ui.debug('source is descendant of destination\n')
490 492 return None
491 493
492 494 cwdancestors.add(cwd)
493 495 rebasingbranch = cwdancestors - targetancestors
494 496 source = min(rebasingbranch)
495 497
496 498 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
497 499 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
498 500 state.update(dict.fromkeys(detachset, nullmerge))
499 501 state[source] = nullrev
500 502 return repo['.'].rev(), repo[dest].rev(), state
501 503
502 504 def pullrebase(orig, ui, repo, *args, **opts):
503 505 'Call rebase after pull if the latter has been invoked with --rebase'
504 506 if opts.get('rebase'):
505 507 if opts.get('update'):
506 508 del opts['update']
507 509 ui.debug('--update and --rebase are not compatible, ignoring '
508 510 'the update flag\n')
509 511
510 512 cmdutil.bail_if_changed(repo)
511 513 revsprepull = len(repo)
512 514 origpostincoming = commands.postincoming
513 515 def _dummy(*args, **kwargs):
514 516 pass
515 517 commands.postincoming = _dummy
516 518 try:
517 519 orig(ui, repo, *args, **opts)
518 520 finally:
519 521 commands.postincoming = origpostincoming
520 522 revspostpull = len(repo)
521 523 if revspostpull > revsprepull:
522 524 rebase(ui, repo, **opts)
523 525 branch = repo[None].branch()
524 526 dest = repo[branch].rev()
525 527 if dest != repo['.'].rev():
526 528 # there was nothing to rebase we force an update
527 529 hg.update(repo, dest)
528 530 else:
529 531 orig(ui, repo, *args, **opts)
530 532
531 533 def uisetup(ui):
532 534 'Replace pull with a decorator to provide --rebase option'
533 535 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
534 536 entry[1].append(('', 'rebase', None,
535 537 _("rebase working directory to branch head"))
536 538 )
537 539
538 540 cmdtable = {
539 541 "rebase":
540 542 (rebase,
541 543 [
542 544 ('s', 'source', '', _('rebase from the specified changeset')),
543 545 ('b', 'base', '', _('rebase from the base of the specified changeset '
544 546 '(up to greatest common ancestor of base and dest)')),
545 547 ('d', 'dest', '', _('rebase onto the specified changeset')),
546 548 ('', 'collapse', False, _('collapse the rebased changesets')),
547 549 ('', 'keep', False, _('keep original changesets')),
548 550 ('', 'keepbranches', False, _('keep original branch names')),
549 551 ('', 'detach', False, _('force detaching of source from its original '
550 552 'branch')),
551 553 ('c', 'continue', False, _('continue an interrupted rebase')),
552 554 ('a', 'abort', False, _('abort an interrupted rebase'))] +
553 555 templateopts,
554 556 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
555 557 'hg rebase {-a|-c}'))
556 558 }
@@ -1,43 +1,44 b''
1 1 % initialize repository
2 2 adding a
3 3 adding b
4 4 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
5 5 adding c
6 6 created new head
7 7 adding d
8 8 % bookmark list
9 9 * two 3:2ae46b1d99a7
10 10 one 1:925d80f479bb
11 11 % rebase
12 saved backup bundle to
12 13 adding branch
13 14 adding changesets
14 15 adding manifests
15 16 adding file changes
16 17 added 1 changesets with 1 changes to 1 files (-1 heads)
17 18 rebase completed
18 19 changeset: 3:9163974d1cb5
19 20 tag: one
20 21 tag: tip
21 22 tag: two
22 23 parent: 1:925d80f479bb
23 24 parent: 2:db815d6d32e6
24 25 user: test
25 26 date: Thu Jan 01 00:00:00 1970 +0000
26 27 summary: 3
27 28
28 29 changeset: 2:db815d6d32e6
29 30 parent: 0:f7b1eb17ad24
30 31 user: test
31 32 date: Thu Jan 01 00:00:00 1970 +0000
32 33 summary: 2
33 34
34 35 changeset: 1:925d80f479bb
35 36 user: test
36 37 date: Thu Jan 01 00:00:00 1970 +0000
37 38 summary: 1
38 39
39 40 changeset: 0:f7b1eb17ad24
40 41 user: test
41 42 date: Thu Jan 01 00:00:00 1970 +0000
42 43 summary: 0
43 44
@@ -1,31 +1,32 b''
1 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 created new head
3 3 @ 4: L2
4 4 |
5 5 o 3: L1
6 6 |
7 7 | o 2: C3
8 8 |/
9 9 o 1: C2
10 10 |
11 11 o 0: C1
12 12
13 13
14 14 % Conflicting rebase
15 15 warning: conflicts during merge.
16 16 merging common failed!
17 17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
18 18 merging common
19 19
20 20 % Abort
21 saved backup bundle to
21 22 rebase aborted
22 23 @ 4: L2
23 24 |
24 25 o 3: L1
25 26 |
26 27 | o 2: C3
27 28 |/
28 29 o 1: C2
29 30 |
30 31 o 0: C1
31 32
@@ -1,183 +1,186 b''
1 1
2 2 @ 8:c11d5b3e9c00 F branch: branch3
3 3 |
4 4 o 7:33c9da881988 Branch3 branch: branch3
5 5 |
6 6 | o 6:0e4064ab11a3 E branch: branch2
7 7 | |
8 8 | o 5:5ac035cb5d8f D branch: branch2
9 9 | |
10 10 | | o 4:8e66061486ee C branch: branch2
11 11 | | |
12 12 +---o 3:99567862abbe Branch2 branch: branch2
13 13 | |
14 14 | o 2:65a26a4d12f6 B branch: branch1
15 15 | |
16 16 | o 1:0f3f3010ee16 Branch1 branch: branch1
17 17 |/
18 18 o 0:1994f17a630e A branch:
19 19
20 20
21 21 % Branches
22 22 branch3 8:c11d5b3e9c00
23 23 branch2 6:0e4064ab11a3
24 24 branch1 2:65a26a4d12f6 (inactive)
25 25 default 0:1994f17a630e (inactive)
26 26
27 27 % Heads
28 28 8:c11d5b3e9c00 F branch: branch3
29 29 6:0e4064ab11a3 E branch: branch2
30 30 4:8e66061486ee C branch: branch2
31 31 2:65a26a4d12f6 B branch: branch1
32 32 0:1994f17a630e A branch:
33 33
34 34 % Rebase part of branch2 (5-6) onto branch3 (8)
35 saved backup bundle to
35 36 adding branch
36 37 adding changesets
37 38 adding manifests
38 39 adding file changes
39 40 added 4 changesets with 3 changes to 3 files (+1 heads)
40 41 rebase completed
41 42
42 43 % Branches
43 44 branch3 8:c9bfa9beb84e
44 45 branch2 4:8e66061486ee
45 46 branch1 2:65a26a4d12f6
46 47 default 0:1994f17a630e (inactive)
47 48
48 49 % Heads
49 50 8:c9bfa9beb84e E branch: branch3
50 51 4:8e66061486ee C branch: branch2
51 52 2:65a26a4d12f6 B branch: branch1
52 53 0:1994f17a630e A branch:
53 54
54 55 @ 8:c9bfa9beb84e E branch: branch3
55 56 |
56 57 o 7:bf9037384081 D branch: branch3
57 58 |
58 59 o 6:c11d5b3e9c00 F branch: branch3
59 60 |
60 61 o 5:33c9da881988 Branch3 branch: branch3
61 62 |
62 63 | o 4:8e66061486ee C branch: branch2
63 64 | |
64 65 | o 3:99567862abbe Branch2 branch: branch2
65 66 |/
66 67 | o 2:65a26a4d12f6 B branch: branch1
67 68 | |
68 69 | o 1:0f3f3010ee16 Branch1 branch: branch1
69 70 |/
70 71 o 0:1994f17a630e A branch:
71 72
72 73
73 74 % Rebase head of branch3 (8) onto branch2 (6)
74 75 @ 8:c11d5b3e9c00 F branch: branch3
75 76 |
76 77 o 7:33c9da881988 Branch3 branch: branch3
77 78 |
78 79 | o 6:0e4064ab11a3 E branch: branch2
79 80 | |
80 81 | o 5:5ac035cb5d8f D branch: branch2
81 82 | |
82 83 | | o 4:8e66061486ee C branch: branch2
83 84 | | |
84 85 +---o 3:99567862abbe Branch2 branch: branch2
85 86 | |
86 87 | o 2:65a26a4d12f6 B branch: branch1
87 88 | |
88 89 | o 1:0f3f3010ee16 Branch1 branch: branch1
89 90 |/
90 91 o 0:1994f17a630e A branch:
91 92
93 saved backup bundle to
92 94 adding branch
93 95 adding changesets
94 96 adding manifests
95 97 adding file changes
96 98 added 1 changesets with 1 changes to 1 files
97 99 rebase completed
98 100
99 101 % Branches
100 102 branch2 8:b44d3024f247
101 103 branch3 7:33c9da881988
102 104 branch1 2:65a26a4d12f6 (inactive)
103 105 default 0:1994f17a630e (inactive)
104 106
105 107 % Heads
106 108 8:b44d3024f247 F branch: branch2
107 109 7:33c9da881988 Branch3 branch: branch3
108 110 4:8e66061486ee C branch: branch2
109 111 2:65a26a4d12f6 B branch: branch1
110 112 0:1994f17a630e A branch:
111 113
112 114 @ 8:b44d3024f247 F branch: branch2
113 115 |
114 116 | o 7:33c9da881988 Branch3 branch: branch3
115 117 | |
116 118 o | 6:0e4064ab11a3 E branch: branch2
117 119 | |
118 120 o | 5:5ac035cb5d8f D branch: branch2
119 121 | |
120 122 | | o 4:8e66061486ee C branch: branch2
121 123 | | |
122 124 | | o 3:99567862abbe Branch2 branch: branch2
123 125 | |/
124 126 o | 2:65a26a4d12f6 B branch: branch1
125 127 | |
126 128 o | 1:0f3f3010ee16 Branch1 branch: branch1
127 129 |/
128 130 o 0:1994f17a630e A branch:
129 131
130 132
131 133 % Rebase entire branch3 (7-8) onto branch2 (6)
132 134 @ 8:c11d5b3e9c00 F branch: branch3
133 135 |
134 136 o 7:33c9da881988 Branch3 branch: branch3
135 137 |
136 138 | o 6:0e4064ab11a3 E branch: branch2
137 139 | |
138 140 | o 5:5ac035cb5d8f D branch: branch2
139 141 | |
140 142 | | o 4:8e66061486ee C branch: branch2
141 143 | | |
142 144 +---o 3:99567862abbe Branch2 branch: branch2
143 145 | |
144 146 | o 2:65a26a4d12f6 B branch: branch1
145 147 | |
146 148 | o 1:0f3f3010ee16 Branch1 branch: branch1
147 149 |/
148 150 o 0:1994f17a630e A branch:
149 151
152 saved backup bundle to
150 153 adding branch
151 154 adding changesets
152 155 adding manifests
153 156 adding file changes
154 157 added 1 changesets with 1 changes to 1 files
155 158 rebase completed
156 159
157 160 % Branches
158 161 branch2 7:b44d3024f247
159 162 branch1 2:65a26a4d12f6 (inactive)
160 163 default 0:1994f17a630e (inactive)
161 164
162 165 % Heads
163 166 7:b44d3024f247 F branch: branch2
164 167 4:8e66061486ee C branch: branch2
165 168 2:65a26a4d12f6 B branch: branch1
166 169 0:1994f17a630e A branch:
167 170
168 171 @ 7:b44d3024f247 F branch: branch2
169 172 |
170 173 o 6:0e4064ab11a3 E branch: branch2
171 174 |
172 175 o 5:5ac035cb5d8f D branch: branch2
173 176 |
174 177 | o 4:8e66061486ee C branch: branch2
175 178 | |
176 179 | o 3:99567862abbe Branch2 branch: branch2
177 180 | |
178 181 o | 2:65a26a4d12f6 B branch: branch1
179 182 | |
180 183 o | 1:0f3f3010ee16 Branch1 branch: branch1
181 184 |/
182 185 o 0:1994f17a630e A branch:
183 186
@@ -1,75 +1,76 b''
1 1
2 2 % - Rebasing B onto E - check keep
3 3 @ 5:F:notdefault
4 4 |
5 5 | o 4:E:
6 6 | |
7 7 | o 3:D:
8 8 |/
9 9 | o 2:C:
10 10 | |
11 11 | o 1:B:
12 12 |/
13 13 o 0:A:
14 14
15 15 warning: conflicts during merge.
16 16 merging A failed!
17 17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
18 18 merging A
19 19
20 20 % - Solve the conflict and go on
21 21 rebase completed
22 22 @ 7:C:
23 23 |
24 24 o 6:B:
25 25 |
26 26 | o 5:F:notdefault
27 27 | |
28 28 o | 4:E:
29 29 | |
30 30 o | 3:D:
31 31 |/
32 32 | o 2:C:
33 33 | |
34 34 | o 1:B:
35 35 |/
36 36 o 0:A:
37 37
38 38
39 39 % - Rebase F onto E - check keepbranches
40 40 @ 5:F:notdefault
41 41 |
42 42 | o 4:E:
43 43 | |
44 44 | o 3:D:
45 45 |/
46 46 | o 2:C:
47 47 | |
48 48 | o 1:B:
49 49 |/
50 50 o 0:A:
51 51
52 52 warning: conflicts during merge.
53 53 merging A failed!
54 54 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
55 55 merging A
56 56
57 57 % - Solve the conflict and go on
58 saved backup bundle to
58 59 adding branch
59 60 adding changesets
60 61 adding manifests
61 62 adding file changes
62 63 added 1 changesets with 1 changes to 1 files
63 64 rebase completed
64 65 @ 5:F:notdefault
65 66 |
66 67 o 4:E:
67 68 |
68 69 o 3:D:
69 70 |
70 71 | o 2:C:
71 72 | |
72 73 | o 1:B:
73 74 |/
74 75 o 0:A:
75 76
@@ -1,210 +1,215 b''
1 1 @ 7: H
2 2 |
3 3 | o 6: G
4 4 |/|
5 5 o | 5: F
6 6 | |
7 7 | o 4: E
8 8 |/
9 9 | o 3: D
10 10 | |
11 11 | o 2: C
12 12 | |
13 13 | o 1: B
14 14 |/
15 15 o 0: A
16 16
17 17 % Rebasing B onto H
18 18 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
19 saved backup bundle to
19 20 adding branch
20 21 adding changesets
21 22 adding manifests
22 23 adding file changes
23 24 added 5 changesets with 6 changes to 6 files (+1 heads)
24 25 rebase completed
25 26 @ 5: Collapsed revision
26 27 | * B
27 28 | * C
28 29 | * D
29 30 o 4: H
30 31 |
31 32 | o 3: G
32 33 |/|
33 34 o | 2: F
34 35 | |
35 36 | o 1: E
36 37 |/
37 38 o 0: A
38 39
39 40 Expected A, B, C, D, F, H
40 41 A
41 42 B
42 43 C
43 44 D
44 45 F
45 46 H
46 47
47 48 % Rebasing G onto H
49 saved backup bundle to
48 50 adding branch
49 51 adding changesets
50 52 adding manifests
51 53 adding file changes
52 54 added 3 changesets with 3 changes to 3 files (+1 heads)
53 55 rebase completed
54 56 @ 6: Collapsed revision
55 57 | * E
56 58 | * G
57 59 o 5: H
58 60 |
59 61 o 4: F
60 62 |
61 63 | o 3: D
62 64 | |
63 65 | o 2: C
64 66 | |
65 67 | o 1: B
66 68 |/
67 69 o 0: A
68 70
69 71 Expected A, E, F, H
70 72 A
71 73 E
72 74 F
73 75 H
74 76
75 77 @ 7: H
76 78 |
77 79 | o 6: G
78 80 | |\
79 81 | | o 5: F
80 82 | | |
81 83 | | o 4: E
82 84 | | |
83 85 | o | 3: D
84 86 | |\|
85 87 | o | 2: C
86 88 |/ /
87 89 | o 1: B
88 90 |/
89 91 o 0: A
90 92
91 93
92 94 % Rebase and collapse - more than one external (fail)
93 95 abort: unable to collapse, there is more than one external parent
94 96
95 97 % Rebase and collapse - E onto H
98 saved backup bundle to
96 99 adding branch
97 100 adding changesets
98 101 adding manifests
99 102 adding file changes
100 103 added 2 changesets with 3 changes to 3 files
101 104 rebase completed
102 105 @ 5: Collapsed revision
103 106 |\ * E
104 107 | | * F
105 108 | | * G
106 109 | o 4: H
107 110 | |
108 111 o | 3: D
109 112 |\ \
110 113 | o | 2: C
111 114 | |/
112 115 o / 1: B
113 116 |/
114 117 o 0: A
115 118
116 119 Expected A, B, C, E, F, H
117 120 A
118 121 B
119 122 C
120 123 E
121 124 F
122 125 H
123 126
124 127 @ 8: I
125 128 |
126 129 | o 7: H
127 130 | |\
128 131 | | o 6: G
129 132 | | |
130 133 | | o 5: F
131 134 | | |
132 135 | | o 4: E
133 136 | | |
134 137 | o | 3: D
135 138 | |\|
136 139 | o | 2: C
137 140 |/ /
138 141 | o 1: B
139 142 |/
140 143 o 0: A
141 144
142 145
143 146 % Rebase and collapse - E onto I
144 147 merging E
148 saved backup bundle to
145 149 adding branch
146 150 adding changesets
147 151 adding manifests
148 152 adding file changes
149 153 added 2 changesets with 3 changes to 3 files
150 154 rebase completed
151 155 @ 5: Collapsed revision
152 156 |\ * E
153 157 | | * F
154 158 | | * G
155 159 | | * H
156 160 | o 4: I
157 161 | |
158 162 o | 3: D
159 163 |\ \
160 164 | o | 2: C
161 165 | |/
162 166 o / 1: B
163 167 |/
164 168 o 0: A
165 169
166 170 Expected A, B, C, E, G, I
167 171 A
168 172 B
169 173 C
170 174 E
171 175 G
172 176 I
173 177 Cat E:
174 178 F
175 179
176 180 @ 5: F
177 181 |
178 182 | o 4: E
179 183 | |\
180 184 | | o 3: D
181 185 | | |
182 186 | o | 2: C
183 187 | |/
184 188 | o 1: B
185 189 |/
186 190 o 0: A
187 191
188 192
189 193 % Rebase and collapse - B onto F
194 saved backup bundle to
190 195 adding branch
191 196 adding changesets
192 197 adding manifests
193 198 adding file changes
194 199 added 2 changesets with 4 changes to 4 files
195 200 rebase completed
196 201 @ 2: Collapsed revision
197 202 | * B
198 203 | * C
199 204 | * D
200 205 | * E
201 206 o 1: F
202 207 |
203 208 o 0: A
204 209
205 210 Expected A, B, C, D, F
206 211 A
207 212 B
208 213 C
209 214 D
210 215 F
@@ -1,65 +1,66 b''
1 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 created new head
3 3 @ 5: L3
4 4 |
5 5 o 4: L2
6 6 |
7 7 o 3: L1
8 8 |
9 9 | o 2: C3
10 10 |/
11 11 o 1: C2
12 12 |
13 13 o 0: C1
14 14
15 15
16 16 % Try to call --continue
17 17 abort: no rebase in progress
18 18
19 19 % Conflicting rebase
20 20 merging common
21 21 warning: conflicts during merge.
22 22 merging common failed!
23 23 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
24 24
25 25 % Try to continue without solving the conflict
26 26 abort: unresolved merge conflicts (see hg resolve)
27 27
28 28 % Conclude rebase
29 saved backup bundle to
29 30 adding branch
30 31 adding changesets
31 32 adding manifests
32 33 adding file changes
33 34 added 3 changesets with 3 changes to 3 files
34 35 rebase completed
35 36 @ 5: L3
36 37 |
37 38 o 4: L2
38 39 |
39 40 o 3: L1
40 41 |
41 42 o 2: C3
42 43 |
43 44 o 1: C2
44 45 |
45 46 o 0: C1
46 47
47 48
48 49 % Check correctness
49 50 - Rev. 0
50 51 c1
51 52 - Rev. 1
52 53 c1
53 54 c2
54 55 - Rev. 2
55 56 c1
56 57 c2
57 58 c3
58 59 - Rev. 3
59 60 c1
60 61 c2
61 62 c3
62 63 - Rev. 4
63 64 resolved merge
64 65 - Rev. 5
65 66 resolved merge
@@ -1,130 +1,134 b''
1 1 @ 4: E
2 2 |
3 3 | o 3: D
4 4 | |
5 5 | o 2: C
6 6 | |
7 7 | o 1: B
8 8 |/
9 9 o 0: A
10 10
11 11 % Rebasing D onto E detaching from C
12 saved backup bundle to
12 13 adding branch
13 14 adding changesets
14 15 adding manifests
15 16 adding file changes
16 17 added 2 changesets with 2 changes to 2 files (+1 heads)
17 18 rebase completed
18 19 @ 4: D
19 20 |
20 21 o 3: E
21 22 |
22 23 | o 2: C
23 24 | |
24 25 | o 1: B
25 26 |/
26 27 o 0: A
27 28
28 29 Expected A, D, E
29 30 A
30 31 D
31 32 E
32 33
33 34 @ 4: E
34 35 |
35 36 | o 3: D
36 37 | |
37 38 | o 2: C
38 39 | |
39 40 | o 1: B
40 41 |/
41 42 o 0: A
42 43
43 44 % Rebasing C onto E detaching from B
45 saved backup bundle to
44 46 adding branch
45 47 adding changesets
46 48 adding manifests
47 49 adding file changes
48 50 added 3 changesets with 3 changes to 3 files (+1 heads)
49 51 rebase completed
50 52 @ 4: D
51 53 |
52 54 o 3: C
53 55 |
54 56 o 2: E
55 57 |
56 58 | o 1: B
57 59 |/
58 60 o 0: A
59 61
60 62 Expected A, C, D, E
61 63 A
62 64 C
63 65 D
64 66 E
65 67
66 68 @ 4: E
67 69 |
68 70 | o 3: D
69 71 | |
70 72 | o 2: C
71 73 | |
72 74 | o 1: B
73 75 |/
74 76 o 0: A
75 77
76 78 % Rebasing B onto E using detach (same as not using it)
79 saved backup bundle to
77 80 adding branch
78 81 adding changesets
79 82 adding manifests
80 83 adding file changes
81 84 added 4 changesets with 4 changes to 4 files
82 85 rebase completed
83 86 @ 4: D
84 87 |
85 88 o 3: C
86 89 |
87 90 o 2: B
88 91 |
89 92 o 1: E
90 93 |
91 94 o 0: A
92 95
93 96 Expected A, B, C, D, E
94 97 A
95 98 B
96 99 C
97 100 D
98 101 E
99 102
100 103 @ 4: E
101 104 |
102 105 | o 3: D
103 106 | |
104 107 | o 2: C
105 108 | |
106 109 | o 1: B
107 110 |/
108 111 o 0: A
109 112
110 113 % Rebasing C onto E detaching from B and collapsing
114 saved backup bundle to
111 115 adding branch
112 116 adding changesets
113 117 adding manifests
114 118 adding file changes
115 119 added 2 changesets with 3 changes to 3 files (+1 heads)
116 120 rebase completed
117 121 @ 3: Collapsed revision
118 122 | * C
119 123 | * D
120 124 o 2: E
121 125 |
122 126 | o 1: B
123 127 |/
124 128 o 0: A
125 129
126 130 Expected A, C, D, E
127 131 A
128 132 C
129 133 D
130 134 E
@@ -1,62 +1,64 b''
1 1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2 2 created new head
3 3 @ 4:r2
4 4 |
5 5 o 3:r1
6 6 |
7 7 | o 2:l1
8 8 |/
9 9 o 1:c2
10 10 |
11 11 o 0:c1
12 12
13 13
14 14 % Rebase with no arguments - single revision in source branch
15 15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 saved backup bundle to
16 17 adding branch
17 18 adding changesets
18 19 adding manifests
19 20 adding file changes
20 21 added 3 changesets with 3 changes to 3 files
21 22 rebase completed
22 23 @ 4:l1
23 24 |
24 25 o 3:r2
25 26 |
26 27 o 2:r1
27 28 |
28 29 o 1:c2
29 30 |
30 31 o 0:c1
31 32
32 33 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 34 created new head
34 35 @ 4:r1
35 36 |
36 37 | o 3:l2
37 38 | |
38 39 | o 2:l1
39 40 |/
40 41 o 1:c2
41 42 |
42 43 o 0:c1
43 44
44 45
45 46 % Rebase with no arguments - single revision in target branch
46 47 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
48 saved backup bundle to
47 49 adding branch
48 50 adding changesets
49 51 adding manifests
50 52 adding file changes
51 53 added 3 changesets with 3 changes to 3 files
52 54 rebase completed
53 55 @ 4:l2
54 56 |
55 57 o 3:l1
56 58 |
57 59 o 2:r1
58 60 |
59 61 o 1:c2
60 62 |
61 63 o 0:c1
62 64
@@ -1,22 +1,23 b''
1 1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2 2
3 3 % "Mainstream" import p1.patch
4 4 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
5 5 applying p1.patch
6 6
7 7 % Rebase
8 8 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
9 saved backup bundle to
9 10 adding branch
10 11 adding changesets
11 12 adding manifests
12 13 adding file changes
13 14 added 2 changesets with 2 changes to 2 files
14 15 rebase completed
15 16 @ 3 P0 tags: p0.patch qbase qtip tip
16 17 |
17 18 o 2 P1 tags: qparent
18 19 |
19 20 o 1 R1 tags:
20 21 |
21 22 o 0 C1 tags:
22 23
@@ -1,137 +1,138 b''
1 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 @ 3 P1 tags: f2.patch qtip tip
3 3 |
4 4 o 2 P0 tags: f.patch qbase
5 5 |
6 6 | o 1 R1 tags:
7 7 |/
8 8 o 0 C1 tags: qparent
9 9
10 10
11 11 % Rebase - try to rebase on an applied mq patch
12 12 abort: cannot rebase onto an applied mq patch
13 13
14 14 % Rebase - same thing, but mq patch is default dest
15 15 abort: cannot rebase onto an applied mq patch
16 16
17 17 % Rebase - generate a conflict
18 18 merging f
19 19 warning: conflicts during merge.
20 20 merging f failed!
21 21 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
22 22
23 23 % Fix the 1st conflict
24 24 warning: conflicts during merge.
25 25 merging f failed!
26 26 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
27 27 merging f
28 28
29 29 % Fix the 2nd conflict
30 saved backup bundle to
30 31 adding branch
31 32 adding changesets
32 33 adding manifests
33 34 adding file changes
34 35 added 2 changesets with 2 changes to 1 files
35 36 rebase completed
36 37 @ 3 P1 tags: f2.patch qtip tip
37 38 |
38 39 o 2 P0 tags: f.patch qbase
39 40 |
40 41 o 1 R1 tags: qparent
41 42 |
42 43 o 0 C1 tags:
43 44
44 45
45 46 % Update to qbase
46 47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 48 % f correctly reflects the merge result
48 49 mq1r1
49 50 % And the patch is correct
50 51 # HG changeset patch
51 52 # User test
52 53 # Date
53 54 # Node ID
54 55 # Parent
55 56 P0
56 57
57 58 diff -r x -r y f
58 59 --- a/f
59 60 +++ b/f
60 61 @@ -1,1 +1,1 @@
61 62 -r1
62 63 +mq1r1
63 64
64 65 % Update to qtip
65 66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 67 % f correctly reflects the merge result
67 68 mq1r1mq2
68 69 % And the patch is correct
69 70 # HG changeset patch
70 71 # User test
71 72 # Date
72 73 # Node ID
73 74 # Parent
74 75 P1
75 76
76 77 diff -r x -r y f
77 78 --- a/f
78 79 +++ b/f
79 80 @@ -1,1 +1,1 @@
80 81 -mq1r1
81 82 +mq1r1mq2
82 83
83 84 % Adding one git-style patch and one normal
84 85 popping f2.patch
85 86 popping f.patch
86 87 patch queue now empty
87 88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 89 % Git patch
89 90 P0 (git)
90 91
91 92 diff --git a/p b/p
92 93 new file mode 100644
93 94 --- /dev/null
94 95 +++ b/p
95 96 @@ -0,0 +1,1 @@
96 97 +mq1
97 98
98 99 % Normal patch
99 100 P1
100 101
101 102 diff -r x p
102 103 --- a/p
103 104 +++ b/p
104 105 @@ -1,1 +1,1 @@
105 106 -mq1
106 107 +mq2
107 108
108 109 % Rebase the applied mq patches
109 110 % And the patches are correct
110 111 % Git patch
111 112 # HG changeset patch
112 113 # User test
113 114 # Date
114 115 # Node ID
115 116 # Parent
116 117 P0 (git)
117 118
118 119 diff --git a/p b/p
119 120 new file mode 100644
120 121 --- /dev/null
121 122 +++ b/p
122 123 @@ -0,0 +1,1 @@
123 124 +mq1
124 125
125 126 % Normal patch
126 127 # HG changeset patch
127 128 # User test
128 129 # Date
129 130 # Node ID
130 131 # Parent
131 132 P1
132 133
133 134 --- a/p
134 135 +++ b/p
135 136 @@ -1,1 +1,1 @@
136 137 -mq1
137 138 +mq2
@@ -1,336 +1,344 b''
1 1 % These fail
2 2
3 3 % Use continue and abort
4 4 hg rebase: cannot use both abort and continue
5 5 hg rebase [-s REV | -b REV] [-d REV] [options]
6 6 hg rebase {-a|-c}
7 7
8 8 move changeset (and descendants) to a different branch
9 9
10 10 Rebase uses repeated merging to graft changesets from one part of history
11 11 (the source) onto another (the destination). This can be useful for
12 12 linearizing *local* changes relative to a master development tree.
13 13
14 14 You should not rebase changesets that have already been shared with
15 15 others. Doing so will force everybody else to perform the same rebase or
16 16 they will end up with duplicated changesets after pulling in your rebased
17 17 changesets.
18 18
19 19 If you don't specify a destination changeset ("-d/--dest"), rebase uses
20 20 the tipmost head of the current named branch as the destination. (The
21 21 destination changeset is not modified by rebasing, but new changesets are
22 22 added as its descendants.)
23 23
24 24 You can specify which changesets to rebase in two ways: as a "source"
25 25 changeset or as a "base" changeset. Both are shorthand for a topologically
26 26 related set of changesets (the "source branch"). If you specify source
27 27 ("-s/--source"), rebase will rebase that changeset and all of its
28 28 descendants onto dest. If you specify base ("-b/--base"), rebase will
29 29 select ancestors of base back to but not including the common ancestor
30 30 with dest. Thus, "-b" is less precise but more convenient than "-s": you
31 31 can specify any changeset in the source branch, and rebase will select the
32 32 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
33 33 of the working directory as the base.
34 34
35 35 By default, rebase recreates the changesets in the source branch as
36 36 descendants of dest and then destroys the originals. Use "--keep" to
37 37 preserve the original source changesets. Some changesets in the source
38 38 branch (e.g. merges from the destination branch) may be dropped if they no
39 39 longer contribute any change.
40 40
41 41 One result of the rules for selecting the destination changeset and source
42 42 branch is that, unlike "merge", rebase will do nothing if you are at the
43 43 latest (tipmost) head of a named branch with two heads. You need to
44 44 explicitly specify source and/or destination (or "update" to the other
45 45 head, if it's the head of the intended source branch).
46 46
47 47 If a rebase is interrupted to manually resolve a merge, it can be
48 48 continued with --continue/-c or aborted with --abort/-a.
49 49
50 50 options:
51 51
52 52 -s --source rebase from the specified changeset
53 53 -b --base rebase from the base of the specified changeset (up to
54 54 greatest common ancestor of base and dest)
55 55 -d --dest rebase onto the specified changeset
56 56 --collapse collapse the rebased changesets
57 57 --keep keep original changesets
58 58 --keepbranches keep original branch names
59 59 --detach force detaching of source from its original branch
60 60 -c --continue continue an interrupted rebase
61 61 -a --abort abort an interrupted rebase
62 62 --style display using template map file
63 63 --template display with template
64 64
65 65 use "hg -v help rebase" to show global options
66 66
67 67 % Use continue and collapse
68 68 hg rebase: cannot use collapse with continue or abort
69 69 hg rebase [-s REV | -b REV] [-d REV] [options]
70 70 hg rebase {-a|-c}
71 71
72 72 move changeset (and descendants) to a different branch
73 73
74 74 Rebase uses repeated merging to graft changesets from one part of history
75 75 (the source) onto another (the destination). This can be useful for
76 76 linearizing *local* changes relative to a master development tree.
77 77
78 78 You should not rebase changesets that have already been shared with
79 79 others. Doing so will force everybody else to perform the same rebase or
80 80 they will end up with duplicated changesets after pulling in your rebased
81 81 changesets.
82 82
83 83 If you don't specify a destination changeset ("-d/--dest"), rebase uses
84 84 the tipmost head of the current named branch as the destination. (The
85 85 destination changeset is not modified by rebasing, but new changesets are
86 86 added as its descendants.)
87 87
88 88 You can specify which changesets to rebase in two ways: as a "source"
89 89 changeset or as a "base" changeset. Both are shorthand for a topologically
90 90 related set of changesets (the "source branch"). If you specify source
91 91 ("-s/--source"), rebase will rebase that changeset and all of its
92 92 descendants onto dest. If you specify base ("-b/--base"), rebase will
93 93 select ancestors of base back to but not including the common ancestor
94 94 with dest. Thus, "-b" is less precise but more convenient than "-s": you
95 95 can specify any changeset in the source branch, and rebase will select the
96 96 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
97 97 of the working directory as the base.
98 98
99 99 By default, rebase recreates the changesets in the source branch as
100 100 descendants of dest and then destroys the originals. Use "--keep" to
101 101 preserve the original source changesets. Some changesets in the source
102 102 branch (e.g. merges from the destination branch) may be dropped if they no
103 103 longer contribute any change.
104 104
105 105 One result of the rules for selecting the destination changeset and source
106 106 branch is that, unlike "merge", rebase will do nothing if you are at the
107 107 latest (tipmost) head of a named branch with two heads. You need to
108 108 explicitly specify source and/or destination (or "update" to the other
109 109 head, if it's the head of the intended source branch).
110 110
111 111 If a rebase is interrupted to manually resolve a merge, it can be
112 112 continued with --continue/-c or aborted with --abort/-a.
113 113
114 114 options:
115 115
116 116 -s --source rebase from the specified changeset
117 117 -b --base rebase from the base of the specified changeset (up to
118 118 greatest common ancestor of base and dest)
119 119 -d --dest rebase onto the specified changeset
120 120 --collapse collapse the rebased changesets
121 121 --keep keep original changesets
122 122 --keepbranches keep original branch names
123 123 --detach force detaching of source from its original branch
124 124 -c --continue continue an interrupted rebase
125 125 -a --abort abort an interrupted rebase
126 126 --style display using template map file
127 127 --template display with template
128 128
129 129 use "hg -v help rebase" to show global options
130 130
131 131 % Use continue/abort and dest/source
132 132 hg rebase: abort and continue do not allow specifying revisions
133 133 hg rebase [-s REV | -b REV] [-d REV] [options]
134 134 hg rebase {-a|-c}
135 135
136 136 move changeset (and descendants) to a different branch
137 137
138 138 Rebase uses repeated merging to graft changesets from one part of history
139 139 (the source) onto another (the destination). This can be useful for
140 140 linearizing *local* changes relative to a master development tree.
141 141
142 142 You should not rebase changesets that have already been shared with
143 143 others. Doing so will force everybody else to perform the same rebase or
144 144 they will end up with duplicated changesets after pulling in your rebased
145 145 changesets.
146 146
147 147 If you don't specify a destination changeset ("-d/--dest"), rebase uses
148 148 the tipmost head of the current named branch as the destination. (The
149 149 destination changeset is not modified by rebasing, but new changesets are
150 150 added as its descendants.)
151 151
152 152 You can specify which changesets to rebase in two ways: as a "source"
153 153 changeset or as a "base" changeset. Both are shorthand for a topologically
154 154 related set of changesets (the "source branch"). If you specify source
155 155 ("-s/--source"), rebase will rebase that changeset and all of its
156 156 descendants onto dest. If you specify base ("-b/--base"), rebase will
157 157 select ancestors of base back to but not including the common ancestor
158 158 with dest. Thus, "-b" is less precise but more convenient than "-s": you
159 159 can specify any changeset in the source branch, and rebase will select the
160 160 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
161 161 of the working directory as the base.
162 162
163 163 By default, rebase recreates the changesets in the source branch as
164 164 descendants of dest and then destroys the originals. Use "--keep" to
165 165 preserve the original source changesets. Some changesets in the source
166 166 branch (e.g. merges from the destination branch) may be dropped if they no
167 167 longer contribute any change.
168 168
169 169 One result of the rules for selecting the destination changeset and source
170 170 branch is that, unlike "merge", rebase will do nothing if you are at the
171 171 latest (tipmost) head of a named branch with two heads. You need to
172 172 explicitly specify source and/or destination (or "update" to the other
173 173 head, if it's the head of the intended source branch).
174 174
175 175 If a rebase is interrupted to manually resolve a merge, it can be
176 176 continued with --continue/-c or aborted with --abort/-a.
177 177
178 178 options:
179 179
180 180 -s --source rebase from the specified changeset
181 181 -b --base rebase from the base of the specified changeset (up to
182 182 greatest common ancestor of base and dest)
183 183 -d --dest rebase onto the specified changeset
184 184 --collapse collapse the rebased changesets
185 185 --keep keep original changesets
186 186 --keepbranches keep original branch names
187 187 --detach force detaching of source from its original branch
188 188 -c --continue continue an interrupted rebase
189 189 -a --abort abort an interrupted rebase
190 190 --style display using template map file
191 191 --template display with template
192 192
193 193 use "hg -v help rebase" to show global options
194 194
195 195 % Use source and base
196 196 hg rebase: cannot specify both a revision and a base
197 197 hg rebase [-s REV | -b REV] [-d REV] [options]
198 198 hg rebase {-a|-c}
199 199
200 200 move changeset (and descendants) to a different branch
201 201
202 202 Rebase uses repeated merging to graft changesets from one part of history
203 203 (the source) onto another (the destination). This can be useful for
204 204 linearizing *local* changes relative to a master development tree.
205 205
206 206 You should not rebase changesets that have already been shared with
207 207 others. Doing so will force everybody else to perform the same rebase or
208 208 they will end up with duplicated changesets after pulling in your rebased
209 209 changesets.
210 210
211 211 If you don't specify a destination changeset ("-d/--dest"), rebase uses
212 212 the tipmost head of the current named branch as the destination. (The
213 213 destination changeset is not modified by rebasing, but new changesets are
214 214 added as its descendants.)
215 215
216 216 You can specify which changesets to rebase in two ways: as a "source"
217 217 changeset or as a "base" changeset. Both are shorthand for a topologically
218 218 related set of changesets (the "source branch"). If you specify source
219 219 ("-s/--source"), rebase will rebase that changeset and all of its
220 220 descendants onto dest. If you specify base ("-b/--base"), rebase will
221 221 select ancestors of base back to but not including the common ancestor
222 222 with dest. Thus, "-b" is less precise but more convenient than "-s": you
223 223 can specify any changeset in the source branch, and rebase will select the
224 224 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
225 225 of the working directory as the base.
226 226
227 227 By default, rebase recreates the changesets in the source branch as
228 228 descendants of dest and then destroys the originals. Use "--keep" to
229 229 preserve the original source changesets. Some changesets in the source
230 230 branch (e.g. merges from the destination branch) may be dropped if they no
231 231 longer contribute any change.
232 232
233 233 One result of the rules for selecting the destination changeset and source
234 234 branch is that, unlike "merge", rebase will do nothing if you are at the
235 235 latest (tipmost) head of a named branch with two heads. You need to
236 236 explicitly specify source and/or destination (or "update" to the other
237 237 head, if it's the head of the intended source branch).
238 238
239 239 If a rebase is interrupted to manually resolve a merge, it can be
240 240 continued with --continue/-c or aborted with --abort/-a.
241 241
242 242 options:
243 243
244 244 -s --source rebase from the specified changeset
245 245 -b --base rebase from the base of the specified changeset (up to
246 246 greatest common ancestor of base and dest)
247 247 -d --dest rebase onto the specified changeset
248 248 --collapse collapse the rebased changesets
249 249 --keep keep original changesets
250 250 --keepbranches keep original branch names
251 251 --detach force detaching of source from its original branch
252 252 -c --continue continue an interrupted rebase
253 253 -a --abort abort an interrupted rebase
254 254 --style display using template map file
255 255 --template display with template
256 256
257 257 use "hg -v help rebase" to show global options
258 258
259 259 % Rebase with no arguments - from current
260 260 nothing to rebase
261 261
262 262 % Rebase with no arguments - from the current branch
263 263 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
264 264 nothing to rebase
265 265 % ----------
266 266 % These work
267 267
268 268 % Rebase with no arguments (from 3 onto 7)
269 269 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
270 saved backup bundle to
270 271 adding branch
271 272 adding changesets
272 273 adding manifests
273 274 adding file changes
274 275 added 5 changesets with 5 changes to 5 files
275 276 rebase completed
276 277 % Try to rollback after a rebase (fail)
277 278 no rollback information available
278 279
279 280 % Rebase with base == '.' => same as no arguments (from 3 onto 7)
280 281 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
282 saved backup bundle to
281 283 adding branch
282 284 adding changesets
283 285 adding manifests
284 286 adding file changes
285 287 added 5 changesets with 5 changes to 5 files
286 288 rebase completed
287 289
288 290 % Rebase with dest == default => same as no arguments (from 3 onto 7)
289 291 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
292 saved backup bundle to
290 293 adding branch
291 294 adding changesets
292 295 adding manifests
293 296 adding file changes
294 297 added 5 changesets with 5 changes to 5 files
295 298 rebase completed
296 299
297 300 % Specify only source (from 4 onto 7)
301 saved backup bundle to
298 302 adding branch
299 303 adding changesets
300 304 adding manifests
301 305 adding file changes
302 306 added 4 changesets with 4 changes to 4 files (-1 heads)
303 307 rebase completed
304 308
305 309 % Specify only dest (from 3 onto 6)
306 310 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
311 saved backup bundle to
307 312 adding branch
308 313 adding changesets
309 314 adding manifests
310 315 adding file changes
311 316 added 5 changesets with 5 changes to 5 files (+1 heads)
312 317 rebase completed
313 318
314 319 % Specify only base (from 3 onto 7)
320 saved backup bundle to
315 321 adding branch
316 322 adding changesets
317 323 adding manifests
318 324 adding file changes
319 325 added 5 changesets with 5 changes to 5 files
320 326 rebase completed
321 327
322 328 % Specify source and dest (from 4 onto 6)
329 saved backup bundle to
323 330 adding branch
324 331 adding changesets
325 332 adding manifests
326 333 adding file changes
327 334 added 4 changesets with 4 changes to 4 files
328 335 rebase completed
329 336
330 337 % Specify base and dest (from 3 onto 6)
338 saved backup bundle to
331 339 adding branch
332 340 adding changesets
333 341 adding manifests
334 342 adding file changes
335 343 added 5 changesets with 5 changes to 5 files (+1 heads)
336 344 rebase completed
@@ -1,56 +1,57 b''
1 1 updating to branch default
2 2 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 3 updating to branch default
4 4 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 5
6 6 % Now b has one revision to be pulled from a
7 7 pulling from
8 8 searching for changes
9 9 adding changesets
10 10 adding manifests
11 11 adding file changes
12 12 added 1 changesets with 1 changes to 1 files (+1 heads)
13 saved backup bundle to
13 14 adding branch
14 15 adding changesets
15 16 adding manifests
16 17 adding file changes
17 18 added 2 changesets with 2 changes to 2 files
18 19 rebase completed
19 20 @ 3:L1
20 21 |
21 22 o 2:R1
22 23 |
23 24 o 1:C2
24 25 |
25 26 o 0:C1
26 27
27 28
28 29 % Re-run pull --rebase
29 30 pulling from
30 31 searching for changes
31 32 no changes found
32 33
33 34 % Invoke pull --rebase and nothing to rebase
34 35 pulling from
35 36 searching for changes
36 37 adding changesets
37 38 adding manifests
38 39 adding file changes
39 40 added 1 changesets with 1 changes to 1 files
40 41 nothing to rebase
41 42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 43 @ 2
43 44 |
44 45
45 46 % pull --rebase --update should ignore --update
46 47 pulling from
47 48 searching for changes
48 49 no changes found
49 50
50 51 % pull --rebase doesn't update if nothing has been pulled
51 52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 53 pulling from
53 54 searching for changes
54 55 no changes found
55 56 o 2
56 57 |
@@ -1,138 +1,144 b''
1 1 @ 5: F
2 2 |
3 3 | o 4: E
4 4 |/|
5 5 o | 3: D
6 6 | |
7 7 | o 2: C
8 8 |/
9 9 | o 1: B
10 10 |/
11 11 o 0: A
12 12
13 13 % Rebasing
14 14 % B onto F - simple rebase
15 saved backup bundle to
15 16 adding branch
16 17 adding changesets
17 18 adding manifests
18 19 adding file changes
19 20 added 5 changesets with 4 changes to 4 files (+1 heads)
20 21 rebase completed
21 22 @ 5: B
22 23 |
23 24 o 4: F
24 25 |
25 26 | o 3: E
26 27 |/|
27 28 o | 2: D
28 29 | |
29 30 | o 1: C
30 31 |/
31 32 o 0: A
32 33
33 34 % B onto D - intermediate point
35 saved backup bundle to
34 36 adding branch
35 37 adding changesets
36 38 adding manifests
37 39 adding file changes
38 40 added 5 changesets with 4 changes to 4 files (+2 heads)
39 41 rebase completed
40 42 @ 5: B
41 43 |
42 44 | o 4: F
43 45 |/
44 46 | o 3: E
45 47 |/|
46 48 o | 2: D
47 49 | |
48 50 | o 1: C
49 51 |/
50 52 o 0: A
51 53
52 54 % C onto F - skip of E
55 saved backup bundle to
53 56 adding branch
54 57 adding changesets
55 58 adding manifests
56 59 adding file changes
57 60 added 3 changesets with 3 changes to 3 files (+1 heads)
58 61 rebase completed
59 62 @ 4: C
60 63 |
61 64 o 3: F
62 65 |
63 66 o 2: D
64 67 |
65 68 | o 1: B
66 69 |/
67 70 o 0: A
68 71
69 72 % D onto C - rebase of a branching point (skip E)
73 saved backup bundle to
70 74 adding branch
71 75 adding changesets
72 76 adding manifests
73 77 adding file changes
74 78 added 2 changesets with 2 changes to 2 files
75 79 rebase completed
76 80 @ 4: F
77 81 |
78 82 o 3: D
79 83 |
80 84 o 2: C
81 85 |
82 86 | o 1: B
83 87 |/
84 88 o 0: A
85 89
86 90 % E onto F - merged revision having a parent in ancestors of target
91 saved backup bundle to
87 92 adding branch
88 93 adding changesets
89 94 adding manifests
90 95 adding file changes
91 96 added 2 changesets with 1 changes to 1 files (-1 heads)
92 97 rebase completed
93 98 @ 5: E
94 99 |\
95 100 | o 4: F
96 101 | |
97 102 | o 3: D
98 103 | |
99 104 o | 2: C
100 105 |/
101 106 | o 1: B
102 107 |/
103 108 o 0: A
104 109
105 110 % D onto B - E maintains C as parent
111 saved backup bundle to
106 112 adding branch
107 113 adding changesets
108 114 adding manifests
109 115 adding file changes
110 116 added 3 changesets with 2 changes to 2 files
111 117 rebase completed
112 118 @ 5: F
113 119 |
114 120 | o 4: E
115 121 |/|
116 122 o | 3: D
117 123 | |
118 124 | o 2: C
119 125 | |
120 126 o | 1: B
121 127 |/
122 128 o 0: A
123 129
124 130 % These will fail (using --source)
125 131 % E onto D - rebase onto an ancestor
126 132 abort: source is descendant of destination
127 133 % D onto E - rebase onto a descendant
128 134 abort: source is ancestor of destination
129 135 % E onto B - merge revision with both parents not in ancestors of target
130 136 abort: cannot use revision 4 as base, result would have 3 parents
131 137
132 138 % These will abort gracefully (using --base)
133 139 % E onto E - rebase onto same changeset
134 140 nothing to rebase
135 141 % E onto D - rebase onto an ancestor
136 142 nothing to rebase
137 143 % D onto E - rebase onto a descendant
138 144 nothing to rebase
General Comments 0
You need to be logged in to leave comments. Login now