Introduction
Sometimes you realize you just performed an unwanted merge & push to origin/remote Git repository. E.g. you made a mistake in selecting "target" and "source" branch and merged the "env" branch to some "feature" instead the other way round. And most probably you want to remedy this as soon as possible and before other team members use such "broken" branch any further.
One of the options can be a revert commit but that would undo a previous (or selected) commit, i.e. undo a single commit. But you might have merged a series of commits which you would like to undo at once and set the git branch to a certain state in the past. On top of it, you can even add (cherry-pick) any individual commits that happened after (contributions of your colleagues you want to keep).
Procedure
Disclaimer and preparation
- Following procedure uses a “hard” reset; it is recommended not to perform this in the project phase when rapid development is happenning and/or to communicate your intention with the team.
- Create a copy of the "broken" branch (the one you want to fix) in it's latest state, i.e. make sure you
pull
before creation. The copy can be also the source of selected commits you want to re-apply. - Reccomended: try&test the procedure beforehand on yet another copy of the branch or - at least, read the following script incl. comments to get the idea.
How-to script
# first, let's see the log of the branch from which you want to re-apply selected commits - if there are any
# (write down the list of commit IDs you want to cherry-pick)
git log --oneline <copy-of-broken-branch>
# switch to the branch you want to fix
git checkout <broken-branch>
# now we are going back to a certain point in the past..
git reset --hard <last-known-healthy-commit-id>
# .. and push it to the remote, so the others have the same state
git push --force origin <broken-branch>
# try cherry picking with the first commit ID from the list made in the first step here
# the -x option adds "cherry picked from commit .." text into the commit message
git cherry-pick -x <selected-commit>
# now see and check the state in ONE Desktop, the cherry-picked commit should appear on top of <last-known-healthy-commit> in the History
# carry on with cherry-picking, you can use range of commits (make sure you don't include the commit which originally broke the whole branch)
#the ^ mark means the <starting-commit> will be included
git cherry-pick -x <starting-commit>^..<ending-commit>
# check in ONE Desktop again; if all is ok, you can push, finally
# the branch is actually not broken anymore
git push origin <broken-branch>