diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
index 289fdcd4cb471a28ab115df75be22988a7ee08ac_bWVyY3VyaWFsL2Rpc3BhdGNoLnB5..d36a384bec8743f7c27d85f6a3baa759aba57425_bWVyY3VyaWFsL2Rpc3BhdGNoLnB5 100644
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -243,6 +243,7 @@
         self.opts = []
         self.help = ''
         self.norepo = True
+        self.optionalrepo = False
         self.badalias = False
 
         try:
@@ -312,6 +313,8 @@
             self.args = aliasargs(self.fn, args)
             if cmd not in commands.norepo.split(' '):
                 self.norepo = False
+            if cmd in commands.optionalrepo.split(' '):
+                self.optionalrepo = True
             if self.help.startswith("hg " + cmd):
                 # drop prefix in old-style help lines so hg shows the alias
                 self.help = self.help[4 + len(cmd):]
@@ -370,6 +373,8 @@
         cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
         if aliasdef.norepo:
             commands.norepo += ' %s' % alias
+        if aliasdef.optionalrepo:
+            commands.optionalrepo += ' %s' % alias
 
 def _parse(ui, args):
     options = {}
@@ -495,7 +500,6 @@
     return path, lui
 
 def _checkshellalias(lui, ui, args):
-    norepo = commands.norepo
     options = {}
 
     try:
@@ -506,6 +510,12 @@
     if not args:
         return
 
+    norepo = commands.norepo
+    optionalrepo = commands.optionalrepo
+    def restorecommands():
+        commands.norepo = norepo
+        commands.optionalrepo = optionalrepo
+
     cmdtable = commands.table.copy()
     addaliases(lui, cmdtable)
 
@@ -514,7 +524,7 @@
         aliases, entry = cmdutil.findcmd(cmd, cmdtable,
                                          lui.configbool("ui", "strict"))
     except (error.AmbiguousCommand, error.UnknownCommand):
-        commands.norepo = norepo
+        restorecommands()
         return
 
     cmd = aliases[0]
@@ -524,7 +534,7 @@
         d = lambda: fn(ui, *args[1:])
         return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
 
-    commands.norepo = norepo
+    restorecommands()
 
 _loaded = set()
 def _dispatch(req):
diff --git a/tests/test-alias.t b/tests/test-alias.t
index 289fdcd4cb471a28ab115df75be22988a7ee08ac_dGVzdHMvdGVzdC1hbGlhcy50..d36a384bec8743f7c27d85f6a3baa759aba57425_dGVzdHMvdGVzdC1hbGlhcy50 100644
--- a/tests/test-alias.t
+++ b/tests/test-alias.t
@@ -9,6 +9,7 @@
   > # should clobber ci but not commit (issue2993)
   > ci = version
   > myinit = init
+  > optionalrepo = showconfig alias.myinit
   > cleanstatus = status -c
   > unknown = bargle
   > ambiguous = s
@@ -108,4 +109,8 @@
   $ hg help no--repository
   error in definition for alias 'no--repository': --repository may only be given on the command line
 
+optional repository
+
+  $ hg optionalrepo
+  init
   $ cd alias
@@ -111,5 +116,10 @@
   $ cd alias
-
+  $ cat > .hg/hgrc <<EOF
+  > [alias]
+  > myinit = init -q
+  > EOF
+  $ hg optionalrepo
+  init -q
 
 no usage