Pre-commit stashes unstaged changes on run. Closes #30.

This commit is contained in:
Anthony Sottile 2014-04-05 22:01:29 -07:00
parent a3720c0645
commit 158a3a6d8b
2 changed files with 20 additions and 7 deletions

View file

@ -11,6 +11,7 @@ from pre_commit import commands
from pre_commit import git
from pre_commit.logging_handler import LoggingHandler
from pre_commit.runner import Runner
from pre_commit.staged_files_only import staged_files_only
from pre_commit.util import entry
@ -89,10 +90,11 @@ def _run(runner, args):
logger.addHandler(LoggingHandler(args.color))
logger.setLevel(logging.INFO)
if args.hook:
return run_single_hook(runner, args.hook, args)
else:
return run_hooks(runner, args)
with staged_files_only(runner.cmd_runner):
if args.hook:
return run_single_hook(runner, args.hook, args)
else:
return run_hooks(runner, args)
@entry

View file

@ -1,10 +1,14 @@
import contextlib
import logging
import time
from pre_commit.prefixed_command_runner import CalledProcessError
logger = logging.getLogger('pre_commit')
@contextlib.contextmanager
def staged_files_only(cmd_runner):
"""Clear any unstaged changes from the git working directory inside this
@ -19,10 +23,12 @@ def staged_files_only(cmd_runner):
retcode=None,
)
if retcode:
# TODO: print a warning message that unstaged things are being stashed
patch_filename = cmd_runner.path('patch{0}'.format(int(time.time())))
logger.warning('Unstaged files detected.')
logger.info(
'Stashing unstaged files to {0}.'.format(patch_filename),
)
# Save the current unstaged changes as a patch
# TODO: use a more unique patch filename
patch_filename = cmd_runner.path('patch{0}'.format(time.time()))
with open(patch_filename, 'w') as patch_file:
cmd_runner.run(['git', 'diff', '--binary'], stdout=patch_file)
@ -35,12 +41,17 @@ def staged_files_only(cmd_runner):
try:
cmd_runner.run(['git', 'apply', patch_filename])
except CalledProcessError:
logger.warning(
'Stashed changes conflicted with hook auto-fixes... '
'Rolling back fixes...'
)
# TOOD: print a warning about rolling back changes made by hooks
# We failed to apply the patch, presumably due to fixes made
# by hooks.
# Roll back the changes made by hooks.
cmd_runner.run(['git', 'checkout', '--', '.'])
cmd_runner.run(['git', 'apply', patch_filename])
logger.info('Restored changes from {0}.'.format(patch_filename))
else:
# There weren't any staged files so we don't need to do anything
# special