diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
index 2963c053e4a874c21b3283bbddc07a060d8d972c..9586d3f122c09af520831c4be289d84624b851f0 100644
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -158,8 +158,16 @@ def elide_list(line_list, max_num=10):
         return line_list
 
 
-def disambiguate_spec(spec):
-    matching_specs = spack.store.db.query(spec)
+def disambiguate_spec(spec, env):
+    """Given a spec, figure out which installed package it refers to.
+
+    Arguments:
+        spec (spack.spec.Spec): a spec to disambiguate
+        env (spack.environment.Environment): a spack environment,
+            if one is active, or None if no environment is active
+    """
+    hashes = env.all_hashes() if env else None
+    matching_specs = spack.store.db.query(spec, hashes=hashes)
     if not matching_specs:
         tty.die("Spec '%s' matches no installed packages." % spec)
 
diff --git a/lib/spack/spack/cmd/activate.py b/lib/spack/spack/cmd/activate.py
index de6bbc3ecc5b56098b7d0a33229e05430a061893..44e77d7adeb5a4ee8f804dfc25e533048b96dd00 100644
--- a/lib/spack/spack/cmd/activate.py
+++ b/lib/spack/spack/cmd/activate.py
@@ -8,6 +8,7 @@
 import llnl.util.tty as tty
 
 import spack.cmd
+import spack.environment as ev
 from spack.filesystem_view import YamlFilesystemView
 
 description = "activate a package extension"
@@ -32,7 +33,8 @@ def activate(parser, args):
     if len(specs) != 1:
         tty.die("activate requires one spec.  %d given." % len(specs))
 
-    spec = spack.cmd.disambiguate_spec(specs[0])
+    env = ev.get_env(args, 'activate')
+    spec = spack.cmd.disambiguate_spec(specs[0], env)
     if not spec.package.is_extension:
         tty.die("%s is not an extension." % spec.name)
 
diff --git a/lib/spack/spack/cmd/add.py b/lib/spack/spack/cmd/add.py
index 6dc903ae68ac254c29f9c46f754e4a32e5c265da..69f85be2343e643d641106bdb99065af38d22908 100644
--- a/lib/spack/spack/cmd/add.py
+++ b/lib/spack/spack/cmd/add.py
@@ -22,7 +22,7 @@ def setup_parser(subparser):
 
 
 def add(parser, args):
-    env = ev.get_env(args, 'add')
+    env = ev.get_env(args, 'add', required=True)
 
     for spec in spack.cmd.parse_specs(args.specs):
         if not env.add(spec):
diff --git a/lib/spack/spack/cmd/buildcache.py b/lib/spack/spack/cmd/buildcache.py
index e9aa6d849e718eed5681fc11382c15824e90f272..76016f19af5f166e72c98126796df5cfae63d40f 100644
--- a/lib/spack/spack/cmd/buildcache.py
+++ b/lib/spack/spack/cmd/buildcache.py
@@ -8,6 +8,7 @@
 import llnl.util.tty as tty
 
 import spack.cmd
+import spack.environment as ev
 import spack.repo
 import spack.store
 import spack.spec
@@ -81,7 +82,8 @@ def setup_parser(subparser):
     dlkeys.set_defaults(func=getkeys)
 
 
-def find_matching_specs(pkgs, allow_multiple_matches=False, force=False):
+def find_matching_specs(
+        pkgs, allow_multiple_matches=False, force=False, env=None):
     """Returns a list of specs matching the not necessarily
        concretized specs given from cli
 
@@ -92,12 +94,14 @@ def find_matching_specs(pkgs, allow_multiple_matches=False, force=False):
     Return:
         list of specs
     """
+    hashes = env.all_hashes() if env else None
+
     # List of specs that match expressions given via command line
     specs_from_cli = []
     has_errors = False
     specs = spack.cmd.parse_specs(pkgs)
     for spec in specs:
-        matching = spack.store.db.query(spec)
+        matching = spack.store.db.query(spec, hashes=hashes)
         # For each spec provided, make sure it refers to only one package.
         # Fail and ask user to be unambiguous if it doesn't
         if not allow_multiple_matches and len(matching) > 1:
@@ -179,7 +183,10 @@ def createtarball(args):
     if args.key:
         signkey = args.key
 
