mercurial/manifest.py
changeset 24573 701d3554de0e
parent 24572 b83679eb5f86
child 24600 ea24cf92557a
--- 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