hgext/evolve.py
changeset 1410 2c451fece7a6
parent 1409 3276730e4b32
child 1411 64515965c0df
--- a/hgext/evolve.py	Fri Jun 19 14:32:54 2015 -0700
+++ b/hgext/evolve.py	Fri Jun 19 14:26:33 2015 -0700
@@ -1204,54 +1204,100 @@
     finally:
         lockmod.release(tr, lock, wlock)
 
-def _handlenotrouble(ui, repo, startnode, dryrunopt):
+def _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat):
     """Used by the evolve function to display an error message when
     no troubles can be resolved"""
-    if repo['.'].obsolete():
-        displayer = cmdutil.show_changeset(
-            ui, repo, {'template': shorttemplate})
-        successors = set()
-
-        for successorsset in obsolete.successorssets(repo, repo['.'].node()):
-            for nodeid in successorsset:
-                successors.add(repo[nodeid])
-
-        if not successors:
-            ui.warn(_('parent is obsolete without successors; ' +
-                      'likely killed\n'))
-            return 2
-
-        elif len(successors) > 1:
-            ui.warn(_('parent is obsolete with multiple successors:\n'))
-
-            for ctx in sorted(successors, key=lambda ctx: ctx.rev()):
-                displayer.show(ctx)
-
-            return 2
-
+    troublecategories = ['bumped', 'divergent', 'unstable']
+    unselectedcategories = [c for c in troublecategories if c != targetcat]
+    msg = None
+    hint = None
+
+    troubled = {
+            "unstable": repo.revs("unstable()"),
+            "divergent": repo.revs("divergent()"),
+            "bumped": repo.revs("bumped()"),
+            "all": repo.revs("troubled()"),
+    }
+
+
+    hintmap = {
+            'bumped': _("do you want to use --bumped"),
+            'bumped+divergent': _("do you want to use --bumped or --divergent"),
+            'bumped+unstable': _("do you want to use --bumped or --unstable"),
+            'divergent': _("do you want to use --divergent"),
+            'divergent+unstable': _("do you want to use --divergent"
+                                    " or --unstable"),
+            'unstable': _("do you want to use --unstable"),
+            'any+bumped': _("do you want to use --any (or --rev) and --bumped"),
+            'any+bumped+divergent': _("do you want to use --any (or --rev) and"
+                                      " --bumped or --divergent"),
+            'any+bumped+unstable': _("do you want to use --any (or --rev) and"
+                                     "--bumped or --unstable"),
+            'any+divergent': _("do you want to use --any (or --rev) and"
+                               " --divergent"),
+            'any+divergent+unstable': _("do you want to use --any (or --rev)"
+                                        " and --divergent or --unstable"),
+            'any+unstable': _("do you want to use --any (or --rev)"
+                              "and --unstable"),
+    }
+
+    if revopt:
+        revs = scmutil.revrange(repo, revopt)
+        if not revs:
+            msg = _("set of specified revisions is empty")
         else:
-            ctx = successors.pop()
-
-            ui.status(_('update:'))
-            if not ui.quiet:
-                displayer.show(ctx)
-
-            if dryrunopt:
-                return 0
+            msg = _("no %s changesets in specified revisions") % targetcat
+            othertroubles = []
+            for cat in unselectedcategories:
+                if revs & troubled[cat]:
+                    othertroubles.append(cat)
+            if othertroubles:
+                hint = hintmap['+'.join(othertroubles)]
+
+    elif allopt or anyopt:
+        msg = _("no %s changesets to evolve") % targetcat
+        othertroubles = []
+        for cat in unselectedcategories:
+            if troubled[cat]:
+                othertroubles.append(cat)
+        if othertroubles:
+            hint = hintmap['+'.join(othertroubles)]
+
+    else:
+        # evolve without any option = relative to the current wdir
+        if targetcat == 'unstable':
+            msg = _("nothing to evolve on current working copy parent")
+        else:
+            msg = _("current working copy parent is not %s") % targetcat
+
+        p1 = repo['.'].rev()
+        othertroubles = []
+        for cat in unselectedcategories:
+            if p1 in troubled[cat]:
+                othertroubles.append(cat)
+        if othertroubles:
+            hint = hintmap['+'.join(othertroubles)]
+        else:
+            l = len(troubled[targetcat])
+            if l:
+                hint = (_("%d other %s in the repository, do you want --any or --rev")
+                        % (l, targetcat))
             else:
