Search code examples
gitversion-controlgit-mergegit-revert

How to revert all commits merged from one branch


I've a release branch for example release/4.0.1 which we used to add all change to this release and merge it to our QA branch. We made several commits and made multiple merges to our QA branch. Now, we want to remove all changes in QA which were made from release/4.0.1. There are other merges and commits that were done on the branch.

What is the simplest way to do it ? reverting the changes and commits releated to that branch only.


Solution

  • Let's visualize your scenario:

    o---o---o------o (some-other-branch)
                    \
    o---o---o---M1---N---M2 (QA)
         \     /        /
          A---B---C----D (release/4.0.1)
    

    In order to undo the changes in QA that came from commits A, B, C and D, you need to revert the merge commits M1 and M2.

    First, you need to find the merge commits that happened on QA after release/4.0.1 was forked:

    git log --format='%h %s' --right-only --merges releases/4.0.1...QA
    

    This will return the IDs and commit messages of M1, N and M21. For example:

    18abe3e Merge branch 'release/4.0.1'
    2db6c39 Merge branch 'some-other-branch'
    b49ea3f Merge branch 'release/4.0.1'
    

    At this point, you can revert the merge commits from release/4.0.1 in QA starting from the latest one:

    git switch QA
    git revert -m 1 b49ea3f # Reverts M2
    git revert -m 1 18abe3e # Reverts M1
    

    Alternatively, you can revert all merge commits in a single commit:

    git switch QA
    git revert -m 1 --no-commit b49ea3f # Reverts M2
    git revert -m 1 --no-commit 18abe3e # Reverts M1
    # Verify that everything works
    git commit -m "Revert merge commits M2 and M1"
    

    A word of caution: reverting a merge commit removes the changes, but it does not alter the history of the branches. This complicates things if you ever wanted to merge release/4.0.1 into QA again. Read the documentation for more information on the consequences of reverting a merge.


    1. Unfortunately, it's not possible to filter out merge commits from other branches that happened in between. In this example, N happened between M1 and M2, so it's going to make the cut.