manifest: add manifestctx.readdelta()
This adds an implementation of readdelta to the new manifestctx class and adds a
couple consumers of it. This currently appears to have some duplicate code, but
future patches cause this function to diverge when things like "shallow" are
introduced.
--- a/mercurial/changegroup.py Wed Sep 14 17:12:39 2016 +0200
+++ b/mercurial/changegroup.py Tue Sep 13 16:25:21 2016 -0700
@@ -332,7 +332,7 @@
for cset in xrange(clstart, clend):
mfnode = repo.changelog.read(
repo.changelog.node(cset))[0]
- mfest = repo.manifest.readdelta(mfnode)
+ mfest = repo.manifestlog[mfnode].readdelta()
# store file nodes we must see
for f, n in mfest.iteritems():
needfiles.setdefault(f, set()).add(n)
--- a/mercurial/context.py Wed Sep 14 17:12:39 2016 +0200
+++ b/mercurial/context.py Tue Sep 13 16:25:21 2016 -0700
@@ -532,7 +532,8 @@
@propertycache
def _manifestdelta(self):
- return self._repo.manifest.readdelta(self._changeset.manifest)
+ mfnode = self._changeset.manifest
+ return self._repo.manifestlog[mfnode].readdelta()
@propertycache
def _parents(self):
--- a/mercurial/manifest.py Wed Sep 14 17:12:39 2016 +0200
+++ b/mercurial/manifest.py Tue Sep 13 16:25:21 2016 -0700
@@ -993,6 +993,25 @@
self._data = manifestdict(text)
return self._data
+ def readdelta(self):
+ revlog = self._revlog
+ if revlog._usemanifestv2:
+ # Need to perform a slow delta
+ r0 = revlog.deltaparent(revlog.rev(self._node))
+ m0 = manifestctx(revlog, revlog.node(r0)).read()
+ m1 = self.read()
+ md = manifestdict()
+ for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
+ if n1:
+ md[f] = n1
+ if fl1:
+ md.setflag(f, fl1)
+ return md
+
+ r = revlog.rev(self._node)
+ d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
+ return manifestdict(d)
+
class treemanifestctx(object):
def __init__(self, revlog, dir, node):
revlog = revlog.dirlog(dir)
@@ -1033,6 +1052,20 @@
def node(self):
return self._node
+ def readdelta(self):
+ # Need to perform a slow delta
+ revlog = self._revlog
+ r0 = revlog.deltaparent(revlog.rev(self._node))
+ m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
+ m1 = self.read()
+ md = treemanifest(dir=self._dir)
+ for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
+ if n1:
+ md[f] = n1
+ if fl1:
+ md.setflag(f, fl1)
+ return md
+
class manifest(manifestrevlog):
def __init__(self, opener, dir='', dirlogcache=None):
'''The 'dir' and 'dirlogcache' arguments are for internal use by