On Sun, Jun 8, 2025 at 12:06 PM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > 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.) > > Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> > --- > 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