diff options
-rw-r--r-- | Documentation/diff-options.txt | 8 | ||||
-rw-r--r-- | diff.c | 54 | ||||
-rw-r--r-- | diff.h | 1 | ||||
-rwxr-xr-x | t/t4049-diff-stat-count.sh | 25 |
4 files changed, 78 insertions, 10 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 24f189f96b..4235302ea4 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -48,11 +48,17 @@ endif::git-format-patch[] --patience:: Generate a diff using the "patience diff" algorithm. ---stat[=<width>[,<name-width>]]:: +--stat[=<width>[,<name-width>[,<count>]]]:: Generate a diffstat. You can override the default output width for 80-column terminal by `--stat=<width>`. The width of the filename part can be controlled by giving another width to it separated by a comma. + By giving a third parameter `<count>`, you can limit the + output to the first `<count>` lines, followed by + `...` if there are more. ++ +These parameters can also be set individually with `--stat-width=<width>`, +`--stat-name-width=<name-width>` and `--stat-count=<count>`. --numstat:: Similar to `\--stat`, but shows number of added and @@ -1316,9 +1316,10 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) int i, len, add, del, adds = 0, dels = 0; uintmax_t max_change = 0, max_len = 0; int total_files = data->nr; - int width, name_width; + int width, name_width, count; const char *reset, *add_c, *del_c; const char *line_prefix = ""; + int extra_shown = 0; struct strbuf *msg = NULL; if (data->nr == 0) @@ -1331,6 +1332,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) width = options->stat_width ? options->stat_width : 80; name_width = options->stat_name_width ? options->stat_name_width : 50; + count = options->stat_count ? options->stat_count : data->nr; /* Sanity: give at least 5 columns to the graph, * but leave at least 10 columns for the name. @@ -1347,9 +1349,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) add_c = diff_get_color_opt(options, DIFF_FILE_NEW); del_c = diff_get_color_opt(options, DIFF_FILE_OLD); - for (i = 0; i < data->nr; i++) { + 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 && + (change == 0)) { + count++; /* not shown == room for one more */ + continue; + } fill_print_name(file); len = strlen(file->print_name); if (max_len < len) @@ -1360,6 +1367,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) if (max_change < change) max_change = change; } + count = i; /* min(count, data->nr) */ /* Compute the width of the graph part; * 10 is for one blank at the beginning of the line plus @@ -1374,13 +1382,18 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) else width = max_change; - for (i = 0; i < data->nr; i++) { + for (i = 0; i < count; i++) { const char *prefix = ""; char *name = data->files[i]->print_name; uintmax_t added = data->files[i]->added; uintmax_t deleted = data->files[i]->deleted; int name_len; + if (!data->files[i]->is_renamed && + (added + deleted == 0)) { + total_files--; + continue; + } /* * "scale" the filename */ @@ -1415,11 +1428,6 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) fprintf(options->file, " Unmerged\n"); continue; } - else if (!data->files[i]->is_renamed && - (added + deleted == 0)) { - total_files--; - continue; - } /* * scale the add/delete @@ -1441,6 +1449,20 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) show_graph(options->file, '-', del, del_c, reset); fprintf(options->file, "\n"); } + 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 && + (added + deleted == 0)) { + total_files--; + continue; + } + adds += added; + dels += deleted; + if (!extra_shown) + fprintf(options->file, "%s ...\n", line_prefix); + extra_shown = 1; + } fprintf(options->file, "%s", line_prefix); fprintf(options->file, " %d files changed, %d insertions(+), %d deletions(-)\n", @@ -3208,6 +3230,7 @@ static int stat_opt(struct diff_options *options, const char **av) char *end; int width = options->stat_width; int name_width = options->stat_name_width; + int count = options->stat_count; int argcount = 1; arg += strlen("--stat"); @@ -3235,12 +3258,24 @@ static int stat_opt(struct diff_options *options, const char **av) name_width = strtoul(av[1], &end, 10); argcount = 2; } + } else if (!prefixcmp(arg, "-count")) { + arg += strlen("-count"); + if (*arg == '=') + count = strtoul(arg + 1, &end, 10); + else if (!*arg && !av[1]) + die("Option '--stat-count' requires a value"); + else if (!*arg) { + count = strtoul(av[1], &end, 10); + argcount = 2; + } } break; case '=': width = strtoul(arg+1, &end, 10); if (*end == ',') name_width = strtoul(end+1, &end, 10); + if (*end == ',') + count = strtoul(end+1, &end, 10); } /* Important! This checks all the error cases! */ @@ -3249,6 +3284,7 @@ static int stat_opt(struct diff_options *options, const char **av) options->output_format |= DIFF_FORMAT_DIFFSTAT; options->stat_name_width = name_width; options->stat_width = width; + options->stat_count = count; return argcount; } @@ -3313,7 +3349,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "-s")) options->output_format |= DIFF_FORMAT_NO_OUTPUT; else if (!prefixcmp(arg, "--stat")) - /* --stat, --stat-width, or --stat-name-width */ + /* --stat, --stat-width, --stat-name-width, or --stat-count */ return stat_opt(options, av); /* renames options */ @@ -125,6 +125,7 @@ struct diff_options { int stat_width; int stat_name_width; + int stat_count; const char *word_regex; enum diff_words_type word_diff; diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh new file mode 100755 index 0000000000..641e70d14d --- /dev/null +++ b/t/t4049-diff-stat-count.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# Copyright (c) 2011, Google Inc. + +test_description='diff --stat-count' +. ./test-lib.sh + +test_expect_success setup ' + >a && + >b && + >c && + >d && + git add a b c d && + chmod +x c d && + echo a >a && + echo b >b && + cat >expect <<-\EOF + a | 1 + + b | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + EOF + git diff --stat --stat-count=2 >actual && + test_cmp expect actual +' + +test_done |