Skip to content

Commit 99d698f

Browse files
Olivier Maringitster
authored andcommitted
builtin-rerere: more carefully find conflict markers
When a conflicting file contains a line that begin with "=======", rerere failed to parse conflict markers. This result to a wrong preimage file and an unexpected error for the user. The boundary between ours and theirs not just begin with 7 equals, but is followed by either a SP or a LF. This patch enforces parsing rules so that markers match in the right order, and when ambiguous, the command does not autoresolve the conflicted file. Especially because we are introducing rerere.autoupdate configuration (which is off by default for safety) that automatically stages the resolution made by rerere, it is necessary to make sure that we do not autoresolve when there is any ambiguity. Signed-off-by: Olivier Marin <dkr@freesurf.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent a9a3e82 commit 99d698f

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

builtin-rerere.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,17 @@ static int handle_file(const char *path,
112112
strbuf_init(&one, 0);
113113
strbuf_init(&two, 0);
114114
while (fgets(buf, sizeof(buf), f)) {
115-
if (!prefixcmp(buf, "<<<<<<< "))
115+
if (!prefixcmp(buf, "<<<<<<< ")) {
116+
if (hunk)
117+
goto bad;
116118
hunk = 1;
117-
else if (!prefixcmp(buf, "======="))
119+
} else if (!prefixcmp(buf, "=======") && isspace(buf[7])) {
120+
if (hunk != 1)
121+
goto bad;
118122
hunk = 2;
119-
else if (!prefixcmp(buf, ">>>>>>> ")) {
123+
} else if (!prefixcmp(buf, ">>>>>>> ")) {
124+
if (hunk != 2)
125+
goto bad;
120126
if (strbuf_cmp(&one, &two) > 0)
121127
strbuf_swap(&one, &two);
122128
hunk_no++;
@@ -142,6 +148,10 @@ static int handle_file(const char *path,
142148
strbuf_addstr(&two, buf);
143149
else if (out)
144150
fputs(buf, out);
151+
continue;
152+
bad:
153+
hunk = 99; /* force error exit */
154+
break;
145155
}
146156
strbuf_release(&one);
147157
strbuf_release(&two);

t/t4200-rerere.sh

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ test_description='git rerere
99
. ./test-lib.sh
1010

1111
cat > a1 << EOF
12+
Some title
13+
==========
1214
Whether 'tis nobler in the mind to suffer
1315
The slings and arrows of outrageous fortune,
1416
Or to take arms against a sea of troubles,
@@ -24,6 +26,8 @@ git commit -q -a -m initial
2426

2527
git checkout -b first
2628
cat >> a1 << EOF
29+
Some title
30+
==========
2731
To die, to sleep;
2832
To sleep: perchance to dream: ay, there's the rub;
2933
For in that sleep of death what dreams may come
@@ -35,7 +39,7 @@ git commit -q -a -m first
3539

3640
git checkout -b second master
3741
git show first:a1 |
38-
sed -e 's/To die, t/To die! T/' > a1
42+
sed -e 's/To die, t/To die! T/' -e 's/Some title/Some Title/' > a1
3943
echo "* END *" >>a1
4044
git commit -q -a -m second
4145

@@ -55,14 +59,14 @@ test_expect_success 'conflicting merge' '
5559

5660
sha1=$(sed -e 's/ .*//' .git/rr-cache/MERGE_RR)
5761
rr=.git/rr-cache/$sha1
58-
test_expect_success 'recorded preimage' "grep ======= $rr/preimage"
62+
test_expect_success 'recorded preimage' "grep ^=======$ $rr/preimage"
5963

6064
test_expect_success 'rerere.enabled works, too' '
6165
rm -rf .git/rr-cache &&
6266
git config rerere.enabled true &&
6367
git reset --hard &&
6468
! git merge first &&
65-
grep ======= $rr/preimage
69+
grep ^=======$ $rr/preimage
6670
'
6771

6872
test_expect_success 'no postimage or thisimage yet' \
@@ -71,7 +75,7 @@ test_expect_success 'no postimage or thisimage yet' \
7175
test_expect_success 'preimage has right number of lines' '
7276
7377
cnt=$(sed -ne "/^<<<<<<</,/^>>>>>>>/p" $rr/preimage | wc -l) &&
74-
test $cnt = 9
78+
test $cnt = 13
7579
7680
'
7781

@@ -80,13 +84,23 @@ git show first:a1 > a1
8084
cat > expect << EOF
8185
--- a/a1
8286
+++ b/a1
83-
@@ -6,17 +6,9 @@
87+
@@ -1,4 +1,4 @@
88+
-Some Title
89+
+Some title
90+
==========
91+
Whether 'tis nobler in the mind to suffer
92+
The slings and arrows of outrageous fortune,
93+
@@ -8,21 +8,11 @@
8494
The heart-ache and the thousand natural shocks
8595
That flesh is heir to, 'tis a consummation
8696
Devoutly to be wish'd.
8797
-<<<<<<<
98+
-Some Title
99+
-==========
88100
-To die! To sleep;
89101
-=======
102+
Some title
103+
==========
90104
To die, to sleep;
91105
->>>>>>>
92106
To sleep: perchance to dream: ay, there's the rub;
@@ -124,7 +138,7 @@ test_expect_success 'another conflicting merge' '
124138
'
125139

126140
git show first:a1 | sed 's/To die: t/To die! T/' > expect
127-
test_expect_success 'rerere kicked in' "! grep ======= a1"
141+
test_expect_success 'rerere kicked in' "! grep ^=======$ a1"
128142

129143
test_expect_success 'rerere prefers first change' 'test_cmp a1 expect'
130144

0 commit comments

Comments
 (0)