Remember when merge conflicts would regularly mess up the codebase? TFVC (or TFS), which is the world I come from, used to be a horrible experience for merging and branching project code bases. Git changed the way teams think of merging and branching. In fact, branching and merging are second nature to teams using Git. These are considered relatively low cost operations that are performed frequently as opposed to the ocassional merge that was endemic to TFVC/TFS.

Git uses a distributed but central approach. There is one “source of truth” aka remote named origin (in most cases) from which all developers push and pull code. However, a developer A (for instance) could have their own remote named A and two developers A & B working on a feature together may conduct similar push pulls with each other with remotes A and B. Ultimately, this code will be merged into remote origin.

The central repo aka origin usually has a origin/master branch which almost every Git repo in the world uses. The origin/master HEAD refers to the latest commit in master which should comprise of production-ready code. The central repo may also have a origin/develop branch which is used as an integration branch before merging into master.

The different types of branches we may use are:

  • Feature branches – Feature/Topic branches are often a branch of the origin/develop branch and used to work on features for the next or future releases. They only exist when the feature is under development and will be merged back into the origin/develop branch.
  • Release branches – These are usually a branch from a point-in-time of the origin/develop where it’s deemed ready for a release. It exists to facilitate a production release. Additional minor work may happen on a release branch before it’s merged into the origin/master and origin/develop.
  • Hotfix branches – Hotfixes generally indicate fixes for issues in production that are discovered post-release. Hotfix branches are create from the origin/master and the changes merged into both origin/develop and origin/master branches.

Largely based on the above concepts, Git branching strategies and their origins, the two major families of Git branching strategies are:

Git Flow – Atlassian family

Git Flow comes from the Atlassian family tree. Git Flow describes how feature branches, release branches, master or development branches, and hotfixes are interrelated. Git Flow is useful when you have well defined numbered releases. It’s also extremely handy for large teams building downloadable software, packages and libraries where multiple versions of the project/product may be in production simultaneously. But Git Flow is often considered overkill for smaller software teams and less complicated projects/products.

GitHub Flow – GitHub family

GitHub Flow has it’s origins with the GitHub team. has some of the same elements as Git Flow, such as feature branches. But unlike Git Flow, GitHub Flow combines the master and release branches into a “master” and treats hotfixes just like feature branches. It is better suited to continuous delivery models where changes can be quickly made and easily deployed, sometimes multiple times a day.

Another one people on the Azure DevOps side might come across is:

Release Flow – Microsoft’s Azure DevOps (formerly VSTS) family

Release Flow, a trunk-based development branching, similar to GitHub Flow comes from Microsoft, the Azure DevOps (formerly VSTS) heavily makes use of this strategy – or at least did until recently. In this strategy, the teams do not continuously deploy master to production. Instead, they release the master branch every sprint by creating a branch for each release. When the teams need to bring hotfixes into production, they cherry-pick those changes from master into the release branch. This is a simple strategy that works well particularly for those people familiar with TFVC and prevents the “merge hell” scenario described earlier.

So which one should I use?

As a consultant, I’m used to starting subjective answers with “it depends” but that answer is all the more accurate in this scenario. This quote stood out to me:

Organizations tend to produce branching structures that copy the organization chart.

My suggestion would be to build a battery of questions like:

“What type of product are we releasing?”

“Will we be required to maintain multiple releases of this product in production?”

“Do we need continuous deployment?”

“Is our team better suited and experienced at using Release branches?”

Usually these type of questions start to provide some clarity, and select (or even eliminate) choices. For instance, if my team was more focused on continuous deployment and not ready to use a Release branch with cherry picking from Master to Release, I would eliminate the Release Flow strategy from consideration.

Which one do I use?

It depends. I use GitHub Flow for most of my projects. To me, it provides almost all the functionality that Git Flow does, but is simple enough to explain to other team members and has less overhead. Some complex applications and larger organizations use Git Flow or some modified version of Release Flow.

Looking to learn more, implement a new branching strategy or make your existing one work better for you?

What workflow do you like to use for your development projects? If you’d like to discuss the best approach for your project, Nebbia Technology can help you assess your needs and strengths to help you design one that works best for you.