For me, being a Software Developer is all about learning from your mistakes.
So every time i have a problem and make a mistake solving it, I tend to document the process of what went wrong and how to recover from it. I find this crucial, because not only will this give me a helpful resource to guide me later on should I come across the same issue, but it also allows me to share this information with others, so that they won’t make the same mistakes.
That being said, it’s only fitting that my first blog post should be about how to revert from that horrible mistake you just merged into production.
Why use revert
According to the official git documentation, there are three commands in git to fix mistakes: git revert, git restore and git reset.
- git-revert makes a new commit that reverts the changes made by other commits.
- git-restore is about restoring files in the working tree from either the index or another commit. This command does not update your branch. The command can also be used to restore files in the index from another commit.
- git-reset is about updating your branch, moving the tip in order to add or remove commits from the branch. This operation changes the commit history.
git reset is really powerful and useful, allowing for a variety of ways of manipulating commits messages, removing commits, or even remaking committed work. The problem is: git reset changes the commit history. Meaning this should not be used in common/deployable branches (develop/staging/master/etc) or even on branches pushed to a remote (changes need to be forced pushed and other people can be working on the same changes).
Enter git revert. This command makes a new commit that reverts the changes made from one or more commits. This allows us to revert faulty or unwanted commits without changing the history of a branch.
IMPORTANT NOTE: If you are reverting a merge commit, read the section “Reverting a merge” below for specific instructions.
Reverting a commit
$ git revert <commit-hash>This will make a new commit inverting the changes made by the offending commit.
After the revert
If, at some point in time, you want to recover the changes you reverted, you can:
- revert the revert and commit fixes on top of that.
- Create a new commit with the changes want.
Trying to use the original commit again will not work.
Reverting a merge (by Torvalds himself)
(This is a short version of the how-to from Linus Torvalds on how to revert a faulty merge)
So why is reverting a merge commit different from reverting a commit ?
Say you merged a branch into development with faulty code:

Where 08ad0cf (let’s refer to it as M ) is the merge commit.
If we look at the image above, you realize that before M, git can follow two separate paths: the feature/add-madvillainy branch (that we don't want) and the develop (that we want to keep in our history).
If we want to revert the M commit, we need to tell git which path should be kept.
git revert -m 1 08ad0cf # this will pick the mainlineWhich will result in:

At this point everything is working properly again. But you probably still want to merge that branch, but with the bugfix. You would be tempted so just commit on top of your branch and merge again. DO NOT DO THIS. This will not work.
(Quote) There are two options:
- If the faulty side branch was fixed by adding corrections on top, then doing a revert of the previous revert would be the right thing to do.
- If the faulty side branch, whose effects were discarded by an earlier revert of a merge, was rebuilt from scratch (i.e. rebasing and fixing), then re-merging the result without doing anything else would be the right thing to do. (There is also a case where you can’t change the branching-off point, but I assume this will not be a common scenario.)
First Method:

If you don’t revert the revert, both add lyric: fazers.md and add lyric: figaro.md will not be merged into the mainline, only replace fazers.md with accordion.md.
Second Method (Recommended):

# rebase the branch from the most updated version.git checkout <faulty-branch>
git rebase [-i] --no-ff <main-branch>By doing this (using the flag --no-ff), you will have all new commits with new hashes. Now all you have to do is fix and merge.
Conclusion
Hopefully this article can help you next time you have to revert that merge commit in development that was not quite finished.
Moving forward, I hope to have the time to continue writing articles on specific problems you may face in git and compile them in a handbook.
At Runtime Revolution we take our craft seriously and always go the extra mile to deliver a reliable, maintainable, and testable product. Do you have a project to move forward or a product you’d like to launch? We would love to help you!