diff --git a/pre_commit/clientlib.py b/pre_commit/clientlib.py
index 07423c3..c5b9947 100644
--- a/pre_commit/clientlib.py
+++ b/pre_commit/clientlib.py
@@ -3,6 +3,8 @@ from __future__ import unicode_literals
 
 import argparse
 import functools
+import pipes
+import sys
 
 import cfgv
 from aspy.yaml import ordered_load
@@ -88,8 +90,8 @@ def validate_manifest_main(argv=None):
     return ret
 
 
-_LOCAL_SENTINEL = 'local'
-_META_SENTINEL = 'meta'
+_LOCAL = 'local'
+_META = 'meta'
 
 
 class MigrateShaToRev(object):
@@ -98,12 +100,12 @@ class MigrateShaToRev(object):
         return cfgv.Conditional(
             key, cfgv.check_string,
             condition_key='repo',
-            condition_value=cfgv.NotIn(_LOCAL_SENTINEL, _META_SENTINEL),
+            condition_value=cfgv.NotIn(_LOCAL, _META),
             ensure_absent=True,
         )
 
     def check(self, dct):
-        if dct.get('repo') in {_LOCAL_SENTINEL, _META_SENTINEL}:
+        if dct.get('repo') in {_LOCAL, _META}:
             self._cond('rev').check(dct)
             self._cond('sha').check(dct)
         elif 'sha' in dct and 'rev' in dct:
@@ -121,6 +123,61 @@ class MigrateShaToRev(object):
         pass
 
 
