diff -r b83679eb5f86 -r 701d3554de0e mercurial/manifest.py --- a/mercurial/manifest.py Fri Mar 27 22:26:41 2015 -0700 +++ b/mercurial/manifest.py Tue Mar 31 14:01:33 2015 -0700 @@ -8,6 +8,7 @@ from i18n import _ import mdiff, parsers, error, revlog, util, scmutil import array, struct +import os propertycache = util.propertycache @@ -58,9 +59,15 @@ else: return iter(_parsev1(data)) -def _text(it): +def _text(it, usemanifestv2): """Given an iterator over (path, node, flags) tuples, returns a manifest text""" + if usemanifestv2: + return _textv2(it) + else: + return _textv1(it) + +def _textv1(it): files = [] lines = [] _hex = revlog.hex @@ -73,6 +80,19 @@ _checkforbidden(files) return ''.join(lines) +def _textv2(it): + files = [] + lines = ['\0\n'] + prevf = '' + for f, n, fl in it: + files.append(f) + stem = os.path.commonprefix([prevf, f]) + stemlen = min(len(stem), 255) + lines.append("%c%s\0%s\n%s\n" % (stemlen, f[stemlen:], fl, n)) + prevf = f + _checkforbidden(files) + return ''.join(lines) + class _lazymanifest(dict): """This is the pure implementation of lazymanifest. @@ -134,7 +154,7 @@ def text(self): """Get the full data of this manifest as a bytestring.""" - return _text(self.iterentries()) + return _textv1(self.iterentries()) try: _lazymanifest = parsers.lazymanifest @@ -259,8 +279,12 @@ def iteritems(self): return (x[:2] for x in self._lm.iterentries()) - def text(self): - return self._lm.text() + def text(self, usemanifestv2=False): + if usemanifestv2: + return _textv2(self._lm.iterentries()) + else: + # use (probably) native version for v1 + return self._lm.text() def fastdelta(self, base, changes): """Given a base manifest text as an array.array and a list of changes @@ -621,10 +645,11 @@ _diff(self, m2) return result - def text(self): + def text(self, usemanifestv2=False): """Get the full data of this manifest as a bytestring.""" flags = self.flags - return _text((f, self[f], flags(f)) for f in self.keys()) + return _text(((f, self[f], flags(f)) for f in self.keys()), + usemanifestv2) class manifest(revlog.revlog): def __init__(self, opener): @@ -720,7 +745,7 @@ # just encode a fulltext of the manifest and pass that # through to the revlog layer, and let it handle the delta # process. - text = m.text() + text = m.text(self._usemanifestv2) arraytext = array.array('c', text) cachedelta = None