Repository: pre-commit/pre-commit
Pull request #1344 (2020-02-23 19:37:00)

Ensure files aren't passed to post-checkout hooks


Patch:
diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py
index 43bcaba..2f74578 100644
--- a/pre_commit/commands/run.py
+++ b/pre_commit/commands/run.py
@@ -215,10 +215,12 @@ def _compute_cols(hooks: Sequence[Hook]) -> int:
 
 
 def _all_filenames(args: argparse.Namespace) -> Collection[str]:
-    if args.from_ref and args.to_ref:
-        return git.get_changed_files(args.from_ref, args.to_ref)
+    if args.hook_stage == 'post-checkout':  # no files for post-checkout
+        return ()
     elif args.hook_stage in {'prepare-commit-msg', 'commit-msg'}:
         return (args.commit_msg_filename,)
+    elif args.from_ref and args.to_ref:
+        return git.get_changed_files(args.from_ref, args.to_ref)
     elif args.files:
         return args.files
     elif args.all_files:


Test patch:
diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py
index c76c303..2f6c49f 100644
--- a/tests/commands/install_uninstall_test.py
+++ b/tests/commands/install_uninstall_test.py
@@ -4,6 +4,7 @@ import sys
 from unittest import mock
 
 import pre_commit.constants as C
+from pre_commit import git
 from pre_commit.commands import install_uninstall
 from pre_commit.commands.install_uninstall import CURRENT_HASH
 from pre_commit.commands.install_uninstall import install
@@ -728,27 +729,39 @@ def test_commit_msg_legacy(commit_msg_repo, tempdir_factory, store):
 
 def test_post_checkout_integration(tempdir_factory, store):
     path = git_dir(tempdir_factory)
-    config = {
-        'repo': 'local',
-        'hooks': [{
-            'id': 'post-checkout',
-            'name': 'Post checkout',
-            'entry': 'bash -c "echo ${PRE_COMMIT_ORIGIN}"',
-            'language': 'system',
-            'always_run': True,
-            'verbose': True,
-            'stages': ['post-checkout'],
-        }],
-    }
+    config = [
+        {
+            'repo': 'local',
+            'hooks': [{
+                'id': 'post-checkout',
+                'name': 'Post checkout',
+                'entry': 'bash -c "echo ${PRE_COMMIT_TO_REF}"',
+                'language': 'system',
+                'always_run': True,
+                'verbose': True,
+                'stages': ['post-checkout'],
+            }],
+        },
+        {'repo': 'meta', 'hooks': [{'id': 'identity'}]},
+    ]
     write_config(path, config)
     with cwd(path):
         cmd_output('git', 'add', '.')
         git_commit()
+
+        # add a file only on `feature`, it should not be passed to hooks
+        cmd_output('git', 'checkout', '-b', 'feature')
+        open('some_file', 'a').close()
+        cmd_output('git', 'add', '.')
+        git_commit()
+        cmd_output('git', 'checkout', 'master')
+
         install(C.CONFIG_FILE, store, hook_types=['post-checkout'])
-        retc, _, stderr = cmd_output('git', 'checkout', '-b', 'feature')
+        retc, _, stderr = cmd_output('git', 'checkout', 'feature')
+        assert stderr is not None
         assert retc == 0
-        _, head, _ = cmd_output('git', 'rev-parse', 'HEAD')
-        assert head in str(stderr)
+        assert git.head_rev(path) in stderr
+        assert 'some_file' not in stderr
 
 
 def test_prepare_commit_msg_integration_failing(