Merge branch 'lt/diff-stat-show-0-lines'

We failed to mention a file without any content change but whose
permission bit was modified, or (worse yet) a new file without any
content in the "git diff --stat" output.

* lt/diff-stat-show-0-lines:
  Fix "git diff --stat" for interesting - but empty - file changes
This commit is contained in:
Junio C Hamano 2012-11-25 18:44:06 -08:00
commit 76c39289ba
4 changed files with 42 additions and 36 deletions

25
diff.c
View File

@ -1309,6 +1309,7 @@ struct diffstat_t {
unsigned is_unmerged:1; unsigned is_unmerged:1;
unsigned is_binary:1; unsigned is_binary:1;
unsigned is_renamed:1; unsigned is_renamed:1;
unsigned is_interesting:1;
uintmax_t added, deleted; uintmax_t added, deleted;
} **files; } **files;
}; };
@ -1478,7 +1479,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = 0; (i < count) && (i < data->nr); i++) { for (i = 0; (i < count) && (i < data->nr); i++) {
struct diffstat_file *file = data->files[i]; struct diffstat_file *file = data->files[i];
uintmax_t change = file->added + file->deleted; uintmax_t change = file->added + file->deleted;
if (!data->files[i]->is_renamed && if (!data->files[i]->is_interesting &&
(change == 0)) { (change == 0)) {
count++; /* not shown == room for one more */ count++; /* not shown == room for one more */
continue; continue;
@ -1599,7 +1600,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
uintmax_t deleted = data->files[i]->deleted; uintmax_t deleted = data->files[i]->deleted;
int name_len; int name_len;
if (!data->files[i]->is_renamed && if (!data->files[i]->is_interesting &&
(added + deleted == 0)) { (added + deleted == 0)) {
total_files--; total_files--;
continue; continue;
@ -1678,7 +1679,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = count; i < data->nr; i++) { for (i = count; i < data->nr; i++) {
uintmax_t added = data->files[i]->added; uintmax_t added = data->files[i]->added;
uintmax_t deleted = data->files[i]->deleted; uintmax_t deleted = data->files[i]->deleted;
if (!data->files[i]->is_renamed && if (!data->files[i]->is_interesting &&
(added + deleted == 0)) { (added + deleted == 0)) {
total_files--; total_files--;
continue; continue;
@ -1706,7 +1707,7 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option
if (data->files[i]->is_unmerged) if (data->files[i]->is_unmerged)
continue; continue;
if (!data->files[i]->is_renamed && (added + deleted == 0)) { if (!data->files[i]->is_interesting && (added + deleted == 0)) {
total_files--; total_files--;
} else if (!data->files[i]->is_binary) { /* don't count bytes */ } else if (!data->files[i]->is_binary) { /* don't count bytes */
adds += added; adds += added;
@ -2406,13 +2407,20 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
struct diff_filespec *two, struct diff_filespec *two,
struct diffstat_t *diffstat, struct diffstat_t *diffstat,
struct diff_options *o, struct diff_options *o,
int complete_rewrite) struct diff_filepair *p)
{ {
mmfile_t mf1, mf2; mmfile_t mf1, mf2;
struct diffstat_file *data; struct diffstat_file *data;
int same_contents; int same_contents;
int complete_rewrite = 0;
if (!DIFF_PAIR_UNMERGED(p)) {
if (p->status == DIFF_STATUS_MODIFIED && p->score)
complete_rewrite = 1;
}
data = diffstat_add(diffstat, name_a, name_b); data = diffstat_add(diffstat, name_a, name_b);
data->is_interesting = p->status != 0;
if (!one || !two) { if (!one || !two) {
data->is_unmerged = 1; data->is_unmerged = 1;
@ -3123,11 +3131,10 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
{ {
const char *name; const char *name;
const char *other; const char *other;
int complete_rewrite = 0;
if (DIFF_PAIR_UNMERGED(p)) { if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */ /* unmerged */
builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0); builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p);
return; return;
} }
@ -3140,9 +3147,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
diff_fill_sha1_info(p->one); diff_fill_sha1_info(p->one);
diff_fill_sha1_info(p->two); diff_fill_sha1_info(p->two);
if (p->status == DIFF_STATUS_MODIFIED && p->score) builtin_diffstat(name, other, p->one, p->two, diffstat, o, p);
complete_rewrite = 1;
builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
} }
static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)

View File

@ -32,28 +32,28 @@ test_expect_success 'prepare binary file' '
git commit -m binbin git commit -m binbin
' '
test_expect_success '--stat output after text chmod' ' # test_expect_success '--stat output after text chmod' '
test_chmod -x rezrov && # test_chmod -x rezrov &&
echo " 0 files changed" >expect && # echo " 0 files changed" >expect &&
git diff HEAD --stat >actual && # git diff HEAD --stat >actual &&
test_i18ncmp expect actual # test_i18ncmp expect actual
' # '
#
test_expect_success '--shortstat output after text chmod' ' # test_expect_success '--shortstat output after text chmod' '
git diff HEAD --shortstat >actual && # git diff HEAD --shortstat >actual &&
test_i18ncmp expect actual # test_i18ncmp expect actual
' # '
#
test_expect_success '--stat output after binary chmod' ' # test_expect_success '--stat output after binary chmod' '
test_chmod +x binbin && # test_chmod +x binbin &&
echo " 0 files changed" >expect && # echo " 0 files changed" >expect &&
git diff HEAD --stat >actual && # git diff HEAD --stat >actual &&
test_i18ncmp expect actual # test_i18ncmp expect actual
' # '
#
test_expect_success '--shortstat output after binary chmod' ' # test_expect_success '--shortstat output after binary chmod' '
git diff HEAD --shortstat >actual && # git diff HEAD --shortstat >actual &&
test_i18ncmp expect actual # test_i18ncmp expect actual
' # '
test_done test_done

View File

@ -16,7 +16,8 @@ test_expect_success setup '
cat >expect <<-\EOF cat >expect <<-\EOF
a | 1 + a | 1 +
b | 1 + b | 1 +
2 files changed, 2 insertions(+) ...
4 files changed, 2 insertions(+)
EOF EOF
git diff --stat --stat-count=2 >actual && git diff --stat --stat-count=2 >actual &&
test_i18ncmp expect actual test_i18ncmp expect actual

View File

@ -85,7 +85,7 @@ test_expect_success 'NUL termination' '
test_expect_success 'NUL separation with --stat' ' test_expect_success 'NUL separation with --stat' '
stat0_part=$(git diff --stat HEAD^ HEAD) && stat0_part=$(git diff --stat HEAD^ HEAD) &&
stat1_part=$(git diff --stat --root HEAD^) && stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n" >expected && printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n" >expected &&
git log -z --stat --pretty="format:%s" >actual && git log -z --stat --pretty="format:%s" >actual &&
test_i18ncmp expected actual test_i18ncmp expected actual
@ -93,7 +93,7 @@ test_expect_success 'NUL separation with --stat' '
test_expect_failure 'NUL termination with --stat' ' test_expect_failure 'NUL termination with --stat' '
stat0_part=$(git diff --stat HEAD^ HEAD) && stat0_part=$(git diff --stat HEAD^ HEAD) &&
stat1_part=$(git diff --stat --root HEAD^) && stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n\0" >expected && printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n\0" >expected &&
git log -z --stat --pretty="tformat:%s" >actual && git log -z --stat --pretty="tformat:%s" >actual &&
test_i18ncmp expected actual test_i18ncmp expected actual