Pwnosaurus
Pwnosaurus

Reputation: 2170

Reverting a git merge, then later merging some of the reverted commits

Suppose the following git history (in chronological order):

master    [I]------------------------[M2]---[MG]---[RV]---[MG2]
dev         \---[D1]----------[D2]----------/              /
release            \---[R1]-------------------------------/

Oh no! Now the changes introduced in D1 are not present on master. I want them to be included (but I don't want D2's changes to be present). So my questions are:

  1. Assuming that I've just merged dev to master (MG), is there a command that I can use in place of git revert so that when I merge release into master I'll still have the changes from D1?
  2. Suppose I've already gone ahead with a merge from dev into master and a revert, is there a command I can use in place of git merge so that when I merge release into master I'll still have the changes from D1?

I'm aware that I could achieve this by doing a git reset --hard M2 on the master branch, but I want to avoid rewriting history if at all possible. It would also be great if a solution accounted for the possibility that additional "good" commits were added to the master branch between MG and RV or between RV and MG2.

Upvotes: 0

Views: 576

Answers (2)

Gauthier
Gauthier

Reputation: 42025

The solution proposed here (search for ADDENDUM) is to recreate an alternative to D1 (D1' below), so that its content is not ignored by later merges:

git checkout dev
git rebase --no-ff I

This should result in:

dev         /---[D1']---------[D2']
master    [I]------------------------[M2]---[MG]---[RV]---[MG2]
            \---[D1]----------[D2]----------/              /
release            \---[R1]-------------------------------/

You also need to recreate your release branch so that it starts at D1', then merge that to master:

git checkout release
git rebase D1' 
git checkout master
git merge release

Result:

release             /---[R1']---------------------------------\
dev         /---[D1']---------[D2']                            \
master    [I]------------------------[M2]---[MG]--[RV]--[MG2]--[MG3]
            \---[D1]----------[D2]----------/            /
                   \---[R1]-----------------------------/

Of course, if you've not pushed MG2, it might be a good idea to clean up before. This kind of history could easily confuse people in the future.

Upvotes: 1

Didav
Didav

Reputation: 50

I think you can use git cherry-pick to resolved your mistakes > https://git-scm.com/docs/git-cherry-pick

Upvotes: 0

Related Questions