All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Henrie <alexhenrie24@gmail.com>
To: git@vger.kernel.org, tao@klerks.biz, gitster@pobox.com,
	newren@gmail.com, phillip.wood123@gmail.com,
	Johannes.Schindelin@gmx.de, sorganov@gmail.com
Cc: Alex Henrie <alexhenrie24@gmail.com>
Subject: [PATCH v4 3/3] rebase: add a config option for --rebase-merges
Date: Wed, 22 Feb 2023 22:34:10 -0700	[thread overview]
Message-ID: <20230223053410.644503-3-alexhenrie24@gmail.com> (raw)
In-Reply-To: <20230223053410.644503-1-alexhenrie24@gmail.com>

The purpose of the new option is to accommodate users who would like
--rebase-merges to be on by default and to facilitate possibly turning
on --rebase-merges by default without configuration in a future version
of Git.

Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
---
 Documentation/config/rebase.txt | 10 ++++
 Documentation/git-rebase.txt    |  3 +-
 builtin/rebase.c                | 47 ++++++++++++----
 t/t3430-rebase-merges.sh        | 96 +++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+), 12 deletions(-)

diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt
index f19bd0e040..308baa9dbb 100644
--- a/Documentation/config/rebase.txt
+++ b/Documentation/config/rebase.txt
@@ -67,3 +67,13 @@ rebase.rescheduleFailedExec::
 
 rebase.forkPoint::
 	If set to false set `--no-fork-point` option by default.
+
+rebase.merges::
+	Whether and how to set the `--rebase-merges` option by default. Can
+	be `rebase-cousins`, `no-rebase-cousins`, or a boolean. Setting to
+	true is equivalent to `--rebase-merges` without an argument, setting to
+	`rebase-cousins` or `no-rebase-cousins` is equivalent to
+	`--rebase-merges` with that value as its argument, and setting to false
+	is equivalent to `--no-rebase-merges`. Passing `--rebase-merges` on the
+	command line without an argument overrides a `rebase.merges=false`
+	configuration but does not override other values of `rebase.merge`.
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index c98784a0d2..b02f9cbb8c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -537,7 +537,8 @@ See also INCOMPATIBLE OPTIONS below.
 	by recreating the merge commits. Any resolved merge conflicts or
 	manual amendments in these merge commits will have to be
 	resolved/re-applied manually. `--no-rebase-merges` can be used to
-	countermand a previous `--rebase-merges`.
+	countermand both the `rebase.merges` config option and a previous
+	`--rebase-merges`.
 +
 By default, or when `no-rebase-cousins` was specified, commits which do not
 have `<upstream>` as direct ancestor will keep their original branch point,
diff --git a/builtin/rebase.c b/builtin/rebase.c
index b68fc2fbb7..45cf445d42 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -771,6 +771,20 @@ static int run_specific_rebase(struct rebase_options *opts)
 	return status ? -1 : 0;
 }
 
+static void parse_merges_value(struct rebase_options *options, const char *value)
+{
+	if (value) {
+		if (!strcmp("no-rebase-cousins", value))
+			options->rebase_cousins = 0;
+		else if (!strcmp("rebase-cousins", value))
+			options->rebase_cousins = 1;
+		else
+			die(_("Unknown mode: %s"), value);
+	}
+
+	options->rebase_merges = 1;
+}
+
 static int rebase_config(const char *var, const char *value, void *data)
 {
 	struct rebase_options *opts = data;
@@ -815,6 +829,13 @@ static int rebase_config(const char *var, const char *value, void *data)
 		return 0;
 	}
 
+	if (!strcmp(var, "rebase.merges") && value && *value) {
+		opts->rebase_merges = git_parse_maybe_bool(value);
+		if (opts->rebase_merges < 0)
+			parse_merges_value(opts, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "rebase.backend")) {
 		return git_config_string(&opts->default_backend, var, value);
 	}
