Search code examples
gitgit-merge

Bring master to a particular commit back


I created a feature branch from master and committed the changes. Before me merging into master someone else merged he/her branch and it did not pass sonar quality check. Then, I too merged my feature branch on master branch but upon merging I realised that sonar quality check is failing, this happened because master was already polluted even before my branch merge(I did not pay attention to build fail status before merging). So, now I want to set master to a commit(which I know) where the quality check was successful. But I can't directly make any push on master due to permissions, I need to raise pull request for it.

But before merging my feature branch into master, I did one more stupidity. I merged the changes from another branch which was failing at quality check. I didn't know what sonar quality checks are and thought since maven build was successful, X2 can also be merged but I made the matter worse.

            Another branch : X2 --- 
                                   \
Feature branch :  -- A -> B -> C -> X2 ->D -> E
                /                              \
Mater branch : A --->X1-------------------------- Merge commit ->

Now, I want master to be set at A again where all quality were passed. Please tell me what I can do here. Just for information, the issues in sonar report are also from commits made before A. It appears Sonar is somehow considering old changes as new and applying checks on it.


Solution

  • Ok, going back is kind of easy, even considering that you have to keep current history:

    git checkout the-revision-you-like
    git reset --soft master
    git commit -m "Let's go back to the-revision-you-like"
    

    Now you have a revision on top of master that makes the project go back to the contents of the revision you like.

    git checkout -b XXXX-revertToGoodSonar # create a new branch for this
    git push origin @ # push the branch into remote
    # now create the PR and merge
    

    The tricky part now is the feature branches that were already merged but shouldn't have. For each one of them, you need to do this, so that git thinks that they haven't been merged ever (or they will give you headaches later on when you want to merge them again). Suppose one feature branch is made up of 5 straight revisions:

    git checkout the-feature-branch~5 # checkout the exact revision where it was started from
    git cherry-pick HEAD..the-feature-branch # reapply all revisions
    git branch -f the-feature-branch # reset branch pointer to new revision
    

    Now, the branch is exactly the same except for the fact that it is made up of revisions that git thinks that have never been merged. So when you want to merge them into the fixed master branch, it won't get confused about what should be merged.