* [PATCH v2 1/2] merge/pull: --compact-summary
2025-06-12 22:25 [PATCH v2 0/2] git pull/merge --compact-summary Junio C Hamano
@ 2025-06-12 22:25 ` Junio C Hamano
2025-06-13 12:07 ` Kristoffer Haugsbakk
2025-06-12 22:25 ` [PATCH v2 2/2] merge/pull: extend merge.stat configuration variable to cover --compact-summary Junio C Hamano
1 sibling, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2025-06-12 22:25 UTC (permalink / raw)
To: git
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.
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..2972922b6a 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-rc2-255-gd84100c98d
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 2/2] merge/pull: extend merge.stat configuration variable to cover --compact-summary
2025-06-12 22:25 [PATCH v2 0/2] git pull/merge --compact-summary Junio C Hamano
2025-06-12 22:25 ` [PATCH v2 1/2] merge/pull: --compact-summary Junio C Hamano
@ 2025-06-12 22:25 ` Junio C Hamano
2025-06-13 12:09 ` Kristoffer Haugsbakk
1 sibling, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2025-06-12 22:25 UTC (permalink / raw)
To: git
Existing `merge.stat` configuration variable is a Boolean that
defaults to `true` to control `git merge --[no-]stat` behaviour.
Extend it to be "Boolean or text", that takes false, true, or
"compact", with the last one triggering the --compact-summary
option introduced earlier.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/config/merge.adoc | 12 ++++++++++--
builtin/merge.c | 18 ++++++++++++++++--
t/t7600-merge.sh | 15 +++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/Documentation/config/merge.adoc b/Documentation/config/merge.adoc
index 86359f6dd2..251a48fdf8 100644
--- a/Documentation/config/merge.adoc
+++ b/Documentation/config/merge.adoc
@@ -81,8 +81,16 @@ as `false`. Defaults to `conflict`.
attributes" in linkgit:gitattributes[5].
`merge.stat`::
- Whether to print the diffstat between `ORIG_HEAD` and the merge result
- at the end of the merge. True by default.
+ What, if anything, to print between `ORIG_HEAD` and the merge result
+ at the end of the merge. Possible values are:
++
+--
+`false`;; Show nothing.
+`true`;; Show `git diff --diffstat ORIG_HEAD`.
+`compact`;; Show `git diff --compact-summary ORIG_HEAD`.
+--
++
+If this variable is left unspecified, it defaults to `true`.
`merge.autoStash`::
When set to `true`, automatically create a temporary stash entry
diff --git a/builtin/merge.c b/builtin/merge.c
index 736739d3a9..65fed4b687 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -673,8 +673,22 @@ 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)
- ? MERGE_SHOW_DIFFSTAT : 0;
+ int val = git_parse_maybe_bool_text(v);
+ switch (val) {
+ case 0:
+ show_diffstat = 0;
+ break;
+ case 1:
+ show_diffstat = MERGE_SHOW_DIFFSTAT;
+ break;
+ default:
+ if (!strcmp(v, "compact"))
+ show_diffstat = MERGE_SHOW_COMPACTSUMMARY;
+ else
+ /* setting from the future -- use the default */
+ show_diffstat = MERGE_SHOW_DIFFSTAT;
+ break;
+ }
} else if (!strcmp(k, "merge.verifysignatures")) {
verify_signatures = git_config_bool(k, v);
} else if (!strcmp(k, "pull.twohead")) {
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 2972922b6a..8046c6bb54 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -231,6 +231,21 @@ test_expect_success 'the same merge with compact summary' '
test_cmp expect actual
'
+test_expect_success 'the same merge with merge.stat=compact' '
+ 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 -c merge.stat=compact merge 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-rc2-255-gd84100c98d
^ permalink raw reply related [flat|nested] 7+ messages in thread