Branches are an essential Git feature. They help developers create an independent workflow and experiment with new features. After developing a branch, we can merge it with the main workflow of the project, that is, the master branch.
The git merge command helps us to merge two branches. However, sometimes we may want to undo the effects of a Git Merge. Let's learn how to undo the effects of a Git Merge.
We can use the Git Merge command to abort an ongoing merge. We can use this when the merge is not completed yet, or if there are any merge conflicts. The --abort command helps us in aborting an ongoing merge.
git merge --abort
Note that the above command cannot be used if the merge operation is completed successfully.
The Git Reset command helps us to rewrite the history of our projects. It can undo changes in our repository.
To undo a Git Merge, we need to use the --hard option with Git Reset. We also need to pass the reference to the commit just before the merge commit. We can either use HEAD~1. HEAD~1 is a reference to the commit just before the HEAD, and the HEAD points to the merge commit.
git reset --hard HEAD~1
Or we use the hash of the commit that was made just before the merge. We can use the Git Reflog command to find the commit hash.
git reset --hard <hash-of-commit-before-merge>
Another method is to use the ORIG_HEAD. The ORIG_HEAD points to the commit just before the merge. We don't need to manually look for the correct commit.
git reset --hard ORIG_HEAD
Note that the Git Reset --hard command will reset any uncommitted changes. Make sure to stash such changes before using this command.
The Git Reset --hard command will reset any uncommitted changes from the modified files. A safer approach would be to use the --merge option. It will preserve any uncommitted changes.
We can use HEAD~1 or ORIG_HEAD to pass a reference to the commit before the merge. Or we can directly pass the hash of the commit before the merge.
git reset --merge HEAD~1
git reset --merge ORIG_HEAD
git reset --merge <hash-of-commit-before-merge>
Let's take an example to better understand the commands discussed above. Consider a repository with two branches - master and feature.
A -- B -- C <- master <- HEAD
\
\
 D -- E <- feature
Suppose we merged the feature branch into master. We will run the following command from the master branch.
git merge feature
A new merge commit(commit M) will be created.
A -- B -- C --- M <- master <- HEAD
\ /
\ Â Â /
 D -- E <- feature
But now, we want to undo this merge.
We can use any one of the following commands. To find out the hash of the commit before the merge, use the Git Reflog command. In our case, we need the hash for commit C.
git reset --hard HEAD~1
git reset --hard ORIG_HEAD
git reset --hard <hash-for-commit-C>
A safer approach would be to use the --merge option with Git Reset. It will keep our uncommitted changes safe.
git reset --merge HEAD~1
git reset --merge ORIG_HEAD
git reset --merge <hash-for-commit-C>
Our repository will be back in the same state before the merge.
A -- B -- C <- master <- HEAD
\
\
 D -- E <- feature
The above methods discuss how to undo a merge in our local repository. We can use the Git Revert command to undo a merge that has been pushed to the remote.
The Git Revert command will undo changes without altering the project history. It creates a new commit that contains the inverse of all the changes of the commit that we want to undo. The project history is not modified, and we can push the new reverted commit to the remote.
git revert -m 1 <hash-of-merge-commit>
A Git Merge will combine the changes of multiple branches into a single one. Developers merge their finished work into the master branch. However, sometimes we may merge the wrong changes. Thankfully, Git provides a few methods to undo a merge. We can use the Git Reset command to undo a merge in our local repo. The git reset --merge ORIG_HEAD is the easiest method. We don't need to search for the commit hash. And, any uncommitted changes will not be lost.
We can use the Git Revert command if we have pushed the merged changes to the remote.