26 oktober 2016

Release branches may contain information that should never be merged into the master branch, like versioning information. One possible solution is to cherry pick the desired commits to master, but when pull requests are being used, this is not an option. Also, having to cherry pick indicates that your branching model is wrong. The solution is to merge (without using a pull request) these unwanted commits to master using the merge strategy "ours". The merge will be recorded, but no changes will be transferred to master. This requires that such changes and the corresponding merge are performed before any commits that will be transferred to master.

Perform the following steps:

Create release branch:

git checkout -b release

Make any necessary changes that are release-branch-only, and commit them:

echo release > release-only.txt
git add release-only.txt
git commit -m "add release-only change that should never end up in master"

Merge to master using the 'ours' merge strategy:

git checkout master
# perform a proper merge, but without incorporating any new changes on the release branch
git merge -s ours release -m "merge from release but discard any commits on the release branch by using the merge strategy 'ours'"

Continue work on the release branch, creating bugfix or feature branches off it if desired.

The following bash-script illustrates this in detail:

#!/usr/bin/bash
git init
echo master > code.txt
echo master > master.txt
git add *.txt
git commit -m "initial commit"
# create the release branch
git checkout -b release
# add some changes that should not propagate to master, e.g. versioning information
echo release > release-only.txt
git add release-only.txt
git commit -m "add release-only change that should never end up in master"
git checkout master
# perform a proper merge, but without incorporating any new changes on the release branch
git merge -s ours release -m "merge from release but discard any commits on the release branch by using the merge strategy 'ours'"
git checkout release
# create a feature branch and implement a feature which should end up in both the release branch and master
git checkout -b release-feature
echo release-feature >> code.txt
echo release-feature > release-feature.txt
git add release-feature.txt
git commit -a -m "add a new release feature"
# merge the feature to the relase branch
git checkout release
git merge release-feature -m "merge the release-feature branch into the release branch"
# and to master
git checkout master
git merge release -m "merge the release branch into master"
# start implementing another release feature
git checkout release
git checkout -b release-feature2
echo release-feature2 > release-feature2.txt
git add release-feature2.txt
git commit -m "add release feature 2"
# merge feature 2 into release
git checkout release
git merge release-feature2 -m "merging feature 2"
# merge changes in release to master
git checkout master
git merge release -m "merge all changes from release to master"
# look at master
# the release-only.txt file should not show up here, but feature.txt should, and code.txt should contain new code.
ls -al
git log --all --decorate --oneline --graph