summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2007-12-20 20:22:46 -0800
committerJunio C Hamano <gitster@pobox.com>2007-12-20 20:54:23 -0800
commitd2f82950a9226ae1102a7a97f03440a4bf8c6c09 (patch)
treef93cf439b0d6de5cc258c20ff6152e9746773f36
parentd76a585d83aeb6910e7eb10d36b406dc27202675 (diff)
downloadgit-d2f82950a9226ae1102a7a97f03440a4bf8c6c09.tar.gz
Re(-re)*fix trim_common_tail()
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>
-rw-r--r--xdiff-interface.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 9ee877c6f4..4b8e5cca80 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -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)