Volume XXII, number 279Tuesday, October 6, 2026Latest message 39 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

patchrebase: add --[no-]edit to --continue

5 messages between Jul 21, 2026 and Jul 22, 2026, from Hugo Sales, Junio C Hamano, Phillip Wood.

Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.

Hugo SalesJul 21, 2026, 14:04 UTC on lore

When a rebase stops for conflicts and the user runs `git rebase --continue`, the merge backend opens $EDITOR so the commit message can be revised. That is often useful, but not always: sometimes the user only wants to keep the message that is already there.

This series adds:
- `git rebase --continue --no-edit` to commit without opening an editor
- `rebase.noEdit` to make that the default on continue
- `git rebase --continue --edit` to override `rebase.noEdit`

The command-line flags apply only to the current `--continue` invocation, not to later picks in the same rebase.

Tests are added in t3436. I also ran all tests locally.
Hugo Sales (1):
  rebase: add --[no-]edit to --continue
 Documentation/config/rebase.adoc |  6 ++++
 Documentation/git-rebase.adoc    | 17 +++++++++--
 builtin/rebase.c                 | 29 ++++++++++++++++--
 sequencer.c                      | 29 +++++++++++++++++-
 t/t3436-rebase-more-options.sh   | 52 ++++++++++++++++++++++++++++++++
 5 files changed, 126 insertions(+), 7 deletions(-)
-- 
2.54.0
Hugo SalesJul 21, 2026, 14:04 UTC in reply to Hugo Sales on lore

[PATCH 1/1] rebase: add --[no-]edit to --continue

Allow skipping the editor when continuing after resolving conflicts, via --no-edit or the rebase.noEdit configuration variable. The --edit option overrides rebase.noEdit when both are set.

Signed-off-by: Hugo Sales <hugo@hsal.es>
---
 Documentation/config/rebase.adoc |  6 ++++
 Documentation/git-rebase.adoc    | 17 +++++++++--
 builtin/rebase.c                 | 29 ++++++++++++++++--
 sequencer.c                      | 29 +++++++++++++++++-
 t/t3436-rebase-more-options.sh   | 52 ++++++++++++++++++++++++++++++++
 5 files changed, 126 insertions(+), 7 deletions(-)
Show changes to 5 files +126 −7

Documentation/config/rebase.adoc, Documentation/git-rebase.adoc, builtin/rebase.c, sequencer.c, t/t3436-rebase-more-options.sh

diff --git a/Documentation/config/rebase.adoc b/Documentation/config/rebase.adoc
index c6187ab28b..321ab8b529 100644
--- a/Documentation/config/rebase.adoc
+++ b/Documentation/config/rebase.adoc
@@ -62,6 +62,12 @@ instead of:
 +
 Defaults to false.
 
+rebase.noEdit::
+	When set to true, `git rebase --continue` uses the commit message
+	without launching $EDITOR, as if `--no-edit` were given.  The
+	`--edit` option to `git rebase --continue` overrides this setting.
+	Defaults to false.
+
 rebase.rescheduleFailedExec::
 	Automatically reschedule `exec` commands that failed. This only makes
 	sense in interactive mode (or when an `--exec` option was provided).
diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc
index f6c22d1598..cc0a69b5a5 100644
--- a/Documentation/git-rebase.adoc
+++ b/Documentation/git-rebase.adoc
@@ -181,6 +181,16 @@ including not with each other:
 
 --continue::
 	Restart the rebasing process after having resolved a merge conflict.
++
+-e::
+--edit::
+--no-edit::
+	With `--continue`, edit or do not edit the commit message,
+	respectively. By default, the configured $EDITOR is opened so you
+	can update the commit message after resolving conflicts.
+	`--no-edit` reuses the existing message without launching an
+	editor. The `rebase.noEdit` configuration variable can be used to
+	enable `--no-edit` by default; `--edit` overrides that setting.
 
 --skip::
 	Restart the rebasing process by skipping the current patch.
@@ -783,9 +793,10 @@ Commit Rewording
 When a conflict occurs while rebasing, rebase stops and asks the user
 to resolve.  Since the user may need to make notable changes while
 resolving conflicts, after conflicts are resolved and the user has run
