Constant merge issues from release branch to master and back to development

446 Views Asked by At

We have really weird issues with our merge strategies. We are following git flow branching strategies with master, development, feature and release branches. The one thing we haven't done all the time is merge back master branch to development.

This time we wanted to start merge back master to development after the release hoping that this would solve our issues. So we branched out from development to a release branch, created a PR towards master (got conflicts that we resolved). Got a hotfix on the release branch which was merged from a feature branch (based from release branch) and then merged into master when approved. We then merged back to development branch (got only conflict on hotfix issues).

Then just to try things out we created a PR from development to master which in my mind should be ok without any conflicts, but we get conflicts for probably more than 60-70% of the files.

We have tried changing different merge strategies such as rebase no fast-forward, squash commit, basic merge with no fast-forward and so on. It doesn't seem to matter.

Looking at the lastest commithashes development is now one commit ahead of master as it should. What could be the issue? How should we solve this? It shouldn't be a problem having different merge strategies right?

1

There are 1 best solutions below

0
TTT On

Normally in Git Flow, it is not possible to have conflicts when merging a release branch into master. The reason for this is release should always be fully up to date with master, with the possible exception of some empty merge commits. Note it is possible to have merge conflicts when merging release, or master back down into develop. Hopefully it's rare, but it's certainly possible as a normal course of simultaneous development on two different branches that are eventually merged (e.g. features on develop and bug fixes on release).

Git Flow usage dictates the following rules anytime a release branch is merged into master:

  1. release is merged into master using a regular merge. (Not rebase or squash.) Additionally Git-Flow strongly urges you to use merge --no-ff to preserve the history of the deployment, and many PR tools default to using --no-ff for a regular merge for this reason.
  2. ASAP after merging release into master, you should either merge release into develop as documented by Git Flow, or, you can merge master into develop. I prefer the latter so that the new merge commit on master is brought down into develop "now", which means develop and the next release branch are fully up to date with master in both state and commits. If you merge release into develop instead, over time you'll build up multiple empty merge commits on master which will finally get brought down to develop all in one shot in the future when you finally do a hotfix.

Note for a hotfix branch, the rules are similar, but after merging hotfix into master you should merge master into release if it exists, or develop if there is no pending release branch.

If you always follow those rules it will be impossible to have conflicts when merging release into master.

Additional Notes about your scenario specifics:

The one thing we haven't done all the time is merge back master branch to development.

As mentioned in rule #2 above, this is required. If you skip this step, then any new bug fixes on the release branch may not make their way back to develop, meaning the next release branch may be missing those bug fixes. If you deploy from release instead of master, you might actually undo those bug fixes in the next release. Also, this opens the door to conflicts the next time you merge release into master which normally would not be possible.

We have tried changing different merge strategies such as rebase no fast-forward, squash commit, basic merge with no fast-forward and so on. It doesn't seem to matter.

A similar rule about merge strategies is related to rule #1 above, and this applies to Git in general, not just Git Flow:

Git Merge Rule of Thumb: When merging branch source into branch target, if source is a long-lived shared branch, then you should not rewrite the branch.

This means that when performing "Git Flow" merges such as release into master, master into develop, etc, you should never use rebase or squash, both of which will rewrite the commits on the branch. You should always use a regular merge, and in Git Flow, it's recommended that you also use --no-ff even when a fast-forward would be possible. If you rewrite a shared branch it will lead to unnecessary conflicts in future merges.

Note it is OK to use rebase and squash when merging feature or topic branches into a shared branch, since those branches are not shared and they can be deleted as soon as they are merged into a shared branch. Note for rebase in particular when you have more than 1 commit, Git Flow suggests still forcing a merge commit after the rebase (sometimes called "semi-linear merge"), so that you retain the history of which commits are part of the feature. Squashes and single-commit features have no extra history to retain so it isn't necessary to have an additional merge commit.

Then just to try things out we created a PR from development to master which in my mind should be ok without any conflicts, but we get conflicts for probably more than 60-70% of the files.

This will go away as soon as you start following the two Git Flow rules outlined above. Side note, Git Flow doesn't have a documented scenario where you would ever merge develop into master; instead you should have an in-between release branch. (But it's possible for this to happen if your release branch doesn't have any new commits on it after creation from develop.)