Undoing a merge not yet pushed to a remote
If you haven't yet pushed your merge to the remote repository then you can follow the same procedure as in undo the commit although there are some subtle differences.
A reset is the simplest option as it will undo both the merge commit and any commits added from the branch. However, you will need to know what SHA to reset back to, this can be tricky as your git log
will now show commits from both branches. If you reset to the wrong commit (e.g. one on the other branch) it can destroy committed work.
> git reset --hard <last commit from the branch you are on>
Or, assuming the merge was your most recent commit.
> git reset HEAD~
A revert is safer, in that it won't destroy committed work, but involves more work as you have to revert the revert before you can merge the branch back in again (see the next section).
Undoing a merge pushed to a remote
Assume you merge in a new feature (add-gremlins)
> git merge feature/add-gremlins
...
#Resolve any merge conflicts
> git commit #commit the merge
...
> git push
...
501b75d..17a51fd master -> master
Afterwards you discover that the feature you just merged in broke the system for other developers, it must be undone right away, and fixing the feature itself will take too long so you simply want to undo the merge.
> git revert -m 1 17a51fd
...
> git push
...
17a51fd..e443799 master -> master
At this point the gremlins are out of the system and your fellow developers have stopped yelling at you. However, we are not finished just yet. Once you fix the problem with the add-gremlins feature you will need to undo this revert before you can merge back in.
> git checkout feature/add-gremlins
...
#Various commits to fix the bug.
> git checkout master
...
> git revert e443799
...
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push
At this point your feature is now successfully added. However, given that bugs of this type are often introduced by merge conflicts a slightly different workflow is sometimes more helpful as it lets you fix the merge conflict on your branch.
> git checkout feature/add-gremlins
...
#Merge in master and revert the revert right away. This puts your branch in
#the same broken state that master was in before.
> git merge master
...
> git revert e443799
...
#Now go ahead and fix the bug (various commits go here)
> git checkout master
...
#Don't need to revert the revert at this point since it was done earlier
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push