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

[PATCH RFC v2 2/2] builtin/history: abort reword on same message

From
Pablo Sabater <pabloosabaterr@gmail.com>
Date
Jun 9, 2026, 10:42 UTC
Message-ID
<20260609-ps-history-reword-v2-2-a0e6028ca9b4@gmail.com>
In-Reply-To
<20260609-ps-history-reword-v2-0-a0e6028ca9b4@gmail.com>

When using `git history reword <commit>` if the new message is the same as the original, it continues and rewrites the history when nothing changed.

`git commit --amend` and `git rebase -i` with reword share this behavior and it is wrong as well, but changing them breaks what people are used to. Take the opportunity of `git history` being a new command and handle it correctly from the start.

Create COMMIT_TREE_ABORT_ON_SAME_MESSAGE and make a check for if the messages are the same and the flag is set so other subcommands like fixup that do not want this behavior just don't send the abort flag.

Make commit_tree_ext() return 1 when facing the same message so its callers can choose what to do.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
---
 builtin/history.c         | 14 +++++++++++++-
 t/t3451-history-reword.sh | 16 ++++++++++++++++
 t/t3453-history-fixup.sh  | 22 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/builtin/history.c b/builtin/history.c
index b3e2e5270d..be07690da4 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -96,6 +96,7 @@ static int fill_commit_message(struct repository *repo,
 
 enum commit_tree_flags {
 	COMMIT_TREE_EDIT_MESSAGE = (1 << 0),
+	COMMIT_TREE_ABORT_ON_SAME_MESSAGE = (1 << 1),
 };
 
 static int commit_tree_ext(struct repository *repo,
@@ -135,6 +136,13 @@ static int commit_tree_ext(struct repository *repo,
 					  original_body, action, &commit_message);
 		if (ret < 0)
 			goto out;
+
+		if (flags & COMMIT_TREE_ABORT_ON_SAME_MESSAGE &&
+		    !strcmp(original_body, commit_message.buf)) {
+			fprintf(stderr, _("Message unchanged, aborting reword.\n"));
+			ret = 1;
+			goto out;
+		}
 	} else {
 		strbuf_addstr(&commit_message, original_body);
 	}
@@ -693,7 +701,8 @@ static int cmd_history_reword(int argc,
 	struct strbuf reflog_msg = STRBUF_INIT;
 	struct commit *original, *rewritten;
 	struct rev_info revs = { 0 };
-	enum commit_tree_flags flags = COMMIT_TREE_EDIT_MESSAGE;
+	enum commit_tree_flags flags = COMMIT_TREE_EDIT_MESSAGE |
+				       COMMIT_TREE_ABORT_ON_SAME_MESSAGE;
 	int ret;
 
 	argc = parse_options(argc, argv, prefix, options, usage, 0);
@@ -721,6 +730,9 @@ static int cmd_history_reword(int argc,
 	if (ret < 0) {
 		ret = error(_("failed writing reworded commit"));
 		goto out;
+	} else if (ret == 1) {
+		ret = 0;
+		goto out;
 	}
 
 	strbuf_addf(&reflog_msg, "reword: updating %s", argv[0]);
diff --git a/t/t3451-history-reword.sh b/t/t3451-history-reword.sh
index de7b357685..6e0e278c42 100755
--- a/t/t3451-history-reword.sh
+++ b/t/t3451-history-reword.sh
@@ -396,4 +396,20 @@ test_expect_success 'retains changes in the worktree and index' '
 	)
 '
 
+test_expect_success 'aborts if the commit message is the same' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		test_commit first &&
+		test_commit second &&
+
+		git rev-parse HEAD >oid-before &&
+		GIT_EDITOR=true git history reword HEAD 2>err &&
+		git rev-parse HEAD >oid-after &&
+		test_cmp oid-before oid-after &&
+		test_grep "Message unchanged" err
+	)
+'
+
 test_done
diff --git a/t/t3453-history-fixup.sh b/t/t3453-history-fixup.sh
index 868298e248..9f9a3c93de 100755
--- a/t/t3453-history-fixup.sh
+++ b/t/t3453-history-fixup.sh
@@ -443,6 +443,28 @@ test_expect_success '--reedit-message opens editor for the commit message' '
 	)
 '
 
+test_expect_success 'fixup --reedit-message does not abort with the same commit message' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		test_commit initial &&
+		echo content > file.txt &&
+		git add file.txt &&
+		git commit -m "add file" &&
+
+		echo fix >>file.txt &&
+		git add file.txt &&
+		GIT_EDITOR=true git history fixup --reedit-message HEAD &&
+		expect_changes --branches <<-\EOF
+		add file
+		2	0	file.txt
+		initial
+		1	0	initial.t
+		EOF
+	)
+'
+
 test_expect_success 'retains unstaged working tree changes after fixup' '
 	test_when_finished "rm -rf repo" &&
 	git init repo &&
-- 
2.54.0
Previous: Pablo SabaterNext: Phillip Wood
Message 25 of 36 in “builtin/history: change git history reword behavior and feedback”
  1. 0/2 builtin/history: change git history reword behavior and feedbackPablo Sabater, Jun 7, 2026
  2. 1/2 builtin/history: abort reword on unchanged messagePablo Sabater, Jun 7, 2026
  3. Patrick SteinhardtJun 8, 2026
  4. Pablo SabaterJun 8, 2026
  5. Junio C HamanoJun 8, 2026
  6. Ben KnobleJun 8, 2026
  7. Pablo SabaterJun 9, 2026
  8. Pablo SabaterJun 9, 2026
  9. Kristoffer HaugsbakkJun 9, 2026
  10. Junio C HamanoJun 9, 2026
  11. Pablo SabaterJun 9, 2026
  12. Ben KnobleJun 8, 2026
  13. Pablo SabaterJun 9, 2026
  14. 2/2 builtin/history: print feedback after successful rewordPablo Sabater, Jun 7, 2026
  15. Patrick SteinhardtJun 8, 2026
  16. Pablo SabaterJun 8, 2026
  17. Junio C HamanoJun 8, 2026
  18. Pablo SabaterJun 8, 2026
  19. Ben KnobleJun 8, 2026
  20. Dominique MartinetJul 7, 2026
  21. D. Ben KnobleJul 7, 2026
  22. Patrick SteinhardtJul 8, 2026
  23. 0/2 builtin/history: abort reword on same messagePablo Sabater, Jun 9, 2026
  24. 1/2 builtin/history: refactor function signaturePablo Sabater, Jun 9, 2026
  25. 2/2 builtin/history: abort reword on same messagePablo Sabater, Jun 9, 2026
  26. Phillip WoodJun 9, 2026
  27. Junio C HamanoJun 9, 2026
  28. Pablo SabaterJun 9, 2026
  29. Junio C HamanoJun 9, 2026
  30. Patrick SteinhardtJun 10, 2026
  31. Phillip WoodJun 10, 2026
  32. Junio C HamanoJun 10, 2026
  33. Justin ToblerJun 9, 2026
  34. Junio C HamanoJun 9, 2026
  35. Justin ToblerJun 9, 2026
  36. Phillip WoodJun 10, 2026

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.