77from typing import Generator
88
99from pre_commit import git
10+ from pre_commit .errors import FatalError
1011from pre_commit .util import CalledProcessError
1112from pre_commit .util import cmd_output
1213from pre_commit .util import cmd_output_b
@@ -49,20 +50,24 @@ def _intent_to_add_cleared() -> Generator[None, None, None]:
4950@contextlib .contextmanager
5051def _unstaged_changes_cleared (patch_dir : str ) -> Generator [None , None , None ]:
5152 tree = cmd_output ('git' , 'write-tree' )[1 ].strip ()
52- retcode , diff_stdout_binary , _ = cmd_output_b (
53+ diff_cmd = (
5354 'git' , 'diff-index' , '--ignore-submodules' , '--binary' ,
5455 '--exit-code' , '--no-color' , '--no-ext-diff' , tree , '--' ,
55- check = False ,
5656 )
57- if retcode and diff_stdout_binary .strip ():
57+ retcode , diff_stdout , diff_stderr = cmd_output_b (* diff_cmd , check = False )
58+ if retcode == 0 :
59+ # There weren't any staged files so we don't need to do anything
60+ # special
61+ yield
62+ elif retcode == 1 and diff_stdout .strip ():
5863 patch_filename = f'patch{ int (time .time ())} -{ os .getpid ()} '
5964 patch_filename = os .path .join (patch_dir , patch_filename )
6065 logger .warning ('Unstaged files detected.' )
6166 logger .info (f'Stashing unstaged files to { patch_filename } .' )
6267 # Save the current unstaged changes as a patch
6368 os .makedirs (patch_dir , exist_ok = True )
6469 with open (patch_filename , 'wb' ) as patch_file :
65- patch_file .write (diff_stdout_binary )
70+ patch_file .write (diff_stdout )
6671
6772 # prevent recursive post-checkout hooks (#1418)
6873 no_checkout_env = dict (os .environ , _PRE_COMMIT_SKIP_POST_CHECKOUT = '1' )
@@ -86,10 +91,12 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
8691 _git_apply (patch_filename )
8792
8893 logger .info (f'Restored changes from { patch_filename } .' )
89- else :
90- # There weren't any staged files so we don't need to do anything
91- # special
92- yield
94+ else : # pragma: win32 no cover
95+ # some error occurred while requesting the diff
96+ e = CalledProcessError (retcode , diff_cmd , b'' , diff_stderr )
97+ raise FatalError (
98+ f'pre-commit failed to diff -- perhaps due to permissions?\n \n { e } ' ,
99+ )
93100
94101
95102@contextlib .contextmanager
0 commit comments