phases: move binary encoding into a reusable function
We want to use binary phases for pushing and pulling. We extract the encoding
function out of the bundle2 module first.
--- a/mercurial/bundle2.py Tue Sep 19 22:08:09 2017 +0200
+++ b/mercurial/bundle2.py Tue Sep 19 22:01:31 2017 +0200
@@ -179,8 +179,6 @@
_fpayloadsize = '>i'
_fpartparamcount = '>BB'
-_fphasesentry = struct.Struct('>i20s')
-
preferedchunksize = 4096
_parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
@@ -1480,11 +1478,8 @@
if opts.get('phases', False):
headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
- phasedata = []
- for phase in phases.allphases:
- for head in headsbyphase[phase]:
- phasedata.append(_fphasesentry.pack(phase, head))
- bundler.newpart('phase-heads', data=''.join(phasedata))
+ phasedata = phases.binaryencode(headsbyphase)
+ bundler.newpart('phase-heads', data=phasedata)
def addparttagsfnodescache(repo, bundler, outgoing):
# we include the tags fnode cache for the bundle changeset
@@ -1843,14 +1838,14 @@
def _readphaseheads(inpart):
headsbyphase = [[] for i in phases.allphases]
- entrysize = _fphasesentry.size
+ entrysize = phases._fphasesentry.size
while True:
entry = inpart.read(entrysize)
if len(entry) < entrysize:
if entry:
raise error.Abort(_('bad phase-heads bundle part'))
break
- phase, node = _fphasesentry.unpack(entry)
+ phase, node = phases._fphasesentry.unpack(entry)
headsbyphase[phase].append(node)
return headsbyphase
--- a/mercurial/phases.py Tue Sep 19 22:08:09 2017 +0200
+++ b/mercurial/phases.py Tue Sep 19 22:01:31 2017 +0200
@@ -103,6 +103,7 @@
from __future__ import absolute_import
import errno
+import struct
from .i18n import _
from .node import (
@@ -119,6 +120,8 @@
util,
)
+_fphasesentry = struct.Struct('>i20s')
+
allphases = public, draft, secret = range(3)
trackedphases = allphases[1:]
phasenames = ['public', 'draft', 'secret']
@@ -154,6 +157,18 @@
dirty = True
return roots, dirty
+def binaryencode(phasemapping):
+ """encode a 'phase -> nodes' mapping into a binary stream
+
+ Since phases are integer the mapping is actually a python list:
+ [[PUBLIC_HEADS], [DRAFTS_HEADS], [SECRET_HEADS]]
+ """
+ binarydata = []
+ for phase, nodes in enumerate(phasemapping):
+ for head in nodes:
+ binarydata.append(_fphasesentry.pack(phase, head))
+ return ''.join(binarydata)
+
def _trackphasechange(data, rev, old, new):
"""add a phase move the <data> dictionnary