Only skip diffstats when both oids are valid and identical. This check was causing both false-positives (files included in diffstats with no actual changes (0 lines modified) and false-negatives (showing 0 lines modified in stats when files had actually changed). Also renamed same_contents to same_file to avoid confusion. Signed-off-by: Thomas Guyot-Sionnest <tguyot@xxxxxxxxx> --- Interdiff: diff --git a/diff.c b/diff.c index 2e47bf824e..77e0bd772e 100644 --- a/diff.c +++ b/diff.c @@ -3663,7 +3663,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, { mmfile_t mf1, mf2; struct diffstat_file *data; - int same_contents; + int same_file; int complete_rewrite = 0; if (!DIFF_PAIR_UNMERGED(p)) { @@ -3681,19 +3681,14 @@ static void builtin_diffstat(const char *name_a, const char *name_b, return; } - /* What is_stdin really means is that the file's content is only - * in the filespec's buffer and its oid is zero. We can't compare - * oid's if both are null and we can just diff the buffers */ - if (one->is_stdin && two->is_stdin) - same_contents = (one->size == two->size ? - !memcmp(one->data, two->data, one->size) : 0); - else - same_contents = oideq(&one->oid, &two->oid); + /* saves some reads if true, not a guarantee of diff outcome */ + same_file = one->oid_valid && two->oid_valid && + oideq(&one->oid, &two->oid); if (diff_filespec_is_binary(o->repo, one) || diff_filespec_is_binary(o->repo, two)) { data->is_binary = 1; - if (same_contents) { + if (same_file) { data->added = 0; data->deleted = 0; } else { @@ -3709,7 +3704,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, data->added = count_lines(two->data, two->size); } - else if (!same_contents) { + else if (!same_file) { /* Crazy xdl interfaces.. */ xpparam_t xpp; xdemitconf_t xecfg; @@ -3734,7 +3729,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, diffstat->files[diffstat->nr - 1]; /* * Omit diffstats of modified files where nothing changed. - * Even if !same_contents, this might be the case due to + * Even if !same_file, this might be the case due to * ignoring whitespace changes, etc. * * But note that we special-case additions, deletions, diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 4715e75b68..6eb344be03 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -252,11 +252,7 @@ test_expect_success 'changed commit with --stat diff option' ' git range-diff --no-color --stat topic...changed >actual && cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ a => b | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff.c | 12 +++++++----- t/t3206-range-diff.sh | 12 ++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/diff.c b/diff.c index ee8e8189e9..77e0bd772e 100644 --- a/diff.c +++ b/diff.c @@ -3663,7 +3663,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, { mmfile_t mf1, mf2; struct diffstat_file *data; - int same_contents; + int same_file; int complete_rewrite = 0; if (!DIFF_PAIR_UNMERGED(p)) { @@ -3681,12 +3681,14 @@ static void builtin_diffstat(const char *name_a, const char *name_b, return; } - same_contents = oideq(&one->oid, &two->oid); + /* saves some reads if true, not a guarantee of diff outcome */ + same_file = one->oid_valid && two->oid_valid && + oideq(&one->oid, &two->oid); if (diff_filespec_is_binary(o->repo, one) || diff_filespec_is_binary(o->repo, two)) { data->is_binary = 1; - if (same_contents) { + if (same_file) { data->added = 0; data->deleted = 0; } else { @@ -3702,7 +3704,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, data->added = count_lines(two->data, two->size); } - else if (!same_contents) { + else if (!same_file) { /* Crazy xdl interfaces.. */ xpparam_t xpp; xdemitconf_t xecfg; @@ -3727,7 +3729,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, diffstat->files[diffstat->nr - 1]; /* * Omit diffstats of modified files where nothing changed. - * Even if !same_contents, this might be the case due to + * Even if !same_file, this might be the case due to * ignoring whitespace changes, etc. * * But note that we special-case additions, deletions, diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index e024cff65c..6eb344be03 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -252,17 +252,13 @@ test_expect_success 'changed commit with --stat diff option' ' git range-diff --no-color --stat topic...changed >actual && cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) + a => b | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/ - a => b | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) + a => b | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) EOF test_cmp expect actual ' -- 2.20.1