git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/5] diff-merges: implement [no-]hide option and log.diffMergesHide config

From
Sergey Organov <sorganov@gmail.com>
Date
Nov 27, 2022, 09:37 UTC
Message-ID
<20221127093721.31012-2-sorganov@gmail.com>
In-Reply-To
<20221127093721.31012-1-sorganov@gmail.com>

The set of diff-merges options happened to be incomplete, and failed to implement exact semantics of -m option that hides output of diffs for merge commits unless -p option is active as well.

The new "hide" option fixes this issue, so that now
  --diff-merges=on --diff-merges=hide
combo is the exact synonym for -m.

The log.diffMerges configuration also accepts "hide" and "no-hide" values, and governs the default value for the hide bit. The configuration behaves as if "--diff-merges=[no-]hide" is inserted first in the command-line.

New log.diffMergesHide boolean configuration is implemented as well, for the case when log.diffMerges is already in use for specifying the format.

Signed-off-by: Sergey Organov <sorganov@gmail.com>
---
 Documentation/config/log.txt                  |  6 +++
 Documentation/diff-options.txt                | 13 +++--
 builtin/log.c                                 |  2 +
 diff-merges.c                                 | 40 ++++++++++++--
 diff-merges.h                                 |  2 +
 t/t4013-diff-various.sh                       | 54 ++++++++++++++++++-
 ...ges=first-parent_--diff-merges=hide_master | 34 ++++++++++++
 t/t9902-completion.sh                         |  3 ++
 8 files changed, 147 insertions(+), 7 deletions(-)
 create mode 100644 t/t4013/diff.log_--diff-merges=first-parent_--diff-merges=hide_master
diff --git a/Documentation/config/log.txt b/Documentation/config/log.txt
index cbe34d759221..9c6be643bcf6 100644
--- a/Documentation/config/log.txt
+++ b/Documentation/config/log.txt
@@ -33,6 +33,12 @@ log.diffMerges::
 	Set diff format to be used when `--diff-merges=on` is
 	specified, see `--diff-merges` in linkgit:git-log[1] for
 	details. Defaults to `separate`.
++
+When used with 'hide' or 'no-hide', sets the default hiding of
+diffs for merge commits when `-p` option is not used.
+
+log.diffMergesHide::
+	`true` implies `--diff-merges=hide` option.
 
 log.follow::
 	If `true`, `git log` will act as if the `--follow` option was used when
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 3674ac48e92c..351d51215717 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -34,7 +34,7 @@ endif::git-diff[]
 endif::git-format-patch[]
 
 ifdef::git-log[]
---diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r)::
+--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc|remerge|r|[no-]hide)::
 --no-diff-merges::
 	Specify diff format to be used for merge commits. Default is
 	{diff-merges-default} unless `--first-parent` is in use, in which case
@@ -49,10 +49,11 @@ ifdef::git-log[]
 --diff-merges=m:::
 -m:::
 	This option makes diff output for merge commits to be shown in
-	the default format. `-m` will produce the output only if `-p`
-	is given as well. The default format could be changed using
+	the default format. The default format could be changed using
 	`log.diffMerges` configuration parameter, which default value
 	is `separate`.
++
+	`-m` is a shortcut for '--diff-merges=on --diff-merges=hide'
 +
 --diff-merges=first-parent:::
 --diff-merges=1:::
@@ -72,6 +73,12 @@ ifdef::git-log[]
 	with conflict markers and such.  A diff is then shown between
 	that temporary tree and the actual merge commit.
 +
+--diff-merges=hide:::
+--diff-merges=no-hide:::
+	Hide (do not hide) the diff for merge commits unless `-p` options is given
+	as well. The default `no-hide` could be changed using `log.diffMerges`
+	configuration parameter.
++
 The output emitted when this option is used is subject to change, and
 so is its interaction with other options (unless explicitly
 documented).
diff --git a/builtin/log.c b/builtin/log.c
index 56e2d95e869d..e031021e53b2 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -581,6 +581,8 @@ static int git_log_config(const char *var, const char *value, void *cb)
 	}
 	if (!strcmp(var, "log.diffmerges"))
 		return diff_merges_config(value);
+	if (!strcmp(var, "log.diffmergeshide"))
+		return diff_merges_hide_config(git_config_bool(var, value));
 	if (!strcmp(var, "log.showroot")) {
 		default_show_root = git_config_bool(var, value);
 		return 0;
diff --git a/diff-merges.c b/diff-merges.c
index 85cbefa5afd7..55fe5b70c102 100644
--- a/diff-merges.c
+++ b/diff-merges.c
@@ -7,6 +7,7 @@ static void set_separate(struct rev_info *revs);
 
 static diff_merges_setup_func_t set_to_default = set_separate;
 static int suppress_m_parsing;
+static int hide = 0;
 
 static void suppress(struct rev_info *revs)
 {
@@ -20,10 +21,15 @@ static void suppress(struct rev_info *revs)
 	revs->remerge_diff = 0;
 }
 
+static void set_need_diff(struct rev_info *revs)
+{
+	revs->merges_need_diff = !hide;
+}
+
 static void common_setup(struct rev_info *revs)
 {
 	suppress(revs);
-	revs->merges_need_diff = 1;
+	set_need_diff(revs);
 }
 
 static void set_none(struct rev_info *revs)
@@ -31,6 +37,18 @@ static void set_none(struct rev_info *revs)
 	suppress(revs);
 }
 
