Patchwork [01,of,10,V2] manifest: remove dependency on manifestrevlog being able to create trees

login
register
mail settings
Submitter Durham Goode
Date Nov. 11, 2016, 9:26 a.m.
Message ID <f77a36aa659c05ac3474.1478856394@dev111.prn1.facebook.com>
Download mbox | patch
Permalink /patch/17491/
State Accepted
Headers show

Comments

Durham Goode - Nov. 11, 2016, 9:26 a.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1478772799 28800
#      Thu Nov 10 02:13:19 2016 -0800
# Node ID f77a36aa659c05ac34740046ac6b02e77895bb37
# Parent  494d5cec0b07653a6b5daaaaec768dea92ffa987
manifest: remove dependency on manifestrevlog being able to create trees

A future patch will be removing the read() function from the manifest class.
Since manifestrevlog currently depends on the read function that manifest
implements (as a derived class), we need to break the dependency from
manifestrevlog to read(). We do this by adding an argument to
manifestrevlog.write() which provides it with the ability to read a manifest.

This is good in general because it further separates revlog as the storage
format from the actual inmemory data structure implementation.

Patch

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1183,7 +1183,7 @@  class manifestrevlog(revlog.revlog):
                                                     self._dirlogcache)
         return self._dirlogcache[dir]
 
-    def add(self, m, transaction, link, p1, p2, added, removed):
+    def add(self, m, transaction, link, p1, p2, added, removed, readtree=None):
         if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
             and not self._usemanifestv2):
             # If our first parent is in the manifest cache, we can
@@ -1206,9 +1206,10 @@  class manifestrevlog(revlog.revlog):
             # through to the revlog layer, and let it handle the delta
             # process.
             if self._treeondisk:
-                m1 = self.read(p1)
-                m2 = self.read(p2)
-                n = self._addtree(m, transaction, link, m1, m2)
+                assert readtree, "readtree must be set for treemanifest writes"
+                m1 = readtree(self._dir, p1)
+                m2 = readtree(self._dir, p2)
+                n = self._addtree(m, transaction, link, m1, m2, readtree)
                 arraytext = None
             else:
                 text = m.text(self._usemanifestv2)
@@ -1220,14 +1221,15 @@  class manifestrevlog(revlog.revlog):
 
         return n
 
-    def _addtree(self, m, transaction, link, m1, m2):
+    def _addtree(self, m, transaction, link, m1, m2, readtree):
         # If the manifest is unchanged compared to one parent,
         # don't write a new revision
         if m.unmodifiedsince(m1) or m.unmodifiedsince(m2):
             return m.node()
         def writesubtree(subm, subp1, subp2):
             sublog = self.dirlog(subm.dir())
-            sublog.add(subm, transaction, link, subp1, subp2, None, None)
+            sublog.add(subm, transaction, link, subp1, subp2, None, None,
+                       readtree=readtree)
         m.writesubtrees(m1, m2, writesubtree)
         text = m.dirtext(self._usemanifestv2)
         # Double-check whether contents are unchanged to one parent
@@ -1449,8 +1451,10 @@  class memtreemanifestctx(object):
         return self._treemanifest
 
     def write(self, transaction, link, p1, p2, added, removed):
+        def readtree(dir, node):
+            return self._repo.manifestlog.get(dir, node).read()
         return self._revlog().add(self._treemanifest, transaction, link, p1, p2,
-                                  added, removed)
+                                  added, removed, readtree=readtree)
 
 class treemanifestctx(object):
     def __init__(self, repo, dir, node):