Patchwork [2,of,6,RFC] localrepo: move most of __init__ and required methods

login
register
mail settings
Submitter Gregory Szorc
Date June 9, 2017, 6:36 a.m.
Message ID <b101a96ea2cf32469c6e.1496990166@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/21274/
State Deferred
Headers show

Comments

Gregory Szorc - June 9, 2017, 6:36 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1496978558 25200
#      Thu Jun 08 20:22:38 2017 -0700
# Node ID b101a96ea2cf32469c6e897d372c45608964613a
# Parent  dfe0db942bbf860968b19fd8579865790d78d5e8
localrepo: move most of __init__ and required methods

We now have a new base class for immutable local repositories. Let's
start populating it.

I copied everything in __init__ that should isn't related to
mutating repos. Also along for the ride are support methods to
support code in __init__.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -251,8 +251,6 @@  REVLOGV2_REQUIREMENT = 'exp-revlogv2.0'
 class immutablelocalrepository(object):
     """An immutable repository on local disk."""
 
-class localrepository(immutablelocalrepository):
-
     supportedformats = {
         'revlogv1',
         'generaldelta',
@@ -282,6 +280,7 @@  class localrepository(immutablelocalrepo
         self.requirements = set()
         self.filtername = None
         # wvfs: rooted at the repository root, used to access the working copy
+        # TODO use a read-only VFS to enforce immutability.
         self.wvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
         # vfs: rooted at .hg, used to access repo files outside of .hg/store
         self.vfs = None
@@ -295,6 +294,7 @@  class localrepository(immutablelocalrepo
         self.auditor = pathutil.pathauditor(self.root, self._checknested)
         self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
                                                 realfs=False)
+        # TODO use a read-only VFS to enforce immutability.
         self.vfs = vfsmod.vfs(self.path)
         self.baseui = baseui
         self.ui = baseui.copy()
@@ -326,6 +326,9 @@  class localrepository(immutablelocalrepo
             if engine.revlogheader():
                 self.supported.add('exp-compression-%s' % name)
 
+        # TODO creating repos from a) the constructor b) of a type that
+        # claims to be immutable is not good API design. Move creation
+        # elsewhere.
         if not self.vfs.isdir():
             if create:
                 self.requirements = newreporequirements(self)
@@ -360,6 +363,7 @@  class localrepository(immutablelocalrepo
             sharedpath = self.vfs.read("sharedpath").rstrip('\n')
             if 'relshared' in self.requirements:
                 sharedpath = self.vfs.join(sharedpath)
+            # TODO use a read-only VFS to enforce immutability.
             vfs = vfsmod.vfs(sharedpath, realpath=True)
             s = vfs.base
             if not vfs.exists():
@@ -370,6 +374,7 @@  class localrepository(immutablelocalrepo
             if inst.errno != errno.ENOENT:
                 raise
 
+        # TODO use a read-only VFS to enforce immutability.
         self.store = store.store(
                 self.requirements, self.sharedpath, vfsmod.vfs)
         self.spath = self.store.path
@@ -382,79 +387,15 @@  class localrepository(immutablelocalrepo
 
         self._dirstatevalidatewarned = False
 
-        self._branchcaches = {}
-        self._revbranchcache = None
-        self.filterpats = {}
-        self._datafilters = {}
-        self._transref = self._lockref = self._wlockref = None
-
-        # A cache for various files under .hg/ that tracks file changes,
-        # (used by the filecache decorator)
-        #
-        # Maps a property name to its util.filecacheentry
-        self._filecache = {}
-
-        # hold sets of revision to be filtered
-        # should be cleared when something might have changed the filter value:
-        # - new changesets,
-        # - phase change,
-        # - new obsolescence marker,
-        # - working directory parent change,
-        # - bookmark changes
-        self.filteredrevcache = {}
-
         # generic mapping between names and nodes
         self.names = namespaces.namespaces()
 
-    def close(self):
-        self._writecaches()
+        self.filterpats = {}
+        self._datafilters = {}
 
     def _loadextensions(self):
         extensions.loadall(self.ui)
 
-    def _writecaches(self):
-        if self._revbranchcache:
-            self._revbranchcache.write()
-
-    def _restrictcapabilities(self, caps):
-        if self.ui.configbool('experimental', 'bundle2-advertise', True):
-            caps = set(caps)
-            capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
-            caps.add('bundle2=' + urlreq.quote(capsblob))
-        return caps
-
-    def _applyopenerreqs(self):
-        self.svfs.options = dict((r, 1) for r in self.requirements
-                                           if r in self.openerreqs)
-        # experimental config: format.chunkcachesize
-        chunkcachesize = self.ui.configint('format', 'chunkcachesize')
-        if chunkcachesize is not None:
-            self.svfs.options['chunkcachesize'] = chunkcachesize
-        # experimental config: format.maxchainlen
-        maxchainlen = self.ui.configint('format', 'maxchainlen')
-        if maxchainlen is not None:
-            self.svfs.options['maxchainlen'] = maxchainlen
-        # experimental config: format.manifestcachesize
-        manifestcachesize = self.ui.configint('format', 'manifestcachesize')
-        if manifestcachesize is not None:
-            self.svfs.options['manifestcachesize'] = manifestcachesize
-        # experimental config: format.aggressivemergedeltas
-        aggressivemergedeltas = self.ui.configbool('format',
-            'aggressivemergedeltas', False)
-        self.svfs.options['aggressivemergedeltas'] = aggressivemergedeltas
-        self.svfs.options['lazydeltabase'] = not scmutil.gddeltaconfig(self.ui)
-
-        for r in self.requirements:
-            if r.startswith('exp-compression-'):
-                self.svfs.options['compengine'] = r[len('exp-compression-'):]
-
-        # TODO move "revlogv2" to openerreqs once finalized.
-        if REVLOGV2_REQUIREMENT in self.requirements:
-            self.svfs.options['revlogv2'] = True
-
-    def _writerequirements(self):
-        scmutil.writerequires(self.vfs, self.requirements)
-
     def _checknested(self, path):
         """Determine if path is a legal nested repository."""
         if not path.startswith(self.root):
@@ -493,6 +434,77 @@  class localrepository(immutablelocalrepo
                 parts.pop()
         return False
 
+    def _applyopenerreqs(self):
+        self.svfs.options = dict((r, 1) for r in self.requirements
+                                           if r in self.openerreqs)
+        # experimental config: format.chunkcachesize
+        chunkcachesize = self.ui.configint('format', 'chunkcachesize')
+        if chunkcachesize is not None:
+            self.svfs.options['chunkcachesize'] = chunkcachesize
+        # experimental config: format.maxchainlen
+        maxchainlen = self.ui.configint('format', 'maxchainlen')
+        if maxchainlen is not None:
+            self.svfs.options['maxchainlen'] = maxchainlen
+        # experimental config: format.manifestcachesize
+        manifestcachesize = self.ui.configint('format', 'manifestcachesize')
+        if manifestcachesize is not None:
+            self.svfs.options['manifestcachesize'] = manifestcachesize
+        # experimental config: format.aggressivemergedeltas
+        aggressivemergedeltas = self.ui.configbool('format',
+            'aggressivemergedeltas', False)
+        self.svfs.options['aggressivemergedeltas'] = aggressivemergedeltas
+        self.svfs.options['lazydeltabase'] = not scmutil.gddeltaconfig(self.ui)
+
+        for r in self.requirements:
+            if r.startswith('exp-compression-'):
+                self.svfs.options['compengine'] = r[len('exp-compression-'):]
+
+        # TODO move "revlogv2" to openerreqs once finalized.
+        if REVLOGV2_REQUIREMENT in self.requirements:
+            self.svfs.options['revlogv2'] = True
+
+    def _writerequirements(self):
+        scmutil.writerequires(self.vfs, self.requirements)
+
+class localrepository(immutablelocalrepository):
+
+    def __init__(self, baseui, path, create=False):
+        super(localrepository, self).__init__(baseui, path, create=create)
+        self._branchcaches = {}
+        self._revbranchcache = None
+        self.filterpats = {}
+        self._datafilters = {}
+        self._transref = self._lockref = self._wlockref = None
+
+        # A cache for various files under .hg/ that tracks file changes,
+        # (used by the filecache decorator)
+        #
+        # Maps a property name to its util.filecacheentry
+        self._filecache = {}
+
+        # hold sets of revision to be filtered
+        # should be cleared when something might have changed the filter value:
+        # - new changesets,
+        # - phase change,
+        # - new obsolescence marker,
+        # - working directory parent change,
+        # - bookmark changes
+        self.filteredrevcache = {}
+
+    def close(self):
+        self._writecaches()
+
+    def _writecaches(self):
+        if self._revbranchcache:
+            self._revbranchcache.write()
+
+    def _restrictcapabilities(self, caps):
+        if self.ui.configbool('experimental', 'bundle2-advertise', True):
+            caps = set(caps)
+            capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
+            caps.add('bundle2=' + urlreq.quote(capsblob))
+        return caps
+
     def peer(self):
         return localpeer(self) # not cached to avoid reference cycle