38

If you found a bug in your last commit, you can simply recommit the last commit with

git commit --amend

But if you already committed another commit, how do you resubmit the commit before that one?


Note: I assume, you are aware, that you should only use --amend if you are sure no other developer already used your commit upstream

rubo77
  • 19,527
  • 31
  • 134
  • 226
  • 1
    related: [How to modify a specified commit?](http://stackoverflow.com/q/1186535) – rubo77 Jul 08 '14 at 07:00
  • possible duplicate of [How to modify a specified commit?](http://stackoverflow.com/questions/1186535/how-to-modify-a-specified-commit) –  Jul 08 '14 at 07:03

4 Answers4

36
  1. commit your fixup with

    git commit -a -m "fix commit (this one will be shifted up one line)"

    (the commit message is not important, it will be obsolete once you are finished)

  2. Now the magic:
    rebase the HEAD to the second last commit but edit the commit message before in that way, that you swap the last and the last but one line in the message editor:

    git rebase -i HEAD~3

    The editor will show the last 3 comits like this:

     pick 2a06f16 this was the last commit
     pick 0dbc5ce the last-but-one commit
     pick 2e30418 fix commit (this one will be shifted up one line)
    
     # Rebase 011f3d0..2e30418 onto 011f3d0
     # …
    

    swap the last two lines so the commit message will look for example like this:

     pick 2a06f16 this was the last commit
     fixup 2e30418 fix commit (this one will be shifted up one line)
     pick 0dbc5ce the last-but-one commit
    
     # Rebase 011f3d0..2e30418 onto 011f3d0
     # …
    
  3. Check your log with

    git log HEAD~3
  4. push the corrected commit-line with + to force a new push to the already existing branch with

    git push origin +branchname
rubo77
  • 19,527
  • 31
  • 134
  • 226
  • 3
    There's even shorter way of doing the same: `git commit -a --fixup=HEAD^` (or whatever commit to be fixed), then `git rebase -i HEAD~3` and you don't need to change anything, so you can just close editor and `git` will handle the fixup itself. – aragaer Jul 08 '14 at 07:02
  • It's the same as your answer, the difference is that `--fixup` simply automates step 2. – aragaer Jul 08 '14 at 07:04
  • 1
    can you provide another answer with your version? (you can copy and paste my answer and add your changes) – rubo77 Jul 08 '14 at 07:05
  • @aragaer: your comment doesn't work on my Ubuntu. I created it as answer, is there something missing? – rubo77 Aug 03 '18 at 23:04
  • 1
    Do you actually mean `git log -3` in step 3? I don't see how I can check my log with your provided command. – iron9 Mar 25 '21 at 01:24
21

Well, I landed on this page while searching for the same. Found a better way with many other options

git rebase -i HEAD~2

An editor will open up with the following details

pick 4f4f96f Added git ignore
pick d01e18c Added sample Blog

# Rebase 60e1cd3..d01e18c onto 60e1cd3 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]

press i, change pick to r or reword, something like below

pick 4f4f96f Added git ignore
r d01e18c Added sample Blog

PRESS esc + : + wq

Another window will open up, change the commit message

PRESS esc + : + wq

git push -f 
MyTwoCents
  • 7,284
  • 3
  • 24
  • 52
  • This is by far the easiest one. Also becoming used to `rebase -i` is a good habit as it is very powerful in different situations. – Stuck Nov 24 '21 at 21:03
  • 1
    I used this method to add the issue number in the commit message for the second to last commit. Super easy & quick. Thanks! – Siddhesh T Mar 15 '22 at 09:07
  • Does that add/modify staged files or simply reword the commit message? – ruffin May 13 '22 at 18:42
  • Just wanted to add that if you want to rename the second last commit, you would have to write r in front of the first line, like 'r 4f4f96f Added git ignore' in this case. – Abdur Rafay Jun 01 '23 at 07:22
5

@aragaer 's comment is even shorter way of doing the same:

git commit -a --fixup=HEAD^ #(or whatever commit to be fixed)

then

git rebase -i HEAD~3

and you don't need to change anything, so you can just close editor and git will handle the fixup itself.

Note: This doesn't work on my Ubuntu system!

rubo77
  • 19,527
  • 31
  • 134
  • 226
  • Are you a Windows user? If not, you'll still need to edit that file; only Git for Windows treats `fixup` commits specially during an interactive rebase. – Edward Thomson Aug 11 '16 at 03:26
  • feel free to completely edit my answer, I just wanted to add aragaers comment as answer. If this doesn't work, I will accept my own longer answer as the correct one. I use linux and have no way of testing that on windows – rubo77 Aug 11 '16 at 03:58
0

In a git GUI you can easily achieve this:

  1. add a temp branch to the newest commit
  2. reset the branch master to the commit before the commit you want to edit
  3. cherry pick all commits from the temp branch one by one to master and edit the messages if desired
  4. push the corrected commit-line with + to force a new push to the already existing branch with

    git push origin +master
    
rubo77
  • 19,527
  • 31
  • 134
  • 226