diff --check: detect leftover conflict markers
authorJunio C Hamano <gitster@pobox.com>
Thu, 26 Jun 2008 22:37:21 +0000 (15:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 27 Jun 2008 05:07:54 +0000 (22:07 -0700)
This teaches "diff --check" to detect and complain if the change
adds lines that look like leftover conflict markers.

We should be able to remove the old Perl script used in the sample
pre-commit hook and modernize the script with this facility.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff.c
t/t4017-diff-retval.sh

diff --git a/diff.c b/diff.c
index f31c7211683802844f9aab3e86105695a17f79e5..d515b06ea32d693108ac78902d4f091a52596262 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1143,6 +1143,35 @@ struct checkdiff_t {
        int trailing_blanks_start;
 };
 
+static int is_conflict_marker(const char *line, unsigned long len)
+{
+       char firstchar;
+       int cnt;
+
+       if (len < 8)
+               return 0;
+       firstchar = line[0];
+       switch (firstchar) {
+       case '=': case '>': case '<':
+               break;
+       default:
+               return 0;
+       }
+       for (cnt = 1; cnt < 7; cnt++)
+               if (line[cnt] != firstchar)
+                       return 0;
+       /* line[0] thru line[6] are same as firstchar */
+       if (firstchar == '=') {
+               /* divider between ours and theirs? */
+               if (len != 8 || line[7] != '\n')
+                       return 0;
+       } else if (len < 8 || !isspace(line[7])) {
+               /* not divider before ours nor after theirs */
+               return 0;
+       }
+       return 1;
+}
+
 static void checkdiff_consume(void *priv, char *line, unsigned long len)
 {
        struct checkdiff_t *data = priv;
@@ -1159,6 +1188,12 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
                        data->trailing_blanks_start = 0;
                else if (!data->trailing_blanks_start)
                        data->trailing_blanks_start = data->lineno;
+               if (is_conflict_marker(line + 1, len - 1)) {
+                       data->status |= 1;
+                       fprintf(data->o->file,
+                               "%s:%d: leftover conflict marker\n",
+                               data->filename, data->lineno);
+               }
                bad = ws_check(line + 1, len - 1, data->ws_rule);
                if (!bad)
                        return;
index 0d0fb87f5732e3ecbca8a195843070539353701e..d748d45daec54ec3fa4be2229dbafebd879493eb 100755 (executable)
@@ -113,4 +113,18 @@ test_expect_success 'check should test not just the last line' '
 
 '
 
+test_expect_success 'check detects leftover conflict markers' '
+       git reset --hard &&
+       git checkout HEAD^ &&
+       echo binary >>b &&
+       git commit -m "side" b &&
+       test_must_fail git merge master &&
+       git add b && (
+               git --no-pager diff --cached --check >test.out
+               test $? = 2
+       ) &&
+       test "$(grep "conflict marker" test.out | wc -l)" = 3 &&
+       git reset --hard
+'
+
 test_done