mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Fixes crash during merge conflict. Closes #82.
This commit is contained in:
parent
5f0cab9114
commit
846ddeed67
3 changed files with 35 additions and 2 deletions
|
|
@ -30,6 +30,9 @@ COLS = int(subprocess.Popen(['tput', 'cols'], stdout=subprocess.PIPE).communicat
|
||||||
|
|
||||||
PASS_FAIL_LENGTH = 6
|
PASS_FAIL_LENGTH = 6
|
||||||
|
|
||||||
|
# Grabbed from `git help status`
|
||||||
|
CONFLICTING_GIT_STATUSES = set(('DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'))
|
||||||
|
|
||||||
|
|
||||||
def install(runner):
|
def install(runner):
|
||||||
"""Install the pre-commit hooks."""
|
"""Install the pre-commit hooks."""
|
||||||
|
|
@ -229,11 +232,24 @@ def _run_hook(runner, hook_id, args, write):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
def _has_unmerged_paths(runner):
|
||||||
|
_, stdout, _ = runner.cmd_runner.run(
|
||||||
|
['git', 'status', '--short'], retcode=None,
|
||||||
|
)
|
||||||
|
codes = set(line[:2] for line in stdout.splitlines())
|
||||||
|
return codes & CONFLICTING_GIT_STATUSES > set()
|
||||||
|
|
||||||
|
|
||||||
def run(runner, args, write=sys.stdout.write):
|
def run(runner, args, write=sys.stdout.write):
|
||||||
# Set up our logging handler
|
# Set up our logging handler
|
||||||
logger.addHandler(LoggingHandler(args.color, write=write))
|
logger.addHandler(LoggingHandler(args.color, write=write))
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
# Check if we have unresolved merge conflict files and fail fast.
|
||||||
|
if _has_unmerged_paths(runner):
|
||||||
|
logger.error('Unmerged files. Resolve before committing.')
|
||||||
|
return 1
|
||||||
|
|
||||||
if args.no_stash or args.all_files:
|
if args.no_stash or args.all_files:
|
||||||
ctx = noop_context()
|
ctx = noop_context()
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,17 @@ def test_no_stash(repo_with_passing_hook, no_stash, all_files, expect_stash):
|
||||||
assert warning_msg not in printed
|
assert warning_msg not in printed
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
('mode', 'expected'),
|
||||||
|
[(status, True) for status in commands.CONFLICTING_GIT_STATUSES] +
|
||||||
|
[(' A', False), (' D', False), (' M', False)]
|
||||||
|
)
|
||||||
|
def test_has_unmerged_paths(mode, expected):
|
||||||
|
mock_runner = mock.Mock()
|
||||||
|
mock_runner.cmd_runner.run.return_value = (1, mode + ' foo', '')
|
||||||
|
assert commands._has_unmerged_paths(mock_runner) is expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def in_merge_conflict(repo_with_passing_hook):
|
def in_merge_conflict(repo_with_passing_hook):
|
||||||
local['git']['add', C.CONFIG_FILE]()
|
local['git']['add', C.CONFIG_FILE]()
|
||||||
|
|
@ -298,6 +309,12 @@ def in_merge_conflict(repo_with_passing_hook):
|
||||||
|
|
||||||
|
|
||||||
def test_merge_conflict(in_merge_conflict):
|
def test_merge_conflict(in_merge_conflict):
|
||||||
|
ret, printed = _do_run(in_merge_conflict, _get_opts())
|
||||||
|
assert ret == 1
|
||||||
|
assert 'Unmerged files. Resolve before committing.' in printed
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge_conflict_modified(in_merge_conflict):
|
||||||
# Touch another file so we have unstaged non-conflicting things
|
# Touch another file so we have unstaged non-conflicting things
|
||||||
assert os.path.exists('dummy')
|
assert os.path.exists('dummy')
|
||||||
with open('dummy', 'w') as dummy_file:
|
with open('dummy', 'w') as dummy_file:
|
||||||
|
|
@ -305,4 +322,4 @@ def test_merge_conflict(in_merge_conflict):
|
||||||
|
|
||||||
ret, printed = _do_run(in_merge_conflict, _get_opts())
|
ret, printed = _do_run(in_merge_conflict, _get_opts())
|
||||||
assert ret == 1
|
assert ret == 1
|
||||||
assert 'Resolve merge conflicts before committing' in printed
|
assert 'Unmerged files. Resolve before committing.' in printed
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ def fake_logging_handler():
|
||||||
self.logs = []
|
self.logs = []
|
||||||
|
|
||||||
def emit(self, record):
|
def emit(self, record):
|
||||||
self.logs.append(record)
|
self.logs.append(record) # pragma: no cover (only hit in failure)
|
||||||
|
|
||||||
pre_commit_logger = logging.getLogger('pre_commit')
|
pre_commit_logger = logging.getLogger('pre_commit')
|
||||||
original_level = pre_commit_logger.getEffectiveLevel()
|
original_level = pre_commit_logger.getEffectiveLevel()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue