localrepo: define storage backend in creation options (API)
authorGregory Szorc <gregory.szorc@gmail.com>
Fri, 28 Sep 2018 09:46:50 -0700
changeset 39996 dbcb466d0065
parent 39995 582676acaf6d
child 39997 2f80eaf38ed4
localrepo: define storage backend in creation options (API) We add an experimental config option to define the storage backend for new repositories. By default, it uses "revlogv1," which maps to the current and only modern supported repository format. We add a "backend" creation option to control which backend to use. It defaults to using the value from the config option. newreporequirements() will now barf if it sees a "backend" value that isn't "revlogv1." This forces extensions to monkeypatch the function to handle requirements derivation for custom backends. In order for this to "just work," we factored out obtaining the default creation options into its own function and made callers of newreporequirements() responsible for passing in valid data. Without this, direct callers of newreporequirements() wouldn't get the proper results. Differential Revision: https://phab.mercurial-scm.org/D4791
mercurial/configitems.py
mercurial/localrepo.py
mercurial/upgrade.py
--- a/mercurial/configitems.py	Thu Sep 27 09:23:17 2018 -0700
+++ b/mercurial/configitems.py	Fri Sep 28 09:46:50 2018 -0700
@@ -941,6 +941,9 @@
 coreconfigitem('push', 'pushvars.server',
     default=False,
 )
+coreconfigitem('storage', 'new-repo-backend',
+    default='revlogv1',
+)
 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
     default=True,
     alias=[('format', 'aggressivemergedeltas')],
--- a/mercurial/localrepo.py	Thu Sep 27 09:23:17 2018 -0700
+++ b/mercurial/localrepo.py	Fri Sep 28 09:46:50 2018 -0700
@@ -2808,14 +2808,26 @@
 def islocal(path):
     return True
 
-def newreporequirements(ui, createopts=None):
+def defaultcreateopts(ui, createopts=None):
+    """Populate the default creation options for a repository.
+
+    A dictionary of explicitly requested creation options can be passed
+    in. Missing keys will be populated.
+    """
+    createopts = dict(createopts or {})
+
+    if 'backend' not in createopts:
+        # experimental config: storage.new-repo-backend
+        createopts['backend'] = ui.config('storage', 'new-repo-backend')
+
+    return createopts
+
+def newreporequirements(ui, createopts):
     """Determine the set of requirements for a new local repository.
 
     Extensions can wrap this function to specify custom requirements for
     new repositories.
     """
-    createopts = createopts or {}
-
     # If the repo is being created from a shared repository, we copy
     # its requirements.
     if 'sharedrepo' in createopts:
@@ -2827,6 +2839,14 @@
 
         return requirements
 
+    if 'backend' not in createopts:
+        raise error.ProgrammingError('backend key not present in createopts; '
+                                     'was defaultcreateopts() called?')
+
+    if createopts['backend'] != 'revlogv1':
+        raise error.Abort(_('unable to determine repository requirements for '
+                            'storage backend: %s') % createopts['backend'])
+
     requirements = {'revlogv1'}
     if ui.configbool('format', 'usestore'):
         requirements.add('store')
@@ -2885,6 +2905,7 @@
     they know how to handle.
     """
     known = {
+        'backend',
         'narrowfiles',
         'sharedrepo',
         'sharedrelative',
@@ -2901,6 +2922,8 @@
 
     The following keys for ``createopts`` are recognized:
 
+    backend
+       The storage backend to use.
     narrowfiles
        Set up repository to support narrow file storage.
     sharedrepo
@@ -2912,7 +2935,7 @@
     shareditems
        Set of items to share to the new repository (in addition to storage).
     """
-    createopts = createopts or {}
+    createopts = defaultcreateopts(ui, createopts=createopts)
 
     unknownopts = filterknowncreateopts(ui, createopts)
 
--- a/mercurial/upgrade.py	Thu Sep 27 09:23:17 2018 -0700
+++ b/mercurial/upgrade.py	Fri Sep 28 09:46:50 2018 -0700
@@ -199,7 +199,8 @@
 
     @staticmethod
     def _newreporequirements(ui):
-        return localrepo.newreporequirements(ui)
+        return localrepo.newreporequirements(
+            ui, localrepo.defaultcreateopts(ui))
 
     @classmethod
     def fromrepo(cls, repo):
@@ -747,7 +748,8 @@
 
     # FUTURE there is potentially a need to control the wanted requirements via
     # command arguments or via an extension hook point.
-    newreqs = localrepo.newreporequirements(repo.ui)
+    newreqs = localrepo.newreporequirements(
+        repo.ui, localrepo.defaultcreateopts(repo.ui))
     newreqs.update(preservedrequirements(repo))
 
     noremovereqs = (repo.requirements - newreqs -