Skip to content

Commit 05c8873

Browse files
committed
Add a --show-diff-on-failure option
1 parent 0ece39c commit 05c8873

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

pre_commit/commands/run.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import logging
55
import os
6+
import subprocess
67
import sys
78

89
from pre_commit import color
@@ -152,6 +153,13 @@ def _run_hooks(repo_hooks, args, environ):
152153
retval = 0
153154
for repo, hook in repo_hooks:
154155
retval |= _run_single_hook(hook, repo, args, skips, cols)
156+
if (
157+
retval and
158+
args.show_diff_on_failure and
159+
subprocess.call(('git', 'diff', '--quiet')) != 0
160+
):
161+
print('All changes made by hooks:')
162+
subprocess.call(('git', 'diff'))
155163
return retval
156164

157165

pre_commit/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ def main(argv=None):
149149
'--hook-stage', choices=('commit', 'push'), default='commit',
150150
help='The stage during which the hook is fired e.g. commit or push.',
151151
)
152+
run_parser.add_argument(
153+
'--show-diff-on-failure', action='store_true',
154+
help='When hooks fail, run `git diff` directly afterward.',
155+
)
152156
run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
153157
run_mutex_group.add_argument(
154158
'--all-files', '-a', action='store_true', default=False,

tests/commands/run_test.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def _get_opts(
5858
source='',
5959
allow_unstaged_config=False,
6060
hook_stage='commit',
61+
show_diff_on_failure=False,
6162
):
6263
# These are mutually exclusive
6364
assert not (all_files and files)
@@ -67,11 +68,12 @@ def _get_opts(
6768
color=color,
6869
verbose=verbose,
6970
hook=hook,
70-
hook_stage=hook_stage,
7171
no_stash=no_stash,
7272
origin=origin,
7373
source=source,
7474
allow_unstaged_config=allow_unstaged_config,
75+
hook_stage=hook_stage,
76+
show_diff_on_failure=show_diff_on_failure,
7577
)
7678

7779

@@ -151,6 +153,23 @@ def test_hook_that_modifies_but_returns_zero(
151153
)
152154

153155

156+
def test_show_diff_on_failure(
157+
capfd, cap_out, tempdir_factory, mock_out_store_directory,
158+
):
159+
git_path = make_consuming_repo(
160+
tempdir_factory, 'modified_file_returns_zero_repo',
161+
)
162+
with cwd(git_path):
163+
stage_a_file('bar.py')
164+
_test_run(
165+
cap_out, git_path, {'show_diff_on_failure': True},
166+
# we're only testing the output after running
167+
(), 1, True,
168+
)
169+
out, _ = capfd.readouterr()
170+
assert 'diff --git' in out
171+
172+
154173
@pytest.mark.parametrize(
155174
('options', 'outputs', 'expected_ret', 'stage'),
156175
(

0 commit comments

Comments
 (0)