Sachin Patil

Sachin

Free software developer & Emacser

Lost commit

Where’s my commit after I did git commit --amend?

git commit --amend comes handy if one wants changes in a previous commit or simply want to change a commit message but this results into push errors and an extra over-head of a merge-commit. In this post, lets go through the process.

Say I have three commit in my master branch but I’m not satisfied with the last commit message.

Commit logs before amend
Figure 1: Commit logs before amend

I changed the commit message using the command.

git commit --amend -m 'Attack plan-2'
Amend last commit message
Figure 2: Amend last commit message

and tried to push the changes. Soon I’ll encountered an error(see image below). Something is not right. The remote server is not accepting my changes. It says my local commits are not in-sync with the remote commits. But what did I do? I just changed a commit message.

'git push' throws error
Figure 3: ’git push’ throws error

If I check the commit logs(see image below), I see my updated message. This was expected. But what exactly went wrong?

Commit logs after amend
Figure 4: Commit logs after amend

If I closely examine the commit hash of HEAD before and after the amendment, I can see it has changed.

Which clearly means that amend changed the hash and now my local and remote differs. My remote still has that old hash(with old commit message) but HEAD’s commit hash has changed.

This also means that I lost my old hash and that is now over-written by a brand-new commit.

Below commands can be really handy:

With the last command, I can see local commits plus the lost commit(which still exits on the remote). Below figure can explain the scenario in a better way.

Lost(not visible) commit(in green) after amend
Figure 5: Lost(not visible) commit(in green) after amend

In order to push, I first need to pull that lost commit from remote. A simple

git pull

or

git pull origin master

should do the trick(image below).

Pull(and merge) commits from origin
Figure 6: Pull(and merge) commits from origin

If I check the commit logs, I see my lost commit is in place just below the changed message commit.

Commit logs after pull
Figure 7: Commit logs after pull

But there’s one extra commit, a merge-commit as HEAD(see figure below)

An extra merge-commit(in blue) on top of amended commit
Figure 8: An extra merge-commit(in blue) on top of amended commit

Now I can safely push to the remote as the lost commit exist in my local commit log.

Push merged commits
Figure 9: Push merged commits

Which should sync local & remote repos(figure below)

Local & remote commit are in-sync now
Figure 10: Local & remote commit are in-sync now

PS: If you want to avoid a merge-commit, Git provides an excellent way to achieve it via git-rebase. What it typically does is it rolls-up all the latest commits on the top of all the previous commits. Behind the curtains git-rebase completely re-writes the history. As the matter of fact one should never rebase commits that have been pushed to a public.