A GUIDE ABOUT

GitFlow for SemVer

A branching model that enables semantic versioning to integrate with continuous deployment

Hendrik Prinsloo
7 min readOct 22, 2018

Developers should focus on solving problems by writing code. They don’t need to be concerned about how, why, or where their solutions are deployed. The ecosystem should take responsibility for the technical complexity.

Introduction

The GitFlow Workflow¹, published by Vincent Driessen, is a branching model that allows for multiple streams with strict boundaries between them. The core principles are fairly simple and intuitive.

One of the benefits of this model is that it works quite very well with SemVer² by allowing for patches, release preparation, and feature development.

It also provides a framework for seamless integration with a continuous deployment model.

Before reading this article you should familiarise yourself with the core concepts of SemVer² and determine whether it is applicable.

Target Audience

My opinion is that you should only consider this model if your application can be live in different states. In essence, it means that deployments are controlled by multiple environments.

Stop reading if

  • your application has a single “live” state, and all clients are on the most stable version
  • you are bored

Keep reading if

  • your application has multiple “live” states, client A on v.1.0.1, client B on v.1.0.12, and client C on v.1.3.1
  • you are bored

Overview

The flow is simple to understand, but challenging to explain as a single concept. Diving into a practical overview of each stream should hopefully provide more clarity.

Legend

  • develop — latest unstable version
  • master — latest stable version
  • tag — a snapshot of the version
  • hotfix — temporary branch to fix something on a version
  • release — temporary branch to prepare a new version
  • feature — temporary branch to develop a new feature
Overview of flow

Master versus develop

These two branches are long-lived and should always exist. They each represent a history of the project; in different states.

The master branch represents the official release history. Each new release will be merged into master. This branch is the latest official published state of the project.

The develop branch serves as an integration point for features and contains a full history of the project. New release branches should be created from the develop branch. These release branches would be used as temporary branches to prepare a new version

Tags are always merged into master and master should be merged into develop.

Master and develop

Feature

Each feature should live in its own branch, isolated until it is complete. When a feature is complete it is merged into develop, ready to be part of the next release branch. The feature branches should never interact with master.

Feature scenario

A new feature is requested and the story reads…

As a user I would like to have a view of the amount of beers in my fridge so that I can manage my bar’s stock.

The developer creates a new feature branch by branching off of the develop branch.

git checkout develop
git pull origin develop
git checkout -b feature-beer-grid

The developer implements the solution in the feature-beer-grid branch and sends it for testing. By doing a push to origin it can be picked up in pipelines and deployed to the staging environments.

git checkout feature-beer-grid
git commit -am "VA-125: Implemented the new beer grid in the backend"
git push origin feature-beer-grid

The solution is now tested and the developer gets notified that it failed QA. The developer returns to the feature-beer-grid branch to resolve the problem. Once the issue has been resolved, the developer commits the changes and pushes the branch to origin for another round of testing.

git checkout feature-beer-grid
git commit -am "VA-125: Fixed bug with editing a beer record"
git push origin feature-beer-grid

Once the issue passes testing and is ready to become part of the next release phase the developer is responsible for merging the feature-beer-grid branch into develop.

git checkout develop
git pull origin develop
git merge --no-ff feature-beer-grid
git push origin develop
Example of a feature branch

Hotfix

The hotfix branches are reserved for patch production releases. These patches should be done with caution and the responsibility is on the developer and the testing team to ensure that there won't be a negative impact on the production environments.

This allows the development team to iterate on releases without interrupting the rest of the workflow or waiting for the next release cycle.

Hotfix scenario

An issue is reported to the support team and a bug is logged.

VA-124: Importing beer records from a CSV with semicolon delimiters does not work since version 1.0.0.

The developer assigned to this issue needs to attempt to resolve it in the appropriate minor version. The developer updates his local git repo with the latest tags in order to find the latest tag in the 1.0.X range from which the hotfix branch should be created.

git fetch origin --tags
git tag -ln
git checkout 1.0.1
git checkout -b hotfix-1.0.1-VA-124

The developer implements the solution in the hotfix-1.0.1-VA-124 branch and sends it for testing. By doing a push to origin it will be picked up in pipelines and deployed to the staging environments.

git checkout hotfix-1.0.1-VA-124
git commit -am "VA-124: Found and resolved an issue with the import mechanism. The import mechanism will now dynamically determine the delimiter."
git push origin hotfix-1.0.1-VA-124

The issue passes the QA phase and is now ready to go straight into production. It is the developer’s responsibility to create a new tag for this issue. Creating this tag will publish the release and deploy it in the production environments. The developer also needs to merge this tag forward into master.

git checkout hotfix-1.0.1-VA-124
git fetch origin --tags
git tag -ln
git tag -a 1.0.2 -m "Deployed as 1.0.2"
# Update master and develop
git checkout master
git merge --no-ff 1.1.0
git push origin master
git checkout develop
git merge --no-ff master
git push origin develop
Example of a hotfix branch

Release

The development team will continuously iterate on the develop branch until it has acquired enough features for a new release (or a predetermined release date is approaching). A new release branch is created to allow stabilisation in preparation for the new version.

Once the release branch is created no new features should be introduced and the only changes in the form of bug fixes, minor improvements, documentation and other release-oriented tasks are allowed.

The development team works closely with the support team to iterate on issues in the release branch and polish it until it is considered to be production ready.

Scenario

The development team is nearing a release cycle and committed releasing the new version 1.1 soon.

The developer should create a new release branch from develop and push it to origin to deploy it into the staging environments.

git checkout develop
git pull origin develop
git checkout -b release-1.1

The QA team finds an issue in the release and logs it as:

VA-126: Cannot edit a beer record in the new backend beer grid since version 1.1.X

The developer should now create a new branch off of the release-1.1 branch as release-1.1-VA-126 to solve the issue.

git checkout release-1.1
git pull origin release-1.1
git checkout -b release-1.1-VA-126
# developer makes some changes and commits the solution
git commit -am "VA-126: Fixed javascript error"
git push origin release-1.1-VA-126

The support team tests the release-1.1-VA-126 branch in the staging environment and finally sign it off as flawless.

Now the developer merges the release-1.1-VA-126 branch back into the original release-1.1 preparation branch.

git checkout release-1.1
git pull origin release-1.1
git merge --no-ff release-1.1-VA-126

Once the development team has resolved all (or most of) the issues reported in the release-1.1 range and determines that it is production ready it can be tagged and bagged. The developer also needs to update the master and develop branches accordingly, to ensure that they are up to date with the latest changes.

git checkout release-1.1
git tag -a 1.1.0 -m "Deployed as 1.1.0"
# Update master and develop
git checkout master
git merge --no-ff 1.1.0
git push origin master
git checkout develop
git merge --no-ff master
git push origin develop
Example of a release branch

--

--

Hendrik Prinsloo
Hendrik Prinsloo

Written by Hendrik Prinsloo

Full Stack Developer ● Toaster mechanic ● Technical sales advisor ● Forgotten password specialist ● Let-me-google-that-for-you expert

Responses (1)