From 1cf3d5db9bd11514465d3692216211315f0dc82c Mon Sep 17 00:00:00 2001 From: Matthew Rogers Date: Thu, 20 Aug 2020 00:41:32 +0000 Subject: diff: teach --stat to ignore uninteresting modifications When options such as --ignore-space-change are in use, files with modifications can have no interesting textual changes worth showing. In such cases, "git diff --stat" shows 0 lines of additions and deletions. Teach "git diff --stat" not to show such a path in its output, which would be more natural. However, we don't want to prevent the display of all files that have 0 effective diffs since they could be the result of a rename, permission change, or other similar operation that may still be of interest so we special case additions and deletions as they are always interesting. Signed-off-by: Matthew Rogers Signed-off-by: Junio C Hamano --- diff.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index d24aaa3047..810c513995 100644 --- a/diff.c +++ b/diff.c @@ -3153,16 +3153,19 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o gather_dirstat(options, &dir, changed, "", 0); } +static void free_diffstat_file(struct diffstat_file *f) +{ + free(f->print_name); + free(f->name); + free(f->from_name); + free(f); +} + void free_diffstat_info(struct diffstat_t *diffstat) { int i; - for (i = 0; i < diffstat->nr; i++) { - struct diffstat_file *f = diffstat->files[i]; - free(f->print_name); - free(f->name); - free(f->from_name); - free(f); - } + for (i = 0; i < diffstat->nr; i++) + free_diffstat_file(diffstat->files[i]); free(diffstat->files); } @@ -3718,6 +3721,27 @@ static void builtin_diffstat(const char *name_a, const char *name_b, if (xdi_diff_outf(&mf1, &mf2, discard_hunk_line, diffstat_consume, diffstat, &xpp, &xecfg)) die("unable to generate diffstat for %s", one->path); + + if (DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two)) { + struct diffstat_file *file = + diffstat->files[diffstat->nr - 1]; + /* + * Omit diffstats of modified files where nothing changed. + * Even if !same_contents, this might be the case due to + * ignoring whitespace changes, etc. + * + * But note that we special-case additions, deletions, + * renames, and mode changes as adding an empty file, + * for example is still of interest. + */ + if ((p->status == DIFF_STATUS_MODIFIED) + && !file->added + && !file->deleted + && one->mode == two->mode) { + free_diffstat_file(file); + diffstat->nr--; + } + } } diff_free_filespec_data(one); -- cgit v1.2.1