-`git rebase --continue`, the rebase should open an editor and ask the
-user to update the commit message.  The 'merge' backend does this, while
-the 'apply' backend blindly applies the original commit message.
+`git rebase --continue`, the rebase opens an editor and asks the
+user to update the commit message, unless `rebase.noEdit` is set or
+`--no-edit` is passed to `--continue`.  The 'merge' backend does this,
+while the 'apply' backend blindly applies the original commit message.
 
 Miscellaneous differences
 ~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 10a306310c..5827b20baf 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -43,7 +43,7 @@ static char const * const builtin_rebase_usage[] = {
 		"[--onto <newbase> | --keep-base] [<upstream> [<branch>]]"),
 	N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
 		"--root [<branch>]"),
-	"git rebase --continue | --abort | --skip | --edit-todo",
+	"git rebase --continue [--[no-]edit] | --abort | --skip | --edit-todo",
 	NULL
 };
 
@@ -135,6 +135,8 @@ struct rebase_options {
 	int config_autosquash;
 	int config_rebase_merges;
 	int config_update_refs;
+	int config_no_edit;
+	int edit;
 };
 
 #define REBASE_OPTIONS_INIT {			  	\
@@ -156,6 +158,8 @@ struct rebase_options {
 		.update_refs = -1,                      \
 		.config_update_refs = -1,               \
 		.strategy_opts = STRING_LIST_INIT_NODUP,\
+		.config_no_edit = -1,                   \
+		.edit = -1,                             \
 	}
 
 static void rebase_options_release(struct rebase_options *opts)
@@ -215,6 +219,13 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
 		replay.have_squash_onto = 1;
 	}
 
+	if (opts->action == ACTION_CONTINUE) {
+		if (opts->edit >= 0)
+			replay.edit = opts->edit;
+		else if (opts->config_no_edit > 0)
+			replay.edit = 0;
+	}
+
 	return replay;
 }
 
@@ -841,6 +852,11 @@ static int rebase_config(const char *var, const char *value,
 		return 0;
 	}
 
+	if (!strcmp(var, "rebase.noedit")) {
+		opts->config_no_edit = git_config_bool(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "rebase.forkpoint")) {
 		opts->fork_point = git_config_bool(var, value) ? -1 : 0;
 		return 0;
@@ -1171,6 +1187,8 @@ int cmd_rebase(int argc,
 			    ACTION_CONTINUE),
 		OPT_CMDMODE(0, "skip", &options.action,
 			    N_("skip current patch and continue"), ACTION_SKIP),
+		OPT_BOOL('e', "edit", &options.edit,
+			 N_("edit the commit message")),
 		OPT_CMDMODE(0, "abort", &options.action,
 			    N_("abort and check out the original branch"),
 			    ACTION_ABORT),
@@ -1311,10 +1329,15 @@ int cmd_rebase(int argc,
 			"which is no longer supported; use 'merges' instead"));
 
 	if (options.action != ACTION_NONE && total_argc != 2) {
-		usage_with_options(builtin_rebase_usage,
-				   builtin_rebase_options);
+		if (options.action != ACTION_CONTINUE ||
+		    options.edit < 0 || total_argc != 3)
+			usage_with_options(builtin_rebase_usage,
+					   builtin_rebase_options);
 	}
 
+	if (options.edit >= 0 && options.action != ACTION_CONTINUE)
+		die(_("--edit and --no-edit can only be used with --continue"));
+
 	if (argc > 2)
 		usage_with_options(builtin_rebase_usage,
 				   builtin_rebase_options);
diff --git a/sequencer.c b/sequencer.c
index 1355a99a09..be2945b12d 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2211,6 +2211,25 @@ static int should_edit(struct replay_opts *opts) {
 	return opts->edit;
 }
 
+static int should_edit_rebase_continue(struct replay_opts *opts)
+{
+	if (opts->edit < 0)
+		return 1;
+	return opts->edit;
+}
+
+static void finalize_continue_edit_flags(struct replay_opts *opts,
+					 unsigned int *flags)
+{
+	if (*flags & CLEANUP_MSG)
+		return;
+
+	if (should_edit_rebase_continue(opts))
+		*flags |= EDIT_MSG;
+	else
+		*flags &= ~EDIT_MSG;
+}
+
 static void refer_to_commit(struct repository *r, struct strbuf *msgbuf,
 			    const struct commit *commit,
 			    bool use_commit_reference)
@@ -5281,7 +5300,7 @@ static int commit_staged_changes(struct repository *r,
 				 struct todo_list *todo_list)
 {
 	struct replay_ctx *ctx = opts->ctx;
-	unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
+	unsigned int flags = ALLOW_EMPTY;
 	unsigned int final_fixup = 0, is_clean;
 	struct strbuf rev = STRBUF_INIT;
 	const char *reflog_action = reflog_message(opts, "continue", NULL);
@@ -5446,6 +5465,8 @@ static int commit_staged_changes(struct repository *r,
 		}
 	}
 