-    matches = find_matching_specs(pkgs, False, False)
+    # restrict matching to current environment if one is active
+    env = ev.get_env(args, 'buildcache create')
+
+    matches = find_matching_specs(pkgs, False, False, env=env)
     for match in matches:
         if match.external or match.virtual:
             tty.msg('skipping external or virtual spec %s' %
diff --git a/lib/spack/spack/cmd/concretize.py b/lib/spack/spack/cmd/concretize.py
index 728718e502433c959067b0fda36f66f2ea02b101..e8443c61a916e8f39105357b20c8bada3b598a8d 100644
--- a/lib/spack/spack/cmd/concretize.py
+++ b/lib/spack/spack/cmd/concretize.py
@@ -17,6 +17,6 @@ def setup_parser(subparser):
 
 
 def concretize(parser, args):
-    env = ev.get_env(args, 'concretize')
+    env = ev.get_env(args, 'concretize', required=True)
     env.concretize(force=args.force)
     env.write()
diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py
index 4fd21768c8b855bc51592d707708345350ac5bc5..ae38e256b5a1875b978088c148eaf91e5bbb90db 100644
--- a/lib/spack/spack/cmd/config.py
+++ b/lib/spack/spack/cmd/config.py
@@ -64,7 +64,7 @@ def _get_scope_and_section(args):
 
     # w/no args and an active environment, point to env manifest
     if not args.section:
-        env = ev.get_env(args, 'config edit', required=False)
+        env = ev.get_env(args, 'config edit')
         if env:
             scope = env.env_file_config_scope_name()
 
diff --git a/lib/spack/spack/cmd/deactivate.py b/lib/spack/spack/cmd/deactivate.py
index ef450b1c94f7fae96581efb004a483dccd326885..c1d793f159f64610a642f399848a56dedfd6711b 100644
--- a/lib/spack/spack/cmd/deactivate.py
+++ b/lib/spack/spack/cmd/deactivate.py
@@ -7,6 +7,7 @@
 import llnl.util.tty as tty
 
 import spack.cmd
+import spack.environment as ev
 import spack.store
 from spack.filesystem_view import YamlFilesystemView
 from spack.graph import topological_sort
@@ -37,7 +38,8 @@ def deactivate(parser, args):
     if len(specs) != 1:
         tty.die("deactivate requires one spec.  %d given." % len(specs))
 
-    spec = spack.cmd.disambiguate_spec(specs[0])
+    env = ev.get_env(args, 'deactivate')
+    spec = spack.cmd.disambiguate_spec(specs[0], env)
     pkg = spec.package
 
     if args.view:
diff --git a/lib/spack/spack/cmd/dependencies.py b/lib/spack/spack/cmd/dependencies.py
index fe66bef1df35879ab45e92d4fcde67ef5b9368c0..08c76b3a014526ae9c398ca24328ebf3f625313e 100644
--- a/lib/spack/spack/cmd/dependencies.py
+++ b/lib/spack/spack/cmd/dependencies.py
@@ -8,6 +8,7 @@
 import llnl.util.tty as tty
 from llnl.util.tty.colify import colify
 
+import spack.environment as ev
 import spack.store
 import spack.repo
 import spack.cmd
@@ -38,7 +39,8 @@ def dependencies(parser, args):
         tty.die("spack dependencies takes only one spec.")
 
     if args.installed:
-        spec = spack.cmd.disambiguate_spec(specs[0])
+        env = ev.get_env(args, 'dependencies')
+        spec = spack.cmd.disambiguate_spec(specs[0], env)
 
         tty.msg("Dependencies of %s" % spec.format('$_$@$%@$/', color=True))
         deps = spack.store.db.installed_relatives(
diff --git a/lib/spack/spack/cmd/dependents.py b/lib/spack/spack/cmd/dependents.py
index 46397ed5f0d449de2a7fcda4ed50137adfc7d33d..937dd2cd3a444eedcafe12ba9dd563903f8b626b 100644
--- a/lib/spack/spack/cmd/dependents.py
+++ b/lib/spack/spack/cmd/dependents.py
@@ -8,6 +8,7 @@
 import llnl.util.tty as tty
 from llnl.util.tty.colify import colify
 
+import spack.environment as ev
 import spack.repo
 import spack.store
 import spack.cmd
@@ -81,7 +82,8 @@ def dependents(parser, args):
         tty.die("spack dependents takes only one spec.")
 
     if args.installed:
-        spec = spack.cmd.disambiguate_spec(specs[0])
+        env = ev.get_env(args, 'dependents')
+        spec = spack.cmd.disambiguate_spec(specs[0], env)
 
         tty.msg("Dependents of %s" % spec.cformat('$_$@$%@$/'))
         deps = spack.store.db.installed_relatives(
diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py
index c8b9c169b5ff7c0225a9c02b3888334386ee69c6..5c24de05b17aa48c64807378af0076d8940614cd 100644
--- a/lib/spack/spack/cmd/env.py
+++ b/lib/spack/spack/cmd/env.py
@@ -280,7 +280,7 @@ def env_status_setup_parser(subparser):
 
 
 def env_status(args):
-    env = ev.get_env(args, 'env status', required=False)
+    env = ev.get_env(args, 'env status')
     if env:
         if env.path == os.getcwd():
             tty.msg('Using %s in current directory: %s'
@@ -305,7 +305,7 @@ def env_loads_setup_parser(subparser):
 
 
 def env_loads(args):
-    env = ev.get_env(args, 'env loads')
+    env = ev.get_env(args, 'env loads', required=True)
 
     # Set the module types that have been selected
     module_type = args.module_type
diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
index a564248d631c31c49b9d3e100c3556288d224f12..f505cf908d9373f59e6a6fb79ea86bb96b22000d 100644
--- a/lib/spack/spack/cmd/extensions.py
+++ b/lib/spack/spack/cmd/extensions.py
@@ -8,6 +8,7 @@
 import llnl.util.tty as tty
 from llnl.util.tty.colify import colify
 
+import spack.environment as ev
 import spack.cmd
 import spack.cmd.find
 import spack.repo
@@ -75,7 +76,8 @@ def extensions(parser, args):
     if not spec[0].package.extendable:
         tty.die("%s is not an extendable package." % spec[0].name)
 
-    spec = spack.cmd.disambiguate_spec(spec[0])
+    env = ev.get_env(args, 'extensions')
+    spec = spack.cmd.disambiguate_spec(spec[0], env)
 
     if not spec.package.extendable:
         tty.die("%s does not have extensions." % spec.short_spec)
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index b1ea65dfc1fffac992ae924681cafd7c1d614eb8..cc1d7f51847c0952f0e65603db8087ee4ba0fb78 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -151,7 +151,7 @@ def find(parser, args):
     added = set()
     removed = set()
 
-    env = ev.get_env(args, 'find', required=False)
+    env = ev.get_env(args, 'find')
     if env:
         decorator, added, roots, removed = setup_env(env)
 
diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py
index d42988303f99a908611f83fb56d4c07916b04731..628c2d3564af43d7e02108ac0b9d006e53dc7443 100644
--- a/lib/spack/spack/cmd/install.py
+++ b/lib/spack/spack/cmd/install.py
@@ -160,7 +160,7 @@ def install_spec(cli_args, kwargs, abstract_spec, spec):
 
     # handle active environment, if any
     def install(spec, kwargs):
-        env = ev.get_env(cli_args, 'install', required=False)
+        env = ev.get_env(cli_args, 'install')
         if env:
             env.install(abstract_spec, spec, **kwargs)
             env.write()
@@ -194,7 +194,7 @@ def install(parser, args, **kwargs):
     if not args.package and not args.specfiles:
         # if there are no args but an active environment or spack.yaml file
         # then install the packages from it.
-        env = ev.get_env(args, 'install', required=False)
+        env = ev.get_env(args, 'install')
         if env:
             if not args.only_concrete:
                 env.concretize()
diff --git a/lib/spack/spack/cmd/location.py b/lib/spack/spack/cmd/location.py
index a878f63df8a4f592c841414073e15652668445eb..a9a70142e386ceba68f5c5e2bed6a13a502b5f70 100644
--- a/lib/spack/spack/cmd/location.py
+++ b/lib/spack/spack/cmd/location.py
@@ -9,6 +9,7 @@
 import argparse
 import llnl.util.tty as tty
 
+import spack.environment as ev
 import spack.cmd
 import spack.environment
 import spack.paths
@@ -86,7 +87,8 @@ def location(parser, args):
 
         if args.install_dir:
             # install_dir command matches against installed specs.
-            spec = spack.cmd.disambiguate_spec(specs[0])
+            env = ev.get_env(args, 'location')
+            spec = spack.cmd.disambiguate_spec(specs[0], env)
             print(spec.prefix)
 
         else:
diff --git a/lib/spack/spack/cmd/remove.py b/lib/spack/spack/cmd/remove.py
index ec0b2cd2184c4a5f05bbef9e3617619e00040c92..656d70f51e56d2dd4ab88249a6465522f9f3a583 100644
--- a/lib/spack/spack/cmd/remove.py
+++ b/lib/spack/spack/cmd/remove.py
@@ -28,7 +28,7 @@ def setup_parser(subparser):
 
 
 def remove(parser, args):
-    env = ev.get_env(args, 'remove')
+    env = ev.get_env(args, 'remove', required=True)
 
     if args.all:
         env.clear()
diff --git a/lib/spack/spack/cmd/stage.py b/lib/spack/spack/cmd/stage.py
index 68f2486b0d08bc6c8caab7e4863e0c3b9bbb9bdb..3488548e6e05aeb852204d65393e06f2dd7dad34 100644
--- a/lib/spack/spack/cmd/stage.py
+++ b/lib/spack/spack/cmd/stage.py
@@ -29,7 +29,7 @@ def setup_parser(subparser):
 
 def stage(parser, args):
     if not args.specs:
-        env = ev.get_env(args, 'stage', required=False)
+        env = ev.get_env(args, 'stage')
         if env:
             tty.msg("Staging specs from environment %s" % env.name)
             for spec in env.specs_by_hash.values():
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index 81e84379994dbf02b481c12ddd85ea5e0b203265..3105831ef8d50ffa7a0156ce2d499afd0e1590f9 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -301,7 +301,7 @@ def get_uninstall_list(args, specs, env):
 
 
 def uninstall_specs(args, specs):
-    env = ev.get_env(args, 'uninstall', required=False)
+    env = ev.get_env(args, 'uninstall')
 
     uninstall_list, remove_list = get_uninstall_list(args, specs, env)
     anything_to_do = set(uninstall_list).union(set(remove_list))
diff --git a/lib/spack/spack/cmd/view.py b/lib/spack/spack/cmd/view.py
index 9768458f02af7cce2a3ffcc8ea3e9f4c5de97d86..c95bdf6e5f811d81b96d7dd76d36c83916e76528 100644
--- a/lib/spack/spack/cmd/view.py
+++ b/lib/spack/spack/cmd/view.py
@@ -38,6 +38,7 @@
 import llnl.util.tty as tty
 from llnl.util.link_tree import MergeConflictError
 
+import spack.environment as ev
 import spack.cmd
 import spack.store
 from spack.filesystem_view import YamlFilesystemView
@@ -172,7 +173,8 @@ def view(parser, args):
 
     elif args.action in actions_link:
         # only link commands need to disambiguate specs
-        specs = [spack.cmd.disambiguate_spec(s) for s in specs]
+        env = ev.get_env(args, 'view link')
+        specs = [spack.cmd.disambiguate_spec(s, env) for s in specs]
 
     elif args.action in actions_status:
         # no specs implies all
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 40d63eaa0ed8cf6071b3325b21daac64ccf22553..18bf9984380526d29bea3db253efdeeb0ae13e7e 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -184,7 +184,7 @@ def find_environment(args):
     raise SpackEnvironmentError('no environment in %s' % env)
 
 
-def get_env(args, cmd_name, required=True):
+def get_env(args, cmd_name, required=False):
     """Used by commands to get the active environment.
 
     This first checks for an ``env`` argument, then looks at the
@@ -202,8 +202,8 @@ def get_env(args, cmd_name, required=True):
     Arguments:
         args (Namespace): argparse namespace wtih command arguments
         cmd_name (str): name of calling command
-        required (bool): if ``False``, return ``None`` if no environment
-            is found instead of raising an exception.
+        required (bool): if ``True``, raise an exception when no environment
+            is found; if ``False``, just return ``None``
 
     Returns:
         (Environment): if there is an arg or active environment