From: Linus Torvalds Date: Fri, 4 Dec 2009 20:07:47 +0000 (-0800) Subject: Fix diff -B/--dirstat miscounting of newly added contents X-Git-Tag: v1.6.5.5~1 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=77cd6ab62108c2d4ddd4343abd9bae17c406be4b;p=git.git Fix diff -B/--dirstat miscounting of newly added contents What used to happen is that diffcore_count_changes() simply ignored any hashes in the destination that didn't match hashes in the source. EXCEPT if the source hash didn't exist at all, in which case it would count _one_ destination hash that happened to have the "next" hash value. As a consequence, newly added material was often undercounted, making output from --dirstat and "complete rewrite" detection used by -B unrelialble. This changes it so that: - whenever it bypasses a destination hash (because it doesn't match a source), it counts the bytes associated with that as "literal added" - at the end (once we have used up all the source hashes), we do the same thing with the remaining destination hashes. - when hashes do match, and we use the difference in counts as a value, we also use up that destination hash entry (the 'd++'). Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- diff --git a/diffcore-delta.c b/diffcore-delta.c index e670f8512..7cf431d26 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -201,10 +201,15 @@ int diffcore_count_changes(struct diff_filespec *src, while (d->cnt) { if (d->hashval >= s->hashval) break; + la += d->cnt; d++; } src_cnt = s->cnt; - dst_cnt = d->hashval == s->hashval ? d->cnt : 0; + dst_cnt = 0; + if (d->cnt && d->hashval == s->hashval) { + dst_cnt = d->cnt; + d++; + } if (src_cnt < dst_cnt) { la += dst_cnt - src_cnt; sc += src_cnt; @@ -213,6 +218,10 @@ int diffcore_count_changes(struct diff_filespec *src, sc += dst_cnt; s++; } + while (d->cnt) { + la += d->cnt; + d++; + } if (!src_count_p) free(src_count);