[PATCH 11 of 12 stable] bundle2: gracefully handle PushRaced error during unbundle

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Tue Apr 22 15:10:55 CDT 2014


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1398127918 25200
#      Mon Apr 21 17:51:58 2014 -0700
# Branch stable
# Node ID fbf039ac0e2ea7cfcfdcd7c06b532c31cdaad60f
# Parent  58b0fd92f3e411f68dbf9c6e129d895df5336902
bundle2: gracefully handle PushRaced error during unbundle

Same drill again. We catch the PushRaced error, check if it cames from a bundle2
processing, if so we turn it into a bundle2 with a part transporting error
information to be reraised client side.

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -758,5 +758,11 @@ def handlereplycaps(op, inpart):
 @parthandler('b2x:error:unknownpart')
 def handlereplycaps(op, inpart):
     """Used to transmit unknown part error over the wire"""
     manargs = dict(inpart.mandatoryparams)
     raise UnknownPartError(manargs['parttype'])
+
+ at parthandler('b2x:error:pushraced')
+def handlereplycaps(op, inpart):
+    """Used to transmit push race error over the wire"""
+    manargs = dict(inpart.mandatoryparams)
+    raise error.ResponseError(_('push failed:'), manargs['message'])
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -825,6 +825,13 @@ def unbundle(repo, proto, heads):
             return streamres(bundler.getchunks())
         else:
             sys.stderr.write("abort: %s\n" % inst)
             return pushres(0)
     except error.PushRaced, exc:
-        return pusherr(str(exc))
+        if getattr(exc, 'duringunbundle2', False):
+            bundler = bundle2.bundle20(repo.ui)
+            part = bundle2.bundlepart('B2X:ERROR:PUSHRACED',
+                                      [('message', str(exc))])
+            bundler.addpart(part)
+            return streamres(bundler.getchunks())
+        else:
+            return pusherr(str(exc))
diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t
--- a/tests/test-bundle2.t
+++ b/tests/test-bundle2.t
@@ -925,10 +925,13 @@ Setting up
   >     part = None
   >     if reason == 'abort':
   >         part = bundle2.bundlepart('test:abort')
   >     if reason == 'unknown':
   >         part = bundle2.bundlepart('TEST:UNKNOWN')
+  >     if reason == 'race':
+  >         # 20 Bytes of crap
+  >         part = bundle2.bundlepart('b2x:check:heads', data='01234567890123456789')
   >     if part is not None:
   >         bundler.addpart(part)
   >     return extradata
   > 
   > @bundle2.parthandler("test:abort")
@@ -1010,5 +1013,33 @@ Doing the actual push: unknown mandatory
   $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
   pushing to http://localhost:$HGPORT2/
   searching for changes
   abort: missing support for "'test:unknown'"
   [255]
+
+Doing the actual push: race
+
+  $ cat << EOF >> $HGRCPATH
+  > [failpush]
+  > reason = race
+  > EOF
+
+  $ hg -R main push other -r e7ec4e813ba6
+  pushing to other
+  searching for changes
+  abort: push failed:
+  'repository changed while pushing - please try again'
+  [255]
+
+  $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
+  pushing to ssh://user@dummy/other
+  searching for changes
+  abort: push failed:
+  'repository changed while pushing - please try again'
+  [255]
+
+  $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
+  pushing to http://localhost:$HGPORT2/
+  searching for changes
+  abort: push failed:
+  'repository changed while pushing - please try again'
+  [255]


More information about the Mercurial-devel mailing list