Git development
 help / color / mirror / Atom feed
* [PATCH REGRESSION] builtin/rebase: allow user to amend committed conflicts again
@ 2026-09-23 13:16 Patrick Steinhardt
  2026-09-23 14:02 ` Phillip Wood
  2026-09-23 17:48 ` Elijah Newren
  0 siblings, 2 replies; 13+ messages in thread
From: Patrick Steinhardt @ 2026-09-23 13:16 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Elijah Newren

In 6257588252 (commit: refuse to amend during conflict resolution,
2026-09-01), we have introduced logic to git-commit(1) that makes it
refuse creating a commit in some cases. This was done to remove a set of
common foot guns.

One of these foot guns is when the user is performing an interactive
rebase that stops at a conflict. Most of the time when we stop at a
specific commit we want the user to amend the HEAD commit, so they have
been trained to use `git commit --amend`. But when there's a conflict,
they are instead supposed to commit it directly without amending the
HEAD commit. So to remove that common pit fall, git-commit(1) now
refuses amending in that situation.

The logic that detects this scenario checks whether the file
"rebase-merge/stopped-sha" exists, while "rebase-merge/amend" doesn't.
And this is exactly the case when git-rebase(1) has stopped at such a
conflicting commit.

But there's one problem here: this state persists even after the user
has already committed the resolved conflict, and consequently they still
cannot amend after they have done so. This is overly restrictive though,
as it's quite likely that a user may want to change the resolved commit
once again.

Ideally, we'd be able to easily check whether HEAD has already been
updated to have the resolved conflict. But it seems like we do not have
sufficient information to determine the original state of HEAD when the
interactive rebase has stopped, so this is not a workable solution.

Instead, use the existence of "MERGE_MSG" to figure out whether the user
has already resolved and committed the conflict. It feels somewhat fishy
to base our decisions on the existence of that particular file, as it
really is only a proxy for what we are actually after. But the whole way
that we track rebase state is somewhat iffy in the first place.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
Hi,

this is a regression caused by 6257588252 (commit: refuse to amend
during conflict resolution, 2026-09-01). Ideally, we should probably fix
it before we release Git 2.56.

I'm not particularly happy with the proposed fix -- it feels quite fishy
to use the existence of MERGE_MSG as a proxy for whether or not the user
has already committed the resolved conflict. I couldn't come up with a
better proxy though, so if you have one please let me know.

Thanks!

Patrick
---
 sequencer.c                   |  4 ++++
 t/t3404-rebase-interactive.sh | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/sequencer.c b/sequencer.c
index e25ef5eb61..0f718c1d38 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -7045,9 +7045,13 @@ enum ongoing_operation sequencer_ongoing_operation(struct repository *r,
 	 * `amend` unless it stopped with HEAD already pointing at the commit
 	 * to be amended (a clean edit/reword stop); its absence therefore
 	 * marks a conflicted stop.
+	 *
+	 * Note that we also check for MERGE_MSG. This is to catch the case
+	 * where the user has already resolved and committed the conflict.
 	 */
 	if (file_exists(apply_dir()) ||
 	    (file_exists(rebase_path_stopped_sha()) &&
+	     file_exists(git_path_merge_msg(r)) &&
 	     !file_exists(rebase_path_amend())))
 		return ONGOING_REBASE_CONFLICT;
 
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8c63682b7f..d55afaa113 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -2486,6 +2486,40 @@ test_expect_success 'non-merge commands reject merge commits' '
 	test_cmp expect actual
 '
 
+test_expect_success 'can amend after committing a conflict' '
+	test_when_finished rm -rf repo &&
+	git init repo &&
+	(
+		cd repo &&
+
+		test_commit original file &&
+		test_commit modified file &&
+		cat >todo <<-EOF &&
+		break
+		edit $(git rev-parse HEAD)
+		EOF
+		set_replace_editor todo &&
+		git rebase -i HEAD~ &&
+
+		# Modify "file" to cause a conflict.
+		echo conflict >file &&
+		git commit -a --message conflict &&
+		test_must_fail git rebase --continue 2>err &&
+		test_grep "Resolve all conflicts manually" err &&
+
+		# Resolve the conflict.
+		echo resolved >file &&
+		git add file &&
+		git commit --message resolve &&
+
+		# And now try to amend to the conflict. This operation should
+		# succeed.
+		echo change >file &&
+		git commit --amend -a --no-edit &&
+		git rebase --continue
+	)
+'
+
 # This must be the last test in this file
 test_expect_success '$EDITOR and friends are unchanged' '
 	test_editor_unchanged

---
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
change-id: 20260923-pks-rebase-conflict-bug-176e325ad079


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-09-27  8:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 13:16 [PATCH REGRESSION] builtin/rebase: allow user to amend committed conflicts again Patrick Steinhardt
2026-09-23 14:02 ` Phillip Wood
2026-09-23 14:22   ` Phillip Wood
2026-09-23 17:33     ` Junio C Hamano
2026-09-23 17:49       ` Elijah Newren
2026-09-24  6:10         ` Johannes Sixt
2026-09-27  8:04           ` Jiang Xin
2026-09-23 17:48 ` Elijah Newren
2026-09-23 17:59   ` Junio C Hamano
2026-09-23 18:23   ` Patrick Steinhardt
2026-09-23 18:33     ` Junio C Hamano
2026-09-23 18:38       ` Patrick Steinhardt
2026-09-23 19:11       ` Elijah Newren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox