With a very tiny footprint and lightning fast performance, Git has become the de facto standard for source control management. Branching is an essential feature of a VCS (version control system), that allows developers to diverge from the main line of development and continue their work on multiple features in parallel, without affecting the main line. Branching is often considered as Git's "killer feature" as its incredibly lightweight to perform branch operations, like creating a branch or switching between branches, which are often instantaneous.
Git doesn’t enforce any particular branching strategy and allows teams to tweak it, as it fits the team’s culture. As a result, teams and organizations are often required to choose a particular branching strategy that matches their release cadence, while optimizing productivity depending on their team size, strengths and weaknesses.
This post performs a comparative analysis of the three most popular branching strategies, namely, Git Flow, Trunk based development and GitHub Flow.
The popular branching strategies can be divided into two categories, mainline based and feature based.
Published in 2010 by Vincent Driessen, Git Flow provides a robust workflow with a strict branching model, focusing around project releases. At its core, the repository holds two main branches, with an infinite lifetime:
main(or master) – the official release history of the project
develop(or development) – the integration branch for features
To aid development and release activities, a variety of supporting branches can be used, which are short lived, unlike the main and develop branches, and aim at providing support for production releases, hot fixes, and parallel feature development.
2020-rel-1-hotfix-1(release hotfix branch)
As seen in figure 1 above, Git Flow outlines the below workflow for managing development and release activities:
developbranch is the primary hub for development and collaboration.
- Each new feature resides in its own feature branch and is created from
developas its parent.
- Once a feature is complete, the feature branch is merged to the develop branch and can be deleted.
- A feature branch never interacts with the
- When all the features required for a release are complete and merged in the develop branch, a release branch is forked off of develop.
- Only bug fixes can be added to this release branch from now on.
- Having a separate release branch enables teams to continue working on other features and merge them in develop for integration testing.
- Once the release is complete, the release branch is merged to
mainand tagged with a version number.
- Additionally, the release branch is also merged back to
develop, which may already be ahead with feature merges for the next release.
- Hot-fix branch is used to quickly patch production release and are branched off of
mainbranch. They are similar to release branches and once complete, they are merged back to
mainand tagged with an updated version number.
hot-fixis also merged back to
developbranch, to ensure the fix isn’t missed in the subsequent releases.
TBD is a popular version control strategy in centralized version control systems (VCS) and is equally applicable to distributed VCS, whereby developers commit their changes to a shared
main) branch in repository. The goal of TBD is continuous integration and thereby continuous deployment, which is achieved via a series of small and incremental commits directly into the
Trunk based development outlines the below flow for minimal branching and continuous delivery:
- Feature work is broken down into small batches which are then committed to
trunkby developers at regular intervals, sooner the better.
- This ensures minimal integration overhead and allows Continuous Integration systems to run a suite of automation tests to keep the build process green (up and running).
- To support features that span across releases, Feature toggles are used to conceal the point of entry of the feature.
- Another way to conceal the feature in development is branch by abstraction, which essentially introduces a temporary abstraction layer to encapsulate both new and old behavior during development.
- Decoupling of release from launch via feature toggles or branch by abstraction provides the operational benefit of graceful degradation on failure, and the business benefit of dark launching features.
Created by and extensively used at GitHub, GitHub Flow is a lightweight, branch-based workflow that supports teams and projects focused primarily on continuous delivery. Unlike Git Flow, there are no "releases" to production, deployment happens frequently, almost every day, even multiple times a day.
At its core, the repository holds two types of branches:
main(or master) – the mainline branch
feature(s)– the feature branches to support parallel development.
As seen in figure 3 above, the GitHub flow outlines the below workflow for managing development and release activities:
- Feature branch is created from
mainfor feature development.
- Commits are added as required, locally.
- A pull request is created to start a discussion on the commits to receive feedback on the changes.
- Review comments are a critical part of the process.
- Once the review is complete, tests and checks pass, and the pull request is approved by someone else, the branch can be deployed to production.
- If the feature branch causes any issues in production, rollback can be performed by deploying the
- If the changes work as expected in production, the feature branch is merged into main.
- As this flow promotes continuous deployment, there is no difference between a hotfix and a small feature branch.
Both TBD and GitHub flow follow a trunk or mainline based branching strategy for development and release. However, they differ in one significant way.
GitHub flow proposes deployment to production before merging to
main, whereas TBD proposes deployment after merging to
In an enterprise with large number of developers working on the same project, GitHub flow could lead to significant wait time as every approved pull request should be deployed to production, leading to a bottleneck.
Hence, for such scenarios, TBD with a predefined release cadence, is preferred, where the deployment occurs after merge to main and the commits present in the main branch at the cutoff date are deployed to production.
|Concern||Git flow||GitHub flow||Trunk based|
|Deployment trigger||release cycle||approved pull request||merge to main|
|Most stable branch||main||main||main|
|Hotfixes via||hotfix branch||feature branch||main|
|Merge effort (merge hell)||significant||minimal||minimal|
|Feedback timeline||long and slow||quick||quick|
|Production issues||rollback||quick fix via feature branch||feature toggles|
|Project Types||enterprises||open source, startups||enterprises|
Regardless of the branching strategy your team chooses, here are few practices that we implemented to ensure high code quality.
✓ Static code analysis - new code smells
0 and new bugs
✓ Dynamic scan analysis - Mandatory
0 medium or high issues.
✓ Code coverage - subjective, at-least
80% on new code.
✓ Mandatory work item association.
✓ Reviewed by at-least two other developers.
The images are copyrights of respective authors, as applicable.