* Fix "git diff --stat" for interesting - but empty - file changes
@ 2012-10-17 17:00 Linus Torvalds
2012-10-17 18:28 ` Junio C Hamano
0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2012-10-17 17:00 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
[-- Attachment #1: Type: text/plain, Size: 2306 bytes --]
The behavior of "git diff --stat" is rather odd for files that have
zero lines of changes: it will discount them entirely unless they were
renames.
Which means that the stat output will simply not show files that only
had "other" changes: they were created or deleted, or their mode was
changed.
Now, those changes do show up in the summary, but so do renames, so
the diffstat logic is inconsistent. Why does it show renames with zero
lines changed, but not mode changes or added files with zero lines
changed?
So change the logic to not check for "is_renamed", but for
"is_interesting" instead, where "interesting" is judged to be any
action but a pure data change (because a pure data change with zero
data changed really isn't worth showing, if we ever get one in our
diffpairs).
So if you did
chmod +x Makefile
git diff --stat
before, it would show empty (" 0 files changed"), with this it shows
Makefile | 0
1 file changed, 0 insertions(+), 0 deletions(-)
which I think is a more correct diffstat (and then with "--summary" it
shows *what* the metadata change to Makefile was - this is completely
consistent with our handling of renamed files).
Side note: the old behavior was *really* odd. With no changes at all,
"git diff --stat" output was empty. With just a chmod, it said "0
files changed". No way is our legacy behavior sane.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This was triggered by kernel developers not noticing that they had
added zero-sized files, because those additions never showed up in the
diffstat.
NOTE! This does break two of our tests, so we clearly did this on
purpose, or at least tested for it. I just uncommented the subtests
that this makes irrelevant, and changed the output of another one.
Another test was simply buggy. It used "git diff --root cmit", and
thought that would be the diff against root. It isn't, and never has
been. It just happened to give the same (no file) output before.
Fixing --stat to show new files showed how buggy the test was. The
"--root" thing matters for "git show" or "git log" (when showing a
root commit) and for "git diff-tree" with a single tree.
Maybe we would *want* to make "git diff --root <cmit>" be the "diff
between root and cmit", but that's not what it actually is.
Comments?
[-- Attachment #2: patch.diff --]
[-- Type: application/octet-stream, Size: 6596 bytes --]
diff.c | 25 +++++++++++++----------
t/t4006-diff-mode.sh | 46 +++++++++++++++++++++----------------------
t/t4049-diff-stat-count.sh | 3 ++-
t/t4205-log-pretty-formats.sh | 4 ++--
4 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/diff.c b/diff.c
index 35d3f073859a..95bbad66c686 100644
--- a/diff.c
+++ b/diff.c
@@ -1300,6 +1300,7 @@ struct diffstat_t {
unsigned is_unmerged:1;
unsigned is_binary:1;
unsigned is_renamed:1;
+ unsigned is_interesting:1;
uintmax_t added, deleted;
} **files;
};
@@ -1469,7 +1470,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = 0; (i < count) && (i < data->nr); i++) {
struct diffstat_file *file = data->files[i];
uintmax_t change = file->added + file->deleted;
- if (!data->files[i]->is_renamed &&
+ if (!data->files[i]->is_interesting &&
(change == 0)) {
count++; /* not shown == room for one more */
continue;
@@ -1590,7 +1591,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
uintmax_t deleted = data->files[i]->deleted;
int name_len;
- if (!data->files[i]->is_renamed &&
+ if (!data->files[i]->is_interesting &&
(added + deleted == 0)) {
total_files--;
continue;
@@ -1669,7 +1670,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
for (i = count; i < data->nr; i++) {
uintmax_t added = data->files[i]->added;
uintmax_t deleted = data->files[i]->deleted;
- if (!data->files[i]->is_renamed &&
+ if (!data->files[i]->is_interesting &&
(added + deleted == 0)) {
total_files--;
continue;
@@ -1697,7 +1698,7 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option
if (data->files[i]->is_unmerged)
continue;
- if (!data->files[i]->is_renamed && (added + deleted == 0)) {
+ if (!data->files[i]->is_interesting && (added + deleted == 0)) {
total_files--;
} else if (!data->files[i]->is_binary) { /* don't count bytes */
adds += added;
@@ -2397,13 +2398,20 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
struct diff_filespec *two,
struct diffstat_t *diffstat,
struct diff_options *o,
- int complete_rewrite)
+ struct diff_filepair *p)
{
mmfile_t mf1, mf2;
struct diffstat_file *data;
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->is_interesting = p->status != 0;
if (!one || !two) {
data->is_unmerged = 1;
@@ -3114,11 +3122,10 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
{
const char *name;
const char *other;
- int complete_rewrite = 0;
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
- builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0);
+ builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p);
return;
}
@@ -3131,9 +3138,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
diff_fill_sha1_info(p->one);
diff_fill_sha1_info(p->two);
- if (p->status == DIFF_STATUS_MODIFIED && p->score)
- complete_rewrite = 1;
- builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
+ builtin_diffstat(name, other, p->one, p->two, diffstat, o, p);
}
static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index 3d4b1ba23f9e..05911492ca6d 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -32,28 +32,28 @@ test_expect_success 'prepare binary file' '
git commit -m binbin
'
-test_expect_success '--stat output after text chmod' '
- test_chmod -x rezrov &&
- echo " 0 files changed" >expect &&
- git diff HEAD --stat >actual &&
- test_i18ncmp expect actual
-'
-
-test_expect_success '--shortstat output after text chmod' '
- git diff HEAD --shortstat >actual &&
- test_i18ncmp expect actual
-'
-
-test_expect_success '--stat output after binary chmod' '
- test_chmod +x binbin &&
- echo " 0 files changed" >expect &&
- git diff HEAD --stat >actual &&
- test_i18ncmp expect actual
-'
-
-test_expect_success '--shortstat output after binary chmod' '
- git diff HEAD --shortstat >actual &&
- test_i18ncmp expect actual
-'
+# test_expect_success '--stat output after text chmod' '
+# test_chmod -x rezrov &&
+# echo " 0 files changed" >expect &&
+# git diff HEAD --stat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--shortstat output after text chmod' '
+# git diff HEAD --shortstat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--stat output after binary chmod' '
+# test_chmod +x binbin &&
+# echo " 0 files changed" >expect &&
+# git diff HEAD --stat >actual &&
+# test_i18ncmp expect actual
+# '
+#
+# test_expect_success '--shortstat output after binary chmod' '
+# git diff HEAD --shortstat >actual &&
+# test_i18ncmp expect actual
+# '
test_done
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index b41eb61ca8b1..7b3ef00533f7 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -16,7 +16,8 @@ test_expect_success setup '
cat >expect <<-\EOF
a | 1 +
b | 1 +
- 2 files changed, 2 insertions(+)
+ ...
+ 4 files changed, 2 insertions(+)
EOF
git diff --stat --stat-count=2 >actual &&
test_i18ncmp expect actual
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 2c45de7aeaf2..98a43d457a3d 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -85,7 +85,7 @@ test_expect_success 'NUL termination' '
test_expect_success 'NUL separation with --stat' '
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 &&
git log -z --stat --pretty="format:%s" >actual &&
test_i18ncmp expected actual
@@ -93,7 +93,7 @@ test_expect_success 'NUL separation with --stat' '
test_expect_failure 'NUL termination with --stat' '
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 &&
git log -z --stat --pretty="tformat:%s" >actual &&
test_i18ncmp expected actual
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Fix "git diff --stat" for interesting - but empty - file changes
2012-10-17 17:00 Fix "git diff --stat" for interesting - but empty - file changes Linus Torvalds
@ 2012-10-17 18:28 ` Junio C Hamano
2012-10-17 19:35 ` Linus Torvalds
0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2012-10-17 18:28 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds <torvalds@linux-foundation.org> writes:
> So if you did
>
> chmod +x Makefile
> git diff --stat
>
> before, it would show empty (" 0 files changed"), with this it shows
>
> Makefile | 0
> 1 file changed, 0 insertions(+), 0 deletions(-)
>
> which I think is a more correct diffstat (and then with "--summary" it
> shows *what* the metadata change to Makefile was - this is completely
> consistent with our handling of renamed files).
>
> Side note: the old behavior was *really* odd. With no changes at all,
> "git diff --stat" output was empty. With just a chmod, it said "0
> files changed". No way is our legacy behavior sane.
>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> ---
>
> This was triggered by kernel developers not noticing that they had
> added zero-sized files, because those additions never showed up in the
> diffstat.
> ...
> Comments?
I think listing a file whose content remain unchanged with 0 as the
number of lines affected makes sense, and it will mesh well with
Duy's
http://thread.gmane.org/gmane.comp.version-control.git/207749
I first wondered if we would get a division-by-zero while scaling
the graph, but we do not scale smaller numbers up to fill the
columns, so we should be safe.
These days, we omit 0 insertions and 0 deletions, so I am not sure
what you should get for this case, though:
> Makefile | 0
> 1 file changed, 0 insertions(+), 0 deletions(-)
Should we just say "1 file changed"?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Fix "git diff --stat" for interesting - but empty - file changes
2012-10-17 18:28 ` Junio C Hamano
@ 2012-10-17 19:35 ` Linus Torvalds
0 siblings, 0 replies; 3+ messages in thread
From: Linus Torvalds @ 2012-10-17 19:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On Wed, Oct 17, 2012 at 11:28 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> I think listing a file whose content remain unchanged with 0 as the
> number of lines affected makes sense, and it will mesh well with
> Duy's
>
> http://thread.gmane.org/gmane.comp.version-control.git/207749
>
> I first wondered if we would get a division-by-zero while scaling
> the graph, but we do not scale smaller numbers up to fill the
> columns, so we should be safe.
Note that we should be safe for a totally different - and more
fundamental - reason: the zero line case is by no means new. We've
always done it for the rename case.
> These days, we omit 0 insertions and 0 deletions, so I am not sure
> what you should get for this case, though:
>
>> Makefile | 0
>> 1 file changed, 0 insertions(+), 0 deletions(-)
>
> Should we just say "1 file changed"?
If that is what it does for the rename case, then yes. I think it
should fall out naturally.
Linus
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-10-17 19:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-17 17:00 Fix "git diff --stat" for interesting - but empty - file changes Linus Torvalds
2012-10-17 18:28 ` Junio C Hamano
2012-10-17 19:35 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).