Repository: pre-commit/pre-commit-hooks
Pull request #49 (2015-03-20 23:16:11)

Only check merge conflicts on conflict commits
@guykisel what do you think?

coveralls: 
[![Coverage Status](https://coveralls.io/builds/2162490/badge)](https://coveralls.io/builds/2162490)

Coverage remained the same at 100.0% when pulling **20f3d775d871dc48344f1507f2141460d088c015 on only_check_merge_conflicted_files** into **34444ba2c7f8f899f3198240673418665f811a1c on master**.


Patch:
diff --git a/pre_commit_hooks/check_merge_conflict.py b/pre_commit_hooks/check_merge_conflict.py
index ac405b2..5e274a3 100644
--- a/pre_commit_hooks/check_merge_conflict.py
+++ b/pre_commit_hooks/check_merge_conflict.py
@@ -1,6 +1,7 @@
 from __future__ import print_function
 
 import argparse
+import os.path
 import sys
 
 CONFLICT_PATTERNS = [
@@ -11,11 +12,21 @@ CONFLICT_PATTERNS = [
 WARNING_MSG = 'Merge conflict string "{0}" found in {1}:{2}'
 
 
+def is_in_merge_conflict():
+    return (
+        os.path.exists(os.path.join('.git', 'MERGE_MSG')) and
+        os.path.exists(os.path.join('.git', 'MERGE_HEAD'))
+    )
+
+
 def detect_merge_conflict(argv=None):
     parser = argparse.ArgumentParser()
     parser.add_argument('filenames', nargs='*')
     args = parser.parse_args(argv)
 
+    if not is_in_merge_conflict():
+        return 0
+
     retcode = 0
     for filename in args.filenames:
         with open(filename) as inputfile:
diff --git a/pylintrc b/pylintrc
index 7b2247d..bbd11ba 100644
--- a/pylintrc
+++ b/pylintrc
@@ -1,5 +1,5 @@
 [MESSAGES CONTROL]
-disable=bad-open-mode,invalid-name,missing-docstring,redefined-outer-name,star-args
+disable=bad-open-mode,invalid-name,missing-docstring,redefined-outer-name,star-args,locally-disabled
 
 [REPORTS]
 output-format=colorized


Test patch:
diff --git a/tests/check_merge_conflict_test.py b/tests/check_merge_conflict_test.py
index bcf90eb..f3bd935 100644
--- a/tests/check_merge_conflict_test.py
+++ b/tests/check_merge_conflict_test.py
@@ -1,26 +1,71 @@
-import os.path
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+import io
 
 import pytest
 
 from pre_commit_hooks.check_merge_conflict import detect_merge_conflict
+from pre_commit_hooks.util import cmd_output
+from testing.util import cwd
+from testing.util import write_file
+
+
+# pylint:disable=unused-argument
+
+
+@pytest.yield_fixture
+def f1_is_a_conflict_file(in_tmpdir):
+    # Make a merge conflict
+    cmd_output('git', 'init', 'repo1')
+    with cwd('repo1'):
+        io.open('f1', 'w').close()
+        cmd_output('git', 'add', 'f1')
+        cmd_output('git', 'commit', '-m' 'commit1')
 
-# Input, expected return value
-TESTS = (
-    (b'<<<<<<< HEAD', 1),
-    (b'=======', 1),
-    (b'>>>>>>> master', 1),
-    (b'# <<<<<<< HEAD', 0),
-    (b'# =======', 0),
-    (b'import my_module', 0),
-    (b'', 0),
+    cmd_output('git', 'clone', 'repo1', 'repo2')
+
+    # Commit in master
+    with cwd('repo1'):
+        write_file('f1', 'parent\n')
+        cmd_output('git', 'commit', '-am', 'master commit2')
+
+    # Commit in clone and pull
+    with cwd('repo2'):
+        write_file('f1', 'child\n')
+        cmd_output('git', 'commit', '-am', 'clone commit2')
+        cmd_output('git', 'pull', retcode=None)
+        # We should end up in a merge conflict!
+        assert io.open('f1').read().startswith(
+            '<<<<<<< HEAD\n'
+            'child\n'
+            '=======\n'
+            'parent\n'
+            '>>>>>>>'
+        )
+        yield
+
+
+@pytest.mark.parametrize(
+    'failing_contents', ('<<<<<<< HEAD', '=======', '>>>>>>> master'),
 )
+@pytest.mark.usefixtures('f1_is_a_conflict_file')
+def test_merge_conflicts_failing(failing_contents):
+    write_file('f1', failing_contents)
+    assert detect_merge_conflict(['f1']) == 1
 
 
-@pytest.mark.parametrize(('input_s', 'expected_retval'), TESTS)
-def test_detect_merge_conflict(input_s, expected_retval, tmpdir):
-    path = os.path.join(tmpdir.strpath, 'file.txt')
+@pytest.mark.parametrize(
+    'ok_contents', ('# <<<<<<< HEAD', '# =======', 'import my_module', ''),
+)
+@pytest.mark.usefixtures('f1_is_a_conflict_file')
+def test_merge_conflicts_ok(ok_contents):
+    write_file('f1', ok_contents)
+    assert detect_merge_conflict(['f1']) == 0
 
-    with open(path, 'wb') as file_obj:
-        file_obj.write(input_s)
 
-    assert detect_merge_conflict([path]) == expected_retval
+@pytest.mark.usefixtures('in_tmpdir')
+def test_does_not_care_when_not_in_a_conflict():
+    with io.open('README.md', 'w') as readme_file:
+        readme_file.write('pre-commit\n=================\n')
+    assert detect_merge_conflict(['README.md']) == 0