1. Introduction

The git commit –amend command allows us to edit (or amend) the most recent commit. However, just when we amend a Git commit to fix a mistake or make the commit clearer, we can accidentally make a new mistake. In this tutorial, we’ll examine how to undo the git commit –amend command properly.

First, we’ll have a better understanding of what the issue is. Then, we’ll look at an example case and show the proper solution. Finally, we’ll examine the procedure for undoing a Git amendment in two different ways: first, keeping the content changes made during the amendment, then without keeping any possible changes.

2. Understanding the Issue

Using the Git amend command (git commit –amend), we can change the message of a commit or even its content. But when we amend (or modify) something, it becomes a new thing, right? Therefore, when we change the message or content of a Git commit, the original commit is replaced by a new commit containing the changes.

Actually, after a Git amendment, we’ll still have just one commit containing all our combined content, but with a different hash. In practice, Git makes the old commit private and creates a new public one.

This is great news, as it means we can completely undo the effects of a Git amendment. However, we need to know how to reference the old commit properly so that we can undo the amendments.

3. An Example

To better illustrate the situation, let’s look at an example. In the following section, we’ll use this example scenario to present the procedure for undoing the Git amend command.

So, let’s suppose there were first the following commits on the current branch (feature1, in the example):

$ git log
commit 400071c470b8726ba1c749c19cb6d97cff06120c (HEAD -> feature1)
Author: Amanda Viescinski <[email protected]>
Date:   Tue Feb 27 11:30:49 2024 -0300

    My original commit message

commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <[email protected]>
Date:   Sun Feb 18 17:43:37 2024 -0300

    Initial commit

In this case, we’ll consider the commit 400071c to be the original commit. Next, let’s say that we’ve amended the original commit as follows:

$ touch script.js
$ git add .
$ git commit --amend -m "My updated commit message"
[feature1 3499867] My updated commit message
 Date: Tue Feb 27 11:30:49 2024 -0300
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo.txt
 create mode 100644 script.js

Thus, we have the following result:

$ git log
commit 34998671e2b984de80fa67fd795bd3fb61db474d (HEAD -> feature1)
Author: Amanda Viescinski <[email protected]>
Date:   Tue Feb 27 11:30:49 2024 -0300

    My updated commit message

commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <[email protected]>
Date:   Mon Feb 26 17:43:37 2024 -0300

    Initial commit

As we can see from the output of the command above, we’ve added a new file to the commit (script.js) and changed the text of the message.

Note that although the metadata (such as author and creation date) of the commit remains the same, its hash, message, and content are now different. In particular, the hash has been changed from 400071c to 3499867, while the message has been changed from “My original commit message” to “My updated commit message” and the content includes the script.js file.

Let’s suppose that, for some reason, we regret having made the Git amendment. Therefore, the question now is: How can we undo this Git amendment?

4. Procedure to Undo Git Amend

Now, let’s look at the procedure to undo a Git amendment.

4.1. Find the Commit for Which We’ll Reset the Branch

First, let’s check the Git log to find the commit edited by Git amend:

$ git log
commit 34998671e2b984de80fa67fd795bd3fb61db474d (HEAD -> feature1)
Author: Amanda Viescinski <[email protected]>
Date:   Tue Feb 27 11:30:49 2024 -0300

    My updated commit message

commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <[email protected]>
Date:   Mon Feb 26 17:43:37 2024 -0300

    Initial commit

As we can see from the output above, the commit we edited with Git amend is 3499867. Now, we also need to find the reference for the original commit (before we edited it with Git amend). To do this, we can consult the detailed history of commits via the Git reflog:

$ git reflog
3499867 (HEAD -> feature1) HEAD@{0}: commit (amend): My updated commit message
400071c HEAD@{1}: commit: My original commit message
… 

More specifically, the Git reflog shows an ordered list of the commits to which HEAD has pointed. *So, since Git amend was the most recent change made to the branch, the reference for the commit generated after the amendment is HEAD@{0}, while that of the original commit is HEAD@{1}.*

In fact, HEAD@{1} gives us the commit that HEAD pointed to before moving to where it currently points. Therefore, what we need to do is reset the branch to the state of the HEAD@{1} commit.

4.2. Reset the Branch and Keep the Changes

Now, we can undo the Git amend using the git reset command along with the commit reference/HEAD position we found in the previous step:

$ git reset --soft HEAD@{1}

Moreover, we use the –soft flag to undo the Git amend command without destroying the related changes. Thus, all changes committed during the Git amendment will be saved in the index. In other words, this will re-add the changes as staged, ready for us to commit again.

To check the result, let’s first see what the log looks like:

$ git log
commit 400071c470b8726ba1c749c19cb6d97cff06120c (HEAD -> feature1)
Author: Amanda Viescinski <[email protected]>
Date:   Tue Feb 27 11:30:49 2024 -0300

    My original commit message

commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <[email protected]>
Date:   Sun Feb 18 17:43:37 2024 -0300

    Initial commit

The output of the above command shows us that the commit message, metadata, and hash have been reverted to their initial state (before the Git amendment).

But what about the script.js file that we added during the Git amendment? The command below shows that the script.js file is staged, and ready for us to commit again:

$ git status
On branch feature1
Changes to be committed:
  (use "git restore --staged ..." to unstage)
    new file:   script.js

Therefore, we’ve undone the Git amend command successfully but kept the modifications so that we could continue working on them.

4.3. Reset the Branch and Delete the Changes

In case we choose to undo the Git amendment without keeping the content changes, we can use:

$ git reset --hard HEAD@{1}
HEAD is now at 400071c My original commit message

In the command above, instead of using the –soft flag, we use the –hard flag to indicate that we want to delete the modifications made during the Git amendment. This leaves our staging area empty:

$ git status
On branch feature1
nothing to commit, working tree clean

However, we’ve successfully undone the effects of the Git amend command:

$ git log
commit 400071c470b8726ba1c749c19cb6d97cff06120c (HEAD -> feature1)
Author: Amanda Viescinski 
Date:   Tue Feb 27 11:30:49 2024 -0300

    My original commit message

commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski 
Date:   Sun Feb 18 17:43:37 2024 -0300

    Initial commit

5. Conclusion

In this tutorial, we’ve learned how to undo the Git amend command. *In short, we can undo git commit –amend keeping the changes by running git reset –soft HEAD@{1}. However, to undo the Git amend command by deleting the changes made during the amendment, we can use the git reset –hard HEAD@{1} command.*

As we’ve learned, in both cases, HEAD@{1} refers to the commit to which HEAD pointed before the git commit –amend command moved it.