Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging release into master with no resulting diff

Tags:

git

git-flow

At work we have a git workflow, based on git flow. We have 3 main branches: dev, release and master

Dev is what we are currently working on, master is what we have in production and release is when we are doing a release and making the last bug fixes. When the release is ready the release branch is merged into master and pushed into production.

Any hotfixes made in master are also pushed into dev (and the release branch (if currently running))

The question is now how we ensure that the code in the release branch is actually what is in master after the merge? Put in another way, there should be no diff between release and master (after the merge).

When merging into master from the release branch, we would also not want to deal with conflicts, so any of those should be handled automatically.

like image 560
Casper Avatar asked Feb 18 '23 21:02

Casper


2 Answers

To avoid conflicts when merging into master you can use `git merge --ours' which ignores any changes in master that would conflict with changes in release, but that has the potential for problems when you have more than one stream of development. For instance if you have support issues that fix the code in production (master) or if you have more than one release branch.

Merge conflicts are a package deal when working with branches; they will happen, just adjust your workflow to handle them in isolation to minimize any adverse impact.

To illustrate this, consider the scenario in which there is an existing version in production that has been bug-fixed and a release branch ready to be moved to production (merged to master). It looks something like this:

master  -A---------E------G
          \   \   /      /
bug-fix    \   C-D      /
            \          /
release      B--*--*--F

In this, B & C are branched from A, E is the merge commit of commit D on bug-fix into master and G is the merge commit of commit F on release into master.

At G there can be merge conflicts if the same files have been changed in both bug-fix and release. If git merge --ours has been used at G, the changes made at E can be lost.

A merge can be handled with by branching master and merging release into it, then rebasing this throwaway branch back onto master. This should only be done if the process is well controlled, for instance with a single person designated to make all merges into master.

At this point, G will not be exactly like F, it will also include the changes introduced in the bug-fix commit at E.

It is also possible to merge bug-fix into release as well as master, which would make F and G the same again. However, there is a best practice that says to never merge down. This means, with the branches in the order laid out in the diagram (more stable on top), merges should always be from the lower branch into the upper branch. This has two primary benefits, the first is that stable code is not merged into less stable code and branches stay pure in the sense they only contain the changes relevant to the feature they are introducing. For instance, if D was merged into release it would need to be tested along with release and release then contains both the change-sets from the feature it is introducing and the change-set of the bug fix.

To prevent this from being a problem I always checkout the more stable branch, merge the less stable into it and go from there.

Also, note that --ours is the branch that is checked out, --theirs is the other branch being merged in. When you change the direction of the merge, the changes they are referring to are swapped.

like image 71
David Culp Avatar answered Feb 21 '23 09:02

David Culp


It's not possible for release and master be different after they are merged. Both branches point to the same commit, the merge commit tying the branches together. Thus they are exactly the same.

If you want to make sure the contents of the release branch become the contents of the master branch, you want to use the ours merge strategy. That ignores the changes in the master branch, and just results in nicely superceding the old history of the master branch. So you'd do

git checkout release
git pull --strategy=ours . master
like image 28
Kalle Pokki Avatar answered Feb 21 '23 09:02

Kalle Pokki