When using Git, one of the first problems people encounter is how to undo a commit. Taking a quick look at the help docs, it would seem that “revert” is the way to undo a commit. In Subversion, for example, “revert” actually blows away uncommitted changes to local files. But with Git, “revert” means something entirely different. This is the first in a series of posts on using Git, and I’ve set up a Github repository called git-examples to act as practical reference for some of these issues.
What happens when you revert? Consider the following Git command:
git revert <hash-of-commit-to-reverse>
This will create an additional commit that represents the inverse of commit you want to revert. The commit message will look like this:
The default commit message for a reverted commit will indicate the hash (c74ba1e) of the specific commit that is being reverted.
So what is actually happening when you revert a commit? Simply put, Git creates a commit that is the exact inverse of the targeted commit. Git is NOT undoing the commit. It is literally creating a new commit that reverses the changes of the target reverted commit. The new commit will re-add any code that was deleted from the target commit, and delete any code that was added to the target commit. The original commit will continue to exist in your commit history for eternity! Newcomers to Git are very often confused when they see a brand new commit in their branch, with the original commit continuing to exist.
Take a look at the original commit:
And here is the new commit created by reverting:
Note that code that was added in the target (original) commit, was then deleted in the subsequent commit created by the revert command. For a more in-depth look at those commits, take a look at the branch that I’ve created to demonstrate the use of the revert command.
After grasping what reverting commits is all about, you may decide that using revert is unnecessary since you only need to undo your most recent commit. If that’s the case, you’ll want to use the reset command (which I will discuss in a future post)
So why would anyone use the revert command? IMO, there’s two special cases that may necessitate using revert:
- The commit you want to undo is far back in the commit history, and it’s too late to reset or interactively rebase (I’ll talk more about interactive rebasing in later posts). The example above shows a deadly simple example, but in real life, the commit you want to revert may encompass complicated changes across multiple files, and revert guarantees to reverse exactly those changes.
- Using revert is a way to document a specific code-change. It indicates to future developers/readers of the commit history, that someone very deliberately corrected changes from a previous commit.
For more in-depth explanation of how reverting works in Git, take a look at this great post.
NOTE: The site gitready.com, is hands-down, the BEST resource that I’ve found on the web for all things Git-related!