evolve: make the _solve* functions return a tuple
authorPulkit Goyal <7895pulkit@gmail.com>
Sat, 27 Jan 2018 16:13:19 +0530
changeset 3458 210132852a3d
parent 3457 82e9f9603b1b
child 3459 218fbcc3220c
evolve: make the _solve* functions return a tuple This patch makes _solve* functions return a tuple which will contain information about whether we were able to solve the instability and if yes, then what was the newnode. For more details about tuple, look the fn docs added. There was some refactoring required in next command because of change in return values. This also leds to omitting the wdir update message in case of dry-run which is good.
hgext3rd/evolve/__init__.py
tests/test-prev-next.t
--- a/hgext3rd/evolve/__init__.py	Wed Jan 17 19:12:32 2018 +0530
+++ b/hgext3rd/evolve/__init__.py	Sat Jan 27 16:13:19 2018 +0530
@@ -884,7 +884,10 @@
     pass
 
 def relocate(repo, orig, dest, pctx=None, keepbranch=False):
-    """rewrite <rev> on dest"""
+    """rewrites the orig rev on dest rev
+
+    returns the node of new commit which is formed
+    """
     if orig.rev() == dest.rev():
         raise error.Abort(_('tried to relocate a node on top of itself'),
                           hint=_("This shouldn't happen. If you still "
@@ -1026,7 +1029,14 @@
     _deprecatealias('gdown', 'previous')
 
 def _solveone(ui, repo, ctx, dryrun, confirm, progresscb, category):
-    """Resolve the troubles affecting one revision"""
+    """Resolve the troubles affecting one revision
+
+    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 ''.
+    """
     wlock = lock = tr = None
     try:
         wlock = repo.wlock()
@@ -1716,7 +1726,14 @@
 
 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
                    progresscb=None):
-    """Stabilize an unstable changeset"""
+    """ Tries to stabilize the changeset orig which is orphan.
+
+    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 ''.
+    """
     pctx = orig.p1()
     keepbranch = orig.p1().branch() != orig.branch()
     if len(orig.parents()) == 2:
@@ -1729,11 +1746,11 @@
             ui.warn(_("warning: no support for evolving merge changesets "
                       "with two obsolete parents yet\n") +
                     _("(%s)\n") % hint)
-            return False
+            return (False, '')
 
     if not pctx.obsolete():
         ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
-        return False
+        return (False, '')
     obs = pctx
     newer = compat.successorssets(repo, obs.node())
     # search of a parent which is not killed
@@ -1747,7 +1764,7 @@
         msg = _("skipping %s: divergent rewriting. can't choose "
                 "destination\n") % obs
         ui.write_err(msg)
-        return 2
+        return (False, '')
     targets = newer[0]
     assert targets
     if len(targets) > 1:
@@ -1758,7 +1775,7 @@
         if len(roots) > 1 or len(heads) > 1:
             msg = "cannot solve split across two branches\n"
             ui.write_err(msg)
-            return 2
+            return (False, '')
         target = repo[heads.first()]
     else:
         target = targets[0]
@@ -1775,13 +1792,15 @@
         progresscb()
     todo = 'hg rebase -r %s -d %s\n' % (orig, target)
     if dryrun:
+        return (False, '')
         repo.ui.write(todo)
     else:
         repo.ui.note(todo)
         if progresscb:
             progresscb()
         try:
-            relocate(repo, orig, target, pctx, keepbranch)
+            newid = relocate(repo, orig, target, pctx, keepbranch)
+            return (True, newid)
         except MergeFailure:
             ops = {'current': orig.node()}
             evolvestate = state.cmdstate(repo, opts=ops)
@@ -1794,21 +1813,28 @@
 
 def _solvebumped(ui, repo, bumped, dryrun=False, confirm=False,
                  progresscb=None):
-    """Stabilize a bumped changeset"""
+    """Stabilize a bumped 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()
     bumped = repo[bumped.rev()]
     # For now we deny bumped merge
     if len(bumped.parents()) > 1:
         msg = _('skipping %s : we do not handle merge yet\n') % bumped
         ui.write_err(msg)
-        return 2
+        return (False, '')
     prec = repo.set('last(allprecursors(%d) and public())', bumped).next()
     # For now we deny target merge
     if len(prec.parents()) > 1:
         msg = _('skipping: %s: public version is a merge, '
                 'this is not handled yet\n') % prec
         ui.write_err(msg)
-        return 2
+        return (False, '')
 
     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
     if not ui.quiet or confirm:
@@ -1825,7 +1851,7 @@
         repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
         repo.ui.write(('hg commit --msg "%s update to %s"\n' %
                        (TROUBLES['PHASEDIVERGENT'], bumped)))
-        return 0
+        return (False, '')
     if progresscb:
         progresscb()
     newid = tmpctx = None
@@ -1898,9 +1924,18 @@
     # reroute the working copy parent to the new changeset
     with repo.dirstate.parentchange():
         repo.dirstate.setparents(newid, node.nullid)
+    return (True, newid)
 
 def _solvedivergent(ui, repo, divergent, 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()
     divergent = repo[divergent.rev()]
     base, others = divergentdata(divergent)
@@ -1918,7 +1953,7 @@
                 "| You should contact your local evolution Guru for help.\n"
                 ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
         ui.write_err(msg)
-        return 2
+        return (False, '')
     other = others[0]
     if len(other.parents()) > 1:
         msg = _("skipping %s: %s changeset can't be "
@@ -1928,7 +1963,7 @@
                  "| This probably means redoing the merge and using \n"
                  "| `hg prune` to kill older version.\n")
         ui.write_err(hint)
-        return 2
+        return (False, '')
     if other.p1() not in divergent.parents():
         msg = _("skipping %s: have a different parent than %s "
                 "(not handled yet)\n") % (divergent, other)
@@ -1942,7 +1977,7 @@
                  ) % {'d': divergent, 'o': other}
         ui.write_err(msg)
         ui.write_err(hint)
-        return 2
+        return (False, '')
 
     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
     if not ui.quiet or confirm:
@@ -1963,7 +1998,7 @@
         ui.write(('hg revert --all --rev tip &&\n'))
         ui.write(('hg commit -m "`hg log -r %s --template={desc}`";\n'
                  % divergent))
-        return
+        return (False, '')
     if divergent not in repo[None].parents():
         repo.ui.status(_('updating to "local" conflict\n'))
         hg.update(repo, divergent.rev())
@@ -2008,6 +2043,7 @@
             new = repo['.']
         obsolete.createmarkers(repo, [(other, (new,))])
         phases.retractboundary(repo, tr, other.phase(), [new.node()])
+        return (True, new.node())
     finally:
         repo.ui.restoreconfig(emtpycommitallowed)
 
@@ -2244,10 +2280,11 @@
                 cmdutil.bailifchanged(repo)
                 result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt,
                                    False, lambda: None, category='orphan')
-                if not result:
+                # making sure a next commit is formed
+                if result[0] and result[1]:
                     ui.status(_('working directory now at %s\n')
                               % ui.label(str(repo['.']), 'evolve.node'))
-                return result
+                return 0
             return 1
         return result
     finally:
--- a/tests/test-prev-next.t	Wed Jan 17 19:12:32 2018 +0530
+++ b/tests/test-prev-next.t	Sat Jan 27 16:13:19 2018 +0530
@@ -190,7 +190,6 @@
   move:[2] added c
   atop:[3] added b (2)
   hg rebase -r 4e26ef31f919 -d 9ad178109a19
-  working directory now at 9ad178109a19
 
 (add color output for smoke testing)