[PATCH 16 of 17] rebase: fix rebase of a merge with an ancestor of target

Mads Kiilerich mads at kiilerich.com
Sun Nov 30 13:08:43 CST 2014


# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1417374421 -3600
#      Sun Nov 30 20:07:01 2014 +0100
# Node ID 639a274a5bd418594c9ad21766bf59cb5fcb3758
# Parent  c6efb8f700c44b0183be979854be11c1b551ee66
rebase: fix rebase of a merge with an ancestor of target

Rebasing of merges of a target ancestor was using an unfortunate parent as
ancestor and would thus give hard merges.

Instead, it will now use the target ancestor as merge ancestor. That is not
perfect but happens to work better with the test cases in the test suite and
real world cases.

Arguably, with both parents already being ancestors of the rebase target, there
really isn't anything to rebase. All there is to rebase is that it is a
different merge than the one already rebased so conflicts might have been
resolved differently. There might also have been made other manual changes in
the merge commit. No ancestor choice can possibly help rebasing that.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -613,13 +613,13 @@ def computerebase(repo, rev, target, sta
 
         \  p2     null         ancestor        rebased        outside
       p1 \
-    null       target,rev|   target,rev|p2   p2',rev|p2    target,rev|p2
+    null       target,rev|   target,rev|p2   p2',rev|p1    target,rev|p2
                  target         target           p2'          target
 
     ancestor  target,rev|p1 target,rev|None  p2',rev|p2   target,rev|None
                  target         target           p2'         target,p2
 
-    rebased    p1',rev|p1     p1',rev|p1    target,rev|p1   p1',rev|p1
+    rebased    p1',rev|p1     p1',rev|p2    target,rev|p1   p1',rev|p1
                    p1'            p1'          p1',p2         p1',p2
 
     outside   target,rev|p1 target,rev|None  p2',rev|p2       abort
@@ -664,7 +664,7 @@ def computerebase(repo, rev, target, sta
             return target, rev, None, target, nullrev
         if p2_ >= nullrev:
             repo.ui.debug(' p1 ancestor, p2 rebased\n')
-            return p2_, rev, p2, p2_, nullrev
+            return p2_, rev, p1, p2_, nullrev
         repo.ui.debug(' p1 ancestor, p2 outside\n')
         return target, rev, None, target, p2
     if p1_ >= nullrev:
@@ -673,7 +673,7 @@ def computerebase(repo, rev, target, sta
             return p1_, rev, p1, p1_, nullrev
         if p2 in targetancestors:
             repo.ui.debug(' p1 rebased, p2 ancestor\n')
-            return p1_, rev, p1, p1_, nullrev
+            return p1_, rev, p2, p1_, nullrev
         if p2_ >= nullrev:
             repo.ui.debug(' p1 rebased, p2 rebased\n')
             # TODO: This seems wrong. It should not use target.
diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t
--- a/tests/test-rebase-newancestor.t
+++ b/tests/test-rebase-newancestor.t
@@ -131,16 +131,11 @@ Full rebase all the way back from branch
    ignoring empty rebase of 1:1d1a643d390e
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  remote changed f-default which local deleted
-  use (c)hanged version or leave (d)eleted? c
+   ignoring empty rebase of 4:4b019212aaf6
   rebasing 6:9455ee510502 "dev: merge default"
-  local changed f-default which remote deleted
-  use (c)hanged version or (d)elete? c
    ignoring empty rebase of 6:9455ee510502
   saved backup bundle to $TESTTMP/ancestor-merge/.hg/strip-backup/1d1a643d390e-backup.hg (glob)
   $ hg tglog
-  o  5: 'dev: merge default'
-  |
   o  4: 'dev: f-dev stuff'
   |
   @  3: 'default: f-other stuff'
@@ -161,16 +156,11 @@ Grafty cherry picking rebasing:
    skipping null merge of 1:1d1a643d390e
   rebasing 2:ec2c14fb2984 "dev: f-dev stuff"
   rebasing 4:4b019212aaf6 "dev: merge default"
-  remote changed f-default which local deleted
-  use (c)hanged version or leave (d)eleted? c
+   ignoring empty rebase of 4:4b019212aaf6
   rebasing 6:9455ee510502 "dev: merge default"
-  local changed f-default which remote deleted
-  use (c)hanged version or (d)elete? c
    ignoring empty rebase of 6:9455ee510502
   saved backup bundle to $TESTTMP/ancestor-merge-2/.hg/strip-backup/ec2c14fb2984-backup.hg (glob)
   $ hg tglog
-  o  6: 'dev: merge default'
-  |
   o  5: 'dev: f-dev stuff'
   |
   o  4: 'default: f-other stuff'


More information about the Mercurial-devel mailing list