Re: [PATCH] merge/pull: --compact-summary
- From
D. Ben Knoble <ben.knoble@gmail.com>
- Date
- Jun 10, 2025, 21:16 UTC
- Message-ID
- <CALnO6CCnjP2XnCw1CwyXztkHHMv-U4zrvf8_m2X4-isvPL3ygg@mail.gmail.com>
- In-Reply-To
- <xmqq5xh6xlpm.fsf@gitster.g>
On Sun, Jun 8, 2025 at 12:06 PM Junio C Hamano <gitster@pobox.com> wrote:
Show 9 quoted lines
>
> By default, "git merge" and "git pull" shows "git diff --stat @{1}"
> to show the extent of the changes. While it gives a good overview,
> one thing that is missing in this output is which paths are created
> and/or deleted.
>
> Introduce "--compact-summary" option to these two commands that
> tells it to instead show "git diff --compact-summary @{1}", which
> gives the same diffstat but notes the created or deleted paths.Does this suggest that we either want a "diff options" option (or config), which would be more general? Or perhaps that the intended workflow if you want a compact summary is instead
git [merge|pull] …
git diff --compact-summary HEAD^?
(The code seems reasonable, just wondering about the motivation/workflow.)
Show 179 quoted lines
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> Documentation/git-merge.adoc | 2 +-
> Documentation/merge-options.adoc | 3 +++
> builtin/merge.c | 39 ++++++++++++++++++++++++++++----
> builtin/pull.c | 3 +++
> t/t7600-merge.sh | 28 ++++++++++++++++++++++-
> 5 files changed, 69 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/git-merge.adoc b/Documentation/git-merge.adoc
> index 12aa859d16..d53923c3b7 100644
> --- a/Documentation/git-merge.adoc
> +++ b/Documentation/git-merge.adoc
> @@ -9,7 +9,7 @@ git-merge - Join two or more development histories together
> SYNOPSIS
> --------
> [synopsis]
> -git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
> +git merge [-n] [--stat] [--compact-summary] [--no-commit] [--squash] [--[no-]edit]
> [--no-verify] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
> [--[no-]allow-unrelated-histories]
> [--[no-]rerere-autoupdate] [-m <msg>] [-F <file>]
> diff --git a/Documentation/merge-options.adoc b/Documentation/merge-options.adoc
> index 078f4f6157..95ef491be1 100644
> --- a/Documentation/merge-options.adoc
> +++ b/Documentation/merge-options.adoc
> @@ -113,6 +113,9 @@ include::signoff-option.adoc[]
> With `-n` or `--no-stat` do not show a diffstat at the end of the
> merge.
>
> +`--compact-summary`::
> + Show a compact-summary at the end of the merge.
> +
> `--squash`::
> `--no-squash`::
> Produce the working tree and index state as if a real merge
> diff --git a/builtin/merge.c b/builtin/merge.c
> index ce90e52fe4..736739d3a9 100644
> --- a/builtin/merge.c
> +++ b/builtin/merge.c
> @@ -69,7 +69,10 @@ static const char * const builtin_merge_usage[] = {
> NULL
> };
>
> -static int show_diffstat = 1, shortlog_len = -1, squash;
> +#define MERGE_SHOW_DIFFSTAT 1
> +#define MERGE_SHOW_COMPACTSUMMARY 2
> +
> +static int show_diffstat = MERGE_SHOW_DIFFSTAT, shortlog_len = -1, squash;
> static int option_commit = -1;
> static int option_edit = -1;
> static int allow_trivial = 1, have_message, verify_signatures;
> @@ -243,12 +246,28 @@ static int option_parse_strategy(const struct option *opt UNUSED,
> return 0;
> }
>
> +static int option_parse_compact_summary(const struct option *opt,
> + const char *name UNUSED, int unset)
> +{
> + int *setting = opt->value;
> +
> + if (unset)
> + *setting = 0;
> + else
> + *setting = MERGE_SHOW_COMPACTSUMMARY;
> + return 0;
> +}
> +
> static struct option builtin_merge_options[] = {
> OPT_SET_INT('n', NULL, &show_diffstat,
> N_("do not show a diffstat at the end of the merge"), 0),
> OPT_BOOL(0, "stat", &show_diffstat,
> N_("show a diffstat at the end of the merge")),
> OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")),
> + OPT_CALLBACK_F(0, "compact-summary", &show_diffstat, N_("compact-summary"),
> + N_("show a compactstat at the end of the merge"),
> + PARSE_OPT_NOARG,
> + option_parse_compact_summary),
> {
> .type = OPTION_INTEGER,
> .long_name = "log",
> @@ -494,8 +513,19 @@ static void finish(struct commit *head_commit,
> struct diff_options opts;
> repo_diff_setup(the_repository, &opts);
> init_diffstat_widths(&opts);
> - opts.output_format |=
> - DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
> +
> + switch (show_diffstat) {
> + case MERGE_SHOW_DIFFSTAT: /* 1 */
> + opts.output_format |=
> + DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
> + break;
> + case MERGE_SHOW_COMPACTSUMMARY: /* 2 */
> + opts.output_format |= DIFF_FORMAT_DIFFSTAT;
> + opts.flags.stat_with_summary = 1;
> + break;
> + default:
> + break;
> + }
> opts.detect_rename = DIFF_DETECT_RENAME;
> diff_setup_done(&opts);
> diff_tree_oid(head, new_head, "", &opts);
> @@ -643,7 +673,8 @@ static int git_merge_config(const char *k, const char *v,
> }
>
> if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat")) {
> - show_diffstat = git_config_bool(k, v);
> + show_diffstat = git_config_bool(k, v)
> + ? MERGE_SHOW_DIFFSTAT : 0;
> } else if (!strcmp(k, "merge.verifysignatures")) {
> verify_signatures = git_config_bool(k, v);
> } else if (!strcmp(k, "pull.twohead")) {
> diff --git a/builtin/pull.c b/builtin/pull.c
> index a1ebc6ad33..6e72a2e9a4 100644
> --- a/builtin/pull.c
> +++ b/builtin/pull.c
> @@ -143,6 +143,9 @@ static struct option pull_options[] = {
> OPT_PASSTHRU(0, "summary", &opt_diffstat, NULL,
> N_("(synonym to --stat)"),
> PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),
> + OPT_PASSTHRU(0, "compact-summary", &opt_diffstat, NULL,
> + N_("show a compact-summary at the end of the merge"),
> + PARSE_OPT_NOARG),
> OPT_PASSTHRU(0, "log", &opt_log, N_("n"),
> N_("add (at most <n>) entries from shortlog to merge commit message"),
> PARSE_OPT_OPTARG),
> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
> index 2a8df29219..ce666efbcc 100755
> --- a/t/t7600-merge.sh
> +++ b/t/t7600-merge.sh
> @@ -185,8 +185,19 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' '
> test_expect_success 'merge c0 with c1' '
> echo "OBJID HEAD@{0}: merge c1: Fast-forward" >reflog.expected &&
>
> + cat >expect <<-EOF &&
> + Updating FROM..TO
> + Fast-forward
> + file | 2 +-
> + other | 9 +++++++++
> + 2 files changed, 10 insertions(+), 1 deletion(-)
> + create mode 100644 other
> + EOF
> +
> git reset --hard c0 &&
> - git merge c1 &&
> + git merge c1 >out &&
> + sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
> + test_cmp expect actual &&
> verify_merge file result.1 &&
> verify_head "$c1" &&
>
> @@ -205,6 +216,21 @@ test_expect_success 'merge c0 with c1 with --ff-only' '
> verify_head "$c1"
> '
>
> +test_expect_success 'the same merge with compact summary' '
> + cat >expect <<-EOF &&
> + Updating FROM..TO
> + Fast-forward
> + file | 2 +-
> + other (new) | 9 +++++++++
> + 2 files changed, 10 insertions(+), 1 deletion(-)
> + EOF
> +
> + git reset --hard c0 &&
> + git merge --compact-summary c1 >out &&
> + sed -e "1s/^Updating [0-9a-f.]*/Updating FROM..TO/" out >actual &&
> + test_cmp expect actual
> +'
> +
> test_debug 'git log --graph --decorate --oneline --all'
>
> test_expect_success 'merge from unborn branch' '
> --
> 2.50.0-rc1-276-gda78c2366e
>
>-- D. Ben Knoble