@@ -489,8 +489,12 @@ class cmdalias(object):
return aliasargs(self.fn, args)
def __getattr__(self, name):
- adefaults = {r'norepo': True,
- r'optionalrepo': False, r'inferrepo': False}
+ adefaults = {
+ r'norepo': True,
+ r'optionalrepo': False,
+ r'inferrepo': False,
+ r'immutablerepo': False,
+ }
if name not in adefaults:
raise AttributeError(name)
if self.badalias or util.safehasattr(self, 'shell'):
@@ -883,7 +887,8 @@ def _dispatch(req):
else:
try:
repo = hg.repository(ui, path=path,
- presetupfuncs=req.prereposetups)
+ presetupfuncs=req.prereposetups,
+ immutable=func.immutablerepo)
if not repo.local():
raise error.Abort(_("repository '%s' is not local")
% path)
@@ -10,6 +10,7 @@ from __future__ import absolute_import
import errno
import hashlib
+import inspect
import os
import shutil
@@ -148,9 +149,18 @@ def openpath(ui, path):
# a list of (ui, repo) functions called for wire peer initialization
wirepeersetupfuncs = []
-def _peerorrepo(ui, path, create=False, presetupfuncs=None):
+def _peerorrepo(ui, path, create=False, presetupfuncs=None, immutable=False):
"""return a repository object for the specified path"""
- obj = _peerlookup(path).instance(ui, path, create)
+ factory = _peerlookup(path)
+ try:
+ obj = factory.instance(ui, path, create, immutable=immutable)
+ except TypeError:
+ # Not all types support immutable argument.
+ keywords = inspect.getargspec(factory.instance).keywords or {}
+ if 'immutable' in keywords:
+ raise
+ obj = factory.instance(ui, path, create)
+
ui = getattr(obj, "ui", ui)
for f in presetupfuncs or []:
f(ui, obj)
@@ -163,9 +173,10 @@ def _peerorrepo(ui, path, create=False,
f(ui, obj)
return obj
-def repository(ui, path='', create=False, presetupfuncs=None):
+def repository(ui, path='', create=False, presetupfuncs=None, immutable=False):
"""return a repository object for the specified path"""
- peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs)
+ peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs,
+ immutable=immutable)
repo = peer.local()
if not repo:
raise error.Abort(_("repository '%s' is not local") %
@@ -2060,8 +2060,9 @@ def undoname(fn):
assert name.startswith('journal')
return os.path.join(base, name.replace('journal', 'undo', 1))
-def instance(ui, path, create):
- return localrepository(ui, util.urllocalpath(path), create)
+def instance(ui, path, create, immutable=False):
+ cls = immutablelocalrepository if immutable else localrepository
+ return cls(ui, util.urllocalpath(path), create)
def islocal(path):
return True
@@ -124,13 +124,21 @@ class command(_funcregistrarbase):
command line arguments. If True, arguments will be examined for potential
repository locations. See ``findrepo()``. If a repository is found, it
will be used.
+
+ The _immutablerepo argument defines whether the command is read-only. If
+ set, an immutable repository instance will be passed to the command instead
+ of a mutable one. Once the mutable/immutable split is complete, this API
+ will be refactored. So it should be considered temporary and not used by
+ extensions.
"""
def _doregister(self, func, name, options=(), synopsis=None,
- norepo=False, optionalrepo=False, inferrepo=False):
+ norepo=False, optionalrepo=False, inferrepo=False,
+ _immutablerepo=False):
func.norepo = norepo
func.optionalrepo = optionalrepo
func.inferrepo = inferrepo
+ func.immutablerepo = _immutablerepo
if synopsis:
self._table[name] = func, list(options), synopsis
else: