D4709: localrepo: define "features" on repository instances (API)

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Wed Sep 26 13:24:17 EDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rHGd89d5bc06eaa: localrepo: define "features" on repository instances (API) (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4709?vs=11317&id=11380

REVISION DETAIL
  https://phab.mercurial-scm.org/D4709

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/streamclone.py

CHANGE DETAILS

diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py
--- a/mercurial/streamclone.py
+++ b/mercurial/streamclone.py
@@ -168,7 +168,7 @@
         repo.requirements = requirements | (
                 repo.requirements - repo.supportedformats)
         repo.svfs.options = localrepo.resolvestorevfsoptions(
-            repo.ui, repo.requirements)
+            repo.ui, repo.requirements, repo.features)
         repo._writerequirements()
 
         if rbranchmap:
@@ -643,5 +643,5 @@
     repo.requirements = set(requirements) | (
             repo.requirements - repo.supportedformats)
     repo.svfs.options = localrepo.resolvestorevfsoptions(
-        repo.ui, repo.requirements)
+        repo.ui, repo.requirements, repo.features)
     repo._writerequirements()
diff --git a/mercurial/repository.py b/mercurial/repository.py
--- a/mercurial/repository.py
+++ b/mercurial/repository.py
@@ -19,6 +19,13 @@
 # we should move this to just "narrow" or similar.
 NARROW_REQUIREMENT = 'narrowhg-experimental'
 
+# Local repository feature string.
+
+# Revlogs are being used for file storage.
+REPO_FEATURE_REVLOG_FILE_STORAGE = b'revlogfilestorage'
+# The storage part of the repository is shared from an external source.
+REPO_FEATURE_SHARED_STORAGE = b'sharedstore'
+
 class ipeerconnection(interfaceutil.Interface):
     """Represents a "connection" to a repository.
 
@@ -1275,6 +1282,24 @@
     requirements = interfaceutil.Attribute(
         """Set of requirements this repo uses.""")
 
+    features = interfaceutil.Attribute(
+        """Set of "features" this repository supports.
+
+        A "feature" is a loosely-defined term. It can refer to a feature
+        in the classical sense or can describe an implementation detail
+        of the repository. For example, a ``readonly`` feature may denote
+        the repository as read-only. Or a ``revlogfilestore`` feature may
+        denote that the repository is using revlogs for file storage.
+
+        The intent of features is to provide a machine-queryable mechanism
+        for repo consumers to test for various repository characteristics.
+
+        Features are similar to ``requirements``. The main difference is that
+        requirements are stored on-disk and represent requirements to open the
+        repository. Features are more run-time capabilities of the repository
+        and more granular capabilities (which may be derived from requirements).
+        """)
+
     filtername = interfaceutil.Attribute(
         """Name of the repoview that is active on this repo.""")
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -478,6 +478,8 @@
     # At this point, we know we should be capable of opening the repository.
     # Now get on with doing that.
 
+    features = set()
+
     # The "store" part of the repository holds versioned data. How it is
     # accessed is determined by various requirements. The ``shared`` or
     # ``relshared`` requirements indicate the store lives in the path contained
@@ -494,6 +496,8 @@
             raise error.RepoError(_(b'.hg/sharedpath points to nonexistent '
                                     b'directory %s') % sharedvfs.base)
 
+        features.add(repository.REPO_FEATURE_SHARED_STORAGE)
+
         storebasepath = sharedvfs.base
         cachepath = sharedvfs.join(b'cache')
     else:
@@ -508,7 +512,7 @@
     hgvfs.createmode = store.createmode
 
     storevfs = store.vfs
-    storevfs.options = resolvestorevfsoptions(ui, requirements)
+    storevfs.options = resolvestorevfsoptions(ui, requirements, features)
 
     # The cache vfs is used to manage cache files.
     cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
@@ -528,6 +532,7 @@
         typ = fn(ui=ui,
                  intents=intents,
                  requirements=requirements,
+                 features=features,
                  wdirvfs=wdirvfs,
                  hgvfs=hgvfs,
                  store=store,
@@ -564,6 +569,7 @@
         sharedpath=storebasepath,
         store=store,
         cachevfs=cachevfs,
+        features=features,
         intents=intents)
 
 def gathersupportedrequirements(ui):
@@ -643,7 +649,7 @@
 
     return storemod.basicstore(path, vfstype)
 
-def resolvestorevfsoptions(ui, requirements):
+def resolvestorevfsoptions(ui, requirements, features):
     """Resolve the options to pass to the store vfs opener.
 
     The returned dict is used to influence behavior of the storage layer.
@@ -664,11 +670,11 @@
     # opener options for it because those options wouldn't do anything
     # meaningful on such old repos.
     if b'revlogv1' in requirements or REVLOGV2_REQUIREMENT in requirements:
-        options.update(resolverevlogstorevfsoptions(ui, requirements))
+        options.update(resolverevlogstorevfsoptions(ui, requirements, features))
 
     return options
 
-def resolverevlogstorevfsoptions(ui, requirements):
+def resolverevlogstorevfsoptions(ui, requirements, features):
     """Resolve opener options specific to revlogs."""
 
     options = {}
@@ -756,8 +762,10 @@
 
         return filelog.narrowfilelog(self.svfs, path, self.narrowmatch())
 
-def makefilestorage(requirements, **kwargs):
+def makefilestorage(requirements, features, **kwargs):
     """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
+    features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
+
     if repository.NARROW_REQUIREMENT in requirements:
         return revlognarrowfilestorage
     else:
@@ -831,7 +839,7 @@
 
     def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements,
                  supportedrequirements, sharedpath, store, cachevfs,
-                 intents=None):
+                 features, intents=None):
         """Create a new local repository instance.
 
         Most callers should use ``hg.repository()``, ``localrepo.instance()``,
@@ -873,6 +881,10 @@
         cachevfs
            ``vfs.vfs`` used for cache files.
 
+        features
+           ``set`` of bytestrings defining features/capabilities of this
+           instance.
+
         intents
            ``set`` of system strings indicating what this repo will be used
            for.
@@ -891,6 +903,7 @@
         self.sharedpath = sharedpath
         self.store = store
         self.cachevfs = cachevfs
+        self.features = features
 
         self.filtername = None
 
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1798,7 +1798,7 @@
                 "non-empty and does not use tree manifests"))
         op.repo.requirements.add('treemanifest')
         op.repo.svfs.options = localrepo.resolvestorevfsoptions(
-            op.repo.ui, op.repo.requirements)
+            op.repo.ui, op.repo.requirements, op.repo.features)
         op.repo._writerequirements()
     extrakwargs = {}
     targetphase = inpart.params.get('targetphase')



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list