--- a/mercurial/bundle2.py Fri Jun 16 16:56:16 2017 -0700
+++ b/mercurial/bundle2.py Thu Jun 22 10:10:02 2017 -0700
@@ -158,6 +158,7 @@
changegroup,
error,
obsolete,
+ phases,
pushkey,
pycompat,
tags,
@@ -178,6 +179,8 @@
_fpayloadsize = '>i'
_fpartparamcount = '>BB'
+_fphasesentry = '>i20s'
+
preferedchunksize = 4096
_parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
@@ -1387,6 +1390,14 @@
obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
buildobsmarkerspart(bundler, obsmarkers)
+ if opts.get('phases', False):
+ headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
+ phasedata = []
+ for phase in phases.allphases:
+ for head in headsbyphase[phase]:
+ phasedata.append(_pack(_fphasesentry, phase, head))
+ bundler.newpart('phase-heads', data=''.join(phasedata))
+
def addparttagsfnodescache(repo, bundler, outgoing):
# we include the tags fnode cache for the bundle changeset
# (as an optional parts)
@@ -1721,6 +1732,29 @@
kwargs[key] = inpart.params[key]
raise error.PushkeyFailed(partid=str(inpart.id), **kwargs)
+def _readphaseheads(inpart):
+ headsbyphase = [[] for i in phases.allphases]
+ entrysize = struct.calcsize(_fphasesentry)
+ while True:
+ entry = inpart.read(entrysize)
+ if len(entry) < entrysize:
+ if entry:
+ raise error.Abort(_('bad phase-heads bundle part'))
+ break
+ phase, node = struct.unpack(_fphasesentry, entry)
+ headsbyphase[phase].append(node)
+ return headsbyphase
+
+@parthandler('phase-heads')
+def handlephases(op, inpart):
+ """apply phases from bundle part to repo"""
+ headsbyphase = _readphaseheads(inpart)
+ addednodes = []
+ for entry in op.records['changegroup']:
+ addednodes.extend(entry['addednodes'])
+ phases.updatephases(op.repo.unfiltered(), op.gettransaction(), headsbyphase,
+ addednodes)
+
@parthandler('reply:pushkey', ('return', 'in-reply-to'))
def handlepushkeyreply(op, inpart):
"""retrieve the result of a pushkey request"""