Branching Done Right
A guide on helping you select the best branching strategy for your team
Branching is one of the most fundamental ways teams collaborate around code. Atlassian summarizes branching as:
"Branching allows teams of developers to easily collaborate inside of one central code base. When a developer creates a branch, the version control system creates a copy of the code base at that point in time. Changes to the branch don't affect other developers on the team."
So you're thinking to yourself, great branching is need, but now what? I've often found teams overlook the importance of is picking the appropriate branching strategy for their purposes. The decision is made by a senior engineer or manager and that just sticks, rarely to be revisited.
Also, what does it mean about "collaborating around" code? With multiple developers, they need to communicate when pushing any new changes to the code base. If you are choosing to have the main branch as "the one that gets pushed into production" the other branches are needed for:
Developing new features
To safely experiment in a separate branch without worry
Bug fixes
Refactoring code
And the list goes on..
Setting up branching is also not a one off activity. As a team goes through various stages of maturity, it branching strategy needs to be reconsidered. Collaboration with just 5 employees is very different with 50 and even more so at 500.
Below, I go through the 6 most common branching strategies and 5 major areas to consider when selecting a branching strategy.
Common Branching Strategies
Feature branching - Any development on a new feature triggers a branch which would then be integrated into the main/master once completed. On it's own, it would only be used in small teams or where there is minimal governance. This is not a sustainable long term approach, rather it should be used in combination with the other listed strategies below.
GitFlow - a traditional style of branching where the branches are separated based on purpose. Often a standard setup will have the following branches: main, develop, feature (takes a copy from development branch for specific features), release, and hotfixes. The reason it is labelled as traditional is it's not in the ethos of Continuous Integration and Continuous Deployment (CI/CD), the more common way of developing. It also takes considerable effort to manage various branches, and I've found scenarios where feature branches getting merged (into the main) present complexity in integration as conflicts from multiple merges arise.
Github Flow - Github's way of bringing CI/CD to the traditional GitFlow. There's a single main branch, all development, releases, and hot fixes are done with feature branches. It simplifies the process considerably, encouraging teams to use short-lived feature branches and merge into main/master as soon as possible. This allows it to be easier to integrate in a CI/CD lifecycle.
Trunk-based - Very similar to Github Flow, the goal is the main/master branch as source of truth and focusing on CI/CD. In this strategy, branches are very short lived (a few hours to may be a day) and are continuously merged with main. Whereas Github Flow might require significant pull requests (PR), the goal here is to minimize PRs and automate code quality checks. I does not use feature branching, rather integrates incomplete features sooner and uses feature flags to keep them inactive until ready for production.
Release branching - This strategy focuses on branches based on release versions. If there are long-term support requirements for a code release then this type of branching may be a good option. This option often introduces significant complexity when having to merge conflicts and hotfixes happening to a previous branch but now have new features which can lead to divergence.
Environment branching - Environment branching focuses on individual branches based on where code is being deployed to ie. development, testing, staging, and production. By its nature, this integrates quality control requirements before code moves between branches. A more extreme version is to have independent repos. But these introduce complexity moving between environments.
5 Areas To Consider When Selecting a Branch Strategy
Picking a strategy depends on your needs, and that can differ even between teams. Meta, similar to many large software organizations, work on a mono repo. Teams however, that are committing into a single repo will often use different strategies.
For example at Meta, their front end team has a longer development and experimentation cycle before release so they may use feature branching, while backend development focuses on faster changes which support trunk based branching. Similarly, you might notice that Microsoft Windows and Azure have very different release cycles on products and features, and their branching strategy will reflect it.
The following 5 areas are key considerations when evaluating branching:
Team Structure - Depending on the organization structure, communication for committing changes will be reflected in the branching choices. If your organizational culture focuses on working in silos, then GitFlow is a better fit than trunk based.
Branching should also reflect the type of work a team does (R&D timelines and structure is often different than backend teams for live SaaS products), how frequently the need to collaborate and push code. There are different strategies for distributed teams vs large in office teams - distributed will need to look for ways to minimize disruption to flow and may have members starting their days at different times. In this case, the would want to resolve issues quickly and your strategy will reflect that. A large enterprise team may have more rigid processes and requirements that would need to be reflected.
Security - Engaging security earlier in the development cycle is vital to address critical issues early on, and can be significantly cheaper than addressing later. Veracode's State of Software Security (SOSS) Report found it was 15 - 20 times cheaper to fix issues in design phase than post deployment.
A push to shift left means development teams can have feedback sooner and gets them accustomed to integrating security as part of SDLC. If your branching strategy allows for significant time between code integration, that will reflect in the quality of the code.
Criticality of Environment - It has been stated above but I think it's worth repeating, if Netflix were to go down it's an inconvenience but you'll survive. (You may even decide to read or talk a walk, think of the benefits!) In a healthcare setting on critical systems, which cannot afford down time, they can't be changed frequently.
Even with long-term support products such as Windows, customers wouldn't be happy with constant feature updates - there's needs to be a level of stability for them to work. It's little wonder why Linux systems are popular for applications requiring stability.
The amount of testing and validation is significant, and that would be reflected with the branching strategy selected.
Quality Control Processes - This comes down to organization processes and maturity, based on the items above an organization may have manual quality checks along with automation. For others automation on code quality checks is sufficient to deploy in at least development and staging.
Bug Fixes - It shouldn't be a surprise by this point that branching strategies corelate to frequency of deployments. Another area to consider is managing issues once deployed; this can includes patching, critical hot fixes, and even long-term support.
Release branching is also something to consider, but it's not without issues. You need to be aware what else has been introduced to the main branch since the past release, or take a copy of the previous one. The irony in some cases, is that the issue is already resolved in a future release but can't be used due to licensing or other requirements.
How to get started
Teams will typically have an existing branching strategy since it's fundamental to working in collaboration. It's always worth re-evaluating if the strategy is optimal as conditions may have changed since it was selected.
Assess your branching needs based on:
Team working style
Organizational culture and constraints
Development and release cadence
System criticality
Security requirements
Bug fix strategy
No branching strategy is complete without examining constrains including:
Tooling
Policies
Systems (Legacy)
I find it's helpful to create a matrix to match your teams strengths and needs to branching models and see what is the best fit. Then pick one and pilot. Take the feedback and iterate. This will ensure you have a constantly maturing branching strategy that delivers to your teams needs.



