Mercurial > hg
comparison hgext/rebase.py @ 44341:77bb38be00ea
rebase: always be graft-like, not merge-like, also for merges
Rebase works by updating to a commit and then grafting changes on
top. However, before this patch, it would actually merge in changes
instead of grafting them in in some cases. That is, it would use the
common ancestor as base instead of using one of the parents. That
seems wrong to me, so I'm changing it so `defineparents()` always
returns a value for `base`.
This fixes the bad behavior in test-rebase-newancestor.t, which was
introduced in 65f215ea3e8e (tests: add test for rebasing merges with
ancestors of the rebase destination, 2014-11-30).
The difference in test-rebase-dest.t is because the files in the tip
revision were A, D, E, F before this patch and A, D, F, G after it. I
think both files should ideally be there.
Differential Revision: https://phab.mercurial-scm.org/D7907
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 16 Jan 2020 00:03:19 -0800 |
parents | f546d2170b0f |
children | b42ce825308e |
comparison
equal
deleted
inserted
replaced
44340:6ecc34b31137 | 44341:77bb38be00ea |
---|---|
1676 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)): | 1676 if any(isancestor(x, dests[i]) for x in successorrevs(repo, p)): |
1677 np = dests[i] | 1677 np = dests[i] |
1678 elif p in state and state[p] > 0: | 1678 elif p in state and state[p] > 0: |
1679 np = state[p] | 1679 np = state[p] |
1680 | 1680 |
1681 # "bases" only record "special" merge bases that cannot be | |
1682 # calculated from changelog DAG (i.e. isancestor(p, np) is False). | |
1683 # For example: | |
1684 # | |
1685 # B' # rebase -s B -d D, when B was rebased to B'. dest for C | |
1686 # | C # is B', but merge base for C is B, instead of | |
1687 # D | # changelog.ancestor(C, B') == A. If changelog DAG and | |
1688 # | B # "state" edges are merged (so there will be an edge from | |
1689 # |/ # B to B'), the merge base is still ancestor(C, B') in | |
1690 # A # the merged graph. | |
1691 # | |
1692 # Also see https://bz.mercurial-scm.org/show_bug.cgi?id=1950#c8 | |
1693 # which uses "virtual null merge" to explain this situation. | |
1694 if isancestor(p, np): | |
1695 bases[i] = nullrev | |
1696 | |
1697 # If one parent becomes an ancestor of the other, drop the ancestor | 1681 # If one parent becomes an ancestor of the other, drop the ancestor |
1698 for j, x in enumerate(newps[:i]): | 1682 for j, x in enumerate(newps[:i]): |
1699 if x == nullrev: | 1683 if x == nullrev: |
1700 continue | 1684 continue |
1701 if isancestor(np, x): # CASE-1 | 1685 if isancestor(np, x): # CASE-1 |
1752 # A Z | 1736 # A Z |
1753 # | 1737 # |
1754 # But our merge base candidates (D and E in above case) could still be | 1738 # But our merge base candidates (D and E in above case) could still be |
1755 # better than the default (ancestor(F, Z) == null). Therefore still | 1739 # better than the default (ancestor(F, Z) == null). Therefore still |
1756 # pick one (so choose p1 above). | 1740 # pick one (so choose p1 above). |
1757 if sum(1 for b in set(bases) if b != nullrev) > 1: | 1741 if sum(1 for b in set(bases) if b != nullrev and b not in newps) > 1: |
1758 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i] | 1742 unwanted = [None, None] # unwanted[i]: unwanted revs if choose bases[i] |
1759 for i, base in enumerate(bases): | 1743 for i, base in enumerate(bases): |
1760 if base == nullrev: | 1744 if base == nullrev or base in newps: |
1761 continue | 1745 continue |
1762 # Revisions in the side (not chosen as merge base) branch that | 1746 # Revisions in the side (not chosen as merge base) branch that |
1763 # might contain "surprising" contents | 1747 # might contain "surprising" contents |
1764 other_bases = set(bases) - {base} | 1748 other_bases = set(bases) - {base} |
1765 siderevs = list( | 1749 siderevs = list( |
1779 repo.revs( | 1763 repo.revs( |
1780 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset | 1764 b'%ld - (::%ld) - %ld', siderevs, merges, rebaseset |
1781 ) | 1765 ) |
1782 ) | 1766 ) |
1783 | 1767 |
1784 # Choose a merge base that has a minimal number of unwanted revs. | 1768 if any(revs is not None for revs in unwanted): |
1785 l, i = min( | 1769 # Choose a merge base that has a minimal number of unwanted revs. |
1786 (len(revs), i) | 1770 l, i = min( |
1787 for i, revs in enumerate(unwanted) | 1771 (len(revs), i) |
1788 if revs is not None | 1772 for i, revs in enumerate(unwanted) |
1789 ) | 1773 if revs is not None |
1790 | |
1791 # The merge will include unwanted revisions. Abort now. Revisit this if | |
1792 # we have a more advanced merge algorithm that handles multiple bases. | |
1793 if l > 0: | |
1794 unwanteddesc = _(b' or ').join( | |
1795 ( | |
1796 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs) | |
1797 for revs in unwanted | |
1798 if revs is not None | |
1799 ) | |
1800 ) | 1774 ) |
1801 raise error.Abort( | 1775 |
1802 _(b'rebasing %d:%s will include unwanted changes from %s') | 1776 # The merge will include unwanted revisions. Abort now. Revisit this if |
1803 % (rev, repo[rev], unwanteddesc) | 1777 # we have a more advanced merge algorithm that handles multiple bases. |
1804 ) | 1778 if l > 0: |
1805 | 1779 unwanteddesc = _(b' or ').join( |
1806 # newps[0] should match merge base if possible. Currently, if newps[i] | 1780 ( |
1807 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is | 1781 b', '.join(b'%d:%s' % (r, repo[r]) for r in revs) |
1808 # the other's ancestor. In that case, it's fine to not swap newps here. | 1782 for revs in unwanted |
1809 # (see CASE-1 and CASE-2 above) | 1783 if revs is not None |
1810 if i != 0: | 1784 ) |
1811 if newps[i] != nullrev: | 1785 ) |
1812 newps[0], newps[i] = newps[i], newps[0] | 1786 raise error.Abort( |
1813 bases[0], bases[i] = bases[i], bases[0] | 1787 _(b'rebasing %d:%s will include unwanted changes from %s') |
1788 % (rev, repo[rev], unwanteddesc) | |
1789 ) | |
1790 | |
1791 # newps[0] should match merge base if possible. Currently, if newps[i] | |
1792 # is nullrev, the only case is newps[i] and newps[j] (j < i), one is | |
1793 # the other's ancestor. In that case, it's fine to not swap newps here. | |
1794 # (see CASE-1 and CASE-2 above) | |
1795 if i != 0: | |
1796 if newps[i] != nullrev: | |
1797 newps[0], newps[i] = newps[i], newps[0] | |
1798 bases[0], bases[i] = bases[i], bases[0] | |
1814 | 1799 |
1815 # "rebasenode" updates to new p1, use the corresponding merge base. | 1800 # "rebasenode" updates to new p1, use the corresponding merge base. |
1816 if bases[0] != nullrev: | 1801 base = bases[0] |
1817 base = bases[0] | |
1818 else: | |
1819 base = None | |
1820 | 1802 |
1821 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps)) | 1803 repo.ui.debug(b" future parents are %d and %d\n" % tuple(newps)) |
1822 | 1804 |
1823 return newps[0], newps[1], base | 1805 return newps[0], newps[1], base |
1824 | 1806 |