--- a/mercurial/bundle2.py Sun Oct 15 14:59:55 2017 +0200
+++ b/mercurial/bundle2.py Sun Oct 15 15:01:03 2017 +0200
@@ -156,6 +156,7 @@
from .i18n import _
from . import (
+ bookmarks,
changegroup,
error,
node as nodemod,
@@ -1787,6 +1788,34 @@
replyto = int(inpart.params['in-reply-to'])
op.records.add('changegroup', {'return': ret}, replyto)
+@parthandler('check:bookmarks')
+def handlecheckbookmarks(op, inpart):
+ """check location of bookmarks
+
+ This part is to be used to detect push race regarding bookmark, it
+ contains binary encoded (bookmark, node) tuple. If the local state does
+ not marks the one in the part, a PushRaced exception is raised
+ """
+ bookdata = bookmarks.binarydecode(inpart)
+
+ msgstandard = ('repository changed while pushing - please try again '
+ '(bookmark "%s" move from %s to %s)')
+ msgmissing = ('repository changed while pushing - please try again '
+ '(bookmark "%s" is missing, expected %s)')
+ msgexist = ('repository changed while pushing - please try again '
+ '(bookmark "%s" set on %s, expected missing)')
+ for book, node in bookdata:
+ currentnode = op.repo._bookmarks.get(book)
+ if currentnode != node:
+ if node is None:
+ finalmsg = msgexist % (book, nodemod.short(currentnode))
+ elif currentnode is None:
+ finalmsg = msgmissing % (book, nodemod.short(node))
+ else:
+ finalmsg = msgstandard % (book, nodemod.short(node),
+ nodemod.short(currentnode))
+ raise error.PushRaced(finalmsg)
+
@parthandler('check:heads')
def handlecheckheads(op, inpart):
"""check that head of the repo did not change