Change old commit message using `git rebase`

169,651

Solution 1

It says:

When you save and exit the editor, it will rewind you back to that last commit in that list and drop you on the command line with the following message:

$ git rebase -i HEAD~3
Stopped at 7482e0d... updated the gemspec to hopefully work better
You can amend the commit now, with

It does not mean:

type again git rebase -i HEAD~3

Try to not typing git rebase -i HEAD~3 when exiting the editor, and it should work fine.
(otherwise, in your particular situation, a git rebase -i --abort might be needed to reset everything and allow you to try again)


As Dave Vogt mentions in the comments, git rebase --continue is for going to the next task in the rebasing process, after you've amended the first commit.

Also, Gregg Lind mentions in his answer the reword command of git rebase:

By replacing the command "pick" with the command "edit", you can tell git rebase to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.

If you just want to edit the commit message for a commit, replace the command "pick" with the command "reword", since Git1.6.6 (January 2010).

It does the same thing ‘edit’ does during an interactive rebase, except it only lets you edit the commit message without returning control to the shell. This is extremely useful.
Currently if you want to clean up your commit messages you have to:

$ git rebase -i next

Then set all the commits to ‘edit’. Then on each one:

# Change the message in your editor.
$ git commit --amend
$ git rebase --continue

Using ‘reword’ instead of ‘edit’ lets you skip the git-commit and git-rebase calls.

Solution 2

As Gregg Lind suggested, you can use reword to be prompted to only change the commit message (and leave the commit intact otherwise):

git rebase -i HEAD~n

Here, n is the list of last n commits.

For example, if you use git rebase -i HEAD~4, you may see something like this:

pick e459d80 Do xyz
pick 0459045 Do something
pick 90fdeab Do something else
pick facecaf Do abc

Now replace pick with reword for the commits you want to edit the messages of:

pick e459d80 Do xyz
reword 0459045 Do something
reword 90fdeab Do something else
pick facecaf Do abc

Exit the editor after saving the file, and next you will be prompted to edit the messages for the commits you had marked reword, in one file per message. Note that it would've been much simpler to just edit the commit messages when you replaced pick with reword, but doing that has no effect.

Learn more on GitHub's page for Changing a commit message.

Solution 3

FWIW, git rebase interactive now has a reword option, which makes this much less painful!

Solution 4

Just wanted to provide a different option for this. In my case, I usually work on my individual branches then merge to master, and the individual commits I do to my local are not that important.

Due to a git hook that checks for the appropriate ticket number on Jira but was case sensitive, I was prevented from pushing my code. Also, the commit was done long ago and I didn't want to count how many commits to go back on the rebase.

So what I did was to create a new branch from latest master and squash all commits from problem branch into a single commit on new branch. It was easier for me and I think it's good idea to have it here as future reference.

From latest master:

git checkout -b new-branch

Then

git merge --squash problem-branch
git commit -m "new message" 

Referece: https://github.com/rotati/wiki/wiki/Git:-Combine-all-messy-commits-into-one-commit-before-merging-to-Master-branch

Solution 5

Here's a very nice Gist that covers all the possible cases: https://gist.github.com/nepsilon/156387acf9e1e72d48fa35c4fabef0b4

Overview:

git rebase -i HEAD~X
# X is the number of commits to go back
# Move to the line of your commit, change pick into edit,
# then change your commit message:
git commit --amend
# Finish the rebase with:
git rebase --continue
Share:
169,651

Related videos on Youtube

Alex Jones
Author by

Alex Jones

Programmer. Buenos Aires Argentina.

Updated on July 08, 2022

