##// END OF EJS Templates
rebase: move base calculation from rebasenode() to defineparents()...
Mads Kiilerich -
r23484:cf3495df default
parent child Browse files
Show More
@@ -370,7 +370,7 def rebase(ui, repo, **opts):
370 370 if state[rev] == -1:
371 371 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
372 372 _('changesets'), total)
373 p1, p2 = defineparents(repo, rev, target, state,
373 p1, p2, base = defineparents(repo, rev, target, state,
374 374 targetancestors)
375 375 storestatus(repo, originalwd, target, state, collapsef, keepf,
376 376 keepbranchesf, external, activebookmark)
@@ -380,8 +380,8 def rebase(ui, repo, **opts):
380 380 try:
381 381 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
382 382 'rebase')
383 stats = rebasenode(repo, rev, p1, state, collapsef,
384 target)
383 stats = rebasenode(repo, rev, p1, base, state,
384 collapsef, target)
385 385 if stats and stats[3] > 0:
386 386 raise error.InterventionRequired(
387 387 _('unresolved conflicts (see hg '
@@ -414,7 +414,7 def rebase(ui, repo, **opts):
414 414 ui.note(_('rebase merging completed\n'))
415 415
416 416 if collapsef and not keepopen:
417 p1, p2 = defineparents(repo, min(state), target,
417 p1, p2, _base = defineparents(repo, min(state), target,
418 418 state, targetancestors)
419 419 editopt = opts.get('edit')
420 420 editform = 'rebase.collapse'
@@ -509,7 +509,8 def externalparent(repo, state, targetan
509 509 ', '.join(str(p) for p in sorted(parents))))
510 510
511 511 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
512 '''Commit the changes and store useful information in extra.
512 '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev
513 but also store useful information in extra.
513 514 Return node of committed revision.'''
514 515 try:
515 516 repo.dirstate.beginparentchange()
@@ -539,8 +540,8 def concludenode(repo, rev, p1, p2, comm
539 540 repo.dirstate.invalidate()
540 541 raise
541 542
542 def rebasenode(repo, rev, p1, state, collapse, target):
543 'Rebase a single revision'
543 def rebasenode(repo, rev, p1, base, state, collapse, target):
544 'Rebase a single revision rev on top of p1 using base as merge ancestor'
544 545 # Merge phase
545 546 # Update to target and merge it with local
546 547 if repo['.'].rev() != p1:
@@ -550,48 +551,6 def rebasenode(repo, rev, p1, state, col
550 551 repo.ui.debug(" already in target\n")
551 552 repo.dirstate.write()
552 553 repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev]))
553 if rev == min(state):
554 # Case (1) initial changeset of a non-detaching rebase.
555 # Let the merge mechanism find the base itself.
556 base = None
557 elif not repo[rev].p2():
558 # Case (2) detaching the node with a single parent, use this parent
559 base = repo[rev].p1().rev()
560 else:
561 # In case of merge, we need to pick the right parent as merge base.
562 #
563 # Imagine we have:
564 # - M: currently rebase revision in this step
565 # - A: one parent of M
566 # - B: second parent of M
567 # - D: destination of this merge step (p1 var)
568 #
569 # If we are rebasing on D, D is the successors of A or B. The right
570 # merge base is the one D succeed to. We pretend it is B for the rest
571 # of this comment
572 #
573 # If we pick B as the base, the merge involves:
574 # - changes from B to M (actual changeset payload)
575 # - changes from B to D (induced by rebase) as D is a rebased
576 # version of B)
577 # Which exactly represent the rebase operation.
578 #
579 # If we pick the A as the base, the merge involves
580 # - changes from A to M (actual changeset payload)
581 # - changes from A to D (with include changes between unrelated A and B
582 # plus changes induced by rebase)
583 # Which does not represent anything sensible and creates a lot of
584 # conflicts.
585 for p in repo[rev].parents():
586 if state.get(p.rev()) == p1:
587 base = p.rev()
588 break
589 else: # fallback when base not found
590 base = None
591
592 # Raise because this function is called wrong (see issue 4106)
593 raise AssertionError('no base found to rebase on '
594 '(rebasenode called wrong)')
595 554 if base is not None:
596 555 repo.ui.debug(" detach base %d:%s\n" % (base, repo[base]))
597 556 # When collapsing in-place, the parent is the common ancestor, we
@@ -660,7 +619,50 def defineparents(repo, rev, target, sta
660 619 p2 = p2n
661 620 repo.ui.debug(" future parents are %d and %d\n" %
662 621 (repo[p1].rev(), repo[p2].rev()))
663 return p1, p2
622
623 if rev == min(state):
624 # Case (1) initial changeset of a non-detaching rebase.
625 # Let the merge mechanism find the base itself.
626 base = None
627 elif not repo[rev].p2():
628 # Case (2) detaching the node with a single parent, use this parent
629 base = repo[rev].p1().rev()
630 else:
631 # In case of merge, we need to pick the right parent as merge base.
632 #
633 # Imagine we have:
634 # - M: currently rebase revision in this step
635 # - A: one parent of M
636 # - B: second parent of M
637 # - D: destination of this merge step (p1 var)
638 #
639 # If we are rebasing on D, D is the successors of A or B. The right
640 # merge base is the one D succeed to. We pretend it is B for the rest
641 # of this comment
642 #
643 # If we pick B as the base, the merge involves:
644 # - changes from B to M (actual changeset payload)
645 # - changes from B to D (induced by rebase) as D is a rebased
646 # version of B)
647 # Which exactly represent the rebase operation.
648 #
649 # If we pick the A as the base, the merge involves
650 # - changes from A to M (actual changeset payload)
651 # - changes from A to D (with include changes between unrelated A and B
652 # plus changes induced by rebase)
653 # Which does not represent anything sensible and creates a lot of
654 # conflicts.
655 for p in repo[rev].parents():
656 if state.get(p.rev()) == p1:
657 base = p.rev()
658 break
659 else: # fallback when base not found
660 base = None
661
662 # Raise because this function is called wrong (see issue 4106)
663 raise AssertionError('no base found to rebase on '
664 '(defineparents called wrong)')
665 return p1, p2, base
664 666
665 667 def isagitpatch(repo, patchname):
666 668 'Return true if the given patch is in git format'
General Comments 0
You need to be logged in to leave comments. Login now