12

I want to change a pretty old commit message using:

git rebase -i sha1-of-commit^

That's nice, I do git commit --amend and edit the message, but things get bad when I do:

git rebase --continue

I encounter multiple conflicts but don't understand why as the whole conflict resolution has obviously already been done in the past, and git should just move forward until all commits are rebased.

How can I finish the rebase quickly without having to handle these old conflicts? I just want to change a simple (and old) commit message after all...

leppie
  • 115,091
  • 17
  • 196
  • 297
Totor
  • 1,148
  • 1
  • 10
  • 21
  • 1
    Do you have any merges in your history? `git rebase` does not include merge commits by default. Even with the `--preserve-merges` option, when it attempts to re-merge, it will ignore your previous merge resolution. – Joseph K. Strauss Dec 22 '14 at 16:52
  • @JosephK.Strauss Thanks, do you have a workaround? – Totor Dec 29 '14 at 13:04
  • I believe `git filter-branch` will do what you want, if you use `msg-filter`, but you will have to filter the entire branch, but structure the command to only change the message for the one specified commit. I may leave a better answer late today. – Joseph K. Strauss Dec 29 '14 at 13:10

1 Answers1

17

Make a small script in your /bin directory (or any directory in your path) named git-reword-commit. (You can name it whatever you want as long as the name starts with git-. This will work regardless of whether there are merge commits or not.

#! /bin/bash
REV=$1
MESSAGE=$2
FILTER="test $(echo '$GIT_COMMIT') = $(git rev-parse $REV) && echo $MESSAGE || cat"
git filter-branch --msg-filter "$FILTER" -- --all

To use, execute

git reword-commit <commit> 'new message'

Warning: This will rewrite many commits, so the same issues that apply to rebase, apply here as well, i.e., you will need to force when you push, and other users will have to know about this.

Git puts your original refs (from before the filter-branch) in .git/refs/original. You can use the following aliases to undo/confirm any filter-branch command.

git config alias.undo-filter-branch '! DIR=$(git rev-parse --git-dir); cp -r $DIR/refs/original/refs/ .git/; rm -r $DIR/refs/original/'
git config alias.confirm-filter-branch '! DIR=$(git rev-parse --git-dir); rm -r $DIR/refs/original/'
Joseph K. Strauss
  • 4,683
  • 1
  • 23
  • 40
  • Thanks. What does `==` mean when used with test, as it is [not standard](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html)? – Totor Dec 31 '14 at 09:09
  • Woops. It worked in my Windows Git bash; I guess I was thinking in Java mode. – Joseph K. Strauss Dec 31 '14 at 12:35
  • 3
    I had to change ```echo $MESSAGE``` to ```echo \"$MESSAGE\"``` to make it work. You saved me a lot of hours! thanks! – Mario J. Barchéin May 17 '18 at 17:27
  • Saved me hours of headache, much appreciated! – Tristan Apr 16 '20 at 04:36
  • 1
    don't forget to make git-reword-commit executable – Friedrich Roell Apr 13 '22 at 07:13
  • You just saved a lot of time, as I have to fix the message for all 50 commits I have for a Unity Project. Thanks! However, Git gives a warning message telling us to use git filter-repo instead because git filter-branch is unsafe. Should I be worried if I just want to edit commit messages? – Deewens Nov 23 '22 at 13:39