+	finalize_continue_edit_flags(opts, &flags);
+
 	if (run_git_commit(final_fixup ? NULL : rebase_path_message(),
 			   reflog_action, opts, flags)) {
 		ret = error(_("could not commit staged changes."));
@@ -5503,6 +5524,12 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
 			res = -1;
 			goto release_todo_list;
 		}
+
+		/*
+		 * Command-line --[no-]edit applies only to this
+		 * --continue invocation, not to subsequent picks.
+		 */
+		opts->edit = -1;
 	} else if (!file_exists(get_todo_path(opts)))
 		return continue_single_pick(r, opts);
 	else if ((res = read_populate_todo(r, &todo_list, opts)))
diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh
index 94671d3c46..c84c6717ab 100755
--- a/t/t3436-rebase-more-options.sh
+++ b/t/t3436-rebase-more-options.sh
@@ -201,6 +201,58 @@ test_expect_success '--ignore-date is an alias for --reset-author-date' '
 	test_atime_is_ignored -2
 '
 
+test_expect_success '--no-edit on continue uses existing commit message' '
+	git checkout commit2 &&
+	test_must_fail git rebase -m --onto commit2^^ commit2^ &&
+	echo resolved >foo &&
+	git add foo &&
+	write_script fail-if-editor-invoked <<-\EOF &&
+	echo editor invoked >&2
+	exit 1
+	EOF
+	GIT_EDITOR=./fail-if-editor-invoked git rebase --continue --no-edit &&
+	git log --format=%s -1 >actual &&
+	echo commit2 >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--no-edit cannot be used when starting a rebase' '
+	test_must_fail git rebase --no-edit -m main side 2>err &&
+	test_grep "only be used with --continue" err
+'
+
+test_expect_success 'rebase.noEdit skips editor on continue' '
+	git config rebase.noEdit true &&
+	git checkout commit2 &&
+	test_must_fail git rebase -m --onto commit2^^ commit2^ &&
+	echo resolved >foo &&
+	git add foo &&
+	write_script fail-if-editor-invoked <<-\EOF &&
+	echo editor invoked >&2
+	exit 1
+	EOF
+	GIT_EDITOR=./fail-if-editor-invoked git rebase --continue &&
+	git log --format=%s -1 >actual &&
+	echo commit2 >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success '--edit on continue overrides rebase.noEdit' '
+	git config rebase.noEdit true &&
+	git checkout commit2 &&
+	test_must_fail git rebase -m --onto commit2^^ commit2^ &&
+	echo resolved >foo &&
+	git add foo &&
+	(
+		set_fake_editor &&
+		FAKE_COMMIT_MESSAGE="edited on continue" \
+			git rebase --continue --edit
+	) &&
+	test_write_lines "edited on continue" "" >expect &&
+	git log --format=%B -1 >actual &&
+	test_cmp expect actual
+'
+
 # This must be the last test in this file
 test_expect_success '$EDITOR and friends are unchanged' '
 	test_editor_unchanged
-- 
2.54.0
Junio C HamanoJul 21, 2026, 18:04 UTC in reply to Hugo Sales on lore

Re: [PATCH 0/1] rebase: add --[no-]edit to --continue

Hugo Sales <hugo@hsal.es> writes:
Show 8 quoted lines
> When a rebase stops for conflicts and the user runs `git rebase --continue`, the
> merge backend opens $EDITOR so the commit message can be revised. That is often
> useful, but not always: sometimes the user only wants to keep the message that
> is already there.
>
> This series adds:
>
> - `git rebase --continue --no-edit` to commit without opening an editor
Meh. "GIT_SEQUENCE_EDITOR=: git rebase --continue" is your friend ;-)
> - `rebase.noEdit` to make that the default on continue
> - `git rebase --continue --edit` to override `rebase.noEdit`

The new 'rebase.noEdit' configuration is especially concerning. It encourages users to assume by default that their rebase sessions will not produce notable changes worth recording in the commit logs.

A few immediate edge cases come to mind:
 - What if 'rebase -i' stops to give control back to the user for
   reasons other than a merge conflict?  If the user chose 'edit',
   their original intent was to modify both the commit message and
   the content.  With 'rebase.noEdit' enabled, would they now have
   to remember to pass '--edit' when continuing?  Does the answer
   depend on whether the 'edit' step resulted in a merge conflict?
 - What if the user chose 'reword', which is an explicit signal to
   update the commit message, but 'rebase.noEdit' is enabled?  If
   the rebase does not stop with a conflict, it might open the
   editor regardless of the configuration.  But if a conflict does
   occur and requires manual resolution, will the user still need to
   remember to pass '--edit' when continuing?

