Take the 2-minute tour ×

This question already has an answer here:

I have made 3 git commits, but have not been pushed. How can I amend the older one (ddc6859af44) and (47175e84c) which is not the most recent one?

$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date:   Tue Jan 10 10:57:27 2012 -0800

commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date:   Mon Jan 9 16:29:30 2012 -0800

commit 47175e84c2cb7e47520f7dde824718eae3624550
Date:   Mon Jan 9 13:13:22 2012 -0800
share|improve this question

marked as duplicate by Dan Dascalescu, random, fabian, bjb568, mehdi lotfi Aug 5 at 4:03


Please clarify if you want to combine those 2 commits into 1 commit or if you want to amend each one with further changes. –  Adam Dymitruk Jan 11 '12 at 20:11
I've created a Bash script for this exact purpose: github.com/colinodell/git-amend-old Once installed, you'd use it like this: git amend-old abcd123, where abcd123 is the old commit you want to amend with your staged changes. Hope somebody finds it useful! –  Colin O'Dell May 27 at 17:57

6 Answers 6

You could can use git rebase to rewrite the commit history. This can be potentially destructive to your changes, so use with care.

First commit your "amend" change as a normal commit. Then do an interactive rebase starting on the parent of your oldest commit

git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^

This will fire up your editor with all commits. Reorder them so your "amend" commit comes below the one you want to amend. Then replace the first word on the line with the "amend" commit with s which will combine (s quash) it with the commit before. Save and exit your editor and follow the instructions.

share|improve this answer
He does not want to squash or reorder the commits. –  Adam Dymitruk Jan 11 '12 at 19:07
@AdamDymitruk: Where does he say that? Btw, your answer also suggests rewriting the history. –  Benjamin Bannier Jan 11 '12 at 19:10
he just wants to amend. no mention of squashing commits together or reordering them. –  Adam Dymitruk Jan 11 '12 at 19:40
@AdamDymitruk: amending is a short-hand for committing & squashing the last two commits. Both change the commit SHA1 ("rewrite history"). Please educate me if I have a wrong mental picture. –  Benjamin Bannier Jan 11 '12 at 19:47
you can amend both commits. Squashing is squashing. Amending is something else. –  Adam Dymitruk Jan 11 '12 at 20:11

You can use git rebase --interactive, using the edit command on the commit you want to amend.

share|improve this answer
git rebase -i HEAD^^^

Now mark the ones you want to amend with edit (replace pick). Now save and exit.

Now make your changes, then

git add -A
git commit -C HEAD # reuse the existing commit's message. Omit this option if you want to change that too
git rebase --continue
share|improve this answer
It may be convenient to use git stash or git stash [-p|--patch] (interactive) to easily apply the changes to an older commit during a rebase. –  here Aug 15 at 3:10

In case the OP wants to squash the 2 commits specified into 1, here is an alternate way to do it without rebasing

git checkout HEAD^               # go to the first commit you want squashed
git reset --soft HEAD^           # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@{1}   # use the message from first commit (omit this to change)
git checkout HEAD@{3} -- .       # get the tree from the commit you did not want to touch
git add -A                       # add everything
git commit -C HEAD@{3}           # commit again using the message from that commit

The @{N) syntax is handy to know as it will allow you to reference the history of where your references were. In this case it's HEAD which represents your current commit.

share|improve this answer

I prepared my commit that I wanted to amend with an older one and was surprised to see that rebase -i complained that I have uncommitted changes. But I didn't want to make my changes again specifying edit option of the older commit. So the solution was pretty easy and straightforward:

  1. prepare your update to older commit, add it and commit
  2. git rebase -i <commit you want to amend>^ - notice the ^ so you see the said commit in the text editor
  3. you will get sometihng like this:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    pick e23d23a fix indentation of jgroups.xml
  4. now to combine e23d23a with 8c83e24 you can change line order and use squash like this:

    squash e23d23a fix indentation of jgroups.xml
  5. write and exit the file, you will be present with an editor to merge the commit messages. Do so and save/exit the text document

  6. You are done, your commits are amended

credit goes to: http://git-scm.com/book/en/Git-Tools-Rewriting-History There's also other useful demonstrated git magic.

share|improve this answer
I didn't realize I could reorder the lines in the rebase file. Great tip! –  Dan Mar 14 at 15:31
Thanks for the link; it was very helpful and solved my question. –  Cerran May 15 at 14:22

I've used another way for a few times. In fact, it is a manual git rebase -i and it is useful when you want to rearrange several commits including squashing or splitting some of them. The main advantage is that you don't have to decide about every commit's destiny at the same moment. You'll also have all Git features available during the process unlike during a rebase. For example, you can display the log of both original and rewritten history at any time.

I'll refer to the commits in the following way, so it's readable easily:

C # good commit after a bad one
B # bad commit
A # good commit before a bad one

Your history in the beginning looks like this:

x - A - B - C
|           |
|           master

We'll recreate it to this way:

x - A - B*- C'
|           |
|           master

This is the procedure:

git checkout B       # get working-tree to the state of commit B
git reset --soft A   # tell git that we are working before commit B
git branch rewrite-history        # create a branch for our alternative history
git checkout rewrite-history      # continue on our new branch

Now improve your old commit using git add (git add -i, git stash etc.) now. You can even split your old commit into two or more.

git commit           # recreate commit B (result = B*)
git cherry-pick C    # copy C to our new branch (result = C')

Intermediate result:

x - A - B - C 
|    \      |
|     \     master
|      \
|       B*- C'
|           |
|           rewrite-history

Let's finish:

git checkout master
git reset --hard rewrite-history  # make this branch master

That's it, you can push your progress now.

share|improve this answer
