Skip to content

Commit

Permalink
Fix diff -B/--dirstat miscounting of newly added contents
Browse files Browse the repository at this point in the history
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 <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Dec 5, 2009
1 parent 952dfc6 commit 77cd6ab
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion diffcore-delta.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit 77cd6ab

Please sign in to comment.