How to cancel git merge but keep history

There is a leading branch in our vault, but it looks like one of our colleagues had a master branch with a different story. Yesterday, he united his master into the main owner and pushed him. Therefore, today some of us have already reached out and started to work. When we understood the problem, a couple of hours of work had already passed ...

So my question is how can I undo its merge, but still save the code changes today? The left side is our current state, the right side is what I shoot for. Should I reinstall? or is there a way to cancel the merge? What is the best approach here?

enter image description here

Edit 1: I don’t think it is a duplicate Undo a Git merge that has not yet been pushed since the commit was moved to the beginning and also I have other commits AFTER the error was made and I want to save the history.

Edit 2: I tried to reinstall, the problem is that the rookie has merged into his main branch in the last 2 weeks ... Therefore, even if I return, I will not get rid of the new “timeline” that he created ... I have no problem rewriting history while I am getting rid of its timeline ...

enter image description here

Edit 3:

In the end, I found a version of the repository that was not affected and responded to the changes made after the incident ...

+8
git
source share
2 answers

I see three options: return merge, reload, or filter.

Rollback

The “right” solution, as others say, is to get the merge back - which means that you are not “rewriting the story”, which is usually considered a good thing, not least because it means that everyone else working on this code will not need to change history.

You cannot just use git revert as-is, however, because it does not know which branch of the history to keep. The solution is to simply provide Git with an extra bit of information:

 git revert -m 2 <sha-of-B> 

That -m 2 indicates that you want to keep the second parent, i.e. the one that contains commit C; switch to -m 1 for an alternative.

One warning: if you want to merge this other branch into your main branch, you will run into a problem due to Git, believing that the branch is already in the main branch. There are several solutions for this, but the easiest (IMO) is to return the edge to the branch from the master and, as well as merge it into master, merge it into another branch. This branch is likely to be similar to any version of the master that it forks, and at that moment you can return the reverse, and everything will be fine when you merged in the future.

relocation

Rebasing is probably the easiest option: git rebase <sha-of-B> master --onto <sha-of-C> .

This will move all the commits from B until master on C. It will catch that it “linearizes” the merge history. The story of merging in an image is very simple, but it can be a problem if you want to keep the story or if you do it in a more complex repository.

It also has a catch that it “rewrites history” and everyone who uses this repository will find that they work with a completely different branch of code in the one that was returned, since each change from C will have a different sha1 hash.

Filtration

Using git filter-branch will allow you to get exactly what you are looking for in your image, that is, save the merge history, but this is the most difficult option and still includes rewriting history.

Effectively, you want to use git filter-branch to filter your commits in order to save everything but a single duff merge. This is complicated enough; I am not going to write instructions; you need to combine --commit-filter to remove the abusive merge and --tree-filter to discard the merge changes.

Contraction filtering

Well, here is the fourth method that I include for completeness. You could just check C, and then manually cherry-pick and merge each of the changes you want to have in your main branch one by one.

Further reading

+2
source share

What I would do is go for the return that you are just looking to invert the deltas that you just combined in this union and then commit it.

Pull the un-commit to your C branch, and then Revert to commit to C Branch and commit it. The double negative will be canceled, you will save your whole story, and when you unite again, you will have the results you are looking for.

Git Extensions have a feature for reverses that make this very easy.

+1
source share

All Articles