Skip to content

Commit 868f7d2

Browse files
committed
Merge branch 'nd/diff-stat-with-summary'
"git diff" and friends learned "--compact-summary" that shows the information usually given with the "--summary" option on the same line as the diffstat output of the "--stat" option (which saves vertical space and keeps info on a single path at the same place). * nd/diff-stat-with-summary: diff: add --compact-summary diff.c: refactor pprint_rename() to use strbuf
2 parents d0db9ed + ddf88fa commit 868f7d2

8 files changed

+109
-33
lines changed

Documentation/diff-options.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ have to use `--diff-algorithm=default` option.
128128
These parameters can also be set individually with `--stat-width=<width>`,
129129
`--stat-name-width=<name-width>` and `--stat-count=<count>`.
130130

131+
--compact-summary::
132+
Output a condensed summary of extended header information such
133+
as file creations or deletions ("new" or "gone", optionally "+l"
134+
if it's a symlink) and mode changes ("+x" or "-x" for adding
135+
or removing executable bit respectively) in diffstat. The
136+
information is put betwen the filename part and the graph
137+
part. Implies `--stat`.
138+
131139
--numstat::
132140
Similar to `--stat`, but shows number of added and
133141
deleted lines in decimal notation and pathname without

diff.c

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,11 +2045,10 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
20452045
}
20462046
}
20472047

