8

Let's say I have 3 unpushed commits. Now I want to change the commit message of the first or second commit (changing them for the third one is simple using git commit --amend). How to do that?

CanSpice
  • 34,814
  • 10
  • 72
  • 86
Mot
  • 28,248
  • 23
  • 84
  • 121
  • 1
    That is a bit similar to http://stackoverflow.com/questions/3926768/amend-a-commit-that-wasnt-the-previous-commit. I tried (below) to see how a `commit --amend` could be scripted. Let me know if it works. – VonC Oct 15 '10 at 09:13

2 Answers2

6

This is a job for the powerful git rebase -i command. Also, see the Interactive Rebasing section of the Git book.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Maybe a stupid question, but can `git rebase -i` be used non-interactively? – Mot Oct 15 '10 at 08:14
  • 2
    No, not as such. However, everything that `git rebase -i` does can (in theory) be done using other, scriptable Git commands. So it would be possible to write a script to modify a previous commit message, but I don't know whether such a thing exists yet. – Greg Hewgill Oct 15 '10 at 08:21
  • congrats on your 15th gold badge ;) You are now a true git! (Err... git-guru, I meant) (I mean, guru about the tool name git) (I mean, you know what I mean) – VonC Oct 15 '10 at 12:28
  • @VonC: Thanks, that one kind of snuck up on me! – Greg Hewgill Oct 16 '10 at 00:49
6

To rebound on the sub-question: is there a git commit --amend for a previous commit (and not just the last one), you could try something like (not tested yet, but Colin O'Dell mentions in the comments having written a script for it colinodell/git-amend-old):

git checkout -b tmp
git reset --hard HEAD~2
git commit -amend 
git rebase --onto tmp HEAD@{1} master

That would be like:

x---x---x---x---x
                ^
                |
               (master*) (* = current branch)

git checkout -b tmp
x---x---x---x---x
                ^
                |
               (tmp*, master) 

git reset --hard HEAD~2
x---x---x---x---x
        ^       ^
        |       |
      (tmp*) (master) 

git commit -amend 
      y (tmp*) 
     /
x---x---x---x---x
        |       ^
   (HEAD@{1})   |
          (master) 

git rebase --onto tmp HEAD@{1} master
    (tmp)
      y---x'---x' (master*) 
     /
x---x---x---x---x (only referenced in reflog)
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    On the `rebase --onto`, see http://stackoverflow.com/questions/1994463/how-to-cherry-pick-a-range-of-commits-and-merge-into-another-branch/1994491#1994491 – VonC Oct 15 '10 at 09:15
  • 1
    why bother? rebase -i is much simpler – CharlesB Oct 15 '10 at 09:58
  • 2
    @CharlesB: I agree, `rebase -i` is simpler, but it also *interactive*. Meaning you cannot include it in a script or in an alias grouping a sequence of commands. – VonC Oct 15 '10 at 10:58
  • I've created a Bash script inspired by this answer: https://github.com/colinodell/git-amend-old Hopefully somebody finds it useful. – Colin O'Dell May 27 '14 at 17:53
  • 1
    @ColinO'Dell nice one! i have included a link to your script in the answer for more visibility. – VonC May 27 '14 at 21:52