evolve: add pre-check logic for creation of phase divergence locally draft
authorSushil khanchi <sushilkhanchi97@gmail.com>
Sun, 10 Nov 2019 16:32:34 +0530
changeset 5243 e08900cf4b8b
parent 5242 a6434bdfb387
evolve: add pre-check logic for creation of phase divergence locally Changes in tests reflect the added behaviour.
hgext3rd/evolve/rewriteutil.py
tests/test-evolve-phase-divergence.t
--- a/hgext3rd/evolve/rewriteutil.py	Sun Nov 10 18:08:57 2019 +0530
+++ b/hgext3rd/evolve/rewriteutil.py	Sun Nov 10 16:32:34 2019 +0530
@@ -22,6 +22,7 @@
     node,
     obsolete,
     obsutil,
+    phases,
     revset,
     util,
 )
@@ -101,6 +102,22 @@
             hint = _(b"see 'hg help evolution.instability' for details "
                      b"on content-divergence")
         raise error.Abort(msg, hint=hint)
+    pdivrisk = precheck_phasediv(repo, revs)
+    if pdivrisk and not allowdivergence:
+        rev, pred = repo[pdivrisk[0]], repo[pdivrisk[1]]
+        msg = _(b'%s of %s creates phase-divergence '
+                b'with %s') % (action, rev, pred)
+        hint = _(b"add --verbose for details or see "
+                 b"'hg help evolution.instability'")
+        if repo.ui.verbose:
+            msg += _(b'\n    changeset %s has a public predecessor as %s\n'
+                     b'    rewritting changeset %s would create '
+                     b'phase-divergence\n'
+                     b'    set experimental.evolution.allowdivergence=True to '
+                     b'overwrite this check') % (rev, pred, rev)
+            hint = _(b"see 'hg help evolution.instability' for details "
+                     b"on phase-divergence")
+        raise error.Abort(msg, hint=hint)
 
 def bookmarksupdater(repo, oldid, tr):
     """Return a callable update(newid) updating the current bookmark
@@ -313,3 +330,24 @@
         divergent.append(sset[0][0])
         divergent.append(ctx.node())
     return divergent
+
+def precheck_phasediv(repo, revs):
+    """check if revisions being rewritten has a public predecessor
+
+    this method has similar logic as obsolete._computephasedivergentset
+    except that here we are looking into obsolete revs"""
+    obsrevs = repo.revs(b'%ld and obsolete()', revs)
+    obsstore = repo.obsstore
+    phase = repo._phasecache.phase
+    public = phases.public
+    cl = repo.changelog
+    torev = compat.getgetrev(cl)
+    tonode = cl.node
+    for rev in obsrevs:
+        node = tonode(rev)
+        for pnode in obsutil.allpredecessors(obsstore, [node]):
+            prev = torev(pnode)
+            if (prev is not None) and (phase(repo, prev) <= public):
+                # we have a public predecessor
+                return [rev, prev]
+    return []
--- a/tests/test-evolve-phase-divergence.t	Sun Nov 10 18:08:57 2019 +0530
+++ b/tests/test-evolve-phase-divergence.t	Sun Nov 10 16:32:34 2019 +0530
@@ -2032,4 +2032,13 @@
   1 changesets pruned
 
   $ hg touch --hidden -r 2
-  1 new phase-divergent changesets
+  abort: touch of 603041d63ba0 creates phase-divergence with 7c3bad9141dc
+  (add --verbose for details or see 'hg help evolution.instability')
+  [255]
+  $ hg touch --hidden -r 2 --verbose
+  abort: touch of 603041d63ba0 creates phase-divergence with 7c3bad9141dc
+      changeset 603041d63ba0 has a public predecessor as 7c3bad9141dc
+      rewritting changeset 603041d63ba0 would create phase-divergence
+      set experimental.evolution.allowdivergence=True to overwrite this check
+  (see 'hg help evolution.instability' for details on phase-divergence)
+  [255]