evolve: extract pre merging content-div csets logic to its own function
authorSushil khanchi <sushilkhanchi97@gmail.com>
Sun, 01 Dec 2019 12:41:20 +0530
changeset 5033 7cc3d96eb589
parent 5032 31b0b29245bb
child 5035 c5efcbbd0dc4
evolve: extract pre merging content-div csets logic to its own function
hgext3rd/evolve/evolvecmd.py
--- a/hgext3rd/evolve/evolvecmd.py	Thu Dec 26 20:28:21 2019 +0100
+++ b/hgext3rd/evolve/evolvecmd.py	Sun Dec 01 12:41:20 2019 +0530
@@ -298,17 +298,9 @@
         repo.dirstate.setparents(newid, nodemod.nullid)
     return (True, replacementnode)
 
-def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
-                    confirm=False, progresscb=None):
-    """tries to solve content-divergence of a changeset
-
-    returns a tuple (bool, newnode) where,
-        bool: a boolean value indicating whether the instability was solved
-        newnode: if bool is True, then the newnode of the resultant commit
-                 formed. newnode can be node, when resolution led to no new
-                 commit. If bool is False, this is ".".
-    """
-    repo = repo.unfiltered()
+def _prepcontentdivresolution(ui, repo, divergent, other, evolvestate):
+    """ if relocation required, decide which divergent cset will be relocated
+    to the other side"""
     divergent = repo[divergent.rev()]
     evolvestate[b'divergent'] = divergent.node()
     evolvestate[b'orig-divergent'] = divergent.node()
@@ -327,27 +319,6 @@
     # other for purposes like `--abort` or `--stop`
     evolvestate[b'old-other'] = None
     evolvestate[b'old-divergent'] = None
-    base, others = divergentdata(divergent)
-
-    # we don't handle split in content-divergence yet
-    if len(others) > 1:
-        othersstr = b"[%s]" % (b','.join([bytes(i) for i in others]))
-        msg = _(b"skipping %s: %s with a changeset that got split"
-                b" into multiple ones:\n"
-                b"|[%s]\n"
-                b"| This is not handled by automatic evolution yet\n"
-                b"| You have to fallback to manual handling with commands "
-                b"such as:\n"
-                b"| - hg touch -D\n"
-                b"| - hg prune\n"
-                b"| \n"
-                b"| You should contact your local evolution Guru for help.\n"
-                ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
-        ui.write_err(msg)
-        return (False, b".")
-    other = others[0]
-    evolvestate[b'other-divergent'] = other.node()
-    evolvestate[b'base'] = base.node()
 
     def swapnodes(div, other):
         div, other = other, div
@@ -366,6 +337,7 @@
         else:
             publicdiv = divergent
         evolvestate[b'public-divergent'] = publicdiv.node()
+
     # we don't handle merge content-divergent changesets yet
     if len(other.parents()) > 1:
         msg = _(b"skipping %s: %s changeset can't be "
@@ -483,6 +455,52 @@
         ui.write_err(hint)
         return (False, b".")
 
+    return (True, divergent, other, resolutionparent, relocatereq)
+
+def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
+                    confirm=False, progresscb=None):
+    """tries to solve content-divergence of a changeset
+
+    returns a tuple (bool, newnode) where,
+        bool: a boolean value indicating whether the instability was solved
+        newnode: if bool is True, then the newnode of the resultant commit
+                 formed. newnode can be node, when resolution led to no new
+                 commit. If bool is False, this is ".".
+    """
+    repo = repo.unfiltered()
+    base, others = divergentdata(divergent)
+
+    # we don't handle split in content-divergence yet
+    if len(others) > 1:
+        othersstr = b"[%s]" % (b','.join([bytes(i) for i in others]))
+        msg = _(b"skipping %s: %s with a changeset that got split"
+                b" into multiple ones:\n"
+                b"|[%s]\n"
+                b"| This is not handled by automatic evolution yet\n"
+                b"| You have to fallback to manual handling with commands "
+                b"such as:\n"
+                b"| - hg touch -D\n"
+                b"| - hg prune\n"
+                b"| \n"
+                b"| You should contact your local evolution Guru for help.\n"
+                ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
+        ui.write_err(msg)
+        return (False, b".")
+    other = others[0]
+    evolvestate[b'other-divergent'] = other.node()
+    evolvestate[b'base'] = base.node()
+
+    # setup everything before merging two content-divergent csets
+    datatoproceed = _prepcontentdivresolution(ui, repo, divergent, other,
+                                              evolvestate)
+    if not datatoproceed[0]:
+        return (False, b".")
+    divergent, other, resolutionparent, relocatereq = datatoproceed[1:]
+
+    if relocatereq:
+        evolvestate['relocation-req'] = True
+    evolvestate[b'resolutionparent'] = resolutionparent
+
     if not ui.quiet or confirm:
         ui.write(_(b'merge:'), label=b'evolve.operation')
         displayer.show(divergent)
@@ -552,9 +570,11 @@
                             evolvestate)
     res, newnode = _completecontentdivergent(ui, repo, progresscb, divergent,
                                              other, base, evolvestate)
+    haspubdiv = not (divergent.mutable() and other.mutable())
     if not haspubdiv:
         return (res, newnode)
     else:
+        publicdiv = repo[evolvestate[b'public-divergent']]
         # we have content-divergence with a public cset:
         # after performing content divergence resolution steps, possbile cases:
         # 1) merging results in a new node: