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

login
register
mail settings
Submitter Pierre-Yves David
Date Feb. 14, 2016, 3:38 p.m.
Message ID <191223342dcb0e8e87b2.1455464296@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/13181/
State Accepted
Headers show

Comments

Pierre-Yves David - Feb. 14, 2016, 3:38 p.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 191223342dcb0e8e87b2b3f038fdda98b3d51a26
# Parent  e025ec586bdf3111bb1ca85672c7cab3b407cf46
# EXP-Topic destination
# Available At http://hg.netv6.net/marmoute-wip/mercurial/
#              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 191223342dcb
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.
Martin von Zweigbergk - Feb. 15, 2016, 5:27 a.m.
On Sun, Feb 14, 2016 at 7:38 AM, Pierre-Yves David
<pierre-yves.david@ens-lyon.org> wrote:
> # 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 191223342dcb0e8e87b2b3f038fdda98b3d51a26
> # Parent  e025ec586bdf3111bb1ca85672c7cab3b407cf46
> # EXP-Topic destination
> # Available At http://hg.netv6.net/marmoute-wip/mercurial/
> #              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 191223342dcb
> 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.
>
> 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"""

Unused. Meant to be superclass for the classes below?

> +
> +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'))
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Martin von Zweigbergk - Feb. 15, 2016, 7:32 a.m.
On Sun, Feb 14, 2016 at 9:27 PM, Martin von Zweigbergk
<martinvonz@google.com> wrote:
> On Sun, Feb 14, 2016 at 7:38 AM, Pierre-Yves David
> <pierre-yves.david@ens-lyon.org> wrote:
>> # 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 191223342dcb0e8e87b2b3f038fdda98b3d51a26
>> # Parent  e025ec586bdf3111bb1ca85672c7cab3b407cf46
>> # EXP-Topic destination
>> # Available At http://hg.netv6.net/marmoute-wip/mercurial/
>> #              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 191223342dcb
>> 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.
>>
>> 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"""
>
> Unused. Meant to be superclass for the classes below?

Since I'll be away for a week now, I pushed this series to the
clowncopter. Feel free to fix it up there if you like.

>
>> +
>> +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'))
>> _______________________________________________
>> Mercurial-devel mailing list
>> Mercurial-devel@mercurial-scm.org
>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Pierre-Yves David - Feb. 15, 2016, 10:36 a.m.
On 02/15/2016 07:32 AM, Martin von Zweigbergk wrote:
> On Sun, Feb 14, 2016 at 9:27 PM, Martin von Zweigbergk
> <martinvonz@google.com> wrote:
>> On Sun, Feb 14, 2016 at 7:38 AM, Pierre-Yves David
>> <pierre-yves.david@ens-lyon.org> wrote:
>>> # 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 191223342dcb0e8e87b2b3f038fdda98b3d51a26
>>> # Parent  e025ec586bdf3111bb1ca85672c7cab3b407cf46
>>> # EXP-Topic destination
>>> # Available At http://hg.netv6.net/marmoute-wip/mercurial/
>>> #              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 191223342dcb
>>> 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.
>>>
>>> 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"""
>>
>> Unused. Meant to be superclass for the classes below?
>
> Since I'll be away for a week now, I pushed this series to the
> clowncopter. Feel free to fix it up there if you like.

ah good catch, fixed in flight.

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'))