]> git.neil.brown.name Git - wiggle.git/commitdiff
csl_join should merge adjacent matches.
authorNeilBrown <neilb@suse.de>
Fri, 22 Mar 2013 04:04:48 +0000 (15:04 +1100)
committerNeilBrown <neilb@suse.de>
Fri, 22 Mar 2013 04:04:48 +0000 (15:04 +1100)
When diffing against a patch we treat each hunk separately
and join the result.
This joining doesn't merge adjacent matches so it doesn't really
tell the full story of where the matches are and how big
they are.  This can confuse other code, particularly when
examining hunk headers to create the merger.

So add detection for adjacent matches.

Signed-off-by: NeilBrown <neilb@suse.de>
diff.c

diff --git a/diff.c b/diff.c
index 5eba75a4260582d23b73b03f4bd311a6e275a532..1c3d65600ae1a1445bf848c41e9fa4d043080ed4 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -580,6 +580,7 @@ struct csl *diff_partial(struct file a, struct file b,
 struct csl *csl_join(struct csl *c1, struct csl *c2)
 {
        int cnt1, cnt2;
+       int offset = 0;
        if (c1 == NULL)
                return c2;
        if (c2 == NULL)
@@ -589,9 +590,17 @@ struct csl *csl_join(struct csl *c1, struct csl *c2)
                ;
        for (cnt2 = 0; c2[cnt2].len; cnt2++)
                ;
+       if (cnt1 && cnt2 &&
+           c1[cnt1-1].a + c1[cnt1-1].len == c2[0].a &&
+           c1[cnt1-1].b + c1[cnt1-1].len == c2[0].b) {
+               /* Merge these two */
+               c1[cnt1-1].len += c2[0].len;
+               offset = 1;
+               cnt2--;
+       }
        c1 = realloc(c1, (cnt1+cnt2+1)*sizeof(*c1));
        while (cnt2 >= 0) {
-               c1[cnt1+cnt2] = c2[cnt2];
+               c1[cnt1+cnt2] = c2[cnt2 + offset];
                cnt2--;
        }
        free(c2);