]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Re(-re)*fix trim_common_tail()
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 Dec 2007 04:22:46 +0000 (20:22 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 Dec 2007 04:54:23 +0000 (20:54 -0800)
The tar-ball and the git archive itself is fine, but yes, the diff from
2.6.23 to 2.6.24-rc6 is bad. It's the "trim_common_tail()" optimization
that has caused way too much pain.

Very interesting breakage. The patch was actually "correct" in a (rather
limited) technical sense, but the context at the end was missing because
while the trim_common_tail() code made sure to keep enough common context
to allow a valid diff to be generated, the diff machinery itself could
decide that it could generate the diff differently than the "obvious"
solution.

Thee sad fact is that the git optimization (which is very important for
"git blame", which needs no context), is only really valid for that one
case where we really don't need any context.

[jc: since this is shared with "git diff -U0" codepath, context recovery
to the end of line needs to be done even for zero context case.]

Signed-off-by: Junio C Hamano <gitster@pobox.com>
xdiff-interface.c

index 9ee877c6f4d281ad86c8760aa9ee7b4289f647ac..4b8e5cca804198b0e227454a585fa025281bbe2d 100644 (file)
@@ -115,17 +115,20 @@ static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx)
        char *bp = b->ptr + b->size;
        long smaller = (a->size < b->size) ? a->size : b->size;
 
+       if (ctx)
+               return;
+
        while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) {
                trimmed += blk;
                ap -= blk;
                bp -= blk;
        }
 
-       while (recovered < trimmed && 0 <= ctx)
+       while (recovered < trimmed)
                if (ap[recovered++] == '\n')
-                       ctx--;
-       a->size -= (trimmed - recovered);
-       b->size -= (trimmed - recovered);
+                       break;
+       a->size -= trimmed - recovered;
+       b->size -= trimmed - recovered;
 }
 
 int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *xecb)