+static void set_hide(struct rev_info *revs)
+{
+	hide = 1;
+	set_need_diff(revs);
+}
+
+static void set_no_hide(struct rev_info *revs)
+{
+	hide = 0;
+	set_need_diff(revs);
+}
+
 static void set_separate(struct rev_info *revs)
 {
 	common_setup(revs);
@@ -69,6 +87,10 @@ static diff_merges_setup_func_t func_by_opt(const char *optarg)
 {
 	if (!strcmp(optarg, "off") || !strcmp(optarg, "none"))
 		return set_none;
+	if (!strcmp(optarg, "hide"))
+		return set_hide;
+	if (!strcmp(optarg, "no-hide"))
+		return set_no_hide;
 	if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent"))
 		return set_first_parent;
 	if (!strcmp(optarg, "separate"))
@@ -105,7 +127,19 @@ int diff_merges_config(const char *value)
 	if (!func)
 		return -1;
 
-	set_to_default = func;
+	if (func == set_hide)
+		hide = 1;
+	else if (func == set_no_hide)
+		hide = 0;
+	else
+		set_to_default = func;
+
+	return 0;
+}
+
+int diff_merges_hide_config(int on)
+{
+	hide = on;
 	return 0;
 }
 
@@ -122,7 +156,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv)
 
 	if (!suppress_m_parsing && !strcmp(arg, "-m")) {
 		set_to_default(revs);
-		revs->merges_need_diff = 0;
+		set_hide(revs);
 	} else if (!strcmp(arg, "-c")) {
 		set_combined(revs);
 		revs->merges_imply_patch = 1;
diff --git a/diff-merges.h b/diff-merges.h
index 19639689bb05..e86e5381693b 100644
--- a/diff-merges.h
+++ b/diff-merges.h
@@ -11,6 +11,8 @@ struct rev_info;
 
 int diff_merges_config(const char *value);
 
+int diff_merges_hide_config(int hide);
+
 void diff_merges_suppress_m_parsing(void);
 
 int diff_merges_parse_opts(struct rev_info *revs, const char **argv);
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index dfcf3a0aaae3..4fc8ba2fc59c 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -334,6 +334,7 @@ log --first-parent --diff-merges=off -p master
 log -p --first-parent master
 log -p --diff-merges=first-parent master
 log --diff-merges=first-parent master
+log --diff-merges=first-parent --diff-merges=hide master
 log -m -p --first-parent master
 log -m -p master
 log --cc -m -p master
@@ -460,7 +461,18 @@ EOF
 test_expect_success 'log -m matches pure log' '
 	git log master >result &&
 	process_diffs result >expected &&
-	git log -m >result &&
+	git log -m master >result &&
+	process_diffs result >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'log --diff-merges=on matches -m only with --diff-merges=hide' '
+	git log -m master >result &&
+	process_diffs result >expected &&
+	git log --diff-merges=on master >result &&
+	process_diffs result >actual &&
+	! test_cmp expected actual &&
+	git log --diff-merges=on --diff-merges=hide master >result &&
 	process_diffs result >actual &&
 	test_cmp expected actual
 '
@@ -496,6 +508,46 @@ test_expect_success 'git config log.diffMerges first-parent vs -m' '
 	test_cmp expected actual
 '
 
+test_expect_success 'git config log.diffMerges hide: has effect' '
+	git log --diff-merges=on master >result &&
+	process_diffs result >no-hide &&
+	test_config log.diffMerges hide &&
+	git log --diff-merges=on master >result &&
+	process_diffs result >hide &&
+	! test_cmp no-hide hide
+'
+
+test_expect_success 'git config log.diffMerges no-hide: is the default' '
+	git log --diff-merges=on master >result &&
+	process_diffs result >default &&
+	test_config log.diffMerges no-hide &&
+	git log --diff-merges=on master >result &&
+	process_diffs result >no-hide &&
+	test_cmp default no-hide
+'
+
+# As "-m" is synonym for "--diff-merges=hide --diff-merges=on", the
+# "log.diffMerges=hide" configuration should have no effect on "-m"
+test_expect_success 'git config log.diffMerges hide: has no effect on -m' '
+	git log -m master >result &&
+	process_diffs result >expected &&
+	test_config log.diffMerges hide &&
+	git log -m master >result &&
+	process_diffs result >actual &&
+	test_cmp expected actual
+'
+
+# As "--cc" implies "-p", the "log.diffMerges=hide" configuration
+# should have no effect on "--cc"
+test_expect_success 'git config log.diffMerges hide: has no effect on --cc' '
+	git log --cc master >result &&
+	process_diffs result >expected &&
+	test_config log.diffMerges hide &&
+	git log --cc master >result &&
+	process_diffs result >actual &&
+	test_cmp expected actual
+'
+
 # -m in "git diff-index" means "match missing", that differs
 # from its meaning in "git diff". Let's check it in diff-index.
 # The line in the output for removed file should disappear when
diff --git a/t/t4013/diff.log_--diff-merges=first-parent_--diff-merges=hide_master b/t/t4013/diff.log_--diff-merges=first-parent_--diff-merges=hide_master
new file mode 100644
index 000000000000..596caec64298
--- /dev/null
+++ b/t/t4013/diff.log_--diff-merges=first-parent_--diff-merges=hide_master
@@ -0,0 +1,34 @@
+$ git log --diff-merges=first-parent --diff-merges=hide master
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+Merge: 9a6d494 c7a2ab9
+Author: A U Thor <author@example.com>
+Date:   Mon Jun 26 00:04:00 2006 +0000
+
+    Merge branch 'side'
+
+commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
+Author: A U Thor <author@example.com>
+Date:   Mon Jun 26 00:03:00 2006 +0000
+
+    Side
+
+commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+Author: A U Thor <author@example.com>
+Date:   Mon Jun 26 00:02:00 2006 +0000
+
+    Third
+
+commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
+Author: A U Thor <author@example.com>
+Date:   Mon Jun 26 00:01:00 2006 +0000
+
+    Second
+    
+    This is the second commit.
+
+commit 444ac553ac7612cc88969031b02b3767fb8a353a
+Author: A U Thor <author@example.com>
+Date:   Mon Jun 26 00:00:00 2006 +0000
+
+    Initial
+$
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 43de868b8005..fc6b0722216a 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2497,6 +2497,7 @@ test_expect_success 'git config - variable name' '
 	log.date Z
 	log.decorate Z
 	log.diffMerges Z
+	log.diffMergesHide Z
 	EOF
 '
 
@@ -2525,6 +2526,7 @@ test_expect_success 'git -c - variable name' '
 	log.date=Z
 	log.decorate=Z
 	log.diffMerges=Z
+	log.diffMergesHide=Z
 	EOF
 '
 
@@ -2547,6 +2549,7 @@ test_expect_success 'git clone --config= - variable name' '
 	log.date=Z
 	log.decorate=Z
 	log.diffMerges=Z
+	log.diffMergesHide=Z
 	EOF
 '
 
-- 
2.37.3.526.g5f84746cb16b
Previous: Sergey OrganovNext: Glen Choo
Message 2 of 39 in “diff-merges: more features”
  1. 0/5 diff-merges: more featuresSergey Organov, Nov 27, 2022
  2. 1/5 diff-merges: implement [no-]hide option and log.diffMergesHide configSergey Organov, Nov 27, 2022
  3. Glen ChooDec 8, 2022
  4. Sergey OrganovDec 8, 2022
  5. 2/5 diff-merges: implement log.diffMerges-m-imply-p configSergey Organov, Nov 27, 2022
  6. 3/5 diff-merges: implement log.diffMergesForce configSergey Organov, Nov 27, 2022
  7. Junio C HamanoNov 28, 2022
  8. Sergey OrganovNov 28, 2022
  9. Junio C HamanoNov 29, 2022
  10. Ævar Arnfjörð BjarmasonNov 29, 2022
  11. Sergey OrganovNov 30, 2022
  12. Junio C HamanoNov 30, 2022
  13. Jeff KingNov 29, 2022
  14. Sergey OrganovNov 30, 2022
  15. Elijah NewrenNov 29, 2022
  16. Sergey OrganovNov 30, 2022
  17. 4/5 diff-merges: support list of values for --diff-mergesSergey Organov, Nov 27, 2022
  18. 5/5 diff-merges: issue warning on lone '-m' optionSergey Organov, Nov 27, 2022
  19. Junio C HamanoNov 28, 2022
  20. Sergey OrganovNov 28, 2022
  21. Elijah NewrenNov 29, 2022
  22. Sergey OrganovNov 30, 2022
  23. Elijah NewrenDec 1, 2022
  24. Sergey OrganovDec 1, 2022
  25. Glen ChooDec 7, 2022
  26. Sergey OrganovDec 8, 2022
  27. Glen ChooDec 8, 2022
  28. Sergey OrganovDec 10, 2022
  29. Glen ChooDec 8, 2022
  30. Sergey OrganovDec 8, 2022
  31. 0/5 diff-merges: more features to fix '-m'Sergey Organov, Dec 17, 2022
  32. 1/5 diff-merges: implement [no-]hide option and log.diffMergesHide configSergey Organov, Dec 17, 2022
  33. 2/5 diff-merges: implement log.diffMerges-m-imply-p configSergey Organov, Dec 17, 2022
  34. 3/5 diff-merges: support list of values for --diff-mergesSergey Organov, Dec 17, 2022
  35. 4/5 diff-merges: issue warning on lone '-m' optionSergey Organov, Dec 17, 2022
  36. 5/5 diff-merges: improve --diff-merges documentationSergey Organov, Dec 17, 2022
  37. Junio C HamanoDec 18, 2022
  38. Sergey OrganovDec 19, 2022
  39. Sergey OrganovDec 19, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.