Home > Software design >  Reverting a reverted merge in Git
Reverting a reverted merge in Git

Time:12-01

I have a bit of a situation on the main branch in my repository.

A developer mistakingly pushed a PR from our develop branch directly into main and pushed to remote. We've applied policies so that this cannot happen again.

After this, we reversed this PR by utilising the 'Revert PR' feature in Azure DevOps, which created a branch, undid all the changes, and then merged it all back into main. So far so good.

In the meantime, we've also had to apply some hotfixes to the main branch. When attempting to roll these changes back up to develop, I've realised that the revert commit will also go back up, meaning we will lose changes in develop.

I've also now realised that when we do a PR from dev to main, these previously pushed changes will not be merged back down again.

How do I sort out the situation so that I do not lose the feature changes when merging hotfixes back into develop and also ensure that the feature comes back to main the next time we do a correct PR?

My assumption is that I need to revert the revert (git revert -m 1 ), but is there a better way?

CodePudding user response:

It sounds like you are in a tricky situation. Reverting the revert is one option, but it may not be the best one depending on your specific situation.

One approach you could take is to cherry-pick the hotfixes from the main branch and apply them directly to the develop branch. This would allow you to keep the hotfixes in develop without reintroducing the changes that were mistakenly pushed to main. You could then create a new pull request from develop to main, which would include the hotfixes and any other changes that have been made to develop since the last time it was merged into main.

Another option would be to merge the main branch into develop, which would bring all of the changes from main (including the hotfixes and the revert) into develop. You could then use Git's interactive rebase feature to remove the revert commit from the develop branch. This would leave you with a develop branch that includes the hotfixes and any other changes made since the last merge from main, but not the revert.

Ultimately, the best approach will depend on your specific situation and the exact changes that were made to the develop and main branches. It may be helpful to review the Git history and discuss the situation with your team to determine the best course of action.

CodePudding user response:

Situation:

  • dev was merged into main ("merge X")
  • on main: "merge X" was reverted ("commit Y")

Suggestion:

  • merge main back into dev
  • then on dev: git revert <commit Y> (new "commit Z")
    Note: -m 1 is not needed here, because the revert "commit Y" itself is just a regular commit, not a merge.

Result:

  • Hotfixes from main are now also on dev
  • dev has not lost (the once reverted) changes, because "commit Z" restored them
  • If dev gets merged into main again, the once reverted changes will be applied again (because they now come from "commit Z")

CodePudding user response:

You effectively reverted a merge, but that does not erase the merge. This is a classic situation. See https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt

As that article explains (in the words of Linus, who wrote Git in the first place, so he ought to know), if you revert a merge commit, you can never again merge the commits from the second parent, because they were already merged; the revert of the merge commit removes its effects on the first parent ("so far so good", as you say) , but it does not undo the fact of the merge, whose topology remains part of the history.

Your best bet is to construct that PR afresh, entirely from scratch, perhaps by cherry picking (or rebasing) its commits, so as to get the same effect using different commits. That will give you a new PR that you can merge all the way to main.

  •  Tags:  
  • git
  • Related