diff --git a/hgext/schemes.py b/hgext/schemes.py
--- a/hgext/schemes.py
+++ b/hgext/schemes.py
@@ -78,9 +78,9 @@
     def __repr__(self):
         return '<ShortRepository: %s>' % self.scheme
 
-    def instance(self, ui, url, create):
+    def instance(self, ui, url, create, intents=None):
         url = self.resolve(url)
-        return hg._peerlookup(url).instance(ui, url, create)
+        return hg._peerlookup(url).instance(ui, url, create, intents=intents)
 
     def resolve(self, url):
         # Should this use the util.url class, or is manual parsing better?
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -450,7 +450,7 @@
             self.ui.warn(msg % nodemod.hex(p2))
         return super(bundlerepository, self).setparents(p1, p2)
 
-def instance(ui, path, create):
+def instance(ui, path, create, intents=None):
     if create:
         raise error.Abort(_('cannot create new bundle repository'))
     # internal config: bundle.mainreporoot
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -928,7 +928,8 @@
             else:
                 try:
                     repo = hg.repository(ui, path=path,
-                                         presetupfuncs=req.prereposetups)
+                                         presetupfuncs=req.prereposetups,
+                                         intents=func.intents)
                     if not repo.local():
                         raise error.Abort(_("repository '%s' is not local")
                                           % path)
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -157,9 +157,10 @@
 # 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,
+                intents=None):
     """return a repository object for the specified path"""
-    obj = _peerlookup(path).instance(ui, path, create)
+    obj = _peerlookup(path).instance(ui, path, create, intents=intents)
     ui = getattr(obj, "ui", ui)
     for f in presetupfuncs or []:
         f(ui, obj)
@@ -172,19 +173,20 @@
             f(ui, obj)
     return obj
 
-def repository(ui, path='', create=False, presetupfuncs=None):
+def repository(ui, path='', create=False, presetupfuncs=None, intents=None):
     """return a repository object for the specified path"""
-    peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs)
+    peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs,
+                       intents=intents)
     repo = peer.local()
     if not repo:
         raise error.Abort(_("repository '%s' is not local") %
                          (path or peer.url()))
     return repo.filtered('visible')
 
-def peer(uiorrepo, opts, path, create=False):
+def peer(uiorrepo, opts, path, create=False, intents=None):
     '''return a repository peer for the specified path'''
     rui = remoteui(uiorrepo, opts)
-    return _peerorrepo(rui, path, create).peer()
+    return _peerorrepo(rui, path, create, intents=intents).peer()
 
 def defaultdest(source):
     '''return default destination of clone if none is given
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -990,7 +990,7 @@
     return httppeer(ui, path, respurl, opener, requestbuilder,
                     info['v1capabilities'])
 
-def instance(ui, path, create):
+def instance(ui, path, create, intents=None):
     if create:
         raise error.Abort(_('cannot create new http repository'))
     try:
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -413,7 +413,7 @@
         'bisect.state',
     }
 
-    def __init__(self, baseui, path, create=False):
+    def __init__(self, baseui, path, create=False, intents=None):
         self.requirements = set()
         self.filtername = None
         # wvfs: rooted at the repository root, used to access the working copy
@@ -2332,8 +2332,9 @@
     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, intents=None):
+    return localrepository(ui, util.urllocalpath(path), create,
+                           intents=intents)
 
 def islocal(path):
     return True
diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -587,7 +587,7 @@
         raise error.RepoError(_('unknown version of SSH protocol: %s') %
                               protoname)
 
-def instance(ui, path, create):
+def instance(ui, path, create, intents=None):
     """Create an SSH peer.
 
     The returned object conforms to the ``wireprotov1peer.wirepeer`` interface.
diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
--- a/mercurial/statichttprepo.py
+++ b/mercurial/statichttprepo.py
@@ -215,7 +215,7 @@
     def _writecaches(self):
         pass # statichttprepository are read only
 
-def instance(ui, path, create):
+def instance(ui, path, create, intents=None):
     if create:
         raise error.Abort(_('cannot create new static-http repository'))
     return statichttprepository(ui, path[7:])
diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py
--- a/mercurial/unionrepo.py
+++ b/mercurial/unionrepo.py
@@ -231,7 +231,7 @@
     def getcwd(self):
         return pycompat.getcwd() # always outside the repo
 
-def instance(ui, path, create):
+def instance(ui, path, create, intents=None):
     if create:
         raise error.Abort(_('cannot create new union repository'))
     parentpath = ui.config("bundle", "mainreporoot")