Patchwork [7,of,7] destutil: add more precise error classes for destmerge

login
register
mail settings
Submitter Pierre-Yves David
Date Feb. 14, 2016, 2:16 a.m.
Message ID <7f55e123a198ec9f4e84.1455416189@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/13178/
State Superseded
Headers show

Comments

Pierre-Yves David - Feb. 14, 2016, 2:16 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1455060641 0
#      Tue Feb 09 23:30:41 2016 +0000
# Node ID 7f55e123a198ec9f4e8478645e14bbd6676e9487
# Parent  622bb8fc32e96b0130b733fdc60118a6dd69540f
# EXP-Topic destination
# Available At http://hg.netv6.net/marmoute-wip/mercurial/
#              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 7f55e123a198
destutil: add more precise error classes for destmerge

Having exception classes more precise than 'Abort' will allow us to properly
catch "nothing to rebase" situations when we will be using 'destmerge' in
rebase.

Patch

diff --git a/mercurial/destutil.py b/mercurial/destutil.py
--- a/mercurial/destutil.py
+++ b/mercurial/destutil.py
@@ -207,14 +207,14 @@  def _destmergebook(repo, action='merge',
             node = bmheads[1]
         else:
             node = bmheads[0]
     elif len(bmheads) > 2:
         msg, hint = msgdestmerge['toomanybookmarks'][action]
-        raise error.Abort(msg, hint=hint)
+        raise error.ManyMergeDestAbort(msg, hint=hint)
     elif len(bmheads) <= 1:
         msg, hint = msgdestmerge['nootherbookmarks'][action]
-        raise error.Abort(msg, hint=hint)
+        raise error.NoMergeDestAbort(msg, hint=hint)
     assert node is not None
     return node
 
 def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True):
     """find merge destination based on branch heads"""
@@ -223,17 +223,17 @@  def _destmergebranch(repo, action='merge
     if sourceset is None:
         sourceset = [repo[repo.dirstate.p1()].rev()]
         branch = repo.dirstate.branch()
     elif not sourceset:
         msg, hint = msgdestmerge['emptysourceset'][action]
-        raise error.Abort(msg, hint=hint)
+        raise error.NoMergeDestAbort(msg, hint=hint)
     else:
         branch = None
         for ctx in repo.set('roots(%ld::%ld)', sourceset, sourceset):
             if branch is not None and ctx.branch() != branch:
                 msg, hint = msgdestmerge['multiplebranchessourceset'][action]
-                raise error.Abort(msg, hint=hint)
+                raise error.ManyMergeDestAbort(msg, hint=hint)
             branch = ctx.branch()
 
     bheads = repo.branchheads(branch)
     if onheadcheck and not repo.revs('%ld and %ln', sourceset, bheads):
         # Case A: working copy if not on a head. (merge only)
@@ -254,11 +254,11 @@  def _destmergebranch(repo, action='merge
         # This means that there will be more than 1 candidate. This is
         # ambiguous. We abort asking the user to pick as explicit destination
         # instead.
         msg, hint = msgdestmerge['toomanyheads'][action]
         msg %= (branch, len(bheads) + 1)
-        raise error.Abort(msg, hint=hint)
+        raise error.ManyMergeDestAbort(msg, hint=hint)
     elif not nbhs:
         # Case B: There is no other anonymous heads
         #
         # This means that there is no natural candidate to merge with.
         # We abort, with various messages for various cases.
@@ -267,11 +267,11 @@  def _destmergebranch(repo, action='merge
         elif len(repo.heads()) > 1:
             msg, hint = msgdestmerge['nootherbranchheads'][action]
             msg %= branch
         else:
             msg, hint = msgdestmerge['nootherheads'][action]
-        raise error.Abort(msg, hint=hint)
+        raise error.NoMergeDestAbort(msg, hint=hint)
     else:
         node = nbhs[0]
     assert node is not None
     return node
 
diff --git a/mercurial/error.py b/mercurial/error.py
--- a/mercurial/error.py
+++ b/mercurial/error.py
@@ -70,10 +70,19 @@  class ConfigError(Abort):
     """Exception raised when parsing config files"""
 
 class UpdateAbort(Abort):
     """Raised when an update is aborted for destination issue"""
 
+class MergeDestAbort(Abort):
+    """Raised when an update is aborted for destination issues"""
+
+class NoMergeDestAbort(Abort):
+    """Raised when an update is aborted because there is nothing to merge"""
+
+class ManyMergeDestAbort(Abort):
+    """Raised when an update is aborted because destination is ambigious"""
+
 class ResponseExpected(Abort):
     """Raised when an EOF is received for a prompt"""
     def __init__(self):
         from .i18n import _
         Abort.__init__(self, _('response expected'))