Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: merging branches with very different structures

We have a branch called upgrade that was branched off master 6 months ago. In the upgrade branch we restructured all projects to maven (master is ant projects), so the structure of a project x in the two branches is totally different.

To restructure the projects to maven we used git mv so we have the history preserved. Next we did some code changes on the files on upgrade as the upgrade process required those changes.

Now I want to merge master into upgrade while preserving all structure as it exists in upgrade. How do I do this?

I tried using git merge master while being on the upgrade branch.

But this is not giving me any conflicts on the code changes we made on upgrade; instead it gave me conflicts in property files. (I'm definitely sure of code changes on upgrade that conflict with master) -- what could be wrong?

like image 214
Rose Avatar asked Dec 26 '12 22:12

Rose


1 Answers

What you want is to use the ours strategy (not the strategy option as mentioned in the previous version of this answer); while being on upgrade, use git merge -s ours master. According to the more detailed information in the git merge manpage, this will not try to do an actual merge at all, but simply use the tree from the ours side for the result and discard every other side in the merge.

Using merge with that will keep all history, create a merge commit (showing the convergence of the two branches in history), but use all files from one side of the merge.

Note that the meaning of "ours" and "theirs" is merely depending on which branch you are on when you initiate the merge ("merge upgrade into master" vs. "merge master into upgrade", which both produce the same resulting history). "Ours" is the one branch you're standing on, and "theirs" is/are the branch(es) you specify on the merge command. More about this is explained in the manpage.

EDIT: As a point of explanation: You (most probably) did not get any conflicts on the code changes you made, because master did not diverge sufficiently from the common code base. By default, git merge uses a three-way merge strategy, which takes the latest common ancestor of the two sides you want to merge, and only actually looks at changes relative to that common ancestor. If only one side of the branch progressed, Git will recognize that all changes there supersede the old code (in your case, the code on master), and it will just use the code from upgrade automatically (i.e. it resolved the "conflict" automatically).

A conflict that you must manually resolve will only be brought up when both sides of the merge have changed in comparison to the common ancestor. In that case, Git does not know which side is "better" -- it might even be that the two sides need to be combined for them to work. That's why the user is asked to resolve such conflicts.

Note: Answer was updated because I had previously misinterpreted the -s and -X options.

like image 185
Nevik Rehnel Avatar answered Sep 17 '22 18:09

Nevik Rehnel