{"thread":{"id":"63604","subject":"[PATCH] merge/pull: --compact-summary","startedAt":"2025-06-08T16:05:44Z","lastAt":"2025-06-11T23:26:47Z","messageCount":7,"participants":["Junio C Hamano","D. Ben Knoble","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"519936","messageId":"xmqq5xh6xlpm.fsf@gitster.g","threadId":"63604","inReplyTo":null,"subject":"[PATCH] merge/pull: --compact-summary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-08T16:05:41Z","receivedAt":"2025-06-08T16:05:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"By default, \"git merge\" and \"git pull\" shows \"git diff --stat @{1}\"\nto show the extent of the changes.  While it gives a good overview,\none thing that is missing in this output is which paths are created\nand/or deleted.\n\nIntroduce \"--compact-summary\" option to these two commands that\ntells it to instead show \"git diff --compact-summary @{1}\", which\ngives the same diffstat but notes the created or deleted paths.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-merge.adoc     |  2 +-\n Documentation/merge-options.adoc |  3 +++\n builtin/merge.c                  | 39 ++++++++++++++++++++++++++++----\n builtin/pull.c                   |  3 +++\n t/t7600-merge.sh                 | 28 ++++++++++++++++++++++-\n 5 files changed, 69 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-merge.adoc b/Documentation/git-merge.adoc\nindex 12aa859d16..d53923c3b7 100644\n--- a/Documentation/git-merge.adoc\n+++ b/Documentation/git-merge.adoc\n@@ -9,7 +9,7 @@ git-merge - Join two or more development histories together\n SYNOPSIS\n --------\n [synopsis]\n-git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]\n+git merge [-n] [--stat] [--compact-summary] [--no-commit] [--squash] [--[no-]edit]\n \t[--no-verify] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]\n \t[--[no-]allow-unrelated-histories]\n \t[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>]\ndiff --git a/Documentation/merge-options.adoc b/Documentation/merge-options.adoc\nindex 078f4f6157..95ef491be1 100644\n--- a/Documentation/merge-options.adoc\n+++ b/Documentation/merge-options.adoc\n@@ -113,6 +113,9 @@ include::signoff-option.adoc[]\n With `-n` or `--no-stat` do not show a diffstat at the end of the\n merge.\n \n+`--compact-summary`::\n+\tShow a compact-summary at the end of the merge.\n+\n `--squash`::\n `--no-squash`::\n \tProduce the working tree and index state as if a real merge\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex ce90e52fe4..736739d3a9 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -69,7 +69,10 @@ static const char * const builtin_merge_usage[] = {\n \tNULL\n };\n \n-static int show_diffstat = 1, shortlog_len = -1, squash;\n+#define MERGE_SHOW_DIFFSTAT 1\n+#define MERGE_SHOW_COMPACTSUMMARY 2\n+\n+static int show_diffstat = MERGE_SHOW_DIFFSTAT, shortlog_len = -1, squash;\n static int option_commit = -1;\n static int option_edit = -1;\n static int allow_trivial = 1, have_message, verify_signatures;\n@@ -243,12 +246,28 @@ static int option_parse_strategy(const struct option *opt UNUSED,\n \treturn 0;\n }\n \n+static int option_parse_compact_summary(const struct option *opt,\n+\t\t\t\t\tconst char *name UNUSED, int unset)\n+{\n+\tint *setting = opt->value;\n+\n+\tif (unset)\n+\t\t*setting = 0;\n+\telse\n+\t\t*setting = MERGE_SHOW_COMPACTSUMMARY;\n+\treturn 0;\n+}\n+\n static struct option builtin_merge_options[] = {\n \tOPT_SET_INT('n', NULL, &show_diffstat,\n \t\tN_(\"do not show a diffstat at the end of the merge\"), 0),\n \tOPT_BOOL(0, \"stat\", &show_diffstat,\n \t\tN_(\"show a diffstat at the end of the merge\")),\n \tOPT_BOOL(0, \"summary\", &show_diffstat, N_(\"(synonym to --stat)\")),\n+\tOPT_CALLBACK_F(0, \"compact-summary\", &show_diffstat, N_(\"compact-summary\"),\n+\t\t       N_(\"show a compactstat at the end of the merge\"),\n+\t\t       PARSE_OPT_NOARG,\n+\t\t       option_parse_compact_summary),\n \t{\n \t\t.type = OPTION_INTEGER,\n \t\t.long_name = \"log\",\n@@ -494,8 +513,19 @@ static void finish(struct commit *head_commit,\n \t\tstruct diff_options opts;\n \t\trepo_diff_setup(the_repository, &opts);\n \t\tinit_diffstat_widths(&opts);\n-\t\topts.output_format |=\n-\t\t\tDIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;\n+\n+\t\tswitch (show_diffstat) {\n+\t\tcase MERGE_SHOW_DIFFSTAT: /* 1 */\n+\t\t\topts.output_format |=\n+\t\t\t\tDIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;\n+\t\t\tbreak;\n+\t\tcase MERGE_SHOW_COMPACTSUMMARY: /* 2 */\n+\t\t\topts.output_format |= DIFF_FORMAT_DIFFSTAT;\n+\t\t\topts.flags.stat_with_summary = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n \t\topts.detect_rename = DIFF_DETECT_RENAME;\n \t\tdiff_setup_done(&opts);\n \t\tdiff_tree_oid(head, new_head, \"\", &opts);\n@@ -643,7 +673,8 @@ static int git_merge_config(const char *k, const char *v,\n \t}\n \n \tif (!strcmp(k, \"merge.diffstat\") || !strcmp(k, \"merge.stat\")) {\n-\t\tshow_diffstat = git_config_bool(k, v);\n+\t\tshow_diffstat = git_config_bool(k, v)\n+\t\t\t? MERGE_SHOW_DIFFSTAT : 0;\n \t} else if (!strcmp(k, \"merge.verifysignatures\")) {\n \t\tverify_signatures = git_config_bool(k, v);\n \t} else if (!strcmp(k, \"pull.twohead\")) {\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex a1ebc6ad33..6e72a2e9a4 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -143,6 +143,9 @@ static struct option pull_options[] = {\n \tOPT_PASSTHRU(0, \"summary\", &opt_diffstat, NULL,\n \t\tN_(\"(synonym to --stat)\"),\n \t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN),\n+\tOPT_PASSTHRU(0, \"compact-summary\", &opt_diffstat, NULL,\n+\t\tN_(\"show a compact-summary at the end of the merge\"),\n+\t\tPARSE_OPT_NOARG),\n \tOPT_PASSTHRU(0, \"log\", &opt_log, N_(\"n\"),\n \t\tN_(\"add (at most <n>) entries from shortlog to merge commit message\"),\n \t\tPARSE_OPT_OPTARG),\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 2a8df29219..ce666efbcc 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -185,8 +185,19 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' '\n test_expect_success 'merge c0 with c1' '\n \techo \"OBJID HEAD@{0}: merge c1: Fast-forward\" >reflog.expected &&\n \n+\tcat >expect <<-EOF &&\n+\tUpdating FROM..TO\n+\tFast-forward\n+\t file  | 2 +-\n+\t other | 9 +++++++++\n+\t 2 files changed, 10 insertions(+), 1 deletion(-)\n+\t create mode 100644 other\n+\tEOF\n+\n \tgit reset --hard c0 &&\n-\tgit merge c1 &&\n+\tgit merge c1 >out &&\n+\tsed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n+\ttest_cmp expect actual &&\n \tverify_merge file result.1 &&\n \tverify_head \"$c1\" &&\n \n@@ -205,6 +216,21 @@ test_expect_success 'merge c0 with c1 with --ff-only' '\n \tverify_head \"$c1\"\n '\n \n+test_expect_success 'the same merge with compact summary' '\n+\tcat >expect <<-EOF &&\n+\tUpdating FROM..TO\n+\tFast-forward\n+\t file        | 2 +-\n+\t other (new) | 9 +++++++++\n+\t 2 files changed, 10 insertions(+), 1 deletion(-)\n+\tEOF\n+\n+\tgit reset --hard c0 &&\n+\tgit merge --compact-summary c1 >out &&\n+\tsed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge from unborn branch' '\n-- \n2.50.0-rc1-276-gda78c2366e\n\n"},{"id":"520056","messageId":"CALnO6CCnjP2XnCw1CwyXztkHHMv-U4zrvf8_m2X4-isvPL3ygg@mail.gmail.com","threadId":"63604","inReplyTo":"xmqq5xh6xlpm.fsf@gitster.g","subject":"Re: [PATCH] merge/pull: --compact-summary","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-06-10T21:16:29Z","receivedAt":"2025-06-10T21:16:42Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Sun, Jun 8, 2025 at 12:06 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> By default, \"git merge\" and \"git pull\" shows \"git diff --stat @{1}\"\n> to show the extent of the changes.  While it gives a good overview,\n> one thing that is missing in this output is which paths are created\n> and/or deleted.\n>\n> Introduce \"--compact-summary\" option to these two commands that\n> tells it to instead show \"git diff --compact-summary @{1}\", which\n> gives the same diffstat but notes the created or deleted paths.\n\nDoes this suggest that we either want a \"diff options\" option (or\nconfig), which would be more general? Or perhaps that the intended\nworkflow if you want a compact summary is instead\n\n    git [merge|pull] …\n    git diff --compact-summary HEAD^\n\n?\n\n(The code seems reasonable, just wondering about the motivation/workflow.)\n\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  Documentation/git-merge.adoc     |  2 +-\n>  Documentation/merge-options.adoc |  3 +++\n>  builtin/merge.c                  | 39 ++++++++++++++++++++++++++++----\n>  builtin/pull.c                   |  3 +++\n>  t/t7600-merge.sh                 | 28 ++++++++++++++++++++++-\n>  5 files changed, 69 insertions(+), 6 deletions(-)\n>\n> diff --git a/Documentation/git-merge.adoc b/Documentation/git-merge.adoc\n> index 12aa859d16..d53923c3b7 100644\n> --- a/Documentation/git-merge.adoc\n> +++ b/Documentation/git-merge.adoc\n> @@ -9,7 +9,7 @@ git-merge - Join two or more development histories together\n>  SYNOPSIS\n>  --------\n>  [synopsis]\n> -git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]\n> +git merge [-n] [--stat] [--compact-summary] [--no-commit] [--squash] [--[no-]edit]\n>         [--no-verify] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]\n>         [--[no-]allow-unrelated-histories]\n>         [--[no-]rerere-autoupdate] [-m <msg>] [-F <file>]\n> diff --git a/Documentation/merge-options.adoc b/Documentation/merge-options.adoc\n> index 078f4f6157..95ef491be1 100644\n> --- a/Documentation/merge-options.adoc\n> +++ b/Documentation/merge-options.adoc\n> @@ -113,6 +113,9 @@ include::signoff-option.adoc[]\n>  With `-n` or `--no-stat` do not show a diffstat at the end of the\n>  merge.\n>\n> +`--compact-summary`::\n> +       Show a compact-summary at the end of the merge.\n> +\n>  `--squash`::\n>  `--no-squash`::\n>         Produce the working tree and index state as if a real merge\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index ce90e52fe4..736739d3a9 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -69,7 +69,10 @@ static const char * const builtin_merge_usage[] = {\n>         NULL\n>  };\n>\n> -static int show_diffstat = 1, shortlog_len = -1, squash;\n> +#define MERGE_SHOW_DIFFSTAT 1\n> +#define MERGE_SHOW_COMPACTSUMMARY 2\n> +\n> +static int show_diffstat = MERGE_SHOW_DIFFSTAT, shortlog_len = -1, squash;\n>  static int option_commit = -1;\n>  static int option_edit = -1;\n>  static int allow_trivial = 1, have_message, verify_signatures;\n> @@ -243,12 +246,28 @@ static int option_parse_strategy(const struct option *opt UNUSED,\n>         return 0;\n>  }\n>\n> +static int option_parse_compact_summary(const struct option *opt,\n> +                                       const char *name UNUSED, int unset)\n> +{\n> +       int *setting = opt->value;\n> +\n> +       if (unset)\n> +               *setting = 0;\n> +       else\n> +               *setting = MERGE_SHOW_COMPACTSUMMARY;\n> +       return 0;\n> +}\n> +\n>  static struct option builtin_merge_options[] = {\n>         OPT_SET_INT('n', NULL, &show_diffstat,\n>                 N_(\"do not show a diffstat at the end of the merge\"), 0),\n>         OPT_BOOL(0, \"stat\", &show_diffstat,\n>                 N_(\"show a diffstat at the end of the merge\")),\n>         OPT_BOOL(0, \"summary\", &show_diffstat, N_(\"(synonym to --stat)\")),\n> +       OPT_CALLBACK_F(0, \"compact-summary\", &show_diffstat, N_(\"compact-summary\"),\n> +                      N_(\"show a compactstat at the end of the merge\"),\n> +                      PARSE_OPT_NOARG,\n> +                      option_parse_compact_summary),\n>         {\n>                 .type = OPTION_INTEGER,\n>                 .long_name = \"log\",\n> @@ -494,8 +513,19 @@ static void finish(struct commit *head_commit,\n>                 struct diff_options opts;\n>                 repo_diff_setup(the_repository, &opts);\n>                 init_diffstat_widths(&opts);\n> -               opts.output_format |=\n> -                       DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;\n> +\n> +               switch (show_diffstat) {\n> +               case MERGE_SHOW_DIFFSTAT: /* 1 */\n> +                       opts.output_format |=\n> +                               DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;\n> +                       break;\n> +               case MERGE_SHOW_COMPACTSUMMARY: /* 2 */\n> +                       opts.output_format |= DIFF_FORMAT_DIFFSTAT;\n> +                       opts.flags.stat_with_summary = 1;\n> +                       break;\n> +               default:\n> +                       break;\n> +               }\n>                 opts.detect_rename = DIFF_DETECT_RENAME;\n>                 diff_setup_done(&opts);\n>                 diff_tree_oid(head, new_head, \"\", &opts);\n> @@ -643,7 +673,8 @@ static int git_merge_config(const char *k, const char *v,\n>         }\n>\n>         if (!strcmp(k, \"merge.diffstat\") || !strcmp(k, \"merge.stat\")) {\n> -               show_diffstat = git_config_bool(k, v);\n> +               show_diffstat = git_config_bool(k, v)\n> +                       ? MERGE_SHOW_DIFFSTAT : 0;\n>         } else if (!strcmp(k, \"merge.verifysignatures\")) {\n>                 verify_signatures = git_config_bool(k, v);\n>         } else if (!strcmp(k, \"pull.twohead\")) {\n> diff --git a/builtin/pull.c b/builtin/pull.c\n> index a1ebc6ad33..6e72a2e9a4 100644\n> --- a/builtin/pull.c\n> +++ b/builtin/pull.c\n> @@ -143,6 +143,9 @@ static struct option pull_options[] = {\n>         OPT_PASSTHRU(0, \"summary\", &opt_diffstat, NULL,\n>                 N_(\"(synonym to --stat)\"),\n>                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),\n> +       OPT_PASSTHRU(0, \"compact-summary\", &opt_diffstat, NULL,\n> +               N_(\"show a compact-summary at the end of the merge\"),\n> +               PARSE_OPT_NOARG),\n>         OPT_PASSTHRU(0, \"log\", &opt_log, N_(\"n\"),\n>                 N_(\"add (at most <n>) entries from shortlog to merge commit message\"),\n>                 PARSE_OPT_OPTARG),\n> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\n> index 2a8df29219..ce666efbcc 100755\n> --- a/t/t7600-merge.sh\n> +++ b/t/t7600-merge.sh\n> @@ -185,8 +185,19 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' '\n>  test_expect_success 'merge c0 with c1' '\n>         echo \"OBJID HEAD@{0}: merge c1: Fast-forward\" >reflog.expected &&\n>\n> +       cat >expect <<-EOF &&\n> +       Updating FROM..TO\n> +       Fast-forward\n> +        file  | 2 +-\n> +        other | 9 +++++++++\n> +        2 files changed, 10 insertions(+), 1 deletion(-)\n> +        create mode 100644 other\n> +       EOF\n> +\n>         git reset --hard c0 &&\n> -       git merge c1 &&\n> +       git merge c1 >out &&\n> +       sed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n> +       test_cmp expect actual &&\n>         verify_merge file result.1 &&\n>         verify_head \"$c1\" &&\n>\n> @@ -205,6 +216,21 @@ test_expect_success 'merge c0 with c1 with --ff-only' '\n>         verify_head \"$c1\"\n>  '\n>\n> +test_expect_success 'the same merge with compact summary' '\n> +       cat >expect <<-EOF &&\n> +       Updating FROM..TO\n> +       Fast-forward\n> +        file        | 2 +-\n> +        other (new) | 9 +++++++++\n> +        2 files changed, 10 insertions(+), 1 deletion(-)\n> +       EOF\n> +\n> +       git reset --hard c0 &&\n> +       git merge --compact-summary c1 >out &&\n> +       sed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n> +       test_cmp expect actual\n> +'\n> +\n>  test_debug 'git log --graph --decorate --oneline --all'\n>\n>  test_expect_success 'merge from unborn branch' '\n> --\n> 2.50.0-rc1-276-gda78c2366e\n>\n>\n\n\n-- \nD. Ben Knoble\n"},{"id":"520074","messageId":"xmqqzfefj7j3.fsf@gitster.g","threadId":"63604","inReplyTo":"CALnO6CCnjP2XnCw1CwyXztkHHMv-U4zrvf8_m2X4-isvPL3ygg@mail.gmail.com","subject":"Re: [PATCH] merge/pull: --compact-summary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-11T03:12:32Z","receivedAt":"2025-06-11T03:12:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n\n> Does this suggest that we either want a \"diff options\" option (or\n> config), which would be more general?\n\nIf I have bk/new-topic branch, here is how I would merge it.\n\n    $ git merge --compact-summary bk/new-topic\n\nbut there is an existing merge.stat that (1) is a mere boolean and\n(2) is true by default to force use of \"--stat\" option.  We could\nextend it to \"bool or the string 'compact-summary'\" and when it is\n\n - not set, do the \"--stat\" as before;\n - set to true, do the \"--stat\" as before;\n - set to 'compact-summary', do the \"--compact-summary\".\n\nWith such a configuration variable, \"git merge bk/new-topic\" would\nbe how I would run my merge.\n"},{"id":"520114","messageId":"xmqqfrg6i57t.fsf@gitster.g","threadId":"63604","inReplyTo":"xmqq5xh6xlpm.fsf@gitster.g","subject":"[PATCH 2/1] merge/pull: extend merge.stat configuration variable to cover --compact-summary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-11T17:00:06Z","receivedAt":"2025-06-11T17:00:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Existing `merge.stat` configuration variable is a Boolean that\ndefaults to `true` to control `git merge --[no-]stat` behaviour.\n\nExtend it to be \"Boolean or text\", that takes false, true, or\n\"compact\", with the last one triggering the --compact-summary\noption introduced earlier.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * \"git merge --(summary|stat)[=true/false/compact]\" is a\n   possibility on the command line options side, but options with\n   optional values are generally frowned upon, so [1/1] is unchanged\n   and introduces a new --compact-summary option.\n\n Documentation/config/merge.adoc | 12 ++++++++++--\n builtin/merge.c                 | 18 ++++++++++++++++--\n t/t7600-merge.sh                | 15 +++++++++++++++\n 3 files changed, 41 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config/merge.adoc b/Documentation/config/merge.adoc\nindex 86359f6dd2..251a48fdf8 100644\n--- a/Documentation/config/merge.adoc\n+++ b/Documentation/config/merge.adoc\n@@ -81,8 +81,16 @@ as `false`. Defaults to `conflict`.\n \tattributes\" in linkgit:gitattributes[5].\n \n `merge.stat`::\n-\tWhether to print the diffstat between `ORIG_HEAD` and the merge result\n-\tat the end of the merge.  True by default.\n+\tWhat, if anything, to print between `ORIG_HEAD` and the merge result\n+\tat the end of the merge.  Possible values are:\n++\n+--\n+`false`;; Show nothing.\n+`true`;; Show `git diff --diffstat ORIG_HEAD`.\n+`compact`;; Show `git diff --compact-summary ORIG_HEAD`.\n+--\n++\n+If this variable is left unspecified, it defaults to `true`.\n \n `merge.autoStash`::\n \tWhen set to `true`, automatically create a temporary stash entry\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 736739d3a9..65fed4b687 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -673,8 +673,22 @@ static int git_merge_config(const char *k, const char *v,\n \t}\n \n \tif (!strcmp(k, \"merge.diffstat\") || !strcmp(k, \"merge.stat\")) {\n-\t\tshow_diffstat = git_config_bool(k, v)\n-\t\t\t? MERGE_SHOW_DIFFSTAT : 0;\n+\t\tint val = git_parse_maybe_bool_text(v);\n+\t\tswitch (val) {\n+\t\tcase 0:\n+\t\t\tshow_diffstat = 0;\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tshow_diffstat = MERGE_SHOW_DIFFSTAT;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tif (!strcmp(v, \"compact\"))\n+\t\t\t\tshow_diffstat = MERGE_SHOW_COMPACTSUMMARY;\n+\t\t\telse\n+\t\t\t\t/* setting from the future -- use the default */\n+\t\t\t\tshow_diffstat = MERGE_SHOW_DIFFSTAT;\n+\t\t\tbreak;\n+\t\t}\n \t} else if (!strcmp(k, \"merge.verifysignatures\")) {\n \t\tverify_signatures = git_config_bool(k, v);\n \t} else if (!strcmp(k, \"pull.twohead\")) {\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex ce666efbcc..95842188e3 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -231,6 +231,21 @@ test_expect_success 'the same merge with compact summary' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'the same merge with merge.stat=compact' '\n+\tcat >expect <<-EOF &&\n+\tUpdating FROM..TO\n+\tFast-forward\n+\t file        | 2 +-\n+\t other (new) | 9 +++++++++\n+\t 2 files changed, 10 insertions(+), 1 deletion(-)\n+\tEOF\n+\n+\tgit reset --hard c0 &&\n+\tgit -c merge.stat=compact merge c1 >out &&\n+\tsed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge from unborn branch' '\n-- \n2.50.0-rc2-207-gc448ca4963\n\n"},{"id":"520115","messageId":"CAPig+cRgUWYGPb7o_9UgeQAuE5WN1mtC=bsOP=62rXOzjXJ5Eg@mail.gmail.com","threadId":"63604","inReplyTo":"xmqqfrg6i57t.fsf@gitster.g","subject":"Re: [PATCH 2/1] merge/pull: extend merge.stat configuration variable to cover --compact-summary","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2025-06-11T17:12:20Z","receivedAt":"2025-06-11T17:12:33Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Jun 11, 2025 at 1:00 PM Junio C Hamano <gitster@pobox.com> wrote:\n> Existing `merge.stat` configuration variable is a Boolean that\n> defaults to `true` to control `git merge --[no-]stat` behaviour.\n>\n> Extend it to be \"Boolean or text\", that takes false, true, or\n> \"compact\", with the last one triggering the --compact-summary\n> option introduced earlier.\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\n> @@ -231,6 +231,21 @@ test_expect_success 'the same merge with compact summary' '\n> +test_expect_success 'the same merge with merge.stat=compact' '\n> +       cat >expect <<-EOF &&\n\nDo we want \\EOF (with backslash)?\n\n> +       Updating FROM..TO\n> +       Fast-forward\n> +        file        | 2 +-\n> +        other (new) | 9 +++++++++\n> +        2 files changed, 10 insertions(+), 1 deletion(-)\n> +       EOF\n> +\n> +       git reset --hard c0 &&\n> +       git -c merge.stat=compact merge c1 >out &&\n> +       sed -e \"1s/^Updating [0-9a-f.]*/Updating FROM..TO/\" out >actual &&\n> +       test_cmp expect actual\n> +'\n"},{"id":"520117","messageId":"xmqq7c1ii3v4.fsf@gitster.g","threadId":"63604","inReplyTo":"CAPig+cRgUWYGPb7o_9UgeQAuE5WN1mtC=bsOP=62rXOzjXJ5Eg@mail.gmail.com","subject":"Re: [PATCH 2/1] merge/pull: extend merge.stat configuration variable to cover --compact-summary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-11T17:29:19Z","receivedAt":"2025-06-11T17:29:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> Do we want \\EOF (with backslash)?\n>\n>> +       Updating FROM..TO\n>> +       Fast-forward\n>> +        file        | 2 +-\n>> +        other (new) | 9 +++++++++\n>> +        2 files changed, 10 insertions(+), 1 deletion(-)\n>> +       EOF\n\nIndeed.  There is no interpolation necessary for the contents, so it\nis a very good idea to do that.  The same for the test part of\n[1/1].\n\nThanks.\n"},{"id":"520134","messageId":"CALnO6CCrCcEp1FWWWPQ2fts-n-jHZdfYWsyYsG9W5aUV42gs8Q@mail.gmail.com","threadId":"63604","inReplyTo":"xmqqzfefj7j3.fsf@gitster.g","subject":"Re: [PATCH] merge/pull: --compact-summary","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-06-11T23:26:35Z","receivedAt":"2025-06-11T23:26:47Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Tue, Jun 10, 2025 at 11:12 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> \"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n>\n> > Does this suggest that we either want a \"diff options\" option (or\n> > config), which would be more general?\n>\n> If I have bk/new-topic branch, here is how I would merge it.\n>\n>     $ git merge --compact-summary bk/new-topic\n>\n> but there is an existing merge.stat that (1) is a mere boolean and\n> (2) is true by default to force use of \"--stat\" option.  We could\n> extend it to \"bool or the string 'compact-summary'\" and when it is\n>\n>  - not set, do the \"--stat\" as before;\n>  - set to true, do the \"--stat\" as before;\n>  - set to 'compact-summary', do the \"--compact-summary\".\n>\n> With such a configuration variable, \"git merge bk/new-topic\" would\n> be how I would run my merge.\n\nMakes sense; I suppose my question was more along the lines of \"should\nwe go ahead and support extending the options we give to diff more\nbroadly rather than add a one-off flag (and potentially add more\nlater).\"\n\n-- \nD. Ben Knoble\n"}]}