+def _entry(modname):
+    """the hook `entry` is passed through `shlex.split()` by the command
+    runner, so to prevent issues with spaces and backslashes (on Windows)
+    it must be quoted here.
+    """
+    return '{} -m pre_commit.meta_hooks.{}'.format(
+        pipes.quote(sys.executable), modname,
+    )
+
+
+_meta = (
+    (
+        'check-hooks-apply', (
+            ('name', 'Check hooks apply to the repository'),
+            ('files', C.CONFIG_FILE),
+            ('entry', _entry('check_hooks_apply')),
+        ),
+    ),
+    (
+        'check-useless-excludes', (
+            ('name', 'Check for useless excludes'),
+            ('files', C.CONFIG_FILE),
+            ('entry', _entry('check_useless_excludes')),
+        ),
+    ),
+    (
+        'identity', (
+            ('name', 'identity'),
+            ('verbose', True),
+            ('entry', _entry('identity')),
+        ),
+    ),
+)
+
+META_HOOK_DICT = cfgv.Map(
+    'Hook', 'id',
+    *([
+        cfgv.Required('id', cfgv.check_string),
+        cfgv.Required('id', cfgv.check_one_of(tuple(k for k, _ in _meta))),
+        # language must be system
+        cfgv.Optional('language', cfgv.check_one_of({'system'}), 'system'),
+    ] + [
+        # default to the hook definition for the meta hooks
+        cfgv.ConditionalOptional(key, cfgv.check_any, value, 'id', hook_id)
+        for hook_id, values in _meta
+        for key, value in values
+    ] + [
+        # default to the "manifest" parsing
+        cfgv.OptionalNoDefault(item.key, item.check_fn)
+        # these will always be defaulted above
+        if item.key in {'name', 'language', 'entry'} else
+        item
+        for item in MANIFEST_HOOK_DICT.items
+    ])
+)
 CONFIG_HOOK_DICT = cfgv.Map(
     'Hook', 'id',
 
@@ -140,7 +197,19 @@ CONFIG_REPO_DICT = cfgv.Map(
     'Repository', 'repo',
 
     cfgv.Required('repo', cfgv.check_string),
-    cfgv.RequiredRecurse('hooks', cfgv.Array(CONFIG_HOOK_DICT)),
+
+    cfgv.ConditionalRecurse(
+        'hooks', cfgv.Array(CONFIG_HOOK_DICT),
+        'repo', cfgv.NotIn(_LOCAL, _META),
+    ),
+    cfgv.ConditionalRecurse(
+        'hooks', cfgv.Array(MANIFEST_HOOK_DICT),
+        'repo', _LOCAL,
+    ),
+    cfgv.ConditionalRecurse(
+        'hooks', cfgv.Array(META_HOOK_DICT),
+        'repo', _META,
+    ),
 
     MigrateShaToRev(),
 )
@@ -154,11 +223,11 @@ CONFIG_SCHEMA = cfgv.Map(
 
 
 def is_local_repo(repo_entry):
-    return repo_entry['repo'] == _LOCAL_SENTINEL
+    return repo_entry['repo'] == _LOCAL
 
 
 def is_meta_repo(repo_entry):
-    return repo_entry['repo'] == _META_SENTINEL
+    return repo_entry['repo'] == _META
 
 
 class InvalidConfigError(FatalError):
diff --git a/pre_commit/meta_hooks/check_hooks_apply.py b/pre_commit/meta_hooks/check_hooks_apply.py
index a97830d..b17a9d6 100644
--- a/pre_commit/meta_hooks/check_hooks_apply.py
+++ b/pre_commit/meta_hooks/check_hooks_apply.py
@@ -5,18 +5,9 @@ from pre_commit import git
 from pre_commit.clientlib import load_config
 from pre_commit.commands.run import _filter_by_include_exclude
 from pre_commit.commands.run import _filter_by_types
-from pre_commit.meta_hooks.helpers import make_meta_entry
 from pre_commit.repository import all_hooks
 from pre_commit.store import Store
 
-HOOK_DICT = {
-    'id': 'check-hooks-apply',
-    'name': 'Check hooks apply to the repository',
-    'files': C.CONFIG_FILE,
-    'language': 'system',
-    'entry': make_meta_entry(__name__),
-}
-
 
 def check_all_hooks_match_files(config_file):
     files = git.get_all_files()
diff --git a/pre_commit/meta_hooks/check_useless_excludes.py b/pre_commit/meta_hooks/check_useless_excludes.py
index 7918eb3..18b9f16 100644
--- a/pre_commit/meta_hooks/check_useless_excludes.py
+++ b/pre_commit/meta_hooks/check_useless_excludes.py
@@ -10,15 +10,6 @@ from pre_commit import git
 from pre_commit.clientlib import load_config
 from pre_commit.clientlib import MANIFEST_HOOK_DICT
 from pre_commit.commands.run import _filter_by_types
-from pre_commit.meta_hooks.helpers import make_meta_entry
-
-HOOK_DICT = {
-    'id': 'check-useless-excludes',
-    'name': 'Check for useless excludes',
-    'files': C.CONFIG_FILE,
-    'language': 'system',
-    'entry': make_meta_entry(__name__),
-}
 
 
 def exclude_matches_any(filenames, include, exclude):
diff --git a/pre_commit/meta_hooks/helpers.py b/pre_commit/meta_hooks/helpers.py
deleted file mode 100644
index 7ef7486..0000000
--- a/pre_commit/meta_hooks/helpers.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import pipes
-import sys
-
-
-def make_meta_entry(modname):
-    """the hook `entry` is passed through `shlex.split()` by the command
-    runner, so to prevent issues with spaces and backslashes (on Windows)
-    it must be quoted here.
-    """
-    return '{} -m {}'.format(pipes.quote(sys.executable), modname)
diff --git a/pre_commit/meta_hooks/identity.py b/pre_commit/meta_hooks/identity.py
index 0cec32a..ae7377b 100644
--- a/pre_commit/meta_hooks/identity.py
+++ b/pre_commit/meta_hooks/identity.py
@@ -1,15 +1,6 @@
 import sys
 
 from pre_commit import output
-from pre_commit.meta_hooks.helpers import make_meta_entry
-
-HOOK_DICT = {
-    'id': 'identity',
-    'name': 'identity',
-    'language': 'system',
-    'verbose': True,
-    'entry': make_meta_entry(__name__),
-}
 
 
 def main(argv=None):
diff --git a/pre_commit/repository.py b/pre_commit/repository.py
index 7b98092..a654d08 100644
--- a/pre_commit/repository.py
+++ b/pre_commit/repository.py
@@ -6,9 +6,6 @@ import json
 import logging
 import os
 
-from cfgv import apply_defaults
-from cfgv import validate
-
 import pre_commit.constants as C
 from pre_commit import five
 from pre_commit.clientlib import is_local_repo
@@ -137,15 +134,8 @@ def _hook(*hook_dicts):
     return ret
 
 
-def _hook_from_manifest_dct(dct):
-    dct = apply_defaults(dct, MANIFEST_HOOK_DICT)
-    dct = validate(dct, MANIFEST_HOOK_DICT)
-    dct = _hook(dct)
-    return dct
-
-
-def _local_repository_hooks(repo_config, store):
-    def _local_prefix(language_name, deps):
+def _non_cloned_repository_hooks(repo_config, store):
+    def _prefix(language_name, deps):
         language = languages[language_name]
         # pcre / pygrep / script / system / docker_image do not have
         # environments so they work out of the current directory
@@ -154,45 +144,11 @@ def _local_repository_hooks(repo_config, store):
         else:
             return Prefix(store.make_local(deps))
 
-    hook_dcts = [_hook_from_manifest_dct(h) for h in repo_config['hooks']]
-    return tuple(
-        Hook.create(
-            repo_config['repo'],
-            _local_prefix(hook['language'], hook['additional_dependencies']),
-            hook,
-        )
-        for hook in hook_dcts
-    )
-
-
-def _meta_repository_hooks(repo_config, store):
-    # imported here to prevent circular imports.
-    from pre_commit.meta_hooks import check_hooks_apply
-    from pre_commit.meta_hooks import check_useless_excludes
-    from pre_commit.meta_hooks import identity
-
-    meta_hooks = [
-        _hook_from_manifest_dct(mod.HOOK_DICT)
-        for mod in (check_hooks_apply, check_useless_excludes, identity)
-    ]
-    by_id = {hook['id']: hook for hook in meta_hooks}
-
-    for hook in repo_config['hooks']:
-        if hook['id'] not in by_id:
-            logger.error(
-                '`{}` is not a valid meta hook.  '
-                'Typo? Perhaps it is introduced in a newer version?  '
-                'Often `pip install --upgrade pre-commit` fixes this.'
-                .format(hook['id']),
-            )
-            exit(1)
-
-    prefix = Prefix(os.getcwd())
     return tuple(
         Hook.create(
             repo_config['repo'],
-            prefix,
-            _hook(by_id[hook['id']], hook),
+            _prefix(hook['language'], hook['additional_dependencies']),
+            _hook(hook),
         )
         for hook in repo_config['hooks']
     )
@@ -225,10 +181,8 @@ def _cloned_repository_hooks(repo_config, store):
 
 
 def repository_hooks(repo_config, store):
-    if is_local_repo(repo_config):
-        return _local_repository_hooks(repo_config, store)
-    elif is_meta_repo(repo_config):
-        return _meta_repository_hooks(repo_config, store)
+    if is_local_repo(repo_config) or is_meta_repo(repo_config):
+        return _non_cloned_repository_hooks(repo_config, store)
     else:
         return _cloned_repository_hooks(repo_config, store)
 
diff --git a/setup.py b/setup.py
index f6ea719..6cc52d1 100644
--- a/setup.py
+++ b/setup.py
@@ -36,7 +36,7 @@ setup(
     },
     install_requires=[
         'aspy.yaml',
-        'cfgv>=1.0.0',
+        'cfgv>=1.3.0',
         'identify>=1.0.0',
         # if this makes it into python3.8 move to extras_require
         'importlib-metadata',

meta repos should forbid `language` from being set
currently you can set `language: python` (or any other language) and the repository machinery will create an environment for that hook (though `meta` hooks should always be `system` type).

in the unreleased version, this causes a virtualenv to be written to `.` as `meta` repos now have a hard-coded prefix as the root of the repository.
diff --git a/tests/clientlib_test.py b/tests/clientlib_test.py
index dbae4aa..1f691c2 100644
--- a/tests/clientlib_test.py
+++ b/tests/clientlib_test.py
@@ -5,6 +5,7 @@ import pytest
 
 from pre_commit.clientlib import check_type_tag
 from pre_commit.clientlib import CONFIG_HOOK_DICT
+from pre_commit.clientlib import CONFIG_REPO_DICT
 from pre_commit.clientlib import CONFIG_SCHEMA
 from pre_commit.clientlib import is_local_repo
 from pre_commit.clientlib import MANIFEST_SCHEMA
@@ -236,3 +237,19 @@ def test_migrate_to_sha_ok():
     dct = {'repo': 'a', 'rev': 'b'}
     MigrateShaToRev().apply_default(dct)
     assert dct == {'repo': 'a', 'rev': 'b'}
+
+
+@pytest.mark.parametrize(
+    'config_repo',
+    (
+        # i-dont-exist isn't a valid hook
+        {'repo': 'meta', 'hooks': [{'id': 'i-dont-exist'}]},
+        # invalid to set a language for a meta hook
+        {'repo': 'meta', 'hooks': [{'id': 'identity', 'language': 'python'}]},
+        # name override must be string
+        {'repo': 'meta', 'hooks': [{'id': 'identity', 'name': False}]},
+    ),
+)
+def test_meta_hook_invalid_id(config_repo):
+    with pytest.raises(cfgv.ValidationError):
+        cfgv.validate(config_repo, CONFIG_REPO_DICT)
diff --git a/tests/commands/autoupdate_test.py b/tests/commands/autoupdate_test.py
index 8daf986..df7cb08 100644
--- a/tests/commands/autoupdate_test.py
+++ b/tests/commands/autoupdate_test.py
@@ -8,7 +8,6 @@ import pytest
 
 import pre_commit.constants as C
 from pre_commit import git
-from pre_commit.clientlib import load_config
 from pre_commit.commands.autoupdate import _update_repo
 from pre_commit.commands.autoupdate import autoupdate
 from pre_commit.commands.autoupdate import RepositoryCannotBeUpdatedError
@@ -17,6 +16,7 @@ from testing.auto_namedtuple import auto_namedtuple
 from testing.fixtures import add_config_to_repo
 from testing.fixtures import make_config_from_repo
 from testing.fixtures import make_repo
+from testing.fixtures import read_config
 from testing.fixtures import sample_local_config
 from testing.fixtures import write_config
 from testing.util import get_resource_path
@@ -319,7 +319,7 @@ def test_autoupdate_local_hooks(in_git_dir, store):
     config = sample_local_config()
     add_config_to_repo('.', config)
     assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0
-    new_config_writen = load_config(C.CONFIG_FILE)
+    new_config_writen = read_config('.')
     assert len(new_config_writen['repos']) == 1
     assert new_config_writen['repos'][0] == config
 
@@ -334,7 +334,7 @@ def test_autoupdate_local_hooks_with_out_of_date_repo(
     config = {'repos': [local_config, stale_config]}
     write_config('.', config)
     assert autoupdate(C.CONFIG_FILE, store, tags_only=False) == 0
-    new_config_writen = load_config(C.CONFIG_FILE)
+    new_config_writen = read_config('.')
     assert len(new_config_writen['repos']) == 2
     assert new_config_writen['repos'][0] == local_config
 
diff --git a/tests/commands/gc_test.py b/tests/commands/gc_test.py
index 2f958f6..2a01850 100644
--- a/tests/commands/gc_test.py
+++ b/tests/commands/gc_test.py
@@ -2,6 +2,7 @@ import os
 
 import pre_commit.constants as C
 from pre_commit import git
+from pre_commit.clientlib import load_config
 from pre_commit.commands.autoupdate import autoupdate
 from pre_commit.commands.gc import gc
 from pre_commit.repository import all_hooks
@@ -91,7 +92,7 @@ def test_gc_unused_local_repo_with_env(store, in_git_dir, cap_out):
     store.mark_config_used(C.CONFIG_FILE)
 
     # this causes the repositories to be created
-    all_hooks({'repos': [config]}, store)
+    all_hooks(load_config(C.CONFIG_FILE), store)
 
     assert _config_count(store) == 1
     assert _repo_count(store) == 1
diff --git a/tests/repository_test.py b/tests/repository_test.py
index eecf67b..25fe244 100644
--- a/tests/repository_test.py
+++ b/tests/repository_test.py
@@ -5,12 +5,14 @@ import os.path
 import re
 import shutil
 
+import cfgv
 import mock
 import pytest
 
 import pre_commit.constants as C
 from pre_commit import five
 from pre_commit import parse_shebang
+from pre_commit.clientlib import CONFIG_REPO_DICT
 from pre_commit.clientlib import load_manifest
 from pre_commit.languages import golang
 from pre_commit.languages import helpers
@@ -42,6 +44,8 @@ def _norm_out(b):
 
 
 def _get_hook(config, store, hook_id):
+    config = cfgv.validate(config, CONFIG_REPO_DICT)
+    config = cfgv.apply_defaults(config, CONFIG_REPO_DICT)
     hooks = repository_hooks(config, store)
     install_hook_envs(hooks, store)
     hook, = [hook for hook in hooks if hook.id == hook_id]
@@ -711,17 +715,6 @@ def test_hook_id_not_present(tempdir_factory, store, fake_log_handler):
     )
 
 
-def test_meta_hook_not_present(store, fake_log_handler):
-    config = {'repo': 'meta', 'hooks': [{'id': 'i-dont-exist'}]}
-    with pytest.raises(SystemExit):
-        _get_hook(config, store, 'i-dont-exist')
-    assert fake_log_handler.handle.call_args[0][0].msg == (
-        '`i-dont-exist` is not a valid meta hook.  '
-        'Typo? Perhaps it is introduced in a newer version?  '
-        'Often `pip install --upgrade pre-commit` fixes this.'
-    )
-
-
 def test_too_new_version(tempdir_factory, store, fake_log_handler):
     path = make_repo(tempdir_factory, 'script_hooks_repo')
     with modify_manifest(path) as manifest:

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio mock
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aspy.yaml==1.3.0
cfgv==3.4.0
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
execnet==2.1.1
filelock==3.18.0
identify==2.6.9
importlib_metadata==8.6.1
iniconfig==2.1.0
mock==5.2.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
-e git+https://github.com/pre-commit/pre-commit.git@46ae88c1f06b8dc59f3e049c68b2dcea22bb9a54#egg=pre_commit
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
PyYAML==6.0.2
six==1.17.0
toml==0.10.2
tomli==2.2.1
typing_extensions==4.13.0
virtualenv==20.29.3
zipp==3.21.0

name: pre-commit
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aspy-yaml==1.3.0
      - cfgv==3.4.0
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - filelock==3.18.0
      - identify==2.6.9
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - mock==5.2.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pyyaml==6.0.2
      - six==1.17.0
      - toml==0.10.2
      - tomli==2.2.1
      - typing-extensions==4.13.0
      - virtualenv==20.29.3
      - zipp==3.21.0
prefix: /opt/conda/envs/pre-commit

tests/clientlib_test.py::test_meta_hook_invalid_id[config_repo0] tests/clientlib_test.py::test_meta_hook_invalid_id[config_repo1]
tests/repository_test.py::test_switch_language_versions_doesnt_clobber tests/repository_test.py::test_run_a_ruby_hook tests/repository_test.py::test_run_versioned_ruby_hook tests/repository_test.py::test_run_ruby_hook_with_disable_shared_gems tests/repository_test.py::test_golang_hook tests/repository_test.py::test_rust_hook tests/repository_test.py::test_additional_rust_cli_dependencies_installed[cli:shellharden:3.1.0] tests/repository_test.py::test_additional_rust_cli_dependencies_installed[cli:shellharden] tests/repository_test.py::test_additional_rust_lib_dependencies_installed tests/repository_test.py::test_additional_ruby_dependencies_installed tests/repository_test.py::test_additional_golang_dependencies_installed tests/repository_test.py::test_local_golang_additional_dependencies tests/repository_test.py::test_local_rust_additional_dependencies
tests/clientlib_test.py::test_check_type_tag_failures[definitely-not-a-tag] tests/clientlib_test.py::test_check_type_tag_failures[fiel] tests/clientlib_test.py::test_is_local_repo tests/clientlib_test.py::test_validate_config_main[args0-0] tests/clientlib_test.py::test_validate_config_main[args1-1] tests/clientlib_test.py::test_validate_config_main[args2-1] tests/clientlib_test.py::test_validate_config_main[args3-1] tests/clientlib_test.py::test_config_valid[config_obj0-True] tests/clientlib_test.py::test_config_valid[config_obj1-True] tests/clientlib_test.py::test_config_valid[config_obj2-False] tests/clientlib_test.py::test_local_hooks_with_rev_fails tests/clientlib_test.py::test_config_with_local_hooks_definition_passes[config_obj0] tests/clientlib_test.py::test_config_with_local_hooks_definition_passes[config_obj1] tests/clientlib_test.py::test_config_schema_does_not_contain_defaults tests/clientlib_test.py::test_validate_manifest_main[args0-0] tests/clientlib_test.py::test_validate_manifest_main[args1-1] tests/clientlib_test.py::test_validate_manifest_main[args2-1] tests/clientlib_test.py::test_validate_manifest_main[args3-1] tests/clientlib_test.py::test_valid_manifests[manifest_obj0-True] tests/clientlib_test.py::test_valid_manifests[manifest_obj1-True] tests/clientlib_test.py::test_valid_manifests[manifest_obj2-True] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct0] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct1] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct2] tests/clientlib_test.py::test_migrate_sha_to_rev_ok[dct3] tests/clientlib_test.py::test_migrate_sha_to_rev_dont_specify_both tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct0] tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct1] tests/clientlib_test.py::test_migrate_sha_to_rev_conditional_check_failures[dct2] tests/clientlib_test.py::test_migrate_to_sha_apply_default tests/clientlib_test.py::test_migrate_to_sha_ok tests/clientlib_test.py::test_meta_hook_invalid_id[config_repo2] tests/commands/autoupdate_test.py::test_up_to_date_repo tests/commands/autoupdate_test.py::test_autoupdate_up_to_date_repo tests/commands/autoupdate_test.py::test_autoupdate_old_revision_broken tests/commands/autoupdate_test.py::test_out_of_date_repo tests/commands/autoupdate_test.py::test_autoupdate_out_of_date_repo tests/commands/autoupdate_test.py::test_autoupdate_out_of_date_repo_with_correct_repo_name tests/commands/autoupdate_test.py::test_autoupdate_out_of_date_repo_with_wrong_repo_name tests/commands/autoupdate_test.py::test_does_not_reformat tests/commands/autoupdate_test.py::test_loses_formatting_when_not_detectable tests/commands/autoupdate_test.py::test_autoupdate_tagged_repo tests/commands/autoupdate_test.py::test_autoupdate_tags_only tests/commands/autoupdate_test.py::test_autoupdate_latest_no_config tests/commands/autoupdate_test.py::test_hook_disppearing_repo_raises tests/commands/autoupdate_test.py::test_autoupdate_hook_disappearing_repo tests/commands/autoupdate_test.py::test_autoupdate_local_hooks tests/commands/autoupdate_test.py::test_autoupdate_local_hooks_with_out_of_date_repo tests/commands/autoupdate_test.py::test_autoupdate_meta_hooks tests/commands/autoupdate_test.py::test_updates_old_format_to_new_format tests/commands/gc_test.py::test_gc tests/commands/gc_test.py::test_gc_repo_not_cloned tests/commands/gc_test.py::test_gc_meta_repo_does_not_crash tests/commands/gc_test.py::test_gc_local_repo_does_not_crash tests/commands/gc_test.py::test_gc_unused_local_repo_with_env tests/commands/gc_test.py::test_gc_config_with_missing_hook tests/commands/gc_test.py::test_gc_deletes_invalid_configs tests/commands/gc_test.py::test_invalid_manifest_gcd tests/repository_test.py::TestPygrep::test_grep_hook_matching tests/repository_test.py::TestPygrep::test_grep_hook_case_insensitive tests/repository_test.py::TestPygrep::test_grep_hook_not_matching[nope] tests/repository_test.py::TestPygrep::test_grep_hook_not_matching[foo'bar] tests/repository_test.py::TestPygrep::test_grep_hook_not_matching[^\\[INFO\\]] tests/repository_test.py::TestPCRE::test_grep_hook_matching tests/repository_test.py::TestPCRE::test_grep_hook_case_insensitive tests/repository_test.py::TestPCRE::test_grep_hook_not_matching[nope] tests/repository_test.py::TestPCRE::test_grep_hook_not_matching[foo'bar] tests/repository_test.py::TestPCRE::test_grep_hook_not_matching[^\\[INFO\\]] tests/repository_test.py::TestPCRE::test_pcre_hook_many_files tests/repository_test.py::TestPCRE::test_missing_pcre_support tests/repository_test.py::test_additional_dependencies_roll_forward tests/repository_test.py::test_additional_node_dependencies_installed tests/repository_test.py::test_fail_hooks tests/repository_test.py::test_unknown_keys tests/repository_test.py::test_reinstall tests/repository_test.py::test_really_long_file_paths tests/repository_test.py::test_config_overrides_repo_specifics tests/repository_test.py::test_hook_id_not_present tests/repository_test.py::test_too_new_version tests/repository_test.py::test_versions_ok[0.1.0] tests/repository_test.py::test_versions_ok[1.13.0] tests/repository_test.py::test_manifest_hooks
pre_commit/meta_hooks/identity.py setup.py pre_commit/meta_hooks/check_useless_excludes.py pre_commit/meta_hooks/check_hooks_apply.py pre_commit/meta_hooks/helpers.py pre_commit/repository.py pre_commit/clientlib.py
pre_commit/meta_hooks/identity.py setup.py pre_commit/meta_hooks/check_useless_excludes.py pre_commit/meta_hooks/check_hooks_apply.py pre_commit/meta_hooks/helpers.py pre_commit/repository.py pre_commit/clientlib.py