11

I want to use gitflow in combination with semantic versioning. In gitflow, you bump version numbers on every release or hotfix branch. This inevitably leads to version conflicts if a new development cycle (with a new version number) is started while the current release process is still ongoing.

Let's say, 1.0.0 is on master, and on develop I start the new 2.0.0 release. Now, a hotfix from master occurs (1.0.1). When merging the hotfix onto the develop branch, a conflict will happen.

There is a somewhat similar question here on SE@Stackexchange, with a major difference: Because my gradle and maven build tools heavily rely on version numbers, I have to store them in my code and can't just generate them when building a release. And I have to raise the version number on develop for a new release cycle, otherwise artifacts will get overridden.

So how can I manage my branches and version numbers so that no merge conflicts can occur?

2 Answers 2

8

You cannot reasonably avoid this merge conflict. But it is a very minor conflict and easy to resolve during the merge – but make sure that the version number is only written in one source file.

Hotfixes are probably rare enough that a manual resolution is sufficient. However, it might be sensible to add a kind of test that the correct version number was maintained, e.g. a script to check that the version number in a commit is monotonically increasing from all parent commits. Merging versions 1.0.1 and 2.0.0 would be allowed to result in >= 2.0.0.

Note that the Git-Flow is not always an applicable branching model. It is oriented towards scenarios that have clear, somewhat infrequent releases, where you might need to support old releases. This can be a good fit for off-the-shelf applications or libraries.

Git-Flow is not a good fit when you can update all deployments/users to the newest release, e.g. for in-house software, SaaS, or web/mobile apps. Then, a different branching model without release branches might be more appropriate. This implies that your development branch is always in a releasable state, which in turn means that all features that were merged are ready for release OR are protected by a feature toggle. A hotfix is then an ordinary feature for the next release, and no backporting/merging of the hotfix is necessary.

1

As an alternative, instead of hard coding the version number in a property file you can also inject it via the build system. You would never change this file so it would never result in a merge conflict. This may not be supported by all build tools though.

An example for Gradle would be:

Gradle.properties

# The following properties should be injected by the build process
version=local-SNAPSHOT
buildNumber=0

On the CI the version and buildNumber can be injected as follows:

  • In case of a non-release build: just inject the name of the branch:
./gradlew -Pversion=<branch_name>-SNAPSHOT -PbuildNumber=<ci_build_number> build publish
  • In case of a release build (e.g. triggered via a tag): inject the tag name:
./gradlew -Pversion=<tag_name> -PbuildNumber=<ci_build_number> build publish

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.