Help, I merge PR into the wrong branch

Tram Ho

Working with git is generally easy. Until you merge the wrong branch.

You may already be familiar with gitflow. We have main branches (master, testing …) and people will work on feature branches. Once that’s done, create a pull request to merge your feature branch into the main branch. And there will be a few times in your life you merge feature branch into the main branch (master instead of testing) for example. That’s the case we often see when we use gitflow. In the same case, you merge the feature branch into the main branch and find a bug and want to revert the newly merged commit. So what can we do now?

git push -f

Don’t do that. When there is a problem with git’s history, I often see the solution most people think of is git reset and git rebase , these 2 will make the git history change and you cannot push it anymore. So the solution everyone chooses is git push -f . It is not difficult to understand because this way is always successful. But it will cause others to fail. Now, those who have pulled the main branch will not be able to pull anymore because history is different from the main branch that you have just pushed. Then you go to the table one by one and tell everyone to do one more dangerous thing, git reset --hard to commit where not to fail and pull back.

In short, I hope you will never do this. There is always a way to handle that, at most, rewrite all the old code.

Revert commit merge merge

So now how to fix this.

git revert is a much safer tool than git reset . Its effect on the code may be the same, but it is important that it does not change the history and you can push it without force.

git revert will create a revert commit to reverse all the changes you just made in a commit. For example, your previous commit has the content like this (one more line).

Then revert commit will have the correct content always (delete the line that has just been added).

Usage like this

Where <commit> is the ID of the commit you want to revert. For example, you have just merged the feature branch into the main branch and had M merge commit like this. Imagine that you tie two branches together, there must be a place to tie them together, and merge commit is where you tie them together.

Merge commits usually have messages of type Merge branch ... Merge commit from PR of Github has the form Merge pull request #xxx from xxx . You can use git log to find the ID of the merge commit you want to revert.

However when you run

you will get a notification like this

That’s because merge commits are different from normal commits, they have more than one parent. So now if you want to revert it, it will need to know which parent you want to revert, which -ooo or B So you need to select the commit you want to return with the -mn flag. Where n is the number of the parent you want to return. In our case, the wrong merge is usually 1. So we run like this

You will be given a commit message for revert commit. By default it is of type Revert "..." where ... is the commit message of the commit you want to revert.

revert.png

It’s a long way to say, if you’ve just merged a pull request by mistake on Github then Github has a revert feature that always commits you just merged wrong.

pr-revert.png

This will create a pull request with a revert commit to reverse all the changes you just made during the last merge pull request.

Note that the commit you merged is still there, it’s only reversed completely by the revert commit you’ve just committed. That means you do not delete it, but just rewrite the whole code for it to return as merge.

Bring the commit back to the correct branch to merge

After deleting the commit, the next thing to do is to bring the code to its right place, the branch that we should have merged.

The first way I naively thought of the old days was to create one more pull request to merge into the right branch. But as I said above, the merge commit actually only merges 2 branches together and the content of the code is completely located in the commit of the two branches. So no matter how many merges you make, there are only so many commits. But revert commit is a real commit with the content to delete all newly merged commits. So even if you merge the feature branch merges into the branch you need to merge, after merging with the branch that has revert commits, it will be completely deleted.

Add a picture for easy visualization.

As you can see, despite merging the feature branch into both master and testing , we still only have A , B and 2 merge commits M1 and M2 . When merging the testing branch into the master , the revert commit R is still there and it will again delete A and B

So now we need to remove R to bring A and B back. Remember to mention deleting a commit, don’t think of git reset --hard git push -f and git push -f . So far, our way to delete commits has been to create a new commit to delete all the changes of the commit to delete.

From here on we have a lot of ways and cases to handle.

Immediately after revert

Firstly, at the exact moment when the revert merge commit was mistaken. You can always make a new commit with the content of all changes made by the last commit by using cherry-pick . So we will have a new commit with the content opposite to the revert commit, and after merging into it we will have A and B . Usage like this

Of course, just like revert , for cherry-pick be merged, we also need to select its parent commit.

You can add -e to edit commit messages, or it will also use merge commit messages. Our branch will then look like this, with C newly created cherry-pick commit. And after merging, master , C will overwrite R so we won’t lose code from feature .

After you have merged back into a branch with a revert commit

For example, you are naive as I create 1 more PR into the branch to merge. Or you in case 2 as at the beginning of the article, need to revert back to the merged branch that just merged. Then we already have A and B in the branch to merge already. And after merging into the branch with revert commit R , R will appear and cause A and B color. So we simply delete R . By reverting back to R.

And we will have the RR commit

Small note

No matter how scary git is, the code is still code and we can still fix it. But as noted, both the revert and cherry-pick both make a new commit and the contents of the commit can be super large, making it difficult to find out which changes are added from which commit.

Share the news now

Source : Viblo