-                res = hg.update(repo, ctx.rev())
-                if ctx != startnode:
-                    ui.status(_('working directory is now at %s\n') % ctx)
-                return res
-
-    troubled = repo.revs('troubled()')
-    if troubled:
-        ui.write_err(_('nothing to evolve here\n'))
-        ui.status(_('(%i troubled changesets, do you want --any ?)\n')
-                  % len(troubled))
+                othertroubles = []
+                for cat in unselectedcategories:
+                    if troubled[cat]:
+                        othertroubles.append(cat)
+                if othertroubles:
+                    hint = hintmap['any+'+('+'.join(othertroubles))]
+                else:
+                    msg = _("no troubled changesets")
+
+    assert msg is not None
+    ui.write_err(msg+"\n")
+    if hint:
+        ui.write_err("("+hint+")\n")
         return 2
     else:
-        ui.write_err(_('no troubled changesets\n'))
         return 1
 
 def _cleanup(ui, repo, startnode, showprogress):
@@ -1316,6 +1362,24 @@
                 rdependencies[succ].add(r)
     return dependencies, rdependencies
 
+def _selectrevs(repo, allopt, revopt, anyopt, targetcat):
+    """select troubles in repo matching according to given options"""
+    revs = set()
+    if allopt or revopt:
+        revs = repo.revs(targetcat+'()')
+        if revopt:
+            revs = scmutil.revrange(repo, revopt) & revs
+    elif anyopt:
+        revs = repo.revs('first(%s())' % (targetcat))
+    elif targetcat == 'unstable':
+        tro = _stabilizableunstable(repo, repo['.'])
+        if tro is not None:
+            revs = set([tro])
+    elif targetcat in repo['.'].troubles():
+        revs = set([repo['.'].rev()])
+    return revs
+
+
 def orderrevs(repo, revs):
     """ Compute an ordering to solve instability for the given revs
 
@@ -1425,6 +1489,17 @@
             return 2
 
 
+        ui.status(_('update:'))
+        if not ui.quiet:
+            displayer.show(ctx)
+
+        if dryrunopt:
+            return 0
+        res = hg.update(repo, ctx.rev())
+        if ctx != startnode:
+            ui.status(_('working directory is now at %s\n') % ctx)
+        return res
+
     ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
     troubled = set(repo.revs('troubled()'))
 
@@ -1450,26 +1525,13 @@
 
     if revopt and allopt:
         raise util.Abort('cannot specify both "--rev" and "--all"')
-
-    revs = set()
-    if allopt or revopt:
-        revs = repo.revs(targetcat+'()')
-        if revopt:
-            revs = repo.revs(revopt) & revs
-    elif anyopt:
-        revs = repo.revs('first(%s())' % (targetcat))
-    elif targetcat == 'unstable':
-        tro = _stabilizableunstable(repo, repo['.'])
-        if tro is None:
-            return _handlenotrouble(ui, repo, startnode, dryrunopt)
-        revs = set([tro])
-    elif targetcat in repo['.'].troubles():
-        revs = set([repo['.'].rev()])
     if revopt and anyopt:
         raise util.Abort('cannot specify both "--rev" and "--any"')
+
+    revs = _selectrevs(repo, allopt, revopt, anyopt, targetcat)
+
     if not revs:
-        msg = "no troubled changes in the specified revisions"
-        raise util.Abort(msg)
+        return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat)
 
     # For the progress bar to show
     count = len(revs)