2048-
static char *pprint_rename(const char *a, const char *b)
2048+
static void pprint_rename(struct strbuf *name, const char *a, const char *b)
20492049
{
20502050
const char *old_name = a;
20512051
const char *new_name = b;
2052-
struct strbuf name = STRBUF_INIT;
20532052
int pfx_length, sfx_length;
20542053
int pfx_adjust_for_slash;
20552054
int len_a = strlen(a);
@@ -2059,10 +2058,10 @@ static char *pprint_rename(const char *a, const char *b)
20592058
int qlen_b = quote_c_style(b, NULL, NULL, 0);
20602059

20612060
if (qlen_a || qlen_b) {
2062-
quote_c_style(a, &name, NULL, 0);
2063-
strbuf_addstr(&name, " => ");
2064-
quote_c_style(b, &name, NULL, 0);
2065-
return strbuf_detach(&name, NULL);
2061+
quote_c_style(a, name, NULL, 0);
2062+
strbuf_addstr(name, " => ");
2063+
quote_c_style(b, name, NULL, 0);
2064+
return;
20662065
}
20672066

20682067
/* Find common prefix */
@@ -2109,19 +2108,18 @@ static char *pprint_rename(const char *a, const char *b)
21092108
if (b_midlen < 0)
21102109
b_midlen = 0;
21112110

2112-
strbuf_grow(&name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
2111+
strbuf_grow(name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
21132112
if (pfx_length + sfx_length) {
2114-
strbuf_add(&name, a, pfx_length);
2115-
strbuf_addch(&name, '{');
2113+
strbuf_add(name, a, pfx_length);
2114+
strbuf_addch(name, '{');
21162115
}
2117-
strbuf_add(&name, a + pfx_length, a_midlen);
2118-
strbuf_addstr(&name, " => ");
2119-
strbuf_add(&name, b + pfx_length, b_midlen);
2116+
strbuf_add(name, a + pfx_length, a_midlen);
2117+
strbuf_addstr(name, " => ");
2118+
strbuf_add(name, b + pfx_length, b_midlen);
21202119
if (pfx_length + sfx_length) {
2121-
strbuf_addch(&name, '}');
2122-
strbuf_add(&name, a + len_a - sfx_length, sfx_length);
2120+
strbuf_addch(name, '}');
2121+
strbuf_add(name, a + len_a - sfx_length, sfx_length);
21232122
}
2124-
return strbuf_detach(&name, NULL);
21252123
}
21262124

21272125
struct diffstat_t {
@@ -2131,6 +2129,7 @@ struct diffstat_t {
21312129
char *from_name;
21322130
char *name;
21332131
char *print_name;
2132+
const char *comments;
21342133
unsigned is_unmerged:1;
21352134
unsigned is_binary:1;
21362135
unsigned is_renamed:1;
@@ -2197,23 +2196,20 @@ static void show_graph(struct strbuf *out, char ch, int cnt,
21972196

21982197
static void fill_print_name(struct diffstat_file *file)
21992198
{
2200-
char *pname;
2199+
struct strbuf pname = STRBUF_INIT;
22012200

22022201
if (file->print_name)
22032202
return;
22042203

2205-
if (!file->is_renamed) {
2206-
struct strbuf buf = STRBUF_INIT;
2207-
if (quote_c_style(file->name, &buf, NULL, 0)) {
2208-
pname = strbuf_detach(&buf, NULL);
2209-
} else {
2210-
pname = file->name;
2211-
strbuf_release(&buf);
2212-
}
2213-
} else {
2214-
pname = pprint_rename(file->from_name, file->name);
2215-
}
2216-
file->print_name = pname;
2204+
if (file->is_renamed)
2205+
pprint_rename(&pname, file->from_name, file->name);
2206+
else
2207+
quote_c_style(file->name, &pname, NULL, 0);
2208+
2209+
if (file->comments)
2210+
strbuf_addf(&pname, " (%s)", file->comments);
2211+
2212+
file->print_name = strbuf_detach(&pname, NULL);
22172213
}
22182214

22192215
static void print_stat_summary_inserts_deletes(struct diff_options *options,
@@ -2797,8 +2793,7 @@ static void free_diffstat_info(struct diffstat_t *diffstat)
27972793
int i;
27982794
for (i = 0; i < diffstat->nr; i++) {
27992795
struct diffstat_file *f = diffstat->files[i];
2800-
if (f->name != f->print_name)
2801-
free(f->print_name);
2796+
free(f->print_name);
28022797
free(f->name);
28032798
free(f->from_name);
28042799
free(f);
@@ -3248,6 +3243,32 @@ static void builtin_diff(const char *name_a,
32483243
return;
32493244
}
32503245

3246+
static char *get_compact_summary(const struct diff_filepair *p, int is_renamed)
3247+
{
3248+
if (!is_renamed) {
3249+
if (p->status == DIFF_STATUS_ADDED) {
3250+
if (S_ISLNK(p->two->mode))
3251+
return "new +l";
3252+
else if ((p->two->mode & 0777) == 0755)
3253+
return "new +x";
3254+
else
3255+
return "new";
3256+
} else if (p->status == DIFF_STATUS_DELETED)
3257+
return "gone";
3258+
}
3259+
if (S_ISLNK(p->one->mode) && !S_ISLNK(p->two->mode))
3260+
return "mode -l";
3261+
else if (!S_ISLNK(p->one->mode) && S_ISLNK(p->two->mode))
3262+
return "mode +l";
3263+
else if ((p->one->mode & 0777) == 0644 &&
3264+
(p->two->mode & 0777) == 0755)
3265+
return "mode +x";
3266+
else if ((p->one->mode & 0777) == 0755 &&
3267+
(p->two->mode & 0777) == 0644)
3268+
return "mode -x";
3269+
return NULL;
3270+
}
3271+
32513272
static void builtin_diffstat(const char *name_a, const char *name_b,
32523273
struct diff_filespec *one,
32533274
struct diff_filespec *two,
@@ -3267,6 +3288,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
32673288

32683289
data = diffstat_add(diffstat, name_a, name_b);
32693290
data->is_interesting = p->status != DIFF_STATUS_UNKNOWN;
3291+
if (o->flags.stat_with_summary)
3292+
data->comments = get_compact_summary(p, data->is_renamed);
32703293

32713294
if (!one || !two) {
32723295
data->is_unmerged = 1;
@@ -4553,6 +4576,11 @@ int diff_opt_parse(struct diff_options *options,
45534576
else if (starts_with(arg, "--stat"))
45544577
/* --stat, --stat-width, --stat-name-width, or --stat-count */
45554578
return stat_opt(options, av);
4579+
else if (!strcmp(arg, "--compact-summary")) {
4580+
options->flags.stat_with_summary = 1;
4581+
options->output_format |= DIFF_FORMAT_DIFFSTAT;
4582+
} else if (!strcmp(arg, "--no-compact-summary"))
4583+
options->flags.stat_with_summary = 0;
45564584

45574585
/* renames options */
45584586
else if (starts_with(arg, "-B") ||
@@ -5241,10 +5269,12 @@ static void show_rename_copy(struct diff_options *opt, const char *renamecopy,
52415269
struct diff_filepair *p)
52425270
{
52435271
struct strbuf sb = STRBUF_INIT;
5244-
char *names = pprint_rename(p->one->path, p->two->path);
5272+
struct strbuf names = STRBUF_INIT;
5273+
5274+
pprint_rename(&names, p->one->path, p->two->path);
52455275
strbuf_addf(&sb, " %s %s (%d%%)\n",
5246-
renamecopy, names, similarity_index(p));
5247-
free(names);
5276+
renamecopy, names.buf, similarity_index(p));
5277+
strbuf_release(&names);
52485278
emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
52495279
sb.buf, sb.len, 0);
52505280
show_mode_change(opt, p, 0);

diff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct diff_flags {
9393
unsigned dirstat_by_line:1;
9494
unsigned funccontext:1;
9595
unsigned default_follow_renames:1;
96+
unsigned stat_with_summary:1;
9697
};
9798

9899
static inline void diff_flags_or(struct diff_flags *a,

t/t4013-diff-various.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ diff --no-index --raw dir2 dir
361361
diff --no-index --raw --abbrev=4 dir2 dir
362362
:noellipses diff --no-index --raw --abbrev=4 dir2 dir
363363
diff --no-index --raw --no-abbrev dir2 dir
364+
365+
diff-tree --pretty --root --stat --compact-summary initial
366+
diff-tree --pretty -R --root --stat --compact-summary initial
367+
diff-tree --stat --compact-summary initial mode
368+
diff-tree -R --stat --compact-summary initial mode
364369
EOF
365370

366371
test_expect_success 'log -S requires an argument' '
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
$ git diff-tree --pretty --root --stat --compact-summary initial
2+
commit 444ac553ac7612cc88969031b02b3767fb8a353a
3+
Author: A U Thor <[email protected]>
4+
Date: Mon Jun 26 00:00:00 2006 +0000
5+
6+
Initial
7+
8+
dir/sub (new) | 2 ++
9+
file0 (new) | 3 +++
10+
file2 (new) | 3 +++
11+
3 files changed, 8 insertions(+)
12+
$
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
$ git diff-tree --pretty -R --root --stat --compact-summary initial
2+
commit 444ac553ac7612cc88969031b02b3767fb8a353a
3+
Author: A U Thor <[email protected]>
4+
Date: Mon Jun 26 00:00:00 2006 +0000
5+
6+
Initial
7+
8+
dir/sub (gone) | 2 --
9+
file0 (gone) | 3 ---
10+
file2 (gone) | 3 ---
11+
3 files changed, 8 deletions(-)
12+
$
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$ git diff-tree --stat --compact-summary initial mode
2+
file0 (mode +x) | 0
3+
1 file changed, 0 insertions(+), 0 deletions(-)
4+
$
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$ git diff-tree -R --stat --compact-summary initial mode
2+
file0 (mode -x) | 0
3+
1 file changed, 0 insertions(+), 0 deletions(-)
4+
$

0 commit comments

Comments
 (0)