Repository: pre-commit/pre-commit

Issue:
SKIP skips invocation by alias but doesn't skip "Installing environment"
### search tried in the issue tracker

SKIP alias

### describe your issue

When I run 

```sh
SKIP=pylint-alias2 git commit
```

the hook aliased as `pylint-alias2` is properly skipped, however, its environment is still initialized. I would expect that it also skips the lengthy initialization of the environment.

Indeed, running a single hook ([run.py#153](https://github.com/pre-commit/pre-commit/blob/49f95b9ef391639d09136666be375d99a3dccd04/pre_commit/commands/run.py#153)) checks against `hook.id` and `hook.alias`, however `install_hook_envs` is invoked with only filtering against `hook.id` ([run.py#423](https://github.com/pre-commit/pre-commit/blob/49f95b9ef391639d09136666be375d99a3dccd04/pre_commit/commands/run.py)

Is this inconsistency deliberate? I couldn't find a use case for it. This quick and dirty patch works for us:

```diff
-        to_install = [hook for hook in hooks if hook.id not in skips]
+        to_install = [hook for hook in hooks if hook.id not in skips and hook.alias not in skips]
```

In our use case Initialization is not needed for everyone (monorepo where some non-python devs also do non-python work) and also very expensive unfortunately (6minutes currently to install already cached pip packages)

(An even better solution would be if initialization wouldn't happen at all if the hook run would we skipped in general (because of `SKIP` variable or because there is no files changed, however, that would be a but bigger patch I suppose))

### pre-commit --version

pre-commit 

### .pre-commit-config.yaml

```yaml
repos:
  - repo: https://github.com/PyCQA/pylint
    rev: v2.14.5
    hooks:
      - name: pylint-alias1
        alias: pylint-alias1
        id: pylint
        additional_dependencies:
          - arrow
      - name: pylint-alias2
        alias: pylint-alias2
        id: pylint
        additional_dependencies:
          - hdfs
```


### ~/.cache/pre-commit/pre-commit.log (if present)

_No response_


Discussion:
Additional info: we are very well aware of the caching setups (and quite much like it!) and in our CI builds we do cache everything whenever an `additional_dependencies` changes. 

The most painful use case is really when a developer wants to commit files which has nothing to do with one python project, but since the `additional_dependencies` in another hook, which would not be invoked, changes, then the developer still has to wait for the long initialization step. Respecting `SKIP`  would already be a big improvement 
initialization must happen to resolve the alias -- but it shouldn't be installed -- please don't skip the prompts in the issue template. show the command you ran and the output
Sorry, my vocabulary was confused. Initialization should happen yes. **Installing** the environment should not.

Here is the output (with cleared `~/.cache` before):

```sh
± SKIP=pylint-alias2 pre-commit run --all-files
[INFO] Initializing environment for https://github.com/PyCQA/pylint.
[INFO] Initializing environment for https://github.com/PyCQA/pylint:arrow.
[INFO] Initializing environment for https://github.com/PyCQA/pylint:hdfs.
[INFO] Installing environment for https://github.com/PyCQA/pylint.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/PyCQA/pylint.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
pylint-alias1........................................(no files to check)Skipped
pylint-alias2...........................................................Skipped
```
yep seems like an oversight then, send a tested patch please

Resolving patch:
diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py
--- a/pre_commit/commands/run.py
+++ b/pre_commit/commands/run.py
@@ -420,7 +420,11 @@ def run(
             return 1
 
         skips = _get_skips(environ)
-        to_install = [hook for hook in hooks if hook.id not in skips]
+        to_install = [
+            hook
+            for hook in hooks
+            if hook.id not in skips and hook.alias not in skips
+        ]
         install_hook_envs(to_install, store)
 
         return _run_hooks(config, hooks, skips, args)


Test patch:
diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py
--- a/tests/commands/run_test.py
+++ b/tests/commands/run_test.py
@@ -635,6 +635,32 @@ def test_skip_bypasses_installation(cap_out, store, repo_with_passing_hook):
     assert ret == 0
 
 
+def test_skip_alias_bypasses_installation(
+        cap_out, store, repo_with_passing_hook,
+):
+    config = {
+        'repo': 'local',
+        'hooks': [
+            {
+                'id': 'skipme',
+                'name': 'skipme-1',
+                'alias': 'skipme-1',
+                'entry': 'skipme',
+                'language': 'python',
+                'additional_dependencies': ['/pre-commit-does-not-exist'],
+            },
+        ],
+    }
+    add_config_to_repo(repo_with_passing_hook, config)
+
+    ret, printed = _do_run(
+        cap_out, store, repo_with_passing_hook,
+        run_opts(all_files=True),
+        {'SKIP': 'skipme-1'},
+    )
+    assert ret == 0
+
+
 def test_hook_id_not_in_non_verbose_output(
         cap_out, store, repo_with_passing_hook,
 ):