From 1312af87e5908ac252c0659a60216e96ec5b23bd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Jun 2020 11:11:24 +0200 Subject: Merging upstream version 2.5.1. Signed-off-by: Daniel Baumann --- pre_commit/commands/run.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'pre_commit/commands/run.py') diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index 8c8401c..567b7cd 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -72,13 +72,7 @@ def filter_by_include_exclude( class Classifier: - def __init__(self, filenames: Sequence[str]) -> None: - # on windows we normalize all filenames to use forward slashes - # this makes it easier to filter using the `files:` regex - # this also makes improperly quoted shell-based hooks work better - # see #1173 - if os.altsep == '/' and os.sep == '\\': - filenames = [f.replace(os.sep, os.altsep) for f in filenames] + def __init__(self, filenames: Collection[str]) -> None: self.filenames = [f for f in filenames if os.path.lexists(f)] @functools.lru_cache(maxsize=None) @@ -105,6 +99,22 @@ class Classifier: names = self.by_types(names, hook.types, hook.exclude_types) return tuple(names) + @classmethod + def from_config( + cls, + filenames: Collection[str], + include: str, + exclude: str, + ) -> 'Classifier': + # on windows we normalize all filenames to use forward slashes + # this makes it easier to filter using the `files:` regex + # this also makes improperly quoted shell-based hooks work better + # see #1173 + if os.altsep == '/' and os.sep == '\\': + filenames = [f.replace(os.sep, os.altsep) for f in filenames] + filenames = filter_by_include_exclude(filenames, include, exclude) + return Classifier(filenames) + def _get_skips(environ: EnvironT) -> Set[str]: skips = environ.get('SKIP', '') @@ -221,7 +231,8 @@ def _compute_cols(hooks: Sequence[Hook]) -> int: def _all_filenames(args: argparse.Namespace) -> Collection[str]: - if args.hook_stage == 'post-checkout': # no files for post-checkout + # these hooks do not operate on files + if args.hook_stage in {'post-checkout', 'post-commit'}: return () elif args.hook_stage in {'prepare-commit-msg', 'commit-msg'}: return (args.commit_msg_filename,) @@ -246,10 +257,9 @@ def _run_hooks( """Actually run the hooks.""" skips = _get_skips(environ) cols = _compute_cols(hooks) - filenames = filter_by_include_exclude( + classifier = Classifier.from_config( _all_filenames(args), config['files'], config['exclude'], ) - classifier = Classifier(filenames) retval = 0 for hook in hooks: retval |= _run_single_hook( @@ -323,6 +333,12 @@ def run( f'`--hook-stage {args.hook_stage}`', ) return 1 + # prevent recursive post-checkout hooks (#1418) + if ( + args.hook_stage == 'post-checkout' and + environ.get('_PRE_COMMIT_SKIP_POST_CHECKOUT') + ): + return 0 # Expose from-ref / to-ref as environment variables for hooks to consume if args.from_ref and args.to_ref: @@ -340,6 +356,9 @@ def run( if args.checkout_type: environ['PRE_COMMIT_CHECKOUT_TYPE'] = args.checkout_type + # Set pre_commit flag + environ['PRE_COMMIT'] = '1' + with contextlib.ExitStack() as exit_stack: if stash: exit_stack.enter_context(staged_files_only(store.directory)) -- cgit v1.2.3