643 base = None |
643 base = None |
644 elif not repo[rev].p2(): |
644 elif not repo[rev].p2(): |
645 # Case (2) detaching the node with a single parent, use this parent |
645 # Case (2) detaching the node with a single parent, use this parent |
646 base = repo[rev].p1().rev() |
646 base = repo[rev].p1().rev() |
647 else: |
647 else: |
648 # In case of merge, we need to pick the right parent as merge base. |
648 # Assuming there is a p1, this is the case where there also is a p2. |
|
649 # We are thus rebasing a merge and need to pick the right merge base. |
649 # |
650 # |
650 # Imagine we have: |
651 # Imagine we have: |
651 # - M: currently rebase revision in this step |
652 # - M: current rebase revision in this step |
652 # - A: one parent of M |
653 # - A: one parent of M |
653 # - B: second parent of M |
654 # - B: other parent of M |
654 # - D: destination of this merge step (p1 var) |
655 # - D: destination of this merge step (p1 var) |
655 # |
656 # |
656 # If we are rebasing on D, D is the successors of A or B. The right |
657 # Consider the case where D is a descendant of A or B and the other is |
657 # merge base is the one D succeed to. We pretend it is B for the rest |
658 # 'outside'. In this case, the right merge base is the D ancestor. |
658 # of this comment |
659 # |
|
660 # An informal proof, assuming A is 'outside' and B is the D ancestor: |
659 # |
661 # |
660 # If we pick B as the base, the merge involves: |
662 # If we pick B as the base, the merge involves: |
661 # - changes from B to M (actual changeset payload) |
663 # - changes from B to M (actual changeset payload) |
662 # - changes from B to D (induced by rebase) as D is a rebased |
664 # - changes from B to D (induced by rebase) as D is a rebased |
663 # version of B) |
665 # version of B) |
664 # Which exactly represent the rebase operation. |
666 # Which exactly represent the rebase operation. |
665 # |
667 # |
666 # If we pick the A as the base, the merge involves |
668 # If we pick A as the base, the merge involves: |
667 # - changes from A to M (actual changeset payload) |
669 # - changes from A to M (actual changeset payload) |
668 # - changes from A to D (with include changes between unrelated A and B |
670 # - changes from A to D (with include changes between unrelated A and B |
669 # plus changes induced by rebase) |
671 # plus changes induced by rebase) |
670 # Which does not represent anything sensible and creates a lot of |
672 # Which does not represent anything sensible and creates a lot of |
671 # conflicts. |
673 # conflicts. A is thus not the right choice - B is. |
|
674 # |
|
675 # Note: The base found in this 'proof' is only correct in the specified |
|
676 # case. This base does not make sense if is not D a descendant of A or B |
|
677 # or if the other is not parent 'outside' (especially not if the other |
|
678 # parent has been rebased). The current implementation does not |
|
679 # make it feasible to consider different cases separately. In these |
|
680 # other cases we currently just leave it to the user to correctly |
|
681 # resolve an impossible merge using a wrong ancestor. |
672 for p in repo[rev].parents(): |
682 for p in repo[rev].parents(): |
673 if state.get(p.rev()) == p1: |
683 if state.get(p.rev()) == p1: |
674 base = p.rev() |
684 base = p.rev() |
675 break |
685 break |
676 else: # fallback when base not found |
686 else: # fallback when base not found |