narrow: move excludeddir and related classes to core
authorMartin von Zweigbergk <martinvonz@google.com>
Tue, 03 Apr 2018 00:13:02 -0700
changeset 37372 1b2fa531fd7a
parent 37371 d3286dd2ca2f
child 37373 c50078fc32f3
narrow: move excludeddir and related classes to core Differential Revision: https://phab.mercurial-scm.org/D3044
hgext/narrow/narrowrevlog.py
mercurial/manifest.py
--- a/hgext/narrow/narrowrevlog.py	Thu Apr 05 17:29:32 2018 +0530
+++ b/hgext/narrow/narrowrevlog.py	Tue Apr 03 00:13:02 2018 -0700
@@ -8,7 +8,6 @@
 from __future__ import absolute_import
 
 from mercurial import (
-   error,
    manifest,
    revlog,
    util,
@@ -31,83 +30,6 @@
     # load time.
     pass
 
-class excludeddir(manifest.treemanifest):
-    """Stand-in for a directory that is excluded from the repository.
-
-    With narrowing active on a repository that uses treemanifests,
-    some of the directory revlogs will be excluded from the resulting
-    clone. This is a huge storage win for clients, but means we need
-    some sort of pseudo-manifest to surface to internals so we can
-    detect a merge conflict outside the narrowspec. That's what this
-    class is: it stands in for a directory whose node is known, but
-    whose contents are unknown.
-    """
-    def __init__(self, dir, node):
-        super(excludeddir, self).__init__(dir)
-        self._node = node
-        # Add an empty file, which will be included by iterators and such,
-        # appearing as the directory itself (i.e. something like "dir/")
-        self._files[''] = node
-        self._flags[''] = 't'
-
-    # Manifests outside the narrowspec should never be modified, so avoid
-    # copying. This makes a noticeable difference when there are very many
-    # directories outside the narrowspec. Also, it makes sense for the copy to
-    # be of the same type as the original, which would not happen with the
-    # super type's copy().
-    def copy(self):
-        return self
-
-class excludeddirmanifestctx(manifest.treemanifestctx):
-    """context wrapper for excludeddir - see that docstring for rationale"""
-    def __init__(self, dir, node):
-        self._dir = dir
-        self._node = node
-
-    def read(self):
-        return excludeddir(self._dir, self._node)
-
-    def write(self, *args):
-        raise error.ProgrammingError(
-            'attempt to write manifest from excluded dir %s' % self._dir)
-
-class excludedmanifestrevlog(manifest.manifestrevlog):
-    """Stand-in for excluded treemanifest revlogs.
-
-    When narrowing is active on a treemanifest repository, we'll have
-    references to directories we can't see due to the revlog being
-    skipped. This class exists to conform to the manifestrevlog
-    interface for those directories and proactively prevent writes to
-    outside the narrowspec.
-    """
-
-    def __init__(self, dir):
-        self._dir = dir
-
-    def __len__(self):
-        raise error.ProgrammingError(
-            'attempt to get length of excluded dir %s' % self._dir)
-
-    def rev(self, node):
-        raise error.ProgrammingError(
-            'attempt to get rev from excluded dir %s' % self._dir)
-
-    def linkrev(self, node):
-        raise error.ProgrammingError(
-            'attempt to get linkrev from excluded dir %s' % self._dir)
-
-    def node(self, rev):
-        raise error.ProgrammingError(
-            'attempt to get node from excluded dir %s' % self._dir)
-
-    def add(self, *args, **kwargs):
-        # We should never write entries in dirlogs outside the narrow clone.
-        # However, the method still gets called from writesubtree() in
-        # _addtree(), so we need to handle it. We should possibly make that
-        # avoid calling add() with a clean manifest (_dirty is always False
-        # in excludeddir instances).
-        pass
-
 def makenarrowmanifestrevlog(mfrevlog, repo):
     if util.safehasattr(mfrevlog, '_narrowed'):
         return
@@ -118,7 +40,7 @@
         # child directories when using treemanifests.
         def dirlog(self, d):
             if not repo.narrowmatch().visitdir(d[:-1] or '.'):
-                return excludedmanifestrevlog(d)
+                return manifest.excludedmanifestrevlog(d)
             result = super(narrowmanifestrevlog, self).dirlog(d)
             makenarrowmanifestrevlog(result, repo)
             return result
@@ -130,7 +52,7 @@
     class narrowmanifestlog(mfl.__class__):
         def get(self, dir, node, verify=True):
             if not repo.narrowmatch().visitdir(dir[:-1] or '.'):
-                return excludeddirmanifestctx(dir, node)
+                return manifest.excludeddirmanifestctx(dir, node)
             return super(narrowmanifestlog, self).get(dir, node, verify=verify)
     mfl.__class__ = narrowmanifestlog
 
--- a/mercurial/manifest.py	Thu Apr 05 17:29:32 2018 +0530
+++ b/mercurial/manifest.py	Tue Apr 03 00:13:02 2018 -0700
@@ -1569,3 +1569,80 @@
 
     def find(self, key):
         return self.read().find(key)
+
+class excludeddir(treemanifest):
+    """Stand-in for a directory that is excluded from the repository.
+
+    With narrowing active on a repository that uses treemanifests,
+    some of the directory revlogs will be excluded from the resulting
+    clone. This is a huge storage win for clients, but means we need
+    some sort of pseudo-manifest to surface to internals so we can
+    detect a merge conflict outside the narrowspec. That's what this
+    class is: it stands in for a directory whose node is known, but
+    whose contents are unknown.
+    """
+    def __init__(self, dir, node):
+        super(excludeddir, self).__init__(dir)
+        self._node = node
+        # Add an empty file, which will be included by iterators and such,
+        # appearing as the directory itself (i.e. something like "dir/")
+        self._files[''] = node
+        self._flags[''] = 't'
+
+    # Manifests outside the narrowspec should never be modified, so avoid
+    # copying. This makes a noticeable difference when there are very many
+    # directories outside the narrowspec. Also, it makes sense for the copy to
+    # be of the same type as the original, which would not happen with the
+    # super type's copy().
+    def copy(self):
+        return self
+
+class excludeddirmanifestctx(treemanifestctx):
+    """context wrapper for excludeddir - see that docstring for rationale"""
+    def __init__(self, dir, node):
+        self._dir = dir
+        self._node = node
+
+    def read(self):
+        return excludeddir(self._dir, self._node)
+
+    def write(self, *args):
+        raise error.ProgrammingError(
+            'attempt to write manifest from excluded dir %s' % self._dir)
+
+class excludedmanifestrevlog(manifestrevlog):
+    """Stand-in for excluded treemanifest revlogs.
+
+    When narrowing is active on a treemanifest repository, we'll have
+    references to directories we can't see due to the revlog being
+    skipped. This class exists to conform to the manifestrevlog
+    interface for those directories and proactively prevent writes to
+    outside the narrowspec.
+    """
+
+    def __init__(self, dir):
+        self._dir = dir
+
+    def __len__(self):
+        raise error.ProgrammingError(
+            'attempt to get length of excluded dir %s' % self._dir)
+
+    def rev(self, node):
+        raise error.ProgrammingError(
+            'attempt to get rev from excluded dir %s' % self._dir)
+
+    def linkrev(self, node):
+        raise error.ProgrammingError(
+            'attempt to get linkrev from excluded dir %s' % self._dir)
+
+    def node(self, rev):
+        raise error.ProgrammingError(
+            'attempt to get node from excluded dir %s' % self._dir)
+
+    def add(self, *args, **kwargs):
+        # We should never write entries in dirlogs outside the narrow clone.
+        # However, the method still gets called from writesubtree() in
+        # _addtree(), so we need to handle it. We should possibly make that
+        # avoid calling add() with a clean manifest (_dirty is always False
+        # in excludeddir instances).
+        pass