69

In my local repo I have one commit with an incorrect commit message.

I've already published the incorrect commit message with git push.

Now the remote repo (which is GitHub-hosted) has the incorrect commit message, too.

I've already tried git commit --amend, but found that it will not work for me in this situation because I've made additional commits since the incorrect one.

How would you fix this situation?

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
jonny
  • 1,326
  • 9
  • 44
  • 62
  • complication(?): there are some other commits after 'screwed' (published by me) – jonny Feb 17 '11 at 17:32
  • Isn't this a duplicate of [How do I push amended commit to the remote git repo?](http://stackoverflow.com/questions/253055/how-do-i-push-amended-commit-to-the-remote-git-repo)? – Dan Dascalescu Apr 03 '14 at 10:05

4 Answers4

103

Easiest solution (but please read this whole answer before doing this):

  1. git rebase -i <hash-of-commit-preceding-the-incorrect-one>
  2. In the editor that opens, change pick to reword on the line for the incorrect commit.
  3. Save the file and close the editor.
  4. The editor will open again with the incorrect commit message. Fix it.
  5. Save the file and close the editor.
  6. git push --force to update GitHub.

This will mean you will be publishing a modified version of a previously published repository. If anyone pulled or fetched from your repo between when you made the mistake with the incorrect commit message, and when you fixed it, then they will experience some difficulties later. So be sure you can accept this consequence before trying this.

zzlalani
  • 22,960
  • 16
  • 44
  • 73
Dan Moulding
  • 211,373
  • 23
  • 97
  • 98
  • since this is my home project this will be an ok solution. Thanks! – jonny Feb 17 '11 at 17:51
  • I'd disagree that this is the _easiest_ method. – Abizern Feb 17 '11 at 18:07
  • Ah. Didn't see the extra info provided in the OP's comment. – Abizern Feb 17 '11 at 19:25
  • Mentioning it is touched by only you would make a huge difference in replies ;) – Jeff Ferland Feb 18 '11 at 14:19
  • 5
    This answer is helpful as far as it goes, but is there any way to get more detail on "If anyone pulled or fetched from your repo between when you made the mistake with the screwed commit message, and when you fixed it, then they will experience some (minor) difficulties later"? I can't seem to find any descriptions of the issues and solutions, just warnings... – Tao Apr 05 '12 at 19:12
  • 1
    @Tao: See http://progit.org/book/ch3-6.html#the_perils_of_rebasing for an example of the issues. There are no simple generalizable solutions, hence the warnings. – Dan Moulding Apr 06 '12 at 14:28
  • @DanMoulding: Thanks, that really helps! At a high level, could I summarise this as "Anyone who had commits/branches that depended on your changes will need to rebase all those branches to avoid creating duplicate/redundant histories in later merges"? – Tao Apr 08 '12 at 13:19
  • @Tao: Yes. But I'd also add that rebasing those branches on the changed ones can sometimes be tricky because during the second rebase Git already has a duplicate/redundant history that it needs to sort out, which it doesn't always do correctly. – Dan Moulding Apr 09 '12 at 10:31
  • A little tip, you can do `git rebase -i ^`. Note the `^` character. – gen_Eric Sep 20 '13 at 14:29
  • @RocketHazmat: there is no `^` character in the answer. – Dan Dascalescu Apr 03 '14 at 10:09
  • Would the consequences apply to the upstream branch, once I make a pull request? – harsimranb Jul 28 '14 at 01:03
  • My noob status in dealing with VIM lead me to not solve my problem with this answer. – Rezwan Azfar Haleem Apr 28 '19 at 02:52
36

Rather than go the whole rebase route for one commit:

git reset --soft head~
git commit -m "The message you wanted to use"
git push -f

You can see the options in the git-reset manpage.

For a project that only you are working on, the changed history shouldn't be a problem.

Abizern
  • 146,289
  • 39
  • 203
  • 257
  • 5
    Doing this will lose all of the commit information (but not the content) of commits that were done after the "screwed" commit. All of those subsequent commits will be lumped together in one big commit. – Dan Moulding Feb 17 '11 at 18:30
  • 10
    However this is stll handy just for one commit. – jonny Feb 18 '11 at 08:15
  • 2
    Agreed. Not a good solution for the question at hand, but extremely useful when you immediately realize you need to adjust your last commit. One word of caution, when pushing with `-f` like this make sure you either explicitly reference the target branch or that you don't have other branches that will break what's upstream. – Matt McClure Oct 18 '12 at 15:06
  • 1
    When running `git reset --soft head~`, I get "fatal: ambiguous argument 'head~': unknown revision or path not in the working tree." – Dan Dascalescu Apr 03 '14 at 10:06
  • 1
    That's probably because you're near a merge. Get the sha of the commit you want to reset to and try `git reset --soft ` instead. – Abizern Apr 03 '14 at 10:23
  • Reverting an edit. I work on a Mac which is not case sensitive about head/HEAD. – Abizern Aug 11 '16 at 13:26
  • Worked perfectly for me since I was dealing with my last commit (with humiliating spelling errors) – Rezwan Azfar Haleem Apr 28 '19 at 02:52
  • Same as Rezwan worked a treat since only dealing with last commit – Arnaud Bouchot Oct 20 '22 at 13:39
6

If you have to change an old commit message over multiple branches (i.e., the commit with the erroneous message is present in multiple branches) you might want to use

git filter-branch -f --msg-filter 'sed "s/<old message>/<new message>/g"' -- --all

to replace the commit message.

Git will create a temporary directory for rewriting and additionally backup old references in refs/original/.

-f will enforce the execution of the operation. This is necessary if the the temporary directory is already present or if there are already references stored under refs/original. If that is not the case, you can drop this flag.

-- separates filter-branch options from revision options

--all will make sure, that all branches and tags are rewritten.

Due to the backup of your old references, you can easily go back to the state before executing the command.

Say, you want to recover your master and access it in branch old_master:

git checkout -b old_master refs/original/refs/heads/master

After you are satisfied with your changes use git push -f to push the changes to your public repo.

Note that you should inform your collaborators about this since all the hashes of the commits starting with the first modified one have been changed.

sebers
  • 2,866
  • 1
  • 13
  • 12
2

If you're not pushed the code to your remote branch(Github/Bitbucket) you can change the commit message on the command line as below.

 git commit --amend -m "Your new message"

If you're working on a specific branch do this.

git commit --amend -m "BRANCH-NAME: new message"

If you've already pushed the code with wrong message then you need to be careful when changing the message. i.e after you change the commit message and try pushing it again you end up with having issues. To make it smooth follow these steps. Please read the entire answer before doing it

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Important note: When you use the force push directly you might end up with code issues that other developers are working on the same branch. So to avoid that conflicts you need to pull the code from your branch before making the force push

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

This is the best practice when changing the commit message, if it was already pushed.

Prabhakar
  • 6,458
  • 2
  • 40
  • 51