File conflict_end-2.diff of Package wiggle
Subject: Re: [PATCH] 2 wiggle bugs
From: Chris Mason <mason@suse.com>
To: Neil Brown <neilb@cse.unsw.edu.au>
On Mon, 2004-01-26 at 13:22, Chris Mason wrote:
[] Hi Neil,
[]
[] This patch tries to fix the three bug reports I've sent so far, one
[] turned out to be a different form of the same bug
[]
[] 1) wiggle -x can't extract diff3 output sometimes
[] diff3 doesn't always include the ||||||| section, so I've changed
[] extract.c to be able to switch directly from state 1 to state 3.
[]
[] 2) wiggle file file.rej seems to miss the first hunk in the file
[] sometimes. The missed hunk doesn't produce a conflict or error code, so
[] it gets lost. I'm not sure if it is always the first hunk, it just
[] happened to be that way both times I've seen it.
Well, my first attempt at a fix was broken. Turns out the missing hunks
had been properly resolved by wiggle, but print_merger() decided not to
print them.
After some diffing I found that merge.c:advance() was stepping p->pos
too far when c2 started exactly on the same spot that pos->b was
currently sitting, but only after sliding from in_a = 0 to in_a = 1
I'm not sure why it is only happening after the slide, and I'm wondering
if similar changes need to be made in the in_a = 0 case. Here's my
current patch, please review when you get a chance.
I've attached the test case, wiggle -l nmi.c nmi.c.rej will show the
problem. The diff3 fixes are also included again.
-chris
diff -ur wiggle-0.6.orig/extract.c wiggle-0.6/extract.c
--- wiggle-0.6.orig/extract.c 2004-01-29 16:50:32.000000000 -0500
+++ wiggle-0.6/extract.c 2004-01-28 13:54:21.000000000 -0500
@@ -222,24 +222,30 @@
}
break;
case 1:
+ case 2:
+ /*
+ * diff3 sometimes skips the ||||||| line,
+ * so we have to expect the ======= to come at
+ * any time
+ */
if (len>=8 &&
strncmp(cp, "|||||||", 7)==0 &&
(cp[7] == ' ' || cp[7] == '\n')
) {
state = 2;
skip_eol(&cp, end);
- } else
- copyline(&r1, &cp, end);
- break;
- case 2:
- if (len>=8 &&
+ } else if (len>=8 &&
strncmp(cp, "=======", 7)==0 &&
(cp[7] == ' ' || cp[7] == '\n')
) {
state = 3;
skip_eol(&cp, end);
- } else
- copyline(&r2, &cp, end);
+ } else {
+ if (state == 1)
+ copyline(&r1, &cp, end);
+ else
+ copyline(&r2, &cp, end);
+ }
break;
case 3:
if (len>=8 &&
diff -ur wiggle-0.6.orig/merge.c wiggle-0.6/merge.c
--- wiggle-0.6.orig/merge.c 2003-05-19 00:58:26.000000000 -0400
+++ wiggle-0.6/merge.c 2004-01-29 16:51:35.000000000 -0500
@@ -422,6 +422,14 @@
if (c1[p->c1].len == 0 ||
a < c1[p->c1].a + c1[p->c1].len) {
p->in_a = 0;
+ /*
+ * if we've slid, make sure not to skip over
+ * the stuff in c2.
+ */
+ if(slid && p->c2 != -1 && c2[p->c2].a == b &&
+ c2[p->c2].b > c2[p->c2].a) {
+ c -= c2[p->c2].b - c2[p->c2].a;
+ }
p->pos = c;
slid = 1;
goto retry;