Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with conflicts when merging from development to master

I begun a workflow where I aim to do all new features in a development branch and the master branch will only be for production ready code.

After doing the following:

git checkout master
git merge staging

I received a bunch of conflicts looking like this:

CONFLICT (rename/add): Rename app/assets/stylesheets/mobile.css->app/assets/stylesheets/application.css in HEAD. app/...
CONFLICT (modify/delete): app/views/organizers/mobile.html.erb deleted in HEAD and modified in staging. Version stagi...
CONFLICT (modify/delete): app/views/events/mobile.html.erb deleted in HEAD and modified in staging. Version staging of app/v...

When I now have been googling this, all I read is about reviewing each and every file, resolving the conflicts and commit the changes. But I don't see any point in doing all this, as I know the code and it's only an advancement of the same code set.

How can I merge the changes done in staging into master in a simple manner without having to review and resolve each and every change?

like image 803
Fellow Stranger Avatar asked Oct 22 '13 11:10

Fellow Stranger


People also ask

How do you resolve merge conflicts between master and develop?

This can be resolved by creating a new branch that's identical to master, then merge that.

What happens if you get a conflict during a merge?

Merge conflicts happen when you merge branches that have competing commits, and Git needs your help to decide which changes to incorporate in the final merge. Git can often resolve differences between branches and merge them automatically.


1 Answers

This is a complex problem because it basically means that git cannot figure out intuitively how to combine the two branches. It appears that some files were deleted on master that are then modified in (and therefore used by) staging while another was renamed in master yet added to on staging. The following will mostly be a shot in the dark, and you may still have to manually resolve some (but hopefully fewer) conflicts.

There are a number of different algorithms for merging that git can choose from, so we'll use the one that is simplest, easy to customize, and usually used by default: the recursive strategy. And we'll force its use with the option -s recursive.

The first step to helping git would be to have it spend more time refining the patches, so we'll use the option -Xdiff-algorithm=histogram. This will take the longest but it will force git-merge to produce a better diff output (which will hopefully reduce the conflicts).

The next step is to tell git-merge to spend more time on doing a correct merge. We'll use the use the -Xpatience option to do this.

Since master will depend on the renamed/modified file, while staging will depend on the old file, we can try to trick git into thinking that the file wasn't really renamed with the option -Xrename-threshold=100% (so that the files have to be identical to be considered a rename). Note that you may have some redundant files left over and any changes to files that need to be aware of the other file names won't record old names (just the new ones) so you may want to go back and fix those once you've completed the merge. You could also adjust that 100% to something smaller (the default is 50% and that's currently causing a problem).

Now to include the files that are needed by staging we can use the following option to force them to be added: -Xtheirs. WARNING: this option will silently ignore all merge conflicts and simply use the content of staging by default. Make sure to run a full test suite to check for any inconsistencies. If you do have problems in the test suite after the merge, undo it with git reset --hard HEAD^ and redo the merge without this option. You will likely have a small number of merge conflicts that you'll have to settle manually, but you will know that the source of the errors is from one of those (finitely many) conflicts, which is huge leap forward from guessing in front of a debugger.

Finally, we put it all together to get

git checkout master
git merge staging -s recursive -Xdiff-algorithm=histogram -Xpatience -Xrename-threshold=100% -Xtheirs

Lastly, I suggest you play around with the options. The extra time spent on the merge may make the last two options useless (and even make it worse).

In the future, I suggest you regularly pull any changes in master to your topic branches. This will not only present the conflicts earlier (and thus there are fewer of them at a time) but it will also keep you up to date enough that you may even resolve the conflicts before they occur. The other reason that this is good is because git has a feature called git-rerere that records the conflicts that you resolve manually and then learns how to resolve those same conflicts automatically for you later. So once you resolve it once, you won't have to resolve the same/similar conflict over again.

like image 122
randomusername Avatar answered Sep 22 '22 15:09

randomusername