From adf2223c7624f2553dea2e16d0ea292dadd72cb7 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 2 Feb 2023 11:02:58 +0000 Subject: [PATCH] Add `--no-textconv` to `git diff` calls --- pre_commit/commands/run.py | 6 ++--- pre_commit/staged_files_only.py | 4 ++-- tests/commands/run_test.py | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index e44e70364..a7eb4f45a 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -272,7 +272,8 @@ def _all_filenames(args: argparse.Namespace) -> Collection[str]: def _get_diff() -> bytes: _, out, _ = cmd_output_b( - 'git', 'diff', '--no-ext-diff', '--ignore-submodules', check=False, + 'git', 'diff', '--no-ext-diff', '--no-textconv', '--ignore-submodules', + check=False, ) return out @@ -326,8 +327,7 @@ def _has_unmerged_paths() -> bool: def _has_unstaged_config(config_file: str) -> bool: retcode, _, _ = cmd_output_b( - 'git', 'diff', '--no-ext-diff', '--exit-code', config_file, - check=False, + 'git', 'diff', '--quiet', '--no-ext-diff', config_file, check=False, ) # be explicit, other git errors don't mean it has an unstaged config. return retcode == 1 diff --git a/pre_commit/staged_files_only.py b/pre_commit/staged_files_only.py index 172fb20b1..56c46cb51 100644 --- a/pre_commit/staged_files_only.py +++ b/pre_commit/staged_files_only.py @@ -51,8 +51,8 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]: tree = cmd_output('git', 'write-tree')[1].strip() retcode, diff_stdout_binary, _ = cmd_output_b( 'git', 'diff-index', '--ignore-submodules', '--binary', - '--exit-code', '--no-color', '--no-ext-diff', tree, '--', - check=False, + '--exit-code', '--no-color', '--no-ext-diff', '--no-textconv', tree, + '--', check=False, ) if retcode and diff_stdout_binary.strip(): patch_filename = f'patch{int(time.time())}-{os.getpid()}' diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index 03d741e06..e3bff73c1 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -766,6 +766,47 @@ def test_lots_of_files(store, tempdir_factory): ) +def test_no_textconv(cap_out, store, repo_with_passing_hook): + # git textconv filters can hide changes from hooks + with open('.gitattributes', 'w') as fp: + fp.write('*.jpeg diff=empty\n') + + with open('.git/config', 'a') as fp: + fp.write('[diff "empty"]\n') + fp.write('textconv = "python -c print()"\n') + + config = { + 'repo': 'local', + 'hooks': [ + { + 'id': 'extend-jpeg', + 'name': 'extend-jpeg', + 'language': 'system', + 'entry': ( + 'python -c "import sys; ' + 'open(sys.argv[1], \'ab\').write(b\'\\x00\')"' + ), + 'types': ['jpeg'], + }, + ], + } + add_config_to_repo(repo_with_passing_hook, config) + + stage_a_file('example.jpeg') + + _test_run( + cap_out, + store, + repo_with_passing_hook, + {}, + ( + b'Failed', + ), + expected_ret=1, + stage=False, + ) + + def test_stages(cap_out, store, repo_with_passing_hook): config = { 'repo': 'local',