Comments

  • Alex Jones
    Alex Jones almost 2 years

    I was trying to edit an old commit message as explained here.

    The thing is that now, when I try to run rebase -i HEAD~5 it says interactive rebase already started.

    So then I try: git rebase --continue but got this error:

    error: Ref refs/heads/master is at 7c1645b447a8ea86ee143dd08400710c419b945b but expected c7577b53d05c91026b9906b6d29c1cf44117d6ba
    fatal: Cannot lock the ref 'refs/heads/master'.
    

    Any ideas?

    • U. Windl
      U. Windl about 3 years
      Users are told to add contents for question here, and not in links. One of the reasons is that those links become invalid sooner or later. The link schacon.github.com/history.html no longer works.
    • questionto42standswithUkraine
      questionto42standswithUkraine about 2 years
      The link does work (again?), though.
  • user3518901
    user3518901 almost 14 years
    Also, git rebase --continue goes to the next task in the rebasing process, after you've amended the first commit.
  • Joy
    Joy over 6 years
    Adding the link to github wiki article for changing a commit message
  • Dan Dascalescu
    Dan Dascalescu over 5 years
    When using reword, why doesn't git simply let you edit the commit messages in that file with the list of commits? Instead it will launch the editor with one commit message file per reword line. This is just unnecessary. Even if other actions than pick or reword require launching external commands, reword would not necessitate that.
  • Carlos Parra
    Carlos Parra about 5 years
    Your answer really saved my day :). I was struggling with rebase -i for like about 2 hours and no success. My commit was behind 18 commits, so you can imagine. This was the simpler and handy way I could found without needing to use rebase. Thanks friend!
  • Reza
    Reza almost 4 years
    I did that, and then commits from other branches show up in my branch
  • Punit Vara
    Punit Vara almost 4 years
    @Reza you might have messed up somthing. Try this in some other repo. This solution works perfectly
  • lucidbrot
    lucidbrot over 3 years
    this does not seem to work if my commits since the one in question all were done with --allow-empty and have no actual diff. Rebase just says "Nothing to do"
  • VonC
    VonC over 3 years
    @lucidbrot What version of Git are you using? git rebase -i can retain empty commits since Git 2.26 (Q1 2020): stackoverflow.com/a/60532362/6309
  • lucidbrot
    lucidbrot over 3 years
    @VonC Interesting, thanks! I'm on 2.17. Didn't realize it was out of date - I've got it from the ubuntu apt
  • Ariel Gabizon
    Ariel Gabizon about 3 years
    I think this is better than reword when you want a long commit message, not just one line
  • U. Windl
    U. Windl about 3 years
    What is confusing a bit is the fact that git says "detached HEAD ..." after saving the modified commit message (using reword), but then a git rebase --continue triggers a "fatal: No rebase in progress?". Maybe point that out in the answer, too. Seen in git 2.26.2.
  • U. Windl
    U. Windl about 3 years
    Could it be you are confusing one-line commit messages with full commit messages (You see the commit message title (summary) only when rebasing)?
  • U. Windl
    U. Windl about 3 years
    I'm unsure what happens to the commit history when merging all commits into one. Maybe explain in your answer, maybe showing an example. I tried to understand the manual page's description of the --squash option, but I failed to understand what it actually does.
  • silvio
    silvio over 2 years
    As I mentioned, for this work-around, you should not be worried about the individual commits, as you will lose track of it and make it as one with a new message. Sorry for the delay to respond
  • sharad_kalya
    sharad_kalya over 2 years
    That's helpful and really easy, but comes with the downside, there are now n number of files in a single commit, and also lost the entire commit history.
  • Arpit Bhalla
    Arpit Bhalla over 2 years
    How can I keep commit date same?
  • silvio
    silvio over 2 years
    Yes, on the first 2 paragraphs I explained that I had a very specific use case where I was working on a branch alone for a long time and didnt need the history. Many files changed wasnt a problem as well. cheers
  • questionto42standswithUkraine
    questionto42standswithUkraine about 2 years
    git checkout main --> git pull --> git rebase -i [hash of the 5th last commit] or git rebase HEAD~4 both show the last 4 commits in the interactive editor --> change first line (4th last commit) from "pick" to "reword" --> in vim: wq --> edit the commit message --> in vim wq --> I get back to the main branch. Now, I do not see the changed commit message online, but when I rebase again, the changes are done. Being in "main" again, should I then git push -f? Is it now needed to force push when checked out in "main" to see the changed old commit message online?
  • VonC
    VonC about 2 years
    @questionto42standswithUkraine Any rebase would change the branch history indeed, so a git push --force is needed.
  • questionto42standswithUkraine
    questionto42standswithUkraine about 2 years
    git push --force-with-lease gives: Enumerating objects: 23, done. Counting objects: 100% (23/23), done. ... remote: GitLab: You are not allowed to force push code to a protected branch on this project. This is what I had thought. I cannot just force push to the main. I guess I need to make a new branch only to force push to it even though that is only for refreshing the old commit message.
  • VonC
    VonC about 2 years
    Probably, as main is protected by default
  • questionto42standswithUkraine
    questionto42standswithUkraine about 2 years
    I found out what was the problem in my case. My branch was already merged. That is why I could not and should not change anything in the past anymore. I therefore put the non-truncated commit message to the documentation and leave it as it is.
  • VonC
    VonC about 2 years
    @questionto42standswithUkraine Good catch. That would explain it.