mercurial/bundle2.py
changeset 33031 e8c8d81eb864
parent 33030 3e102a8dd52c
child 33035 6e3a6774d998
--- 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"""