Thread (36 messages) 36 messages, 8 authors, 5d ago

Re: [PATCH RFC 1/2] builtin/history: abort reword on unchanged message

From: Ben Knoble <hidden>
Date: 2026-06-08 16:37:59

I don’t have any strong opinions on the rest…
quoted hunk ↗ jump to hunk
Le 7 juin 2026 à 16:08, Pablo Sabater [off-list ref] a écrit :

When using `git history reword` if the new message is the same as the
original it continues anyway creating a new commit with the same
message and updates its descendants, modifying the history after this
'reworded' commit even though there was no actual change.

`git commit --amend` and `git rebase -i` + reword share this behavior,
however `git history reword` is different:
1. Works in-memory without touching the index or the worktree [1], so
  there are no side effects like staged files that could justify
  rewriting the history when the commit message is the same.
2. `git history` by default updates all the branches [2] that contain the
  original commit making it more costly than `git rebase -i` that only
  updates the current branch.

Add a check if the original commit message is the same as the new one
and abort if so.

[1]: https://lore.kernel.org/git/20260113-b4-pks-history-builtin-v11-8-e74ebfa2652d@pks.im/ (local)
[2]: https://git-scm.com/docs/git-history#_description

Signed-off-by: Pablo Sabater <redacted>
---
builtin/history.c         | 10 ++++++++++
t/t3451-history-reword.sh | 20 ++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/builtin/history.c b/builtin/history.c
index 0fc06fb204..51a22a9a1c 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -135,6 +135,13 @@ static int commit_tree_ext(struct repository *repo,
                     original_body, action, &commit_message);
       if (ret < 0)
           goto out;
+
+        if (!strcmp(original_body, commit_message.buf)) {
+            fprintf(stderr, _("Message unchanged,"
+                      " aborting reword.\n"));
+            ret = 1;
+            goto out;
+        }
   } else {
       strbuf_addstr(&commit_message, original_body);
   }
@@ -718,6 +725,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..54ea8a7207 100755
--- a/t/t3451-history-reword.sh
+++ b/t/t3451-history-reword.sh
@@ -396,4 +396,24 @@ 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 &&
+        write_script fake-editor.sh <<-\EOF &&
+        true
+        EOF
+        test_set_editor "$(pwd)"/fake-editor.sh &&
+        git history reword HEAD 2>err &&
+        git rev-parse HEAD >oid-after &&
+        test_cmp oid-before oid-after &&
+        test_grep "Message unchanged" err
+    )
…but I think this test case could do something like "GIT_EDITOR=true git history reword HEAD" and avoid the script?
+'
+
test_done

--
2.54.0
Best,
Ben
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help