Does amending a commit change its hash?

As all commits are immutable snapshots, any alterations to their content would change the hash. In more strict terms, amending a commit creates a new commit with the desired changes, leaving the original commit untouched. In this post I'll showcase a typical use-case illustrating this.

Does amending a commit change its hash?
Photo by Markus Spiske / Unsplash

Following my previous post describing how every commit in Git is an immutable snapshot of your entire code base – which cannot be altered or tampered with – I got an interesting question from a friend of mine (who also happens to be a developer).

The question was: If I amend a commit by changing its commit message only (and nothing else), does that make it immutable? To put it in more general terms: Does amending a commit change its hash? Even if it's only the commit message that changes.

Let's answer the question by looking at two examples. I'll be addressing amending a commit from its most general use case, that is making changes to the last commit just created (even though it's technically possible to amend any commit in your history).

Amending a local commit

Here's a history containing three commits, two of which are already published remotely (C0 + C1) and one (C2) yet to be published; notice the spelling mistake in the message of the unpublished commit.

History containing three commits.

Now, let's see what happens if we fix the typo using --amend. Will the hash change?

$ git commit --amend -m "Added project documentation"
Oneliner amending the commit HEAD is currently referencing, by simply updating its commit message.
History containing a newly amended commit, with its original commit untouched but unreachable.

As all commits in Git are immutable, with even the commit message infused upon commit creation, making changes using --amend actually rewrites history; just like rebase does! As we can see in the above example, the --amend command generated a new commit (C3) based on the content from C2 – but with the corrected message added! Since the local changes to master had not yet been pushed, it would be safe to publish the new C3 commit straight away. With C2 no longer having a reference to it, Git would delete it from your internal history next time garbage collection runs; until then it would still exist on your machine and be identified using $ git reflog.

If you don't pay attention to the fact that the hash of your newly amended commit actually did change, it's easy to be fooled into believing that the original commit actually was changed. 🤓 Especially since $ git log wouldn't show the original commit no more.

Amending an already published commit

What if C2 would have been published already? What would the history then look like post amending? In this scenario, the fact that no commits can be altered becomes even clearer, as we can easily see how the two histories now have diverged.

History containing three commits, all of which are published.

With above starting position, amending C2 would create the following case.

Final state post amending.

If we now compare this history with our final state from the first example we can see that C2 still exists in our history – as the remote master branch references it. In this case, simply pushing our newly amended commit would not work as the two branches have diverging histories.

Generally it's not good practice to rewrite history of already published commits, but as long as you know what you are doing it's perfectly fine. To replace C2 completely from history, our only option here is to force push the change; knowing that we're actually deleting existing data.

Conclusion

As all commits are immutable snapshots, any alterations to their content would change the hash. In more strict terms, amending a commit creates a new commit with the desired changes, leaving the original commit untouched.

Want to know how and what makes up the commit hash? Check out my other post on the subject, if you haven't done that already! 😎

Immutable Snapshots – One of Git’s Core Concepts 🚀
One of Git’s core concepts, that’s easily overlooked and sometimes misunderstood, is the fact that all commits are immutable snapshots of the entire project! In this post I’ll illustrate what this really means.

Thanks for reading, and I hope you got a slightly better understanding about what amending a commit really means!