Track
We can compromise an application by merging problematic code, whether it’s due to accidentally integrating unfinished work into the main branch or overlooking a critical bug that slipped past automated tests.
In this article, I will guide you through the process of using git revert to safely undo a merge, ensuring that the commit history remains intact and the project's integrity is preserved.
Become a Data Engineer
How git revert Works
We can think of git revert as Git’s version of an undo command. However, the git revert command doesn’t delete commits or jump to a previous state of the branch. Instead, it creates a new commit that reverts the changes from a specific commit.

The syntax to revert a commit with hash <commit_hash> is:
git revert <commit_hash>
We can list the commits together with their hash identifiers using the git log command. The output of git log lists the commits from most recent to oldest commit, like so:

For instance, to revert the commit that implements the subtract function, we would use the command:
git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151
Using git revert we can undo the changes of a specific commit without affecting the commit history.
Note that git revert isn’t magical, and depending on the commit history, it can result in a conflict that has to be manually resolved.
Advantages of git revert Over Manual Changes
Why is git revert useful if we may need to resolve a conflict manually? Wouldn’t it be easier to just manually undo the changes? Let’s see its advantages:
- Preserves history:
git revertcreates a new commit that undoes the changes of a specified commit while preserving the entire commit history. This helps maintain a transparent history of changes and reversals. - Atomic reversal: It ensures that the reversals are atomic and consistent. When we manually delete and commit changes, there's a risk of human error.
- Conflict awareness: It ensures that we are alerted through conflicts if there are any integrations or changes dependent on the original commit. This might seem inconvenient, but it safeguards against unintended side effects.
- Metadata: The new commit created by git revert includes metadata and a commit message that contextually describes what was reverted, aiding in future understanding. Without
git revert, this context might be lost.
Reverting a Merge In Different Scenarios
In this section, we learn how to undo a merge. For the sake of example, we’re assuming we are merging a branch named feature into the main branch executing the command from the main branch:
git merge feature
What we learn here can be applied to any two branches by replacing the names appropriately.
Reverting a merge that has no associated commit
The git merge command doesn’t always create a new commit. A commit is created only if the main branch has diverged from the feature branch. Because git revert requires a commit to operate one, we can’t use it in this case.
The main and feature branches diverge when new commits are created on main that are not ancestors of the feature branch. In other words, new commits were created on main after feature was created.
If the branches haven’t diverged, when we run the command git merge feature on the main branch, Git will use fast-forward to merge. This means that it moves the HEAD of the main branch to the HEAD of the feature branch.

We can observe that this happened by looking at the result of git merge:

To undo such a merge, we only need to move the HEAD of the main branch back to where it was. For this, we:
- Identify the previous
HEADusing thegit reflog - Reset the
HEADto the previous one usinggit reset --hard <previous_head>, replacing<previous_head>with the previousHEAD.
The output of git reflog will look something like this:

We can identify the previous HEAD by looking at the line that says “checkout: moving from feature to main” (it writes feature and main because those are the names of our branches).
In this case, the previous head is fe59838. To move the HEAD of the main branch back to it and undo the merge, we then use the command:
git reset --hard fe59838

Reverting a merge that has an associated commit
If the main branch and feature branch have diverged, then when we merge two branches, a new commit is created, called a merge commit.

The merge commit applies the changes from one branch to another one. In this case, the changes in feature are applied to the main branch.
To revert the changes on the main branch, we use the git revert on the merge commit. This will create a new commit that undoes the changes brought into the main branch with the merge, effectively restoring the state of the main branch to what it was before the merge.
First, we need to identify the hash of the merge commit. We can do this using the git log command:

Because the merge commit has two parents, the syntax of git revert is slightly different. We need to use the -m 1 option to specify that we want to revert the changes relative to the main branch:
git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d

Conflict Resolution When Reverting a Commit
Sometimes, conflicts may arise when reverting a commit, particularly if the commit being reverted conflicts with later changes in the codebase. In such cases:
- Git will pause the revert: We need to manually resolve conflicts. Git will mark the conflicting files and require intervention.
- Resolve the conflicts: We open each conflicting file, resolve the conflicts marked by Git, and save the changes.
- Stage the resolved files:
git add <file-path> - Continue the revert:
git revert --continue
Conclusion
Using git revert to undo merge commits ensures that every change and correction is documented within the commit history.
Additionally, understanding the appropriate scenarios to apply git reset versus git revert enables us to make better decisions, especially when considering collaborative workflows or local-only changes.
You can read more about this subject in the FAQs section below. If you want to learn more about Git, I recommend these resources:
FAQs
Can I revert an already-pushed merge with git revert?
Yes, that's the main use case for git revert on merges. If the changes are local then git reset is an easier way to undo the merge.
For others to see the changes, we need to push them to the remote repository. So, to undo an already-pushed merge, we do:
git revert -m 1 <merge_commit_hash>
git push origin <branch_name>
Replacing <merge_commit_hash> with the hash of the merge commit and <brach_name> with the name of the branch where the merge was performed.
Will the merge commit be deleted after using git revert?
No. The merge commit remains in history, but its changes are undone by the new commit. The whole point of undoing a merge with git revert is to preserve the commit history.
Are there ways other than git revert to undo a merge?
An alternative way to undo a merge is to use git reset. This method resets the branch to a state before the merge commit. This approach is more intrusive and can cause problems if other collaborators have already based their work on the commits we are planning to reset. Therefore, it is recommended only when we are sure that it won't affect others.
git reset --hard <commit_hash>
git push --force
Replacing <commit_hash> with the hash of the commit we want to go back to.
When should I use git reset to undo a merge?
I recommend only using git reset to undo a merge when the merge only happened locally and hasn't been pushed yet.

