{"thread":{"id":"47605","subject":"[PATCH/RFC] diff: add --compact-summary option to complement --stat","startedAt":"2018-01-13T13:22:25Z","lastAt":"2018-01-19T21:53:50Z","messageCount":14,"participants":["Nguyễn Thái Ngọc Duy","Philip Oakley","Simon Ruderich","Duy Nguyen","Eric Sunshine","Ævar Arnfjörð Bjarmason","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"336558","messageId":"20180113132211.13350-1-pclouds@gmail.com","threadId":"47605","inReplyTo":null,"subject":"[PATCH/RFC] diff: add --compact-summary option to complement --stat","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-13T13:22:11Z","receivedAt":"2018-01-13T13:22:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is partly inspired by gerrit web interface which shows diffstat\nlike this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\nthird line):\n\n     Documentation/merge-config.txt     |  4 +\n     builtin/merge.c                    |  2 +\n   A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n     t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n   4 files changed, 132 insertions(+)\n\nIn other words, certain information currently shown with --summary is\nembedded in the diffstat. This helps reading (all information of the\nsame file in the same line instead of two) and can reduce the number of\nlines if you add/delete a lot of files.\n\nThe new option --compact-summary implements this with a tweak to support\nmode change, which is shown in --summary too.\n\nFor mode changes, executable bit is denoted as \"(+x)\" or \"(-x)\" when\nit's added or removed respectively. The same for when a regular file is\nreplaced with a symlink \"(+l)\" or the other way \"(-l)\". This also\napplies to new files. New regulare files are \"A\", while new executable\nfiles or symlinks are \"A+x\" or \"A+l\".\n\nNote, there is still one piece of information missing from --summary,\nthe rename/copy percentage. That could probably be added later. It's not\nas useful as the others anyway.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n I have had something similar for years but the data is shown after\n the path name instead (it's incidentally shown in the diffstat right\n below). I was going to clean it up and submit it again, but my recent\n experience with Gerrit changed my mind a bit about the output.\n\n Documentation/diff-options.txt                     | 11 ++++\n diff.c                                             | 64 +++++++++++++++++++++-\n diff.h                                             |  1 +\n t/t4013-diff-various.sh                            |  5 ++\n ...y_--root_--stat_--compact-summary_initial (new) | 12 ++++\n ...R_--root_--stat_--compact-summary_initial (new) | 12 ++++\n ...ree_--stat_--compact-summary_initial_mode (new) |  4 ++\n ..._-R_--stat_--compact-summary_initial_mode (new) |  4 ++\n 8 files changed, 110 insertions(+), 3 deletions(-)\n create mode 100644 t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n create mode 100644 t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n create mode 100644 t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n create mode 100644 t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex 9d1586b956..ff93ff74d0 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -188,6 +188,17 @@ and accumulating child directory counts in the parent directories:\n \tOutput a condensed summary of extended header information\n \tsuch as creations, renames and mode changes.\n \n+--compact-summary::\n+\tOutput a condensed summary of extended header information in\n+\tfront of the file name part of diffstat. This option is\n+\tignored if --stat is not specified.\n++\n+Fle creations or deletions are denoted with \"A\" or \"D\" respectively,\n+optionally \"+l\" if it's a symlink, or \"+x\" if it's executable.\n+Mode changes are put in brackets, e.g. \"+x\" or \"-x\" for adding or\n+removing executable bit respectively, \"+l\" or \"-l\" for becoming a\n+symlink or a regular file.\n+\n ifndef::git-format-patch[]\n --patch-with-stat::\n \tSynonym for `-p --stat`.\ndiff --git a/diff.c b/diff.c\nindex fb22b19f09..3f6767777d 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -2131,6 +2131,7 @@ struct diffstat_t {\n \t\tchar *from_name;\n \t\tchar *name;\n \t\tchar *print_name;\n+\t\tconst char *status_code;\n \t\tunsigned is_unmerged:1;\n \t\tunsigned is_binary:1;\n \t\tunsigned is_renamed:1;\n@@ -2271,6 +2272,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n {\n \tint i, len, add, del, adds = 0, dels = 0;\n \tuintmax_t max_change = 0, max_len = 0;\n+\tint max_status_len = 0;\n \tint total_files = data->nr, count;\n \tint width, name_width, graph_width, number_width = 0, bin_width = 0;\n \tconst char *reset, *add_c, *del_c;\n@@ -2287,6 +2289,18 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \tadd_c = diff_get_color_opt(options, DIFF_FILE_NEW);\n \tdel_c = diff_get_color_opt(options, DIFF_FILE_OLD);\n \n+\tfor (i = 0; (i < count) && (i < data->nr); i++) {\n+\t\tconst struct diffstat_file *file = data->files[i];\n+\t\tint len;\n+\n+\t\tif (!file->status_code)\n+\t\t\tcontinue;\n+\t\tlen = strlen(file->status_code) + 1;\n+\n+\t\tif (len > max_status_len)\n+\t\t\tmax_status_len = len;\n+\t}\n+\n \t/*\n \t * Find the longest filename and max number of changes\n \t */\n@@ -2383,6 +2397,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t      options->stat_name_width < max_len) ?\n \t\toptions->stat_name_width : max_len;\n \n+\tname_width += max_status_len;\n+\n \t/*\n \t * Adjust adjustable widths not to exceed maximum width\n \t */\n@@ -2402,6 +2418,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\tgraph_width = width - number_width - 6 - name_width;\n \t}\n \n+\tname_width -= max_status_len;\n+\n \t/*\n \t * From here name_width is the width of the name area,\n \t * and graph_width is the width of the graph area.\n@@ -2409,6 +2427,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t */\n \tfor (i = 0; i < count; i++) {\n \t\tconst char *prefix = \"\";\n+\t\tconst char *status_code = \"\";\n \t\tstruct diffstat_file *file = data->files[i];\n \t\tchar *name = file->print_name;\n \t\tuintmax_t added = file->added;\n@@ -2418,6 +2437,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\tif (!file->is_interesting && (added + deleted == 0))\n \t\t\tcontinue;\n \n+\t\tif (file->status_code)\n+\t\t\tstatus_code = file->status_code;\n+\n \t\t/*\n \t\t * \"scale\" the filename\n \t\t */\n@@ -2434,7 +2456,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t}\n \n \t\tif (file->is_binary) {\n-\t\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t\t    max_status_len, status_code,\n+\t\t\t\t    prefix, len, name);\n \t\t\tstrbuf_addf(&out, \" %*s\", number_width, \"Bin\");\n \t\t\tif (!added && !deleted) {\n \t\t\t\tstrbuf_addch(&out, '\\n');\n@@ -2455,7 +2479,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\tcontinue;\n \t\t}\n \t\telse if (file->is_unmerged) {\n-\t\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t\t    max_status_len, status_code,\n+\t\t\t\t    prefix, len, name);\n \t\t\tstrbuf_addstr(&out, \" Unmerged\\n\");\n \t\t\temit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,\n \t\t\t\t\t out.buf, out.len, 0);\n@@ -2482,7 +2508,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\t\tadd = total - del;\n \t\t\t}\n \t\t}\n-\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t    max_status_len, status_code,\n+\t\t\t    prefix, len, name);\n \t\tstrbuf_addf(&out, \" %*\"PRIuMAX\"%s\",\n \t\t\tnumber_width, added + deleted,\n \t\t\tadded + deleted ? \" \" : \"\");\n@@ -3248,6 +3276,32 @@ static void builtin_diff(const char *name_a,\n \treturn;\n }\n \n+static const char *get_compact_summary(const struct diff_filepair *p, int is_renamed)\n+{\n+\tif (!is_renamed) {\n+\t\tif (p->status == DIFF_STATUS_ADDED) {\n+\t\t\tif (S_ISLNK(p->two->mode))\n+\t\t\t\treturn \"A+l\";\n+\t\t\telse if ((p->two->mode & 0777) == 0755)\n+\t\t\t\treturn \"A+x\";\n+\t\t\telse\n+\t\t\t\treturn \"A\";\n+\t\t} else if (p->status == DIFF_STATUS_DELETED)\n+\t\t\treturn \"D\";\n+\t}\n+\tif (S_ISLNK(p->one->mode) && !S_ISLNK(p->two->mode))\n+\t\treturn \"(-l)\";\n+\telse if (!S_ISLNK(p->one->mode) && S_ISLNK(p->two->mode))\n+\t\treturn \"(+l)\";\n+\telse if ((p->one->mode & 0777) == 0644 &&\n+\t\t (p->two->mode & 0777) == 0755)\n+\t\treturn \"(+x)\";\n+\telse if ((p->one->mode & 0777) == 0755 &&\n+\t\t (p->two->mode & 0777) == 0644)\n+\t\treturn \"(-x)\";\n+\treturn NULL;\n+}\n+\n static void builtin_diffstat(const char *name_a, const char *name_b,\n \t\t\t     struct diff_filespec *one,\n \t\t\t     struct diff_filespec *two,\n@@ -3267,6 +3321,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,\n \n \tdata = diffstat_add(diffstat, name_a, name_b);\n \tdata->is_interesting = p->status != DIFF_STATUS_UNKNOWN;\n+\tif (o->flags.compact_summary)\n+\t\tdata->status_code = get_compact_summary(p, data->is_renamed);\n \n \tif (!one || !two) {\n \t\tdata->is_unmerged = 1;\n@@ -4537,6 +4593,8 @@ int diff_opt_parse(struct diff_options *options,\n \telse if (starts_with(arg, \"--stat\"))\n \t\t/* --stat, --stat-width, --stat-name-width, or --stat-count */\n \t\treturn stat_opt(options, av);\n+\telse if (!strcmp(arg, \"--compact-summary\"))\n+\t\toptions->flags.compact_summary = 1;\n \n \t/* renames options */\n \telse if (starts_with(arg, \"-B\") ||\ndiff --git a/diff.h b/diff.h\nindex 7cf276f077..843276196c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -93,6 +93,7 @@ struct diff_flags {\n \tunsigned funccontext:1;\n \tunsigned pickaxe_ignore_case:1;\n \tunsigned default_follow_renames:1;\n+\tunsigned compact_summary:1;\n };\n \n static inline void diff_flags_or(struct diff_flags *a,\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex f10798b2df..3f9a24fd56 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -361,6 +361,11 @@ diff --no-index --raw dir2 dir\n diff --no-index --raw --abbrev=4 dir2 dir\n :noellipses diff --no-index --raw --abbrev=4 dir2 dir\n diff --no-index --raw --no-abbrev dir2 dir\n+\n+diff-tree --pretty --root --stat --compact-summary initial\n+diff-tree --pretty -R --root --stat --compact-summary initial\n+diff-tree --stat --compact-summary initial mode\n+diff-tree -R --stat --compact-summary initial mode\n EOF\n \n test_expect_success 'log -S requires an argument' '\ndiff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\nnew file mode 100644\nindex 0000000000..0f086907fc\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n@@ -0,0 +1,12 @@\n+$ git diff-tree --pretty --root --stat --compact-summary initial\n+commit 444ac553ac7612cc88969031b02b3767fb8a353a\n+Author: A U Thor <author@example.com>\n+Date:   Mon Jun 26 00:00:00 2006 +0000\n+\n+    Initial\n+\n+ A dir/sub | 2 ++\n+ A file0   | 3 +++\n+ A file2   | 3 +++\n+ 3 files changed, 8 insertions(+)\n+$\ndiff --git a/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\nnew file mode 100644\nindex 0000000000..eeed5872e0\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n@@ -0,0 +1,12 @@\n+$ git diff-tree --pretty -R --root --stat --compact-summary initial\n+commit 444ac553ac7612cc88969031b02b3767fb8a353a\n+Author: A U Thor <author@example.com>\n+Date:   Mon Jun 26 00:00:00 2006 +0000\n+\n+    Initial\n+\n+ D dir/sub | 2 --\n+ D file0   | 3 ---\n+ D file2   | 3 ---\n+ 3 files changed, 8 deletions(-)\n+$\ndiff --git a/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\nnew file mode 100644\nindex 0000000000..b674ef9c31\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n@@ -0,0 +1,4 @@\n+$ git diff-tree --stat --compact-summary initial mode\n+ (+x) file0 | 0\n+ 1 file changed, 0 insertions(+), 0 deletions(-)\n+$\ndiff --git a/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\nnew file mode 100644\nindex 0000000000..877e9ae19d\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n@@ -0,0 +1,4 @@\n+$ git diff-tree -R --stat --compact-summary initial mode\n+ (-x) file0 | 0\n+ 1 file changed, 0 insertions(+), 0 deletions(-)\n+$\n-- \n2.15.1.600.g899a5f85c6\n\n"},{"id":"336565","messageId":"B26EDC46DA964EA0B40B994E6EF453B9@PhilipOakley","threadId":"47605","inReplyTo":"20180113132211.13350-1-pclouds@gmail.com","subject":"Re: [PATCH/RFC] diff: add --compact-summary option to complement --stat","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2018-01-13T18:37:26Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"(one spelling spotted)..\nFrom: \"Nguyễn Thái Ngọc Duy\" <pclouds@gmail.com>\n> This is partly inspired by gerrit web interface which shows diffstat\n> like this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\n> third line):\n>\n>     Documentation/merge-config.txt     |  4 +\n>     builtin/merge.c                    |  2 +\n>   A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n>     t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n>   4 files changed, 132 insertions(+)\n>\n> In other words, certain information currently shown with --summary is\n> embedded in the diffstat. This helps reading (all information of the\n> same file in the same line instead of two) and can reduce the number of\n> lines if you add/delete a lot of files.\n>\n> The new option --compact-summary implements this with a tweak to support\n> mode change, which is shown in --summary too.\n>\n> For mode changes, executable bit is denoted as \"(+x)\" or \"(-x)\" when\n> it's added or removed respectively. The same for when a regular file is\n> replaced with a symlink \"(+l)\" or the other way \"(-l)\". This also\n> applies to new files. New regulare files are \"A\", while new executable\n> files or symlinks are \"A+x\" or \"A+l\".\n>\n> Note, there is still one piece of information missing from --summary,\n> the rename/copy percentage. That could probably be added later. It's not\n> as useful as the others anyway.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n> I have had something similar for years but the data is shown after\n> the path name instead (it's incidentally shown in the diffstat right\n> below). I was going to clean it up and submit it again, but my recent\n> experience with Gerrit changed my mind a bit about the output.\n>\n> Documentation/diff-options.txt                     | 11 ++++\n> diff.c                                             | 64 \n> +++++++++++++++++++++-\n> diff.h                                             |  1 +\n> t/t4013-diff-various.sh                            |  5 ++\n> ...y_--root_--stat_--compact-summary_initial (new) | 12 ++++\n> ...R_--root_--stat_--compact-summary_initial (new) | 12 ++++\n> ...ree_--stat_--compact-summary_initial_mode (new) |  4 ++\n> ..._-R_--stat_--compact-summary_initial_mode (new) |  4 ++\n> 8 files changed, 110 insertions(+), 3 deletions(-)\n> create mode 100644 \n> t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n> create mode 100644 \n> t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n> create mode 100644 \n> t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n> create mode 100644 \n> t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n>\n> diff --git a/Documentation/diff-options.txt \n> b/Documentation/diff-options.txt\n> index 9d1586b956..ff93ff74d0 100644\n> --- a/Documentation/diff-options.txt\n> +++ b/Documentation/diff-options.txt\n> @@ -188,6 +188,17 @@ and accumulating child directory counts in the parent \n> directories:\n>  Output a condensed summary of extended header information\n>  such as creations, renames and mode changes.\n>\n> +--compact-summary::\n> + Output a condensed summary of extended header information in\n> + front of the file name part of diffstat. This option is\n> + ignored if --stat is not specified.\n> ++\n> +Fle creations or deletions are denoted with \"A\" or \"D\" respectively,\n\ns/Fle/File/ ?\n\n> +optionally \"+l\" if it's a symlink, or \"+x\" if it's executable.\n> +Mode changes are put in brackets, e.g. \"+x\" or \"-x\" for adding or\n> +removing executable bit respectively, \"+l\" or \"-l\" for becoming a\n> +symlink or a regular file.\n> +\n> ifndef::git-format-patch[]\n> --patch-with-stat::\n>  Synonym for `-p --stat`.\n> diff --git a/diff.c b/diff.c\n> index fb22b19f09..3f6767777d 100644\n> --- a/diff.c\n> +++ b/diff.c\n> @@ -2131,6 +2131,7 @@ struct diffstat_t {\n>  char *from_name;\n>  char *name;\n>  char *print_name;\n> + const char *status_code;\n>  unsigned is_unmerged:1;\n>  unsigned is_binary:1;\n>  unsigned is_renamed:1;\n> @@ -2271,6 +2272,7 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n> {\n>  int i, len, add, del, adds = 0, dels = 0;\n>  uintmax_t max_change = 0, max_len = 0;\n> + int max_status_len = 0;\n>  int total_files = data->nr, count;\n>  int width, name_width, graph_width, number_width = 0, bin_width = 0;\n>  const char *reset, *add_c, *del_c;\n> @@ -2287,6 +2289,18 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  add_c = diff_get_color_opt(options, DIFF_FILE_NEW);\n>  del_c = diff_get_color_opt(options, DIFF_FILE_OLD);\n>\n> + for (i = 0; (i < count) && (i < data->nr); i++) {\n> + const struct diffstat_file *file = data->files[i];\n> + int len;\n> +\n> + if (!file->status_code)\n> + continue;\n> + len = strlen(file->status_code) + 1;\n> +\n> + if (len > max_status_len)\n> + max_status_len = len;\n> + }\n> +\n>  /*\n>  * Find the longest filename and max number of changes\n>  */\n> @@ -2383,6 +2397,8 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>        options->stat_name_width < max_len) ?\n>  options->stat_name_width : max_len;\n>\n> + name_width += max_status_len;\n> +\n>  /*\n>  * Adjust adjustable widths not to exceed maximum width\n>  */\n> @@ -2402,6 +2418,8 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  graph_width = width - number_width - 6 - name_width;\n>  }\n>\n> + name_width -= max_status_len;\n> +\n>  /*\n>  * From here name_width is the width of the name area,\n>  * and graph_width is the width of the graph area.\n> @@ -2409,6 +2427,7 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  */\n>  for (i = 0; i < count; i++) {\n>  const char *prefix = \"\";\n> + const char *status_code = \"\";\n>  struct diffstat_file *file = data->files[i];\n>  char *name = file->print_name;\n>  uintmax_t added = file->added;\n> @@ -2418,6 +2437,9 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  if (!file->is_interesting && (added + deleted == 0))\n>  continue;\n>\n> + if (file->status_code)\n> + status_code = file->status_code;\n> +\n>  /*\n>  * \"scale\" the filename\n>  */\n> @@ -2434,7 +2456,9 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  }\n>\n>  if (file->is_binary) {\n> - strbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n> + strbuf_addf(&out, \" %-*s%s%-*s |\",\n> +     max_status_len, status_code,\n> +     prefix, len, name);\n>  strbuf_addf(&out, \" %*s\", number_width, \"Bin\");\n>  if (!added && !deleted) {\n>  strbuf_addch(&out, '\\n');\n> @@ -2455,7 +2479,9 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  continue;\n>  }\n>  else if (file->is_unmerged) {\n> - strbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n> + strbuf_addf(&out, \" %-*s%s%-*s |\",\n> +     max_status_len, status_code,\n> +     prefix, len, name);\n>  strbuf_addstr(&out, \" Unmerged\\n\");\n>  emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,\n>  out.buf, out.len, 0);\n> @@ -2482,7 +2508,9 @@ static void show_stats(struct diffstat_t *data, \n> struct diff_options *options)\n>  add = total - del;\n>  }\n>  }\n> - strbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n> + strbuf_addf(&out, \" %-*s%s%-*s |\",\n> +     max_status_len, status_code,\n> +     prefix, len, name);\n>  strbuf_addf(&out, \" %*\"PRIuMAX\"%s\",\n>  number_width, added + deleted,\n>  added + deleted ? \" \" : \"\");\n> @@ -3248,6 +3276,32 @@ static void builtin_diff(const char *name_a,\n>  return;\n> }\n>\n> +static const char *get_compact_summary(const struct diff_filepair *p, int \n> is_renamed)\n> +{\n> + if (!is_renamed) {\n> + if (p->status == DIFF_STATUS_ADDED) {\n> + if (S_ISLNK(p->two->mode))\n> + return \"A+l\";\n> + else if ((p->two->mode & 0777) == 0755)\n> + return \"A+x\";\n> + else\n> + return \"A\";\n> + } else if (p->status == DIFF_STATUS_DELETED)\n> + return \"D\";\n> + }\n> + if (S_ISLNK(p->one->mode) && !S_ISLNK(p->two->mode))\n> + return \"(-l)\";\n> + else if (!S_ISLNK(p->one->mode) && S_ISLNK(p->two->mode))\n> + return \"(+l)\";\n> + else if ((p->one->mode & 0777) == 0644 &&\n> + (p->two->mode & 0777) == 0755)\n> + return \"(+x)\";\n> + else if ((p->one->mode & 0777) == 0755 &&\n> + (p->two->mode & 0777) == 0644)\n> + return \"(-x)\";\n> + return NULL;\n> +}\n> +\n> static void builtin_diffstat(const char *name_a, const char *name_b,\n>       struct diff_filespec *one,\n>       struct diff_filespec *two,\n> @@ -3267,6 +3321,8 @@ static void builtin_diffstat(const char *name_a, \n> const char *name_b,\n>\n>  data = diffstat_add(diffstat, name_a, name_b);\n>  data->is_interesting = p->status != DIFF_STATUS_UNKNOWN;\n> + if (o->flags.compact_summary)\n> + data->status_code = get_compact_summary(p, data->is_renamed);\n>\n>  if (!one || !two) {\n>  data->is_unmerged = 1;\n> @@ -4537,6 +4593,8 @@ int diff_opt_parse(struct diff_options *options,\n>  else if (starts_with(arg, \"--stat\"))\n>  /* --stat, --stat-width, --stat-name-width, or --stat-count */\n>  return stat_opt(options, av);\n> + else if (!strcmp(arg, \"--compact-summary\"))\n> + options->flags.compact_summary = 1;\n>\n>  /* renames options */\n>  else if (starts_with(arg, \"-B\") ||\n> diff --git a/diff.h b/diff.h\n> index 7cf276f077..843276196c 100644\n> --- a/diff.h\n> +++ b/diff.h\n> @@ -93,6 +93,7 @@ struct diff_flags {\n>  unsigned funccontext:1;\n>  unsigned pickaxe_ignore_case:1;\n>  unsigned default_follow_renames:1;\n> + unsigned compact_summary:1;\n> };\n>\n> static inline void diff_flags_or(struct diff_flags *a,\n> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\n> index f10798b2df..3f9a24fd56 100755\n> --- a/t/t4013-diff-various.sh\n> +++ b/t/t4013-diff-various.sh\n> @@ -361,6 +361,11 @@ diff --no-index --raw dir2 dir\n> diff --no-index --raw --abbrev=4 dir2 dir\n> :noellipses diff --no-index --raw --abbrev=4 dir2 dir\n> diff --no-index --raw --no-abbrev dir2 dir\n> +\n> +diff-tree --pretty --root --stat --compact-summary initial\n> +diff-tree --pretty -R --root --stat --compact-summary initial\n> +diff-tree --stat --compact-summary initial mode\n> +diff-tree -R --stat --compact-summary initial mode\n> EOF\n>\n> test_expect_success 'log -S requires an argument' '\n> diff --git \n> a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial \n> b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n> new file mode 100644\n> index 0000000000..0f086907fc\n> --- /dev/null\n> +++ \n> b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n> @@ -0,0 +1,12 @@\n> +$ git diff-tree --pretty --root --stat --compact-summary initial\n> +commit 444ac553ac7612cc88969031b02b3767fb8a353a\n> +Author: A U Thor <author@example.com>\n> +Date:   Mon Jun 26 00:00:00 2006 +0000\n> +\n> +    Initial\n> +\n> + A dir/sub | 2 ++\n> + A file0   | 3 +++\n> + A file2   | 3 +++\n> + 3 files changed, 8 insertions(+)\n> +$\n> diff --git \n> a/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial \n> b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n> new file mode 100644\n> index 0000000000..eeed5872e0\n> --- /dev/null\n> +++ \n> b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n> @@ -0,0 +1,12 @@\n> +$ git diff-tree --pretty -R --root --stat --compact-summary initial\n> +commit 444ac553ac7612cc88969031b02b3767fb8a353a\n> +Author: A U Thor <author@example.com>\n> +Date:   Mon Jun 26 00:00:00 2006 +0000\n> +\n> +    Initial\n> +\n> + D dir/sub | 2 --\n> + D file0   | 3 ---\n> + D file2   | 3 ---\n> + 3 files changed, 8 deletions(-)\n> +$\n> diff --git a/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode \n> b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n> new file mode 100644\n> index 0000000000..b674ef9c31\n> --- /dev/null\n> +++ b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n> @@ -0,0 +1,4 @@\n> +$ git diff-tree --stat --compact-summary initial mode\n> + (+x) file0 | 0\n> + 1 file changed, 0 insertions(+), 0 deletions(-)\n> +$\n> diff --git \n> a/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode \n> b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n> new file mode 100644\n> index 0000000000..877e9ae19d\n> --- /dev/null\n> +++ b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n> @@ -0,0 +1,4 @@\n> +$ git diff-tree -R --stat --compact-summary initial mode\n> + (-x) file0 | 0\n> + 1 file changed, 0 insertions(+), 0 deletions(-)\n> +$\n> -- \n> 2.15.1.600.g899a5f85c6\n> \n\n"},{"id":"336575","messageId":"20180114093535.GA2518@ruderich.org","threadId":"47605","inReplyTo":"20180113132211.13350-1-pclouds@gmail.com","subject":"Re: [PATCH/RFC] diff: add --compact-summary option to complement --stat","fromName":"Simon Ruderich","fromEmail":"simon@ruderich.org","sentAt":"2018-01-14T09:37:41Z","receivedAt":"2018-01-14T09:37:47Z","isPatch":true,"sender":{"key":"simon@ruderich.org","avatar":"https://avatars.githubusercontent.com/u/390994?v=4"},"body":"On Sat, Jan 13, 2018 at 08:22:11PM +0700, Nguyễn Thái Ngọc Duy wrote:\n> [snip]\n>\n> For mode changes, executable bit is denoted as \"(+x)\" or \"(-x)\" when\n> it's added or removed respectively. The same for when a regular file is\n> replaced with a symlink \"(+l)\" or the other way \"(-l)\". This also\n> applies to new files. New regulare files are \"A\", while new executable\n> files or symlinks are \"A+x\" or \"A+l\".\n\nI like the short summary. However I find the use of parentheses\ninconsistent. Why not use them either always (also for \"(A+l)\")\nor never? Was there a specific reason why you added them just in\none place?\n\nRegards\nSimon\n-- \n+ privacy is necessary\n+ using gnupg http://gnupg.org\n+ public key id: 0x92FEFDB7E44C32F9\n"},{"id":"336579","messageId":"CACsJy8BsV9+pxTzTD4mr6ZwThyxir5w2+a4ArqrhBPgyE3q5AA@mail.gmail.com","threadId":"47605","inReplyTo":"20180114093535.GA2518@ruderich.org","subject":"Re: [PATCH/RFC] diff: add --compact-summary option to complement --stat","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-14T10:24:18Z","receivedAt":"2018-01-14T10:24:53Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Jan 14, 2018 at 4:37 PM, Simon Ruderich <simon@ruderich.org> wrote:\n> On Sat, Jan 13, 2018 at 08:22:11PM +0700, Nguyễn Thái Ngọc Duy wrote:\n>> [snip]\n>>\n>> For mode changes, executable bit is denoted as \"(+x)\" or \"(-x)\" when\n>> it's added or removed respectively. The same for when a regular file is\n>> replaced with a symlink \"(+l)\" or the other way \"(-l)\". This also\n>> applies to new files. New regulare files are \"A\", while new executable\n>> files or symlinks are \"A+x\" or \"A+l\".\n>\n> I like the short summary. However I find the use of parentheses\n> inconsistent.\n\nI agree. I put them in parentheses because somehow to me plain \"+x\"\nlooks weird to me.\n\n> Why not use them either always (also for \"(A+l)\")\n> or never? Was there a specific reason why you added them just in\n> one place?\n\nActually shortly after I sent the mail, I realized I could do better.\nSince this is a mode _modification_, we could denote it with \"M\" (most\nfiles in diffstat are \"M\" for obvious reasons, we just don't print it\nbecause it adds no value), so here we could print \"M+x\" or \"M-x\". This\naligns well with \"A+l\" or \"A+x\" for example and is one character\nshorter than my old way.\n-- \nDuy\n"},{"id":"336763","messageId":"20180118100546.32251-1-pclouds@gmail.com","threadId":"47605","inReplyTo":"20180113132211.13350-1-pclouds@gmail.com","subject":"[PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-18T10:05:46Z","receivedAt":"2018-01-18T10:06:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is partly inspired by gerrit web interface which shows diffstat\nlike this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\nthird line):\n\n     Documentation/merge-config.txt     |  4 +\n     builtin/merge.c                    |  2 +\n   A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n     t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n   4 files changed, 132 insertions(+)\n\nIn other words, certain information currently shown with --summary is\nembedded in the diffstat. This helps reading (all information of the\nsame file in the same line instead of two) and can reduce the number of\nlines if you add/delete a lot of files.\n\nThe new option --compact-summary implements this with a tweak to support\nmode change, which is shown in --summary too.\n\nFor mode changes, executable bit is denoted as \"M+x\" or \"M-x\" when it's\nadded or removed respectively. The same for when a regular file is\nreplaced with a symlink \"M+l\" or the other way \"M-l\". This also applies\nto new files. New regulare files are \"A\", while new executable files or\nsymlinks are \"A+x\" or \"A+l\".\n\nWith this tweak, the actual printout is like this\n\n     Documentation/merge-config.txt     |  4 ++\n     builtin/merge.c                    |  2 +\n A+x t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++\n     t/t7612-merge-verify-signatures.sh | 45 +++++++++++++\n 4 files changed, 132 insertions(+)\n\nNote, there is still one piece of information missing from --summary,\nthe rename/copy percentage. That could probably be added later. It's not\nas useful as the others anyway.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n v2 changes \"(+x)\" and friends to \"M+x\" and fixes the \"Fle\" typo.\n\n Documentation/diff-options.txt                     | 11 ++++\n diff.c                                             | 64 +++++++++++++++++++++-\n diff.h                                             |  1 +\n t/t4013-diff-various.sh                            |  5 ++\n ...y_--root_--stat_--compact-summary_initial (new) | 12 ++++\n ...R_--root_--stat_--compact-summary_initial (new) | 12 ++++\n ...ree_--stat_--compact-summary_initial_mode (new) |  4 ++\n ..._-R_--stat_--compact-summary_initial_mode (new) |  4 ++\n 8 files changed, 110 insertions(+), 3 deletions(-)\n create mode 100644 t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n create mode 100644 t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n create mode 100644 t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n create mode 100644 t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex 743af97b06..92cbf7696f 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -188,6 +188,17 @@ and accumulating child directory counts in the parent directories:\n \tOutput a condensed summary of extended header information\n \tsuch as creations, renames and mode changes.\n \n+--compact-summary::\n+\tOutput a condensed summary of extended header information in\n+\tfront of the file name part of diffstat. This option is\n+\tignored if --stat is not specified.\n++\n+File creations or deletions are denoted wigth \"A\" or \"D\" respectively,\n+optionally \"+l\" if it's a symlink, or \"+x\" if it's executable.\n+Mode changes are shown \"M+x\" or \"M-x\" for adding or removing\n+executable bit respectively, \"M+l\" or \"M-l\" for becoming a symlink or\n+a regular file.\n+\n ifndef::git-format-patch[]\n --patch-with-stat::\n \tSynonym for `-p --stat`.\ndiff --git a/diff.c b/diff.c\nindex fb22b19f09..ce1d24b417 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -2131,6 +2131,7 @@ struct diffstat_t {\n \t\tchar *from_name;\n \t\tchar *name;\n \t\tchar *print_name;\n+\t\tconst char *status_code;\n \t\tunsigned is_unmerged:1;\n \t\tunsigned is_binary:1;\n \t\tunsigned is_renamed:1;\n@@ -2271,6 +2272,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n {\n \tint i, len, add, del, adds = 0, dels = 0;\n \tuintmax_t max_change = 0, max_len = 0;\n+\tint max_status_len = 0;\n \tint total_files = data->nr, count;\n \tint width, name_width, graph_width, number_width = 0, bin_width = 0;\n \tconst char *reset, *add_c, *del_c;\n@@ -2287,6 +2289,18 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \tadd_c = diff_get_color_opt(options, DIFF_FILE_NEW);\n \tdel_c = diff_get_color_opt(options, DIFF_FILE_OLD);\n \n+\tfor (i = 0; (i < count) && (i < data->nr); i++) {\n+\t\tconst struct diffstat_file *file = data->files[i];\n+\t\tint len;\n+\n+\t\tif (!file->status_code)\n+\t\t\tcontinue;\n+\t\tlen = strlen(file->status_code) + 1;\n+\n+\t\tif (len > max_status_len)\n+\t\t\tmax_status_len = len;\n+\t}\n+\n \t/*\n \t * Find the longest filename and max number of changes\n \t */\n@@ -2383,6 +2397,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t      options->stat_name_width < max_len) ?\n \t\toptions->stat_name_width : max_len;\n \n+\tname_width += max_status_len;\n+\n \t/*\n \t * Adjust adjustable widths not to exceed maximum width\n \t */\n@@ -2402,6 +2418,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\tgraph_width = width - number_width - 6 - name_width;\n \t}\n \n+\tname_width -= max_status_len;\n+\n \t/*\n \t * From here name_width is the width of the name area,\n \t * and graph_width is the width of the graph area.\n@@ -2409,6 +2427,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t */\n \tfor (i = 0; i < count; i++) {\n \t\tconst char *prefix = \"\";\n+\t\tconst char *status_code = \"\";\n \t\tstruct diffstat_file *file = data->files[i];\n \t\tchar *name = file->print_name;\n \t\tuintmax_t added = file->added;\n@@ -2418,6 +2437,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\tif (!file->is_interesting && (added + deleted == 0))\n \t\t\tcontinue;\n \n+\t\tif (file->status_code)\n+\t\t\tstatus_code = file->status_code;\n+\n \t\t/*\n \t\t * \"scale\" the filename\n \t\t */\n@@ -2434,7 +2456,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t}\n \n \t\tif (file->is_binary) {\n-\t\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t\t    max_status_len, status_code,\n+\t\t\t\t    prefix, len, name);\n \t\t\tstrbuf_addf(&out, \" %*s\", number_width, \"Bin\");\n \t\t\tif (!added && !deleted) {\n \t\t\t\tstrbuf_addch(&out, '\\n');\n@@ -2455,7 +2479,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\tcontinue;\n \t\t}\n \t\telse if (file->is_unmerged) {\n-\t\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t\t    max_status_len, status_code,\n+\t\t\t\t    prefix, len, name);\n \t\t\tstrbuf_addstr(&out, \" Unmerged\\n\");\n \t\t\temit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,\n \t\t\t\t\t out.buf, out.len, 0);\n@@ -2482,7 +2508,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n \t\t\t\tadd = total - del;\n \t\t\t}\n \t\t}\n-\t\tstrbuf_addf(&out, \" %s%-*s |\", prefix, len, name);\n+\t\tstrbuf_addf(&out, \" %-*s%s%-*s |\",\n+\t\t\t    max_status_len, status_code,\n+\t\t\t    prefix, len, name);\n \t\tstrbuf_addf(&out, \" %*\"PRIuMAX\"%s\",\n \t\t\tnumber_width, added + deleted,\n \t\t\tadded + deleted ? \" \" : \"\");\n@@ -3248,6 +3276,32 @@ static void builtin_diff(const char *name_a,\n \treturn;\n }\n \n+static const char *get_compact_summary(const struct diff_filepair *p, int is_renamed)\n+{\n+\tif (!is_renamed) {\n+\t\tif (p->status == DIFF_STATUS_ADDED) {\n+\t\t\tif (S_ISLNK(p->two->mode))\n+\t\t\t\treturn \"A+l\";\n+\t\t\telse if ((p->two->mode & 0777) == 0755)\n+\t\t\t\treturn \"A+x\";\n+\t\t\telse\n+\t\t\t\treturn \"A\";\n+\t\t} else if (p->status == DIFF_STATUS_DELETED)\n+\t\t\treturn \"D\";\n+\t}\n+\tif (S_ISLNK(p->one->mode) && !S_ISLNK(p->two->mode))\n+\t\treturn \"M-l\";\n+\telse if (!S_ISLNK(p->one->mode) && S_ISLNK(p->two->mode))\n+\t\treturn \"M+l\";\n+\telse if ((p->one->mode & 0777) == 0644 &&\n+\t\t (p->two->mode & 0777) == 0755)\n+\t\treturn \"M+x\";\n+\telse if ((p->one->mode & 0777) == 0755 &&\n+\t\t (p->two->mode & 0777) == 0644)\n+\t\treturn \"M-x\";\n+\treturn NULL;\n+}\n+\n static void builtin_diffstat(const char *name_a, const char *name_b,\n \t\t\t     struct diff_filespec *one,\n \t\t\t     struct diff_filespec *two,\n@@ -3267,6 +3321,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,\n \n \tdata = diffstat_add(diffstat, name_a, name_b);\n \tdata->is_interesting = p->status != DIFF_STATUS_UNKNOWN;\n+\tif (o->flags.compact_summary)\n+\t\tdata->status_code = get_compact_summary(p, data->is_renamed);\n \n \tif (!one || !two) {\n \t\tdata->is_unmerged = 1;\n@@ -4537,6 +4593,8 @@ int diff_opt_parse(struct diff_options *options,\n \telse if (starts_with(arg, \"--stat\"))\n \t\t/* --stat, --stat-width, --stat-name-width, or --stat-count */\n \t\treturn stat_opt(options, av);\n+\telse if (!strcmp(arg, \"--compact-summary\"))\n+\t\toptions->flags.compact_summary = 1;\n \n \t/* renames options */\n \telse if (starts_with(arg, \"-B\") ||\ndiff --git a/diff.h b/diff.h\nindex 7cf276f077..843276196c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -93,6 +93,7 @@ struct diff_flags {\n \tunsigned funccontext:1;\n \tunsigned pickaxe_ignore_case:1;\n \tunsigned default_follow_renames:1;\n+\tunsigned compact_summary:1;\n };\n \n static inline void diff_flags_or(struct diff_flags *a,\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex f10798b2df..3f9a24fd56 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -361,6 +361,11 @@ diff --no-index --raw dir2 dir\n diff --no-index --raw --abbrev=4 dir2 dir\n :noellipses diff --no-index --raw --abbrev=4 dir2 dir\n diff --no-index --raw --no-abbrev dir2 dir\n+\n+diff-tree --pretty --root --stat --compact-summary initial\n+diff-tree --pretty -R --root --stat --compact-summary initial\n+diff-tree --stat --compact-summary initial mode\n+diff-tree -R --stat --compact-summary initial mode\n EOF\n \n test_expect_success 'log -S requires an argument' '\ndiff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\nnew file mode 100644\nindex 0000000000..0f086907fc\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--compact-summary_initial\n@@ -0,0 +1,12 @@\n+$ git diff-tree --pretty --root --stat --compact-summary initial\n+commit 444ac553ac7612cc88969031b02b3767fb8a353a\n+Author: A U Thor <author@example.com>\n+Date:   Mon Jun 26 00:00:00 2006 +0000\n+\n+    Initial\n+\n+ A dir/sub | 2 ++\n+ A file0   | 3 +++\n+ A file2   | 3 +++\n+ 3 files changed, 8 insertions(+)\n+$\ndiff --git a/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\nnew file mode 100644\nindex 0000000000..eeed5872e0\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--pretty_-R_--root_--stat_--compact-summary_initial\n@@ -0,0 +1,12 @@\n+$ git diff-tree --pretty -R --root --stat --compact-summary initial\n+commit 444ac553ac7612cc88969031b02b3767fb8a353a\n+Author: A U Thor <author@example.com>\n+Date:   Mon Jun 26 00:00:00 2006 +0000\n+\n+    Initial\n+\n+ D dir/sub | 2 --\n+ D file0   | 3 ---\n+ D file2   | 3 ---\n+ 3 files changed, 8 deletions(-)\n+$\ndiff --git a/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\nnew file mode 100644\nindex 0000000000..5d4d511dd5\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_--stat_--compact-summary_initial_mode\n@@ -0,0 +1,4 @@\n+$ git diff-tree --stat --compact-summary initial mode\n+ M+x file0 | 0\n+ 1 file changed, 0 insertions(+), 0 deletions(-)\n+$\ndiff --git a/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\nnew file mode 100644\nindex 0000000000..6b8c4531b4\n--- /dev/null\n+++ b/t/t4013/diff.diff-tree_-R_--stat_--compact-summary_initial_mode\n@@ -0,0 +1,4 @@\n+$ git diff-tree -R --stat --compact-summary initial mode\n+ M-x file0 | 0\n+ 1 file changed, 0 insertions(+), 0 deletions(-)\n+$\n-- \n2.15.1.600.g899a5f85c6\n\n"},{"id":"336813","messageId":"CAPig+cQLgs59JYxcmK30qY307ArwqJx6pNOo95Z39_jJ9+D6+g@mail.gmail.com","threadId":"47605","inReplyTo":"20180118100546.32251-1-pclouds@gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-01-18T18:57:16Z","receivedAt":"2018-01-18T18:57:22Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Jan 18, 2018 at 5:05 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> [...]\n> The new option --compact-summary implements this with a tweak to support\n> mode change, which is shown in --summary too.\n>\n> For mode changes, executable bit is denoted as \"M+x\" or \"M-x\" when it's\n> added or removed respectively. The same for when a regular file is\n> replaced with a symlink \"M+l\" or the other way \"M-l\". This also applies\n> to new files. New regulare files are \"A\", while new executable files or\n\ns/regulare/regular/\n\n> symlinks are \"A+x\" or \"A+l\".\n> [...]\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n> diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\n> @@ -188,6 +188,17 @@ and accumulating child directory counts in the parent directories:\n> +--compact-summary::\n> +       Output a condensed summary of extended header information in\n> +       front of the file name part of diffstat. This option is\n> +       ignored if --stat is not specified.\n\nRather than ignoring this option if --stat is not specified, a\ndifferent approach would be for --compact-summary to imply --stat.\n\nAlso, per documentation:\n\n    --stat[=<width>[,<name-width>[,<count>]]]::\n\n    These parameters can also be set individually with `--stat-width=<width>`,\n    `--stat-name-width=<name-width>` and `--stat-count=<count>`.\n\nOne wonders if \"compact\" could be another modifier recognized by --stat.\n\n(Genuine questions/observations; I haven't formed strong opinions either way.)\n\n> diff --git a/diff.c b/diff.c\n> @@ -2287,6 +2289,18 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n> +       for (i = 0; (i < count) && (i < data->nr); i++) {\n\nNoisy extra parentheses...\n\n    for (i = 0; i < count && i < data->nr; i++) {\n\nperhaps? (Not at all worth a re-roll.)\n\n> +               const struct diffstat_file *file = data->files[i];\n> +               int len;\n> +\n> +               if (!file->status_code)\n> +                       continue;\n> +               len = strlen(file->status_code) + 1;\n\nThe +1 is for the space following the status code? (Reading ahead,\nthat seems to be the case.)\n\n    len = strlen(file->status_code) + strlen(\" \");\n\nperhaps? (Probably not worth a re-roll.)\n\n> +               if (len > max_status_len)\n> +                       max_status_len = len;\n> +       }\n> +\n> @@ -2383,6 +2397,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)\n>                       options->stat_name_width < max_len) ?\n>                 options->stat_name_width : max_len;\n>\n> +       name_width += max_status_len;\n\nI wonder if it would be clearer to account for the space after the the\nstatus code here rather than above when it was not obvious what +1 was\nfor.\n\n    name_width += max_status_len + strlen(\" \");\n\n(and drop the earlier +1)\n"},{"id":"336823","messageId":"87bmhqj1y6.fsf@evledraar.gmail.com","threadId":"47605","inReplyTo":"20180118100546.32251-1-pclouds@gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-01-18T21:23:45Z","receivedAt":"2018-01-18T21:24:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Jan 18 2018, Nguyễn Thái Ngọc Duy jotted:\n\n> This is partly inspired by gerrit web interface which shows diffstat\n> like this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\n> third line):\n>\n>\n>      Documentation/merge-config.txt     |  4 +\n>      builtin/merge.c                    |  2 +\n>    A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n>      t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n>    4 files changed, 132 insertions(+)\n\nThis feature is awesome. This has bothered me about --stat, but I\nhaven't done anything about it.\n\n> In other words, certain information currently shown with --summary is\n> embedded in the diffstat. This helps reading (all information of the\n> same file in the same line instead of two) and can reduce the number of\n> lines if you add/delete a lot of files.\n\nWait, isn't there a bug here in the existing --summary code, its\ndocumentation says it'll show information \"such as creations, renames\nand mode changes\".\n\nBut even though your --compact-summary shows that the file is being\nadded and its mode changed:\n\n    $ diff -ru <(./git-show --stat 0433d533f1) <(./git-show --stat --compact-summary 0433d533f1)\n    --- /dev/fd/63  2018-01-18 21:11:51.186570555 +0000\n    +++ /dev/fd/62  2018-01-18 21:11:51.186570555 +0000\n    @@ -14,8 +14,8 @@\n           t: add tests for pull --verify-signatures\n           merge: add config option for verifySignatures\n\n    - Documentation/merge-config.txt     |  4 ++\n    - builtin/merge.c                    |  2 +\n    - t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++++++++++++++++\n    - t/t7612-merge-verify-signatures.sh | 45 +++++++++++++++++++++\n    +     Documentation/merge-config.txt     |  4 ++\n    +     builtin/merge.c                    |  2 +\n    + A+x t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++++++++++++\n    +     t/t7612-merge-verify-signatures.sh | 45 +++++++++++++++++++\n      4 files changed, 132 insertions(+)\n\nThere is no difference between --stat with and without --summary on the\nsame commit, shouldn't it show \"create mode [...]\" ?\n\nE.g. 95450bbbaa will do the trick for both:\n\n    $ diff -ru <(./git-show --stat 95450bbbaa) <(./git-show --stat --summary 95450bbbaa)\n    --- /dev/fd/63  2018-01-18 21:14:20.770050599 +0000\n    +++ /dev/fd/62  2018-01-18 21:14:20.770050599 +0000\n    @@ -14,3 +14,4 @@\n      git-svn.perl                    |  1 +\n      t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n      2 files changed, 28 insertions(+)\n    + create mode 100755 t/t9169-git-svn-dcommit-crlf.sh\n\n    $ diff -ru <(./git-show --stat --summary 95450bbbaa) <(./git-show --stat --compact-summary 95450bbbaa)\n    --- /dev/fd/63  2018-01-18 21:14:30.646016210 +0000\n    +++ /dev/fd/62  2018-01-18 21:14:30.646016210 +0000\n    @@ -11,7 +11,6 @@\n         Reported-by: Brian Bennett <Brian.Bennett@Transamerica.com>\n         Signed-off-by: Eric Wong <e@80x24.org>\n\n    - git-svn.perl                    |  1 +\n    - t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n    +     git-svn.perl                    |  1 +\n    + A+x t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n      2 files changed, 28 insertions(+)\n    - create mode 100755 t/t9169-git-svn-dcommit-crlf.sh\n\n> +--compact-summary::\n> +\tOutput a condensed summary of extended header information in\n> +\tfront of the file name part of diffstat. This option is\n> +\tignored if --stat is not specified.\n> ++\n\nIf for some reason the lack of information about the commit under\n--summary isn't a bug/fixable it makes sense to document the differences\nhere.\n\n> +File creations or deletions are denoted wigth \"A\" or \"D\" respectively,\n\ns/wigth/with/\n\n> +optionally \"+l\" if it's a symlink, or \"+x\" if it's executable.\n> +Mode changes are shown \"M+x\" or \"M-x\" for adding or removing\n\n\"Mode changes are shown as\" is better worded.\n"},{"id":"336846","messageId":"20180118224814.GA8473@sigill.intra.peff.net","threadId":"47605","inReplyTo":"20180118100546.32251-1-pclouds@gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-01-18T22:48:14Z","receivedAt":"2018-01-18T22:48:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 18, 2018 at 05:05:46PM +0700, Nguyễn Thái Ngọc Duy wrote:\n\n> This is partly inspired by gerrit web interface which shows diffstat\n> like this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\n> third line):\n> \n>      Documentation/merge-config.txt     |  4 +\n>      builtin/merge.c                    |  2 +\n>    A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n>      t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n>    4 files changed, 132 insertions(+)\n\nI like the general concept. Perusing \"git log\" output, though, it felt\nlike the summary column was very close to the filenames. What do you\nthink of putting it after the \"|\", where it is only close to a number?\n\nSomething like the patch below (on top of yours, but it probably needs\ntweaked further for graph_width), which gives:\n\n   t/t5573-pull-verify-signatures.sh | A+x  78 ++++++++++++++++++++++++++++\n\n(I know this is a bikeshed, so I'm perfectly willing to take \"yuck, I\ndon't like that as well\" as a response).\n\n> The new option --compact-summary implements this with a tweak to support\n> mode change, which is shown in --summary too.\n\nOne thing I noticed is that --compact-summary by itself does nothing.\nShould it imply --stat?\n\n-Peff\n"},{"id":"336861","messageId":"CACsJy8B5qrN8T1aai3y3nfEc5baqn2Xkk6vZozMp5Lh-mPZ0VQ@mail.gmail.com","threadId":"47605","inReplyTo":"CAPig+cQLgs59JYxcmK30qY307ArwqJx6pNOo95Z39_jJ9+D6+g@mail.gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-19T00:01:04Z","receivedAt":"2018-01-19T00:01:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 19, 2018 at 1:57 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\n>> @@ -188,6 +188,17 @@ and accumulating child directory counts in the parent directories:\n>> +--compact-summary::\n>> +       Output a condensed summary of extended header information in\n>> +       front of the file name part of diffstat. This option is\n>> +       ignored if --stat is not specified.\n>\n> Rather than ignoring this option if --stat is not specified, a\n> different approach would be for --compact-summary to imply --stat.\n>\n> Also, per documentation:\n>\n>     --stat[=<width>[,<name-width>[,<count>]]]::\n>\n>     These parameters can also be set individually with `--stat-width=<width>`,\n>     `--stat-name-width=<name-width>` and `--stat-count=<count>`.\n>\n> One wonders if \"compact\" could be another modifier recognized by --stat.\n>\n> (Genuine questions/observations; I haven't formed strong opinions either way.)\n\nI left open an option to combine this with other --*stat like numstat\n(or unlikely, dirstat). I haven't really thought about this. Yeah\nperhaps putting this in --stat would be a better move.\n--\nDuy\n"},{"id":"336862","messageId":"CACsJy8CXPP_75TEHvcWStm1ZneMDP+ioA=7iYcL25oEUiVHKxw@mail.gmail.com","threadId":"47605","inReplyTo":"87bmhqj1y6.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-19T00:06:17Z","receivedAt":"2018-01-19T00:06:53Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 19, 2018 at 4:23 AM, Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> Wait, isn't there a bug here in the existing --summary code, its\n> documentation says it'll show information \"such as creations, renames\n> and mode changes\".\n>\n> But even though your --compact-summary shows that the file is being\n> added and its mode changed:\n>\n>     $ diff -ru <(./git-show --stat 0433d533f1) <(./git-show --stat --compact-summary 0433d533f1)\n>     --- /dev/fd/63  2018-01-18 21:11:51.186570555 +0000\n>     +++ /dev/fd/62  2018-01-18 21:11:51.186570555 +0000\n>     @@ -14,8 +14,8 @@\n>            t: add tests for pull --verify-signatures\n>            merge: add config option for verifySignatures\n>\n>     - Documentation/merge-config.txt     |  4 ++\n>     - builtin/merge.c                    |  2 +\n>     - t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++++++++++++++++\n>     - t/t7612-merge-verify-signatures.sh | 45 +++++++++++++++++++++\n>     +     Documentation/merge-config.txt     |  4 ++\n>     +     builtin/merge.c                    |  2 +\n>     + A+x t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++++++++++++\n>     +     t/t7612-merge-verify-signatures.sh | 45 +++++++++++++++++++\n>       4 files changed, 132 insertions(+)\n>\n> There is no difference between --stat with and without --summary on the\n> same commit, shouldn't it show \"create mode [...]\" ?\n>\n> E.g. 95450bbbaa will do the trick for both:\n>\n>     $ diff -ru <(./git-show --stat 95450bbbaa) <(./git-show --stat --summary 95450bbbaa)\n>     --- /dev/fd/63  2018-01-18 21:14:20.770050599 +0000\n>     +++ /dev/fd/62  2018-01-18 21:14:20.770050599 +0000\n>     @@ -14,3 +14,4 @@\n>       git-svn.perl                    |  1 +\n>       t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n>       2 files changed, 28 insertions(+)\n>     + create mode 100755 t/t9169-git-svn-dcommit-crlf.sh\n>\n>     $ diff -ru <(./git-show --stat --summary 95450bbbaa) <(./git-show --stat --compact-summary 95450bbbaa)\n>     --- /dev/fd/63  2018-01-18 21:14:30.646016210 +0000\n>     +++ /dev/fd/62  2018-01-18 21:14:30.646016210 +0000\n>     @@ -11,7 +11,6 @@\n>          Reported-by: Brian Bennett <Brian.Bennett@Transamerica.com>\n>          Signed-off-by: Eric Wong <e@80x24.org>\n>\n>     - git-svn.perl                    |  1 +\n>     - t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n>     +     git-svn.perl                    |  1 +\n>     + A+x t/t9169-git-svn-dcommit-crlf.sh | 27 +++++++++++++++++++++++++++\n>       2 files changed, 28 insertions(+)\n>     - create mode 100755 t/t9169-git-svn-dcommit-crlf.sh\n\nInteresting. 0433d533f1 is a merge commit, perhaps that has something\nto do with this. Adding --first-parent does show \"create mode\" line.\nI'll check this later.\n-- \nDuy\n"},{"id":"336866","messageId":"CACsJy8CPHk+aXHr-mkHZi27s=c3+ny8D9CSuzOSO8PweviBcqQ@mail.gmail.com","threadId":"47605","inReplyTo":"20180118224814.GA8473@sigill.intra.peff.net","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-19T00:26:28Z","receivedAt":"2018-01-19T00:27:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 19, 2018 at 5:48 AM, Jeff King <peff@peff.net> wrote:\n> On Thu, Jan 18, 2018 at 05:05:46PM +0700, Nguyễn Thái Ngọc Duy wrote:\n>\n>> This is partly inspired by gerrit web interface which shows diffstat\n>> like this, e.g. with commit 0433d533f1 (notice the \"A\" column on the\n>> third line):\n>>\n>>      Documentation/merge-config.txt     |  4 +\n>>      builtin/merge.c                    |  2 +\n>>    A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n>>      t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n>>    4 files changed, 132 insertions(+)\n>\n> I like the general concept. Perusing \"git log\" output, though, it felt\n> like the summary column was very close to the filenames. What do you\n> think of putting it after the \"|\", where it is only close to a number?\n>\n> Something like the patch below (on top of yours, but it probably needs\n> tweaked further for graph_width), which gives:\n>\n>    t/t5573-pull-verify-signatures.sh | A+x  78 ++++++++++++++++++++++++++++\n>\n> (I know this is a bikeshed, so I'm perfectly willing to take \"yuck, I\n> don't like that as well\" as a response).\n\nThe position of A+x column is exactly where gerrit put it. Though web\npages have more flexibility than our terminal console so its position\ndoes not have to be the same. I'm just throwing options out there\n\nFor many years I have this instead\n\n t/t5573-pull-verify-signatures.sh (new +x) | 81 ++++++++++++++++++++\n\nAnother option is just wrap the code in [] to make it look like check\nboxes. But that wastes two more columns\n\n       builtin/merge.c                    |  2 +\n [A+x] t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++\n       t/t7612-merge-verify-signatures.sh | 45 +++++++++++++\n\nBack to your suggestion, I kinda like the closeness between the +/-\ncount and \"|\" though. The output on 10c78a162f is like this, which\nmakes \"A\" looks a bit umm.. disconnected from the path name?\n\n  Documentation/RelNotes/2.14.0.txt | A  97 +++++++++++++++++++++++++++\n  GIT-VERSION-GEN                   |     2 +-\n  RelNotes                          |     2 +-\n\nAnother way is just separate the status code from file name\n\n A | Documentation/RelNotes/2.14.0.txt | 97 +++++++++++++++++++++++++++\n   | GIT-VERSION-GEN                   |  2 +-\n   | RelNotes                          |  2 +-\n\nLast note. With colored diffstat, we should be able to use a separate\ncolor (or something in the +/- part) to denote new/deleted files. I\ndidn't think about this...\n\n>> The new option --compact-summary implements this with a tweak to support\n>> mode change, which is shown in --summary too.\n>\n> One thing I noticed is that --compact-summary by itself does nothing.\n> Should it imply --stat?\n\nIt might go with --numstat or --dirstat in future too. Didn't really\nthink hard about this yet. But I probably will go with Eric suggestion\nand keep this in --stat=.... unless it really makes sense to have\nsomething like this in --numstat or --dirstat.\n-- \nDuy\n"},{"id":"336937","messageId":"xmqq607xpmty.fsf@gitster.mtv.corp.google.com","threadId":"47605","inReplyTo":"20180118100546.32251-1-pclouds@gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-01-19T21:20:41Z","receivedAt":"2018-01-19T21:20:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n>      Documentation/merge-config.txt     |  4 +\n>      builtin/merge.c                    |  2 +\n>    A t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++\n>      t/t7612-merge-verify-signatures.sh | 45 ++++++++++\n>    4 files changed, 132 insertions(+)\n> ...\n> With this tweak, the actual printout is like this\n>\n>      Documentation/merge-config.txt     |  4 ++\n>      builtin/merge.c                    |  2 +\n>  A+x t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++\n>      t/t7612-merge-verify-signatures.sh | 45 +++++++++++++\n>  4 files changed, 132 insertions(+)\n\nI like the concept but given that additions and mode changes are\nrare events, I am not so sure if it is worth always wasting three\ncolumns like the above.  Assuming that this is solely meant for\nhuman consumption and machine parsability is of no concern, I\nactually prefer the output format you said you've been using your\npersonal fork, e.g.\n\n Documentation/merge-config.txt              |  4 ++\n builtin/merge.c                             |  2 +\n t/t5573-pull-verify-signatures.sh (new, +x) | 81 ++++++++++++++++++++++++\n t/t7612-merge-verify-signatures.sh          | 45 +++++++++++++\n\nThat is\n\n (1) do not change the starting column at the leftmost end, and\n (2) do not permanently allocate the columns for \"compact\" summary.\n\nInstead, the above may be (a) just stealing the columns needed for\n\"(new, +x)\" from the pathname portion of the output, and/or (2)\nwidening the pathname portion of the output for the whole thing\nwhile doing so.\n\n"},{"id":"336943","messageId":"20180119215219.GC12074@sigill.intra.peff.net","threadId":"47605","inReplyTo":"CACsJy8CPHk+aXHr-mkHZi27s=c3+ny8D9CSuzOSO8PweviBcqQ@mail.gmail.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-01-19T21:52:19Z","receivedAt":"2018-01-19T21:52:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 19, 2018 at 07:26:28AM +0700, Duy Nguyen wrote:\n\n> > (I know this is a bikeshed, so I'm perfectly willing to take \"yuck, I\n> > don't like that as well\" as a response).\n> \n> The position of A+x column is exactly where gerrit put it. Though web\n> pages have more flexibility than our terminal console so its position\n> does not have to be the same. I'm just throwing options out there\n> \n> For many years I have this instead\n> \n>  t/t5573-pull-verify-signatures.sh (new +x) | 81 ++++++++++++++++++++\n> \n> Another option is just wrap the code in [] to make it look like check\n> boxes. But that wastes two more columns\n> \n>        builtin/merge.c                    |  2 +\n>  [A+x] t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++\n>        t/t7612-merge-verify-signatures.sh | 45 +++++++++++++\n\nYeah, I almost suggested brackets, but wasn't sure if people would balk\nat the extra 2 columns. But they do help it stand out more. Colors would\nhelp, too, as you noted. Though they would not transfer over email, and\nI wonder if people would want to use this for format-patch.\n\n> Back to your suggestion, I kinda like the closeness between the +/-\n> count and \"|\" though. The output on 10c78a162f is like this, which\n> makes \"A\" looks a bit umm.. disconnected from the path name?\n> \n>   Documentation/RelNotes/2.14.0.txt | A  97 +++++++++++++++++++++++++++\n>   GIT-VERSION-GEN                   |     2 +-\n>   RelNotes                          |     2 +-\n\nYeah, I was trying to get it away from the pathname, since it doesn't\nstand out as much. I guess it depends how you think of the \"A\". To me it\nis sensible as a modifier for the line-count change. I.e., My read on\nthe output above is \"here is a path; it was added with 97 lines\".\n\n> > One thing I noticed is that --compact-summary by itself does nothing.\n> > Should it imply --stat?\n> \n> It might go with --numstat or --dirstat in future too. Didn't really\n> think hard about this yet. But I probably will go with Eric suggestion\n> and keep this in --stat=.... unless it really makes sense to have\n> something like this in --numstat or --dirstat.\n\nI'd think that most consumers of --numstat are not human, and would\njust use \"--numstat --raw\" to get all the information. But I also have\nnot thought hard about it.\n\nAnyway, thanks for listening. :)\n\n-Peff\n"},{"id":"336944","messageId":"20180119215344.GD12074@sigill.intra.peff.net","threadId":"47605","inReplyTo":"xmqq607xpmty.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2] diff: add --compact-summary option to complement --stat","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-01-19T21:53:44Z","receivedAt":"2018-01-19T21:53:50Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 19, 2018 at 01:20:41PM -0800, Junio C Hamano wrote:\n\n> >      Documentation/merge-config.txt     |  4 ++\n> >      builtin/merge.c                    |  2 +\n> >  A+x t/t5573-pull-verify-signatures.sh  | 81 ++++++++++++++++++++++++\n> >      t/t7612-merge-verify-signatures.sh | 45 +++++++++++++\n> >  4 files changed, 132 insertions(+)\n> \n> I like the concept but given that additions and mode changes are\n> rare events, I am not so sure if it is worth always wasting three\n> columns like the above.  Assuming that this is solely meant for\n> human consumption and machine parsability is of no concern, I\n> actually prefer the output format you said you've been using your\n> personal fork, e.g.\n> \n>  Documentation/merge-config.txt              |  4 ++\n>  builtin/merge.c                             |  2 +\n>  t/t5573-pull-verify-signatures.sh (new, +x) | 81 ++++++++++++++++++++++++\n>  t/t7612-merge-verify-signatures.sh          | 45 +++++++++++++\n> \n> That is\n> \n>  (1) do not change the starting column at the leftmost end, and\n>  (2) do not permanently allocate the columns for \"compact\" summary.\n\nI think the patch already does (2). In fact, it computes the max\ncompact-status size (so if you only have \"A\" and not \"A+x\", it wastes\nonly the one column).\n\nI agree that (1) would save space in some cases, though IMHO it's a\nlittle hard to notice.\n\n-Peff\n"}]}