diff --stat: enable limiting of the graph part

A new option --stat-graph-width=<width> can be used to limit the width of the graph part even is more space is available. Up to <width> columns will be used for the graph. If commits changing a lot of lines are displayed in a wide terminal window (200 or more columns), and the +- graph uses the full width, the output can be hard to comfortably scan with a horizontal movement of human eyes. Messages wrapped to about 80 columns would be interspersed with very long +- lines. It makes sense to limit the width of the graph part to a fixed value (e.g. 70 columns), even if more columns are available. Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Zbigniew Jędrzejewski-Szmek committed Mar 1, 2012 at 13:26 UTC 969fe57b844a514747c1d5d66e0698dc53ed473d
4 files changed +30 -2
Documentation/diff-options.txt
+2
@@ -59,6 +59,8 @@ endif::git-format-patch[]
59 or 80 columns if not connected to a terminal, and can be
60 overriden by `<width>`. The width of the filename part can be
61 limited by giving another width `<name-width>` after a comma.
62 + The width of the graph part can be limited by using
63 + `--stat-graph-width=<width>`.
64 By giving a third parameter `<count>`, you can limit the
65 output to the first `<count>` lines, followed by `...` if
66 there are more.
diff.c
+21 -2
@@ -1375,13 +1375,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
1375 /*
1376 * We have width = stat_width or term_columns() columns total.
1377 * We want a maximum of min(max_len, stat_name_width) for the name part.
1378 + * We want a maximum of min(max_change, stat_graph_width) for the +- part.
1379 * We also need 1 for " " and 4 + decimal_width(max_change)
1380 * for " | NNNN " and one the empty column at the end, altogether
1381 * 6 + decimal_width(max_change).
1382 *
1383 * If there's not enough space, we will use the smaller of
1384 * stat_name_width (if set) and 5/8*width for the filename,
1384 - * and the rest for constant elements + graph part.
1385 + * and the rest for constant elements + graph part, but no more
1386 + * than stat_graph_width for the graph part.
1387 * (5/8 gives 50 for filename and 30 for the constant parts + graph
1388 * for the standard terminal size).
1389 *
@@ -1406,7 +1408,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
1408 /*
1409 * First assign sizes that are wanted, ignoring available width.
1410 */
1409 - graph_width = max_change;
1411 + graph_width = (options->stat_graph_width &&
1412 + options->stat_graph_width < max_change) ?
1413 + options->stat_graph_width : max_change;
1414 name_width = (options->stat_name_width > 0 &&
1415 options->stat_name_width < max_len) ?
1416 options->stat_name_width : max_len;
@@ -1417,6 +1421,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
1421 if (name_width + number_width + 6 + graph_width > width) {
1422 if (graph_width > width * 3/8 - number_width - 6)
1423 graph_width = width * 3/8 - number_width - 6;
1424 + if (options->stat_graph_width &&
1425 + graph_width > options->stat_graph_width)
1426 + graph_width = options->stat_graph_width;
1427 if (name_width > width - number_width - 6 - graph_width)
1428 name_width = width - number_width - 6 - graph_width;
1429 else
@@ -3289,6 +3296,7 @@ static int stat_opt(struct diff_options *options, const char **av)
3296 char *end;
3297 int width = options->stat_width;
3298 int name_width = options->stat_name_width;
3299 + int graph_width = options->stat_graph_width;
3300 int count = options->stat_count;
3301 int argcount = 1;
3302
@@ -3317,6 +3325,16 @@ static int stat_opt(struct diff_options *options, const char **av)
3325 name_width = strtoul(av[1], &end, 10);
3326 argcount = 2;
3327 }
3328 + } else if (!prefixcmp(arg, "-graph-width")) {
3329 + arg += strlen("-graph-width");
3330 + if (*arg == '=')
3331 + graph_width = strtoul(arg + 1, &end, 10);
3332 + else if (!*arg && !av[1])
3333 + die("Option '--stat-graph-width' requires a value");
3334 + else if (!*arg) {
3335 + graph_width = strtoul(av[1], &end, 10);
3336 + argcount = 2;
3337 + }
3338 } else if (!prefixcmp(arg, "-count")) {
3339 arg += strlen("-count");
3340 if (*arg == '=')
@@ -3342,6 +3360,7 @@ static int stat_opt(struct diff_options *options, const char **av)
3360 return 0;
3361 options->output_format |= DIFF_FORMAT_DIFFSTAT;
3362 options->stat_name_width = name_width;
3363 + options->stat_graph_width = graph_width;
3364 options->stat_width = width;
3365 options->stat_count = count;
3366 return argcount;
diff.h
+1
@@ -129,6 +129,7 @@ struct diff_options {
129
130 int stat_width;
131 int stat_name_width;
132 + int stat_graph_width;
133 int stat_count;
134 const char *word_regex;
135 enum diff_words_type word_diff;
t/t4052-stat-output.sh
+6
@@ -136,6 +136,12 @@ do
136 grep " | " output >actual &&
137 test_cmp expect actual
138 '
139 +
140 + test_expect_success "$cmd --stat-graph--width with big change" '
141 + git $cmd $args --stat-graph-width=26 >output
142 + grep " | " output >actual &&
143 + test_cmp expect actual
144 + '
145 done <<\EOF
146 format-patch -1 --stdout
147 diff HEAD^ HEAD --stat