Search code examples
gitgit-mergegit-revert

My changes are deleted during merge with master after revert


I have merged a development branch into master. But it was discovered the merge introduced bugs to master, so I reverted my commit. I have fixed the bugs, but when I try to pull from master into my branch, I see that this will delete many of my changes as Git probably determines master to be more up-to-date than some files on my branch due to revert.

How can I merge all my work, including both bug fixes and other content without losing anything?

Ideally, I would like to tell git to treat my branch as the newest content because no new commits to master were made since my revert.

To clarify: my original merge included modifications to existing files and some new files. When a bug was found, I've reverted everything. The fix affected only several lines of code. Now, when I try to create a merge request or just pull from master, Git recognizes only these fixes as new content which should be merged, and everything else as old content which should be deleted.


Solution

  • This is the normal consequence of reverting a merge commit. So, for example, suppose we have this:

    A -- B -- C <- main
     \
      --- X -- Y <- feature
    

    We now merge feature into main:

    A -- B -- C -- M <- main
     \           /
      --- X -- Y <- feature
    

    We now revert the merge:

    A -- B -- C -- M -- Mrevert <- main
     \           /
      --- X -- Y <- feature
    

    We then continue working on feature:

    A -- B -- C -- M -- Mrevert <- main
     \           /
      --- X -- Y -- Z <- feature
    

    We now attempt to merge feature into main again and we are horrified to discover that most of it is not arriving into main! What's happening?

    What's happening is that for all the commits that were already merged (X and Y in the diagram), the merge train has left the station. The revert has reverted the state of main but the topology of main is unaffected; thanks to the merge, X and Y are now on main. Those commits have thus already been merged into main and they can never be merged again.

    Solution — well, there are a number of ways around this situation. The easiest is probably to make a whole new branch off of main at the same point where feature branched off it, and git cherry-pick the commits of feature onto it:

    A -- B -- C -- M -- Mrevert <- main
     \           /
      --- X -- Y -- Z <- feature
       \
        --- Xnew -- Ynew -- Znew <- featureNew
    

    The commits Xnew, Ynew, and Znew will look like X, Y, and Z, but they are different commits and so they can be merged into main. Thus, merging featureNew into main will now have the desired effect.