@@ -980,6 +1001,18 @@ static int parse_opt_empty(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+static int parse_opt_merges(const struct option *opt, const char *arg, int unset)
+{
+	struct rebase_options *options = opt->value;
+
+	if (unset)
+		options->rebase_merges = 0;
+	else
+		parse_merges_value(options, arg);
+
+	return 0;
+}
+
 static void NORETURN error_on_missing_default_upstream(void)
 {
 	struct branch *current_branch = branch_get(NULL);
@@ -1035,7 +1068,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	struct object_id branch_base;
 	int ignore_whitespace = 0;
 	const char *gpg_sign = NULL;
-	const char *rebase_merges = NULL;
 	struct string_list strategy_options = STRING_LIST_INIT_NODUP;
 	struct object_id squash_onto;
 	char *squash_onto_name = NULL;
@@ -1137,10 +1169,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 			   &options.allow_empty_message,
 			   N_("allow rebasing commits with empty messages"),
 			   PARSE_OPT_HIDDEN),
-		{OPTION_STRING, 'r', "rebase-merges", &rebase_merges,
-			N_("mode"),
+		OPT_CALLBACK_F('r', "rebase-merges", &options, N_("mode"),
 			N_("try to rebase merges instead of skipping them"),
-			PARSE_OPT_OPTARG, NULL, (intptr_t)"no-rebase-cousins"},
+			PARSE_OPT_OPTARG, parse_opt_merges),
 		OPT_BOOL(0, "fork-point", &options.fork_point,
 			 N_("use 'merge-base --fork-point' to refine upstream")),
 		OPT_STRING('s', "strategy", &options.strategy,
@@ -1436,14 +1467,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	if (options.exec.nr)
 		imply_merge(&options, "--exec");
 
-	if (rebase_merges) {
-		if (!strcmp("rebase-cousins", rebase_merges))
-			options.rebase_cousins = 1;
-		else if (strcmp("no-rebase-cousins", rebase_merges))
-			die(_("Unknown mode: %s"), rebase_merges);
-		options.rebase_merges = 1;
+	if (options.rebase_merges)
 		imply_merge(&options, "--rebase-merges");
-	}
 
 	if (options.type == REBASE_APPLY) {
 		if (ignore_whitespace)
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index c73949df18..d4b0e8fd49 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -284,6 +284,102 @@ test_expect_success '--rebase-merges="" is invalid syntax' '
 	test_cmp expect actual
 '
 
+test_expect_success 'rebase.merges="" is equivalent to not passing --rebase-merges' '
+	test_config rebase.merges "" &&
+	git checkout -b config-merges-blank E &&
+	git rebase C &&
+	test_cmp_graph C.. <<-\EOF
+	* B
+	* D
+	o C
+	EOF
+'
+
+test_expect_success 'rebase.merges=rebase-cousins is equivalent to --rebase-merges=rebase-cousins' '
+	test_config rebase.merges rebase-cousins &&
+	git checkout -b config-rebase-cousins main &&
+	git rebase HEAD^ &&
+	test_cmp_graph HEAD^.. <<-\EOF
+	*   Merge the topic branch '\''onebranch'\''
+	|\
+	| * D
+	| * G
+	|/
+	o H
+	EOF
+'
+
+test_expect_success '--no-rebase-merges overrides rebase.merges=no-rebase-cousins' '
+	test_config rebase.merges no-rebase-cousins &&
+	git checkout -b override-config-no-rebase-cousins E &&
+	git rebase --no-rebase-merges C &&
+	test_cmp_graph C.. <<-\EOF
+	* B
+	* D
+	o C
+	EOF
+'
+
+test_expect_success '--rebase-merges=no-rebase-cousins overrides rebase.merges=rebase-cousins' '
+	test_config rebase.merges rebase-cousins &&
+	git checkout -b override-config-rebase-cousins main &&
+	git rebase --rebase-merges=no-rebase-cousins HEAD^ &&
+	test_cmp_graph HEAD^.. <<-\EOF
+	*   Merge the topic branch '\''onebranch'\''
+	|\
+	| * D
+	| * G
+	o | H
+	|/
+	o A
+	EOF
+'
+
+test_expect_success '--rebase-merges overrides rebase.merges=false' '
+	test_config rebase.merges false &&
+	git checkout -b override-config-merges-false E &&
+	before="$(git rev-parse --verify HEAD)" &&
+	test_tick &&
+	git rebase --rebase-merges C &&
+	test_cmp_rev HEAD $before
+'
+
+test_expect_success '--rebase-merges does not override rebase.merges=rebase-cousins' '
+	test_config rebase.merges rebase-cousins &&
+	git checkout -b no-override-config-rebase-cousins main &&
+	git rebase --rebase-merges HEAD^ &&
+	test_cmp_graph HEAD^.. <<-\EOF
+	*   Merge the topic branch '\''onebranch'\''
+	|\
+	| * D
+	| * G
+	|/
+	o H
+	EOF
+'
+
+test_expect_success 'local rebase.merges=false overrides global rebase.merges=true' '
+	test_config_global rebase.merges true &&
+	test_config rebase.merges false &&
+	git checkout -b override-global-config E &&
+	git rebase C &&
+	test_cmp_graph C.. <<-\EOF
+	* B
+	* D
+	o C
+	EOF
+'
+
+test_expect_success 'local rebase.merges="" does not override global rebase.merges=true' '
+	test_config_global rebase.merges no-rebase-cousins &&
+	test_config rebase.merges "" &&
+	git checkout -b no-override-global-config E &&
+	before="$(git rev-parse --verify HEAD)" &&
+	test_tick &&
+	git rebase C &&
+	test_cmp_rev HEAD $before
+'
+
 test_expect_success 'refs/rewritten/* is worktree-local' '
 	git worktree add wt &&
 	cat >wt/script-from-scratch <<-\EOF &&
-- 
2.39.2


  parent reply	other threads:[~2023-02-23  5:34 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-23  5:34 [PATCH v4 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-02-23  5:34 ` [PATCH v4 2/3] rebase: stop accepting --rebase-merges="" Alex Henrie
2023-02-24 13:54   ` Johannes Schindelin
2023-02-24 17:20     ` Junio C Hamano
2023-02-24 17:50       ` Alex Henrie
2023-02-24 18:08         ` Junio C Hamano
2023-02-24 18:23           ` Alex Henrie
2023-02-24 18:40             ` Junio C Hamano
2023-02-24 18:55               ` Alex Henrie
2023-02-24 19:13                 ` Junio C Hamano
2023-02-24 19:24                   ` Alex Henrie
2023-02-24 19:24                   ` Phillip Wood
2023-02-24 19:56                     ` Alex Henrie
2023-02-23  5:34 ` Alex Henrie [this message]
2023-02-24 13:53   ` [PATCH v4 3/3] rebase: add a config option for --rebase-merges Johannes Schindelin
2023-02-24 17:49     ` Alex Henrie
2023-02-24 14:55   ` Phillip Wood
2023-02-24 17:51     ` Alex Henrie
2023-02-23 17:28 ` [PATCH v4 1/3] rebase: add documentation and test for --no-rebase-merges Junio C Hamano
2023-02-24 13:57   ` Johannes Schindelin
2023-02-24 19:16     ` Junio C Hamano
2023-02-25 18:09     ` Alex Henrie
2023-02-25 18:03 ` [PATCH v5 0/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-02-25 18:03   ` [PATCH v5 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-03-01 23:23     ` Glen Choo
2023-02-25 18:03   ` [PATCH v5 2/3] rebase: deprecate --rebase-merges="" Alex Henrie
2023-03-01 23:46     ` Glen Choo
2023-03-02 10:07     ` Phillip Wood
2023-03-02 18:02     ` Calvin Wan
2023-02-25 18:03   ` [PATCH v5 3/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-03-01 23:43     ` Glen Choo
2023-03-02  9:37     ` Phillip Wood
2023-03-04 23:24       ` Alex Henrie
2023-03-07 16:23         ` Phillip Wood
2023-03-12 20:57           ` Alex Henrie
2023-03-13 14:20             ` Phillip Wood
2023-03-13 16:12               ` Felipe Contreras
2023-03-13 19:46             ` Junio C Hamano
2023-03-24 14:47             ` About replaying "evil" merges... " Johannes Schindelin
2023-03-02 18:02     ` Calvin Wan
2023-03-04 23:24       ` Alex Henrie
2023-03-01 23:14   ` [PATCH v5 0/3] " Glen Choo
2023-03-02  5:02     ` Alex Henrie
2023-03-02  5:09       ` Alex Henrie
2023-03-05  5:07   ` [PATCH v6 0/3] rebase: document, clean up, and introduce " Alex Henrie
2023-03-05  5:07     ` [PATCH v6 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-03-08 22:25       ` Sergey Organov
2023-03-05  5:07     ` [PATCH v6 2/3] rebase: deprecate --rebase-merges="" Alex Henrie
2023-03-07 14:59       ` Phillip Wood
2023-03-05  5:07     ` [PATCH v6 3/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-03-07 14:56       ` Phillip Wood
2023-03-07 18:32         ` Junio C Hamano
2023-03-12 21:01           ` Alex Henrie
2023-03-08  0:09         ` Glen Choo
2023-03-08  0:02       ` Glen Choo
2023-03-12 21:03         ` Alex Henrie
2023-03-15  2:52         ` Alex Henrie
2023-03-16 17:32           ` Glen Choo
2023-03-16 18:11             ` Felipe Contreras
2023-03-16 22:46               ` Glen Choo
2023-03-16 23:48                 ` Felipe Contreras
2023-03-16 20:27             ` Alex Henrie
2023-03-16 22:39               ` Glen Choo
2023-03-18  5:59                 ` Alex Henrie
2023-03-24 15:05               ` Johannes Schindelin
2023-03-25 16:59               ` Sergey Organov
2023-03-05 12:22     ` [PATCH v6 0/3] rebase: document, clean up, and introduce " Sergey Organov
2023-03-05 21:33       ` Alex Henrie
2023-03-05 22:54         ` Sergey Organov
2023-03-06  0:02           ` Alex Henrie
2023-03-06 13:23             ` Sergey Organov
2023-03-06 19:08             ` Junio C Hamano
2023-03-06 17:19           ` Junio C Hamano
2023-03-06 16:24     ` Phillip Wood
2023-03-06 17:36       ` Alex Henrie
2023-03-07 15:07         ` Phillip Wood
2023-03-08  0:13     ` Glen Choo
2023-03-12 21:04     ` [PATCH v7 " Alex Henrie
2023-03-12 21:04       ` [PATCH v7 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-03-12 21:04       ` [PATCH v7 2/3] rebase: deprecate --rebase-merges="" Alex Henrie
2023-03-12 21:04       ` [PATCH v7 3/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-03-20  5:59       ` [PATCH v8 0/3] rebase: document, clean up, and introduce " Alex Henrie
2023-03-20  5:59         ` [PATCH v8 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-03-20  5:59         ` [PATCH v8 2/3] rebase: deprecate --rebase-merges="" Alex Henrie
2023-03-20  5:59         ` [PATCH v8 3/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-03-22 16:54           ` Phillip Wood
2023-03-23 18:45             ` Junio C Hamano
2023-03-24 14:52               ` Phillip Wood
2023-03-25  5:23               ` Alex Henrie
2023-03-25  5:21             ` Alex Henrie
2023-03-26  3:06         ` [PATCH v9 0/3] rebase: document, clean up, and introduce " Alex Henrie
2023-03-26  3:06           ` [PATCH v9 1/3] rebase: add documentation and test for --no-rebase-merges Alex Henrie
2023-03-26  3:06           ` [PATCH v9 2/3] rebase: deprecate --rebase-merges="" Alex Henrie
2023-03-26  3:06           ` [PATCH v9 3/3] rebase: add a config option for --rebase-merges Alex Henrie
2023-03-26 15:12           ` [PATCH v9 0/3] rebase: document, clean up, and introduce " Phillip Wood
2023-03-27 16:33             ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230223053410.644503-3-alexhenrie24@gmail.com \
    --to=alexhenrie24@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=newren@gmail.com \
    --cc=phillip.wood123@gmail.com \
    --cc=sorganov@gmail.com \
    --cc=tao@klerks.biz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.