Search code examples
gitgit-mergemerge-strategy

Git and forcing to accept changes from other branch


I am trying to merge a branch into master, but want to ensure all changes from the other branch take effect, no matter what, but not sure how to go about it? The main issue is that we are ending up with merge conflicts in 50 files, where we don't care about the previous state of master.

The story: The master branch had been maintained for a release in 2018, while work for 2019 release had been done in another branch. The changes in the 2019 are complex and required throwing away a good portion of the 2018 changes, because of impacts of runtime environment dependency changes. We now want to take all the changes from 2019 and make them the new state of master.

What I have tried so far (as separate attempts):

git merge 2019-release
git merge -X theirs 2019-release
git merge -s recursive -X theirs 2019-release

The last one seems better, but runs into issues with renamed and deleted files, which there are many of, since the framework we include has been rewritten.

Wondering whether to do a scorched-earth type of approach to master (clearing all files and committing), followed by a merge would be an alternative approach?

I did try looking around Stack Overflow, but haven't found an answer that seems to properly address the issue.

Any suggestions would be appreciated?


Solution

  • What you're looking for is close to the last one you tried.

    git merge -X ours (or even git merge -s recursive -X ours) automatically resolve conflicts using ours side. (doc)

    git merge -s ours takes everything from the receiving branch, conflicts or not, thus completely discarding changes from theirs side.

    Oddly, the corresponding paragraphs in the page have the same anchor link, must be a minor bug, but be sure to check both entries and compare. I couldn't link the most relevant one since it also points to the other but it says :

    This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches. Note that this is different from the -Xours option to the recursive merge strategy.


    And so

    # we have to work from the 2019-release side since there is no theirs version for -s
    git checkout 2019-release
    git merge -s ours master
    
    # at this point we have to reflect the operation on master
    # (the second merge is just a fast-forward)
    git checkout master
    git merge 2019-release
    

    This will take everything from 2019-release side, and still mark the operation as a merge, although some might argue this is technically an overwrite.