evolve: implement resolution of content-divergence when on differet parents
authorPulkit Goyal <7895pulkit@gmail.com>
Fri, 01 Jun 2018 19:52:06 +0530
changeset 3805 2410e7063692
parent 3804 509b1e66f0b9
child 3806 99469bb3854e
evolve: implement resolution of content-divergence when on differet parents This patch implements the basic version of resolution of content-divergence changesets when they are on different parents but one of the parent is gca of both the different parents. The functionality first relocates the divergent changeset which was left behind and then resolves the content-divergence like it resolves in normal cases. This is a very basic implementation because it still does not work on interrupted evolution. Test changes in this patch shows the basic functionality working. The output of dry-run is also required to be tweaked in such cased. Upcoming patches will add more tests and will improve the implementation to work during conflicts too.
hgext3rd/evolve/evolvecmd.py
tests/test-evolve-content-divergence.t
--- a/hgext3rd/evolve/evolvecmd.py	Fri Jun 01 19:57:19 2018 +0530
+++ b/hgext3rd/evolve/evolvecmd.py	Fri Jun 01 19:52:06 2018 +0530
@@ -376,8 +376,36 @@
         ui.write_err(hint)
         return (False, '')
 
-    # we don't handle content-divergent changesets with different parents yet
-    if other.p1() not in divergent.parents():
+    otherp1 = other.p1().rev()
+    divp1 = divergent.p1().rev()
+    gca = repo.revs("ancestor(%d, %d)" % (otherp1, divp1))
+
+    # is relocation of one of the changeset required
+    relocatereq = False
+
+    # testing how both the divergent changesets are arranged, there can be 4
+    # possible cases here:
+    #
+    # 1) both have the same parents
+    # 2) both have different parents but greatest common anscestor of them is
+    #    parent of one of them
+    # 3) both have different parents and gca is not parent of any of them
+    # 4) one of them is parent of other
+    #
+    # we are handling 1) very good now.
+    # for 2) we will relocate one which is behind to the parent of ahead one and
+    # then solve the content-divergence the way we solve 1)
+    # for 3) and 4), we still have to decide
+    if otherp1 in gca and divp1 in gca:
+        # both are on the same parents
+        pass
+    elif otherp1 in gca and divp1 not in gca:
+        relocatereq = True
+        pass
+    elif divp1 in gca and otherp1 not in gca:
+        relocatereq = True
+        divergent, other = other, divergent
+    else:
         msg = _("skipping %s: have a different parent than %s "
                 "(not handled yet)\n") % (divergent, other)
         hint = _("| %(d)s, %(o)s are not based on the same changeset.\n"
@@ -412,6 +440,15 @@
         ui.write(('hg commit -m "`hg log -r %s --template={desc}`";\n'
                  % divergent))
         return (False, '')
+
+    # relocate the other divergent if required
+    if relocatereq:
+        ui.status(_('rebasing "other" content-divergent changeset %s on'
+                    ' %s\n' % (other, divergent.p1())))
+        newother = relocate(repo, other, divergent.p1(), evolvestate,
+                            keepbranch=True)
+        other = repo[newother]
+
     if divergent not in repo[None].parents():
         repo.ui.status(_("updating to \"local\" side of the conflict: %s\n") %
                        divergent.hex()[:12])
--- a/tests/test-evolve-content-divergence.t	Fri Jun 01 19:57:19 2018 +0530
+++ b/tests/test-evolve-content-divergence.t	Fri Jun 01 19:52:06 2018 +0530
@@ -332,27 +332,40 @@
       () [default] draft
 
   $ hg evolve --content-divergent
-  skipping 7ed0642d644b: have a different parent than da4b96f4a8d6 (not handled yet)
-  | 7ed0642d644b, da4b96f4a8d6 are not based on the same changeset.
-  | With the current state of its implementation, 
-  | evolve does not work in that case.
-  | rebase one of them next to the other and run 
-  | this command again.
-  | - either: hg rebase --dest 'p1(7ed0642d644b)' -r da4b96f4a8d6
-  | - or:     hg rebase --dest 'p1(da4b96f4a8d6)' -r 7ed0642d644b
+  merge:[5] added b
+  with: [6] added b
+  base: [2] added b
+  rebasing "other" content-divergent changeset da4b96f4a8d6 on c7586e2a9264
+  updating to "local" side of the conflict: 7ed0642d644b
+  merging "other" content-divergent changeset '11f849d7159f'
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  nothing changed
 
   $ hg glog
-  *  6:da4b96f4a8d6 added b
+  @  5:7ed0642d644b added b
   |   () [default] draft
-  | @  5:7ed0642d644b added b
+  | *  4:c41c793e0ef1 added d
   | |   () [default] draft
-  | | *  4:c41c793e0ef1 added d
-  | | |   () [default] draft
-  | | *  3:ca1b80f7960a added c
-  | | |   () [default] draft
-  | | x  2:b1661037fa25 added b
-  | |/    () [default] draft
-  | o  1:c7586e2a9264 added a
+  | *  3:ca1b80f7960a added c
+  | |   () [default] draft
+  | x  2:b1661037fa25 added b
   |/    () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
   o  0:8fa14d15e168 added hgignore
       () [default] draft
+
+  $ hg exp
+  # HG changeset patch
+  # User test
+  # Date 0 0
+  #      Thu Jan 01 00:00:00 1970 +0000
+  # Node ID 7ed0642d644bb9ad93d252dd9ffe7b4729febe48
+  # Parent  c7586e2a92645e473645847a7b69a6dc52be4276
+  added b
+  
+  diff -r c7586e2a9264 -r 7ed0642d644b b
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/b	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +bar