[PATCH 5 of 5] manifestv2: add support for writing new manifest format
Martin von Zweigbergk
martinvonz at google.com
Wed Apr 1 12:34:50 CDT 2015
# HG changeset patch
# User Martin von Zweigbergk <martinvonz at google.com>
# Date 1427835693 25200
# Tue Mar 31 14:01:33 2015 -0700
# Node ID 2fbe921fa4f43a3897d4c74ce74cafd73f0deddb
# Parent aca6ee57dddf4b39732833a2bb603dcd19148754
manifestv2: add support for writing new manifest format
If .hg/requires has 'manifestv2', the manifest will be written using
the new format.
diff -r aca6ee57dddf -r 2fbe921fa4f4 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
diff -r aca6ee57dddf -r 2fbe921fa4f4 tests/test-manifest.py
--- a/tests/test-manifest.py Fri Mar 27 22:26:41 2015 -0700
+++ b/tests/test-manifest.py Tue Mar 31 14:01:33 2015 -0700
@@ -146,6 +146,12 @@
self.assertIn('bar/qux/foz.py', m)
self.assertIn(256 * 'x' + '/x', m)
self.assertIn(256 * 'x' + '/y', m)
+ self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True))
+
+ def testTextV2(self):
+ m1 = parsemanifest(A_SHORT_MANIFEST)
+ v2text = m1.text(usemanifestv2=True)
+ self.assertEqual(A_SHORT_MANIFEST_V2, v2text)
def testSetItem(self):
want = BIN_HASH_1
diff -r aca6ee57dddf -r 2fbe921fa4f4 tests/test-manifestv2.t
--- a/tests/test-manifestv2.t Fri Mar 27 22:26:41 2015 -0700
+++ b/tests/test-manifestv2.t Tue Mar 31 14:01:33 2015 -0700
@@ -23,9 +23,9 @@
checking files
3 files, 2 changesets, 4 total revisions
-TODO: Check that manifest revlog is smaller than for v1
+Check that manifest revlog is smaller than for v1
$ hg debugindex -m
rev offset length base linkrev nodeid p1 p2
- 0 0 106 0 0 f6279f9f8b31 000000000000 000000000000
- 1 106 59 0 1 cd20459b75e6 f6279f9f8b31 000000000000
+ 0 0 81 0 0 57361477c778 000000000000 000000000000
+ 1 81 33 0 1 aeaab5a2ef74 57361477c778 000000000000
diff -r aca6ee57dddf -r 2fbe921fa4f4 tests/test-subrepo-git.t
--- a/tests/test-subrepo-git.t Fri Mar 27 22:26:41 2015 -0700
+++ b/tests/test-subrepo-git.t Tue Mar 31 14:01:33 2015 -0700
@@ -978,6 +978,7 @@
adding s/c.c (glob)
adding s/cpp.cpp (glob)
adding s/foobar.orig (glob)
+ $ ls -l s/.hg
$ hg st --subrepos s
A s/.gitignore
A s/snake.python
@@ -987,9 +988,11 @@
? s/foobar.orig
error given when adding an already tracked file
+ $ ls -l s/.hg
$ hg add s/.gitignore
s/.gitignore already tracked!
[1]
+ $ ls -l s/.hg
$ hg add s/g
s/g already tracked!
[1]
@@ -997,9 +1000,11 @@
removed files can be re-added
removing files using 'rm' or 'git rm' has the same effect,
since we ignore the staging area
+ $ ls -l s/.hg
$ hg ci --subrepos -m 'snake'
committing subrepository s
$ cd s
+ $ ls -l .hg
$ rm snake.python
(remove leftover .hg so Mercurial doesn't look for a root here)
$ rm -r .hg
More information about the Mercurial-devel
mailing list