The proposed tests only cover the code path where control returns to the user due to a conflict. This is understandable since that scenario was your primary motivation. However, they do not verify what happens when there are no conflicts but the user explicitly intended to edit the message from the start. You may want to expand the test coverage to address these scenarios (and potentially others, as this is not an exhaustive list).

Thanks.
Phillip WoodJul 22, 2026, 13:39 UTC in reply to Junio C Hamano on lore

Re: [PATCH 0/1] rebase: add --[no-]edit to --continue

On 21/07/2026 19:04, Junio C Hamano wrote:
Show 12 quoted lines
> Hugo Sales <hugo@hsal.es> writes:
> 
>> When a rebase stops for conflicts and the user runs `git rebase --continue`, the
>> merge backend opens $EDITOR so the commit message can be revised. That is often
>> useful, but not always: sometimes the user only wants to keep the message that
>> is already there.
>>
>> This series adds:
>>
>> - `git rebase --continue --no-edit` to commit without opening an editor
> 
> Meh. "GIT_SEQUENCE_EDITOR=: git rebase --continue" is your friend ;-)

Do you mean "GIT_EDITOR=:"? The sequence editor is only relevant for editing the todo list. The last time this came up [1] I shared an alias that only suppresses the editor if HEAD has not changed since the user continued the rebase, but that does not stop the user suppressing the editor when continuing a "reword" command. I share the concerns you listed below about this patch in its current form.

Thanks
Phillip

[1] https://lore.kernel.org/git/fbf859ca-43f4-433e-b111-377aa60f1947@gmail.com

Show 33 quoted lines
>> - `rebase.noEdit` to make that the default on continue
>> - `git rebase --continue --edit` to override `rebase.noEdit`
> 
> The new 'rebase.noEdit' configuration is especially concerning.  It
> encourages users to assume by default that their rebase sessions
> will not produce notable changes worth recording in the commit logs.
> 
> A few immediate edge cases come to mind:
> 
>   - What if 'rebase -i' stops to give control back to the user for
>     reasons other than a merge conflict?  If the user chose 'edit',
>     their original intent was to modify both the commit message and
>     the content.  With 'rebase.noEdit' enabled, would they now have
>     to remember to pass '--edit' when continuing?  Does the answer
>     depend on whether the 'edit' step resulted in a merge conflict?
> 
>   - What if the user chose 'reword', which is an explicit signal to
>     update the commit message, but 'rebase.noEdit' is enabled?  If
>     the rebase does not stop with a conflict, it might open the
>     editor regardless of the configuration.  But if a conflict does
>     occur and requires manual resolution, will the user still need to
>     remember to pass '--edit' when continuing?
> 
> The proposed tests only cover the code path where control returns to
> the user due to a conflict.  This is understandable since that
> scenario was your primary motivation.  However, they do not verify
> what happens when there are no conflicts but the user explicitly
> intended to edit the message from the start.  You may want to expand
> the test coverage to address these scenarios (and potentially
> others, as this is not an exhaustive list).
> 
> Thanks.
> 
Junio C HamanoJul 22, 2026, 15:36 UTC in reply to Phillip Wood on lore

Re: [PATCH 0/1] rebase: add --[no-]edit to --continue

Phillip Wood <phillip.wood123@gmail.com> writes:
Show 15 quoted lines
> On 21/07/2026 19:04, Junio C Hamano wrote:
>> Hugo Sales <hugo@hsal.es> writes:
>> 
>>> When a rebase stops for conflicts and the user runs `git rebase --continue`, the
>>> merge backend opens $EDITOR so the commit message can be revised. That is often
>>> useful, but not always: sometimes the user only wants to keep the message that
>>> is already there.
>>>
>>> This series adds:
>>>
>>> - `git rebase --continue --no-edit` to commit without opening an editor
>> 
>> Meh. "GIT_SEQUENCE_EDITOR=: git rebase --continue" is your friend ;-)
>
> Do you mean "GIT_EDITOR=:"? The sequence editor is only relevant for 

Oh, absolutely. I made a last minute change s/_EDITOR/SEQUENCE_&/ before sending it out, without realizing that I made a totally unnecessary change X-<.

Thanks for spotting.
> editing the todo list.

Back to recent threads