Versioning on development and release branches (git-flow)

14.5k Views Asked by At

On http://nvie.com/posts/a-successful-git-branching-model/ it says:

Release branches are created from the develop branch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state of develop is ready for the “next release” and we have decided that this will become version 1.2 (rather than 1.1.6 or 2.0). So we branch off and give the release branch a name reflecting the new version number:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

Now I have a number of issues with that:

  • The develop branch is still at 1.1.5; when will this be updated? Does it make sense that the develop branch is "behind" a release branch in terms of version numbers at a certain moment in time?
  • So say I increase my version numbers before creating the release branch. If I do so, I have the same version number on dev and release branch until the next release, which I think makes more sense. What are the reasons for bumping version numbers after creating the branch?

Even then, actually I want my development branch to have a version number that clearly indicates that this is a development version (because no one who finds a generated "myproject-1.2.jar" file somewhere should consider for a second to run this jar file in a production environment). So from the moment I create the release branch I would like the version numbers to reflect "this is version 1.2.0" and "this is a development version based on 1.2".

Unfortunately, when creating the release branch, bumping the version number to "1.2" there and to something like "1.2+dev" on the development branch will result in a conflict every time I will try to merge changes from the release branch back into develop. Do you have any advice how to get this kind of versioning in place using git?

2

There are 2 best solutions below

0
On

It seems like the following workflow is actually able to realize the desired versioning in git:

  • Version on the develop branch is <last-release>+dev.
  • When releasing a new version from the develop branch:
    • Change version numbers in files to <next-release> and commit.
    • Create the branch releases/v<next-release> from develop.
    • On develop, change version numbers in files to <next-release>+dev and commit.
    • When release is complete, merge the releases/v<next-release> branch into master and tag it.

This way,

  • it is easy to know which release version the current dev code is based on,
  • a jar file created on the develop-based branch is easily detectable as development version,
  • while the commits on the release branch can still be merged back to the develop branch.
0
On

So we have encountered this same problem and have come up with three possible solutions:

1.) When we create the release branch and bump the version in the initial commit for the release, we then change the version in the develop branch to the next likely version and append alpha to the version e.g. 2.0.0-alpha so that we know this is now the pre release of a future possible version (alpha means new features are likely to be merged). If the next version number ends up being different from what we had entered, then we just change it to the correct version.

2.) The develop branch has +development appended to the last version so it's clear it is a development version of whatever the last release was that was branched off from the branch and/or deployed from master. However we found that this wasn't clear as it could give the impression it means the development version of that version... which isn't true... as it's ahead of that version!

3.) We combine both ideas... we amend the version on the develop branch but we do it dynamically based on the branch name... and we use something more meaningful that shows that it really is a development version and NOT a release of any kind at this stage... So for example in Rails:

major = 1
minor = 0
patch = 0

version = [major, minor, patch].compact.join('.')

# only release and master branch have a version
# bugfix/hotfix/feature branches are NOT releases and therefore don't have a version!
branch = `git rev-parse --abbrev-ref HEAD`
release = branch.match? /release|master/

VERSION = if release
            version
          else
            "X.X.x-#{branch} (based on: #{version})"
          end

So for example we deployed a feature branch for testing and the VERSION was:

X.X.X-feature/rest-api (based on: 1.0.0)

Or if you don't want to use the branch name...

You can do:

VERSION = if release
            version
          else
            commits = `git rev-list --all --count`
            "rev #{commits} (based on: #{version})"
          end

So you get a sort of build number based on the last release version.