diff --stat: add config option to limit filename width

Add new configuration option diff.statNameWidth=<width> that is equivalent to the command-line option --stat-name-width=<width>, but it is ignored by format-patch. This follows the logic established by the already existing configuration option diff.statGraphWidth=<width>. Limiting the widths of names and graphs in the --stat output makes sense for interactive work on wide terminals with many columns, hence the support for these configuration options. They don't affect format-patch because it already adheres to the traditional 80-column standard. Update the documentation and add more tests to cover new configuration option diff.statNameWidth=<width>. While there, perform a few minor code and whitespace cleanups here and there, as spotted. Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Dragan Simic committed Sep 11, 2023 at 17:39 UTC bd48adc31d0522e7877aa494ce7df91581e09587
9 files changed +60 -18
Documentation/config/diff.txt
+4
@@ -52,6 +52,10 @@ directories with less than 10% of the total amount of changed files,
52 and accumulating child directory counts in the parent directories:
53 `files,10,cumulative`.
54
55 +diff.statNameWidth::
56 + Limit the width of the filename part in --stat output. If set, applies
57 + to all commands generating --stat output except format-patch.
58 +
59 diff.statGraphWidth::
60 Limit the width of the graph part in --stat output. If set, applies
61 to all commands generating --stat output except format-patch.
Documentation/diff-options.txt
+9 -8
@@ -204,14 +204,15 @@ have to use `--diff-algorithm=default` option.
204 part. Maximum width defaults to terminal width, or 80 columns
205 if not connected to a terminal, and can be overridden by
206 `<width>`. The width of the filename part can be limited by
207 - giving another width `<name-width>` after a comma. The width
208 - of the graph part can be limited by using
209 - `--stat-graph-width=<width>` (affects all commands generating
210 - a stat graph) or by setting `diff.statGraphWidth=<width>`
211 - (does not affect `git format-patch`).
212 - By giving a third parameter `<count>`, you can limit the
213 - output to the first `<count>` lines, followed by `...` if
214 - there are more.
207 + giving another width `<name-width>` after a comma or by setting
208 + `diff.statNameWidth=<width>`. The width of the graph part can be
209 + limited by using `--stat-graph-width=<width>` or by setting
210 + `diff.statGraphWidth=<width>`. Using `--stat` or
211 + `--stat-graph-width` affects all commands generating a stat graph,
212 + while setting `diff.statNameWidth` or `diff.statGraphWidth`
213 + does not affect `git format-patch`.
214 + By giving a third parameter `<count>`, you can limit the output to
215 + the first `<count>` lines, followed by `...` if there are more.
216 +
217 These parameters can also be set individually with `--stat-width=<width>`,
218 `--stat-name-width=<name-width>` and `--stat-count=<count>`.
builtin/diff.c
+1
@@ -475,6 +475,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
475
476 /* Set up defaults that will apply to both no-index and regular diffs. */
477 rev.diffopt.stat_width = -1;
478 + rev.diffopt.stat_name_width = -1;
479 rev.diffopt.stat_graph_width = -1;
480 rev.diffopt.flags.allow_external = 1;
481 rev.diffopt.flags.allow_textconv = 1;
builtin/log.c
+1
@@ -178,6 +178,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
178 rev->verbose_header = 1;
179 rev->diffopt.flags.recursive = 1;
180 rev->diffopt.stat_width = -1; /* use full terminal width */
181 + rev->diffopt.stat_name_width = -1; /* respect statNameWidth config */
182 rev->diffopt.stat_graph_width = -1; /* respect statGraphWidth config */
183 rev->abbrev_commit = default_abbrev_commit;
184 rev->show_root_diff = default_show_root;
builtin/merge.c
+1
@@ -467,6 +467,7 @@ static void finish(struct commit *head_commit,
467 struct diff_options opts;
468 repo_diff_setup(the_repository, &opts);
469 opts.stat_width = -1; /* use full terminal width */
470 + opts.stat_name_width = -1; /* respect statNameWidth config */
471 opts.stat_graph_width = -1; /* respect statGraphWidth config */
472 opts.output_format |=
473 DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
builtin/rebase.c
+1
@@ -1804,6 +1804,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1804 /* We want color (if set), but no pager */
1805 repo_diff_setup(the_repository, &opts);
1806 opts.stat_width = -1; /* use full terminal width */
1807 + opts.stat_name_width = -1; /* respect statNameWidth config */
1808 opts.stat_graph_width = -1; /* respect statGraphWidth config */
1809 opts.output_format |=
1810 DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
diff.c
+9 -2
@@ -65,6 +65,7 @@ int diff_auto_refresh_index = 1;
65 static int diff_mnemonic_prefix;
66 static int diff_no_prefix;
67 static int diff_relative;
68 +static int diff_stat_name_width;
69 static int diff_stat_graph_width;
70 static int diff_dirstat_permille_default = 30;
71 static struct diff_options default_diff_options;
@@ -410,6 +411,10 @@ int git_diff_ui_config(const char *var, const char *value,
411 diff_relative = git_config_bool(var, value);
412 return 0;
413 }
414 + if (!strcmp(var, "diff.statnamewidth")) {
415 + diff_stat_name_width = git_config_int(var, value, ctx->kvi);
416 + return 0;
417 + }
418 if (!strcmp(var, "diff.statgraphwidth")) {
419 diff_stat_graph_width = git_config_int(var, value, ctx->kvi);
420 return 0;
@@ -2704,12 +2709,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
2709 number_width = decimal_width(max_change) > number_width ?
2710 decimal_width(max_change) : number_width;
2711
2712 + if (options->stat_name_width == -1)
2713 + options->stat_name_width = diff_stat_name_width;
2714 if (options->stat_graph_width == -1)
2715 options->stat_graph_width = diff_stat_graph_width;
2716
2717 /*
2711 - * Guarantee 3/8*16==6 for the graph part
2712 - * and 5/8*16==10 for the filename part
2718 + * Guarantee 3/8*16 == 6 for the graph part
2719 + * and 5/8*16 == 10 for the filename part
2720 */
2721 if (width < 16 + 6 + number_width)
2722 width = 16 + 6 + number_width;
graph.c
-1
@@ -339,7 +339,6 @@ void graph_setup_line_prefix(struct diff_options *diffopt)
339 diffopt->output_prefix = diff_output_prefix_callback;
340 }
341
342 -
342 struct git_graph *graph_init(struct rev_info *opt)
343 {
344 struct git_graph *graph = xmalloc(sizeof(struct git_graph));
t/t4052-stat-output.sh
+34 -7
@@ -49,12 +49,41 @@ log -1 --stat
49 EOF
50
51 cat >expect.60 <<-'EOF'
52 - ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
52 + ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
53 EOF
54 cat >expect.6030 <<-'EOF'
55 ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
56 EOF
57 -cat >expect2.60 <<-'EOF'
57 +while read verb expect cmd args
58 +do
59 + # No width limit applied when statNameWidth is ignored
60 + case "$expect" in expect72|expect.6030)
61 + test_expect_success "$cmd $verb statNameWidth config with long name" '
62 + git -c diff.statNameWidth=30 $cmd $args >output &&
63 + grep " | " output >actual &&
64 + test_cmp $expect actual
65 + ';;
66 + esac
67 + # Maximum width limit still applied when statNameWidth is ignored
68 + case "$expect" in expect.60|expect.6030)
69 + test_expect_success "$cmd --stat=width $verb statNameWidth config with long name" '
70 + git -c diff.statNameWidth=30 $cmd $args --stat=60 >output &&
71 + grep " | " output >actual &&
72 + test_cmp $expect actual
73 + ';;
74 + esac
75 +done <<\EOF
76 +ignores expect72 format-patch -1 --stdout
77 +ignores expect.60 format-patch -1 --stdout
78 +respects expect.6030 diff HEAD^ HEAD --stat
79 +respects expect.6030 show --stat
80 +respects expect.6030 log -1 --stat
81 +EOF
82 +
83 +cat >expect.40 <<-'EOF'
84 + ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
85 +EOF
86 +cat >expect2.40 <<-'EOF'
87 ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
88 ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
89 EOF
@@ -67,16 +96,16 @@ do
96 test_expect_success "$cmd --stat=width: a long name is given more room when the bar is short" '
97 git $cmd $args --stat=40 >output &&
98 grep " | " output >actual &&
70 - test_cmp $expect.60 actual
99 + test_cmp $expect.40 actual
100 '
101
102 test_expect_success "$cmd --stat-width=width with long name" '
103 git $cmd $args --stat-width=40 >output &&
104 grep " | " output >actual &&
76 - test_cmp $expect.60 actual
105 + test_cmp $expect.40 actual
106 '
107
79 - test_expect_success "$cmd --stat=...,name-width with long name" '
108 + test_expect_success "$cmd --stat=width,name-width with long name" '
109 git $cmd $args --stat=60,30 >output &&
110 grep " | " output >actual &&
111 test_cmp $expect.6030 actual
@@ -94,7 +123,6 @@ expect show --stat
123 expect log -1 --stat
124 EOF
125
97 -
126 test_expect_success 'preparation for big change tests' '
127 >abcd &&
128 git add abcd &&
@@ -207,7 +235,6 @@ respects expect40 show --stat
235 respects expect40 log -1 --stat
236 EOF
237
210 -
238 cat >expect <<'EOF'
239 abcd | 1000 ++++++++++++++++++++++++++
240 EOF