BACK
TOP
Version Control and Branching Strategies – Concepts and Best Practices
Matías Creimerman - Buenos Aires, Argentina - 2020-04-20

Version Control & Branches Strategies – Concepts & Best Practices

The last month (March 2020) it was the 20th anniversary of my professional career. I had many software development positions but
as a Solution Architect, Release/Delivery Manager, DevOps and Development Process Manager, positions that are related to this post, I gathered a lot experience in the important thing of coordinate and manage the whole development process to deliver a successful project.

The version control of code and the branches strategies for any development project (code management) is a vital and it’s the heart of any development process. The value that it provides is often undervalued and misunderstood.

Having a poor code management leading to poor implementations, bad practices and missed opportunities.

Six years ago I wrote a post related to branching strategies (today I think I would say it is obsolete, but not so much), due to a situation I found myself in a young company (young in knowledge) and I was even ashamed to write about it. But then I dedicated by myself to change things and I was given a promotion and gave great value to the company. OLD POST (the real post was published in my old blog website in 2014). In this post I formulated a new strategy called “branching by environment”.

The evolution in new architectures, new teams distribution, new types of software, infrastructure and devices, made a new evolution on code management and include new security and DevOps paradigms.

Today, in the digital era, the software is a important part (often the main) of any business success. The way that the code is developed, manage, deployed and distributed, has never been more critical than before.

First of all, I want to talk about source code control/versioning. Because is 90% common that any team, inherit source code control tools and processes that never or have not been reviewed in a serious way before or that not be the right option to the new one.

Also, as part of the DIGITAL TRANSFORMATION, is important to review the old processes and tools of any management project. Products are now more complex than before, also required different and several software and component integrations, that need another vision to be released. In favor of not evolved teams I can say that it’s something that is green, but in the mayor cases, best practices have been compromised due to lack of functionality in tools, the obsoleted tools used, and the competitivity for delivered a new value and new customer satisfaction.

To manage code is important a few thing:

*- Multidisciplinary teams work together around the world
*- Delivery software (without issues) when is required
*- Evolve the software, the code and the projects in a clean way
*- Testable code
*- Code Quality and best practices management and control
*- Maintainable code (easy way to make changes and fix bugs)
*- Version history and clean rollbacks
*- Code backup
*- Merge versions and features easily
*- Traceability
*- Changes audit
*- Easy setup (of environment, project and products versions)
*- Automation of development process (versioning, deploy, rollback, testing, integration, merging, etc)
*- Isolate new features or versions
*- Code review
*- Code Analysis
*- High availability and cover disaster
*- Clean deployment and continuous deployment
*- Continuous integration


I think these concepts are topics that each developer, manager, architect, tester, automation, devops, and any development professional profile knows, but that none apply or do in the best (or optimal) way.

So, I want to help with this post to evaluate what strategy is the most optimum to you:

Version Control and Best Practices

A version control is a software that allow you to manages changes on files over time. It’s an important and vital component of your development process. Allow to the teams to track the code changes, see the revision history for the code, and revert to previous versions if is needed.
Also, you can isolate your work until it’s ready, and quickly find issues or bug fixing. Help streamline the development process and provide a centralized/shared source for all your code.

The main propose of a version control is enable to multiple people work together in a same code of a project. Is like a database of your code project progress. The part that manage the versioning is the repository and the part that each user have to make the changes is the working copy.

It’s important to have a version control in a development project to keep safe the code and collaborate along the teams.

Depending of the version control type or the version control strategy we can have different ways to do that.

The main premise is that the work of each team member not interfere the work of the other members.

The second premise is that the version control would be the insurance against data loss.

The third premise is that the version control must track every change on the code to allow the rollback or move on an specific version in the time.

First you need to choose the type of the repository:

Types of repositories

Centralized: It was the first approach, and it evolve in different stages. At the First generation, in a no-internet world (and no-common-distributed-teams), the teams use a powerful server which manage the repository, and the developers use a light client to access the files. When a developer edit a file, it was locked preventing any other change. If another dev did a change, it need to update the file and merge the changes locally and then commit the changes and update its local copy before start any work. All work was shared and controlled in the server, the local copy of each dev it not was tracked. With the evolution of development and large teams, the centralized server was a bottleneck with locking and distribution problems, but at the second generation some other tools and the evolution of client/server communications, allowed to continue working in a centralized way with better locking mechanisms and sharing options.

Distributed: With the boom of internet and distributed teams, began to be necessary, to find a new way to repository the code. With appearance of open source projects, new tools was emerge and the combination of centralized and distributed repositories appeared. The third generation was a local centralized repository by each developer workstation that was shared between the others as a centralized repository.

Centralized-Distributed:
But it was only in the fourth generation when only a true hybrid approach was used and satisfy the new modern products development.
Now its common that each dev use a centralized power repository and also have a local repository. A famous and clear example of that is Git. For example, with Microsoft, you can use the Azure DevOps tool and have a cloud repository (which can have its folders, branches, versioning, components, etc.) and each developer will have a local copy as a repository with a working copy and work locally and then pull and push the changes to the centralized version between local and server repository.

The most important thing is choose the best option that can be used in your development process. Is important to estimate costs, licensing, the team distribution, the software versioning, the isolation needed to work, and the tools to deploy and merge the code and of course the type of project/software.

Repository Structure

Secondly, you need to evaluate the structure of your repository. In this days the repository is strong-related to the versioning control tool and the workflow you use, and is very common to use distributed repositories.
Is important to separate logical units, components, utilities, project layers in the same repository but in different folder structure.

Check-in

The check-in/commit/submit is the operation to store a new record on the repository with a version of one or more files. Each check-in have a identification, a source, a date, an user and a comment (maybe some other data in particular tool).

A bad strategy on check-in slows down productivity. To make a health repository you need to follow these best practices:

*- Atomic check-ins:
It’s like ACID with databases: atomic, consistent, isolated and durable.
*- Single intent:
It should represent a single purpose. If you fix 5 bugs, you should have 5 check-in, no one check-in of all of them. The best practice is to relate your check-in with your assigned task.
*-Narrow scope:
If your changes have, for example, a changes in a database and in a part of code, it should be split in two check-ins.
*-The description explains the “Why” of the change:
The description of the check-in should explain the reason of the change.
*-Be Consistent:
The check-in should not make the project corrupt.
*-Be Complete:
The check-in should not be partial. Maybe in your environment works, but a partial check-in maybe break the work of another team member or another environment. For example, you check-in the changes in code, but forget the settings or the database part.
*-Code review:
Before a central/shared repository check-in, is a good practice to put your code in review. Using a review system or pull request. Using reviewers is a great way to get another point of view of your changes and detect early bugs, possible inconsistencies or bad practices.
*-Traceability:
In addition of the check-in information is important to related your work with the tracking systems or management system to related your changes and check-ins with the work, audit and reviewing.
*-Be Reversible:
The check-in should be removable or rollbackable alone, as a piece of unit.
*-Frequently:
Check-in frequently to make your changes visible to the rest of the team.

Resolve Conflicts & Merging

When different devs make changes on their working copy of same files or someone combine two working copies and need to decide which change is the winner on the repository, is need to do a conflict resolution. Modern tools do the resolution automatic, but in old tools or in a particular situation when the repository can’t resolve automatically, is necessary the human interaction to resolve the conflict.
In the automation way, usually the tools compare the head of commits, the time of the change, and in modern tools some AI decide for the best option. The files that are not modified in both parts, be merged automatically.

Branching

A branch is a copy of the main code to work parallel and isolated environment. Branching is the practice to do this copies to retain the original work and stability and allow parallel development, isolated testing and working, facility to bug fixing, releasing, deploying, and versioning. Also allow the integration of different features and versions.

In an ideal world without issues, errors, bugs, etc, no branches would be needed. But in the development process is not the case.

There are many and varied branching techniques and strategies. Is very important to choose the right one that best fits your project. Also, you can change the strategy in different moments of your project.

All version controls manage branches. This is because while your project will be released, the team need to still developing and fixing bugs. For example, after a release of your project, the client request a new feature and find 5 bugs too, so, the team need to work with this bugs in parallel and with the feature too and also maintain the original version to release a version if is needed. Your team will create 6 branches to work and after the work done, the changes will be merged to a new release (or several releases).

But in projects with few developers as in those with many, branching needs to follow a strategy to avoid serious problems. Spreading the changes is not an easy task, and without guidance, strategy and good practices it can be a strong headache or the loss of changes, new bugs, bad conflict resolution or a loss project.

Branching Strategies

The goal of a branching strategy is to coordinate the development process work, build clean releases, continuous integration, continuous deployment, deployment automation, move between states of your code, fast release and rollback, clean test, enable parallel work, optimize productivity, support versions and patches.

Some teams create a lot of branches to “manage” the work but often is not the best approach. If it’s the case it’s the responsibility of the experiment team member to educate these people. The goal of branching strategy is to give us a easy no-headache development and delivery process.

Is important to communicate to all teams the strategy and why each step is adopted for the strategy, because the strategy in this modern agile and dynamic world change and evolve more frequently.

The strategy often depends of the type of software product, how we release the product, what type of deployment process we follow, what is our testing strategy, the type and the needs of the client, the experience of the team, etc.

There are some patterns of branching strategies that solve common problems already known:

Codeline/Mainline Branching

Some people confuses this strategy with main centered or trunk based strategy and use this name to this another strategy in books or blogs. Also for streams branching strategy.

In this strategy, we have one main branch/line which represents the stable version and live forever. When we start the project we create a main branch to start to commit all team code. When the first release comes, we create a new branch called “Release 1” and freeze/block the main branch. The code in Release 1 is the first release of the product. If any bug appears in the release, the team continue working on the Release 1 branch. Before a new release comes, we merge all Release 1 branch to the main branch and then create a new branch for the new release, could it be “Release 1.1” or maybe “Release 2”. We have the “stable” version on the product on the main branch and the released version on the release branch. If some bug appears on the release, we continue working in the release version. If any feature or new develop is required, we create a new branch with the release name from main branch. Before the next release, we merge the previous release with the new release in the main branch. In some case, some teams merge the previous release branch to the current release branch to have all the bugfixing in the current release branch and then merge to mainline.


Advantages:
In a small product or smalls teams or single developer project could be enough.
Isolate bug fixing
Isolate features
Isolate releases

Disadvantages:
An only branch for fixing or development could be a problem.
An only branch for fixing or development couldn’t isolate the testing/QA environment.
Can’t allow multiple large teams working together.
Can’t allow a clean continuous deployment/integration flow.
A rollback with parallel working could be a mess.
Block the team development process on releases.
The mainline could be a mess with a big and slow merge every time a release is needed.
Any small disorganization in the team or lazy merges could destroy the strategy.
Too many branches complicate the release and merge work.
A perfect estimation and plan is needed.

Codeline/Mainline Cascade Branching

This strategy is an evolve of the previous one.
To prevent some problems of previous strategy some teams decide to create a branch per release and develop and fix in the same branch and then use this branch to release the product. In this case the team never merge to mainline and always create a new branch per release.

Advantages:
In a small product or smalls teams or single developer project could be enough.
Few branches.
Clean rollback (but stop work).

Disadvantages:
An only branch for fixing or development could be a problem.
An only branch for fixing or development couldn’t isolate the testing/QA environment.
Can’t allow multiple large teams working together.
Can’t allow a clean continuous deployment/integration flow.
Block the team development process on releases.
Slow development (non agile delivery).
A perfect estimation and plan is needed.

Main centered Branching

In this strategy we have a main/trunk branch line to have the last version of the product. Any branch line is a child of main or a child of a main child. The idea is to have a releasable and main line to track all product changes but with the flexibility to create any child branches you need.
First, before a test environment deploy the team work in a main branch. After the first test environment deploy, we create a new branch called for example, “Development 1”. All work is integrated on Development 1, so, for each task and bug we create child branches from Development 1. When a release 1 is needed we merge all tasks and bugs to Development 1 and after that, we merge to main/trunk line. For the release we create another branch from main called “Release 1”. To continue we close Development 1 branch and create a new branch called “Development 2” and create any branch needed to each tasks and bugs. Before a new release, we merge all work to Development 2 to test and then to have a releasable version merge Development 2 to main. When release the version we create a new branch called “Release 2” and we freeze the Release 1 branch. To continue repeat the same process for each development cycle.

Advantages:
Few branches per development cycle.
One branch for all versions and work.
Clean rollback to any state of the main line.
Clean rollback or re-base to any release.
Concentrate the testing and a QA/Staged version on one point to code review, testing and ensure quality version.
Preserve separated release for contingency.
Isolate tasks/bugs work per dev or small teams.

Disadvantages:
A one point to test and validate the work could be a mess.
A one point to test and validate the work could block the future work.
The teams (quality, testing, review, developers, devops and release) wait to a clean version to continue working.
The versioning, deployment and release always is centered in one point that could be a blocker.
Fixing and develop could be a problem in the current development branch if the team have lazy merging or blocker or delay in fixing or developing.

Milestones Branching

This strategy is particular for cases when the team wants to have a main branch and create special branches for each milestone moment . For example, the team start to work in a main branch. Before the release, create a new branch called “Milestone 1” for the new version and freeze the main branch. The Milestone 1 is released and any bug reported is fixed in this branch. On the main branch the team continue the work and for a new release the team create a new milestone branch. The milestone branch fixes never be merge with any other branch. This strategy isolate any release in milestones and if the team need to merge a bug fix from another milestone to the new one or another, just refactor the code in the current milestone (in some cases just copy the code or improve the bug in the new milestone). Sometimes the bugs are reworking or refactoring.
This strategy is ideal for teams with an abstract idea of product/code evolution. In some product versioning (for example, products that releases a version by a year or a period) the bugs are fixed in the main branch and the milestones branch never touch after a release.

Advantages:
Only branches for each release.
Separate versions of products.
Prevent merges.
Create a branch to release and no block the main branch to continue working.
Isolate each release.
Prevent inheritance of branches and allow to find the particular version.
Support different and several release at the same time.

Disadvantages:
Is not an option for the most common project, is particular for prototypes, demos or versions products.
Cannot isolate dev work.
Cannot isolate testing.
Cannot create different deployment continuous flows.
If a release have a big issue (it can happen if the quality fail, or if you tray to develop a standard product but not work in all environments) maybe the team need to merge the fix to the main branch or deprecate a version or the wrong release (the deprecate option is the common option and the team rollback the changes in the main line and works in fixing in this line and then create a new milestone branch for the new version).

Trunk-based Branching

Maybe this is the most famous strategy, because in the old repository or old tools was the way to flow the code (also in the old centralized repositories). This strategy start and maintain all the code from the “trunk” main line. For example, the team star to work in the trunk main line, check-in theirs changes and when a release is needed the team create a new branch called “Release 1”. After the release the new developments continue in the trunk line and the bugs are fixed on the release branch, after the fixing are accepted they are merged to the trunk line. If any new feature or experimental development is need to isolate (maybe a new module development) a new branch is created. But the common way is to develop in the trunk. And with a new release, the team create a new branch called “Release 2” and the flow continue in the same way. So, we have a stable version in one line, all bugs are fixing in release branch and then merged to trunk and any developed maintain the same line and experimental developments are in a new branch. This require an experimented team, an agile work, and continuous merge, review, integration, testing and deploy.
For some moment in the history of development this strategy was ignored but in this time has acquired new value. Facebook and Google used this strategy for all products. Some teams use this strategy combined with temporal branches and pull request (the tools allow this flow in a low cost option).

Advantages:
Real time feedback
Better quality (one line of production will be stable to continue working)
Shared code/changes in real time
More collaboration
Push the team to be agile
Easy continuous integration and continuous deployment.
The code that broke the trunk be priority.
Real time visibility of the flow of code.
Better reviewing.
Less commits and history.
Isolate fixing and releases.
Eliminates unnecessary branching.
Minimize merge conflicts and lots of long live branches.
The team move fast.

Disadvantages:
Need experienced team
Poor tool poor strategy.
If the team is not agile and works as a agile team, the bottlenecks will be repetitive.
Lazy commits mismatches the work.
Poor quality broke the main line.
Poor fixing broke the main line.
Cannot isolate developments.
Multiple blocks or locks.
Poor quality code commits make a collisions and a bottleneck which stop all the commits (fixed with development branches).
Poor or slow code reviewer, blocks the work in the trunk.

Task/Story/Feature Branching

This strategy takes notice in multi-large teams around the world, first in open source contribution projects and then in project with offshore teams or distributed teams that contribute to a core/main team. For example, the core team start a project in a main line and any tasks, story or feature assigned to other team is developed in a new branch. Each branch is child of the main branch.
After each team or developer end their work, do a pull request to merge their changes to the main line. The core teams evaluates, test and review this pull request and when it is approved the code is merged to the main line. For the releases exists two options, some teams creates new branches of releases from the main line, and other just tag the main line to released.

Advantages:
Isolate tasks and bugs.
Few branches and merges.
Fast CI/CD.
Could be scalable to features branches or teams branches.
Less conflict resolutions.

Disadvantages:
Lazy merge, lazy commits, or long live branches could be a mess.
If the team have a poor stories/bugs/tasks/feature management, the strategy will be poor too.
Stabilization of code could be repetitive or recurrent.
Conflicts on main line could blocks teams work.
A merge or a lot of pull requests merged at same moment could in-stabilize the code.
A devops or deployment issue could block the main line.

Featuring Flag Branching

This strategy is a variant of the previous strategy. To prevent long live branches of features (and sometimes for partial fixed bugs), the code is merged on certain period of time and if the work is not finished the feature is flagged to disabled. When the work if finished or reviewed or tested, the flag is enable to put up the feature. This strategy usually is used in combination of previous strategy to fix some lazy branches.

Advantages:
Isolate tasks and bugs.
Few branches and merges.
Fast CI/CD.
Could be scalable to features branches or teams branches.
Less conflict resolutions.
Prevent long live feature branches.

Disadvantages:
If the team have a poor stories/bugs/tasks/feature management, the strategy will be poor too.
Stabilization of code could be repetitive or recurrent.
Conflicts on main line could blocks teams work.
A merge or a lot of pull requests merged at same moment could in-stabilize the code.
A devops or deployment issue could block the main line.
A lot of flags could be a problem.
A lot of disabled and obsolete features.
Code that is never updated again and remains hidden.
Features that already exists are coded again.

Releases Branching

This strategy is an old and obsolete strategy. Is similar to milestone strategy but with the difference that in this strategy the branches are created to store a version release of a same product. Is used when a company sell a product with different features by version and maintain different versions on each client.

Advantages:
Only branches for each release.
Separate versions of products and evolution.
Prevent merges.
Create a branch to release and no block the main branch to continue working.
Isolate each release.
Prevent inheritance of branches and allow to find the particular version.
Support different and several release at the same time.
Product version individual evolution.

Disadvantages:
Is not an option for the most common project, is particular for version products.
Cannot isolate dev work.
Cannot isolate testing.
Cannot create different deployment continuous flows.
If a release have a big issue (it can happen if the quality fail, or if you tray to develop a standard product but not work in all environments) maybe the team need to merge the fix to the main branch or deprecate a version or the wrong release (the deprecate option is the common option and the team rollback the changes in the main line and works in fixing in this line and then create a new milestone branch for the new version).

Staging Branching

This strategy is used when the team have a non-versionable product.
Usually used in live/online/high demand products. For example, a website application that give an online service 24/7 for end-user customers (maybe a homebanking website). In this case, any bug fixing or new feature is deployed and the website is continuous updated.
For this strategy, the team works in a main line branch and have any “staged” branch that need to merge the next update and to review and test before go live. For example: Main-QA-Live

Advantages:
One main line to developed and fix having an agile flow.
Prevent unstable code in production.
A branch to review and gain quality.
Block bad code and focused on fix issues.
Live/production branch to use in critical bug fixing to separate the code of low branches.
Disadvantages:
Cannot isolate development code.
Cannot isolate fixing code.
QA branch have a lot of merges
QA could block a feature or fix if the environment is unstable.
No version/release branch (only one product and only one rollback)

Environment Branching

This is a strategy to separated the code on each stage of the deployment and delivery process. The team have a main/live/production/stable branch line. Then with any commit the team create a Stage branch that represent the staging or preproduction environment. Then create a QA/Testing branch for testing and quality proposes (some teams need or use a UAT branch between QA and Stage). Then create a development branch and finally create a features/fixes branches.
The “main” branch for development is the development branch, when a new feature is started, the dev create a new feature/bug branch. After end the work, the dev or a release manager merge the candidate changes of the release to development and do the unit testing and code review. When the code is approved by the architect or by the release manager, the code is merged to QA branch. When the QA team approved the version, the release manager merge the code to stage branch and use a copy of production data to validate the version with a real version. If the version is approved the release manager merge the code to the main branch. The deploy could be automated to deploy on each environment. If the team need more environment, the team could create any branch is needed and each one need to have a parent and a child branch (process flow environment relation). Maybe you could need two QA stages or two Stage branches, or use development branches for each team (maybe in this case the teams work in different modules or component of the product).

Advantages:
The code is reviewed and deployed in different stages to be approved and to guarantee a better release version.
The issues and bugs could be detected early.
Isolate features and bugs.
Isolate the code to have a valid integrated version (reviewed in development) a tested version (validated and tested in QA) a staged version (validate the new version with current data and changes in production to guarantee a production version with less issues).
Fast CD/CI
Disadvantages:
More team process.
More management (maybe a devops or release manager dedicated).
More merge.
More branches.
More conflict resolution.

Development Branching

This is a small strategy used when the team wants to have a main line to develop and when need a branch to develop a more complex feature or bug, create a branch and merge as fast as can. The releases are tagged on the main.

Advantages:
Real time feedback
Better quality (one line of production will be stable to continue working)
Shared code/changes in real time
More collaboration
Push the team to be agile
Easy continuous integration and continuous deployment.
The code that broke the trunk be priority.
Real time visibility of the flow of code.
Better reviewing.
Less commits and history.
Isolate complex development/fix.
Eliminates unnecessary branching.
Minimize merge conflicts and lots of long live branches.
The team move fast.

Disadvantages:
Need experienced team
Poor tool poor strategy.
If the team is not agile and works as a agile team, the bottlenecks will be repetitive.
Lazy commits mismatches the work.
Poor quality broke the main line.
Poor fixing broke the main line.
Multiple blocks or locks.
Poor or slow code reviewer, blocks the work in the main line.

Streams Branching

This strategy is similar to mainline strategy but with the difference of multiple fixing and development branches. The team have a main line, a release line per each release, and a lot of development branch as is necessary. Also the changes and features between development branches could be shared or merged.

Advantages:
Isolate bug fixing
Isolate features
Isolate releases
Disadvantages:
An only branch for fixing or development could be a problem.
An only branch for fixing or development couldn’t isolate the testing/QA environment.
Can’t allow multiple large teams working together.
Can’t allow a clean continuous deployment/integration flow.
A rollback with parallel working could be a mess.
Block the team development process on releases or in merges.
The main line could be a mess with a big and slow merge every time a release is needed.
Any small disorganization in the team or lazy merges could destroy the strategy.
Too many branches complicate the release and merge work.
A perfect estimation and plan is needed.

Integrations Branching

In this strategy the team have a main line branch and create a branch for each feature. When a new release is coming, the team create a new parallel branch from main line to merge all included features. If the merge, review, test and deploy is ok, the integration branch is merge to main line.

Advantages:
Isolate features and bugs developments.
Integrate the version before a release.
Disadvantages:
Too branches
Too merges
Slow release to production.
Blocks on integration merge.

GitHub Flow Branching

In this strategy the team only have a main branch line and create branches for each new feature or isolate dev development/fixing.
Is published by GitHub on 2011. Is commonly used with collaboration/open source projects.
The main line represents the stable/deployable/releaseable version. For each new development or fix the dev create a new branch, work in this branch and dev start a pull request. When the pull request is approved by the community the branch is merged to the main line and a new version is available to release (often, after pull request approve the version is released). GitHub use this flow in their repositories.

Advantages:
Last commits/version ready to continue.
Fast CI/CD.
Simple.
The best for single/online/live versions to maintain (commonly used for opensource frameworks or libraries)
No branches and merges conflicts.
No blockers.
Developers isolation.
Easy to update.
Always fast-forward.

Disadvantages:
Unstable production code.
Bad option to version products or releases plan
No resolve infrastructure or devops problems.
Long live branches out-of-date version.
Lazy pull request make branches obsolete.

GitFlow Branching

This strategy takes notice in multi-large teams around the world. Is the most popular with Git. In this strategy exists four main lines branches. One the master line that represent the main source. The develop line that represents the main line of features. The hotfix line that represents the line to do the bug fixing and the release line that represents the releases branches. The first step is create the master branch. From the master branch the team create the develop branch, and for each feature that the team start, they create a branch (feature 1, 2, 3, n…). After the features done, all features are pull requested to the develop branch. With each approve, the code is merged to develop. When the work is finish in develop, the code is merge to release branch to freeze the code to the release. After a correct release the code is merged to master. After the first release the team create the bugfixing line branch to do the fixing and after that the changes would merged to master (and to develop from master, some teams merge directly from hotfix to develop). After a new development cycle the develop branch is merge to release to the new release and the cycle start again.

Advantages:
Branches isolation.
Devs isolation.
Pull request agile mechanism.
Flexibility.
Clean staged branches (stable version, releases, develop and fixing).
Agile development cycle

Disadvantages:
Too much merges.
Long live branches issues.
Rollbacks lost merge and version work.
Complex for small teams
Too much pull request required too much server process to testing and deploy.
Lazy merge between develop and hotfix equals merge and integration problems.
More management to integrate and release versions.
In large teams CI/CD integrations problems.

Forking Flow Branching

This strategy is selected when work in a large teams with public or open source project when the merge of integrations of all changes of each contributor could be a mess. Each dev have a public repository and when need other feature fork/clone the feature of another dev in own repository. The “official” public repository is the main repository. The idea is to isolate the team work from the main/public repository without interfering on the official repository and no have non-official tracking.
For example, let’s say that Microsoft have a public repository of one their product called “Azure Cache”. Microsoft decide to include a new feature of another company that develops cache systems and request to this company to develop this new feature in their product repository. To maintain the main product stable and the current version live and the new feature isolated (because include a bag of features that represented the big feature), the other company “forks” this repository to their own repository and start to work on this. After new changes in public repository the other company synchronize their repository with the public repository and still working isolate. When the other company finish a release make a pull request between repositories and if Microsoft approved, Microsoft can merge this changes to their master product branch or to another branch to still working.

Advantages:
Isolate team work without interfering public/main repository
Hide minor changes on the mayor changes
Merge different branching strategies
Clean synchronization
Best option for opensource/public projects with new features by other teams.
Clean pull-request
Own team policy and control.
Free to choose another branching strategy.
Version isolation.
Disadvantages:
Lazy up-to-date in related features could be a mess.

Support Branching

This strategy is used in any other strategy. Is used to give support to special release or version without do changes in other or current version.
For example, a product that have a 3 versions and the first one only run in Windows old version. If the team need to give support to this old version, create a new branch for this support and maintain the version in this branch.

Advantages:
Isolate old version and give support on particular version without interfering new versions.
Dedicated work.
Compatible with any other strategy
Create new old version merging new features in old versions.
Disadvantages:
Depend on the problem that resolves, but it have a low probability of troubles.

Product Version Branching

This strategy of course depends on the products needs but essentially resolve a product different version problem and it can be used in two ways:

Ahead approach:
In this case the mayor versions contains the minor versions. Each version open a new branch and bugs must be detected in the minor version to fix. After fixing all minor version must be merged before the new mayor version is released. All alive version must be alive in branches until they be deprecated. The team must never do a backward merge, always be forward. The new features always be in the new version. If the client new a particular feature in old version, we need to create a new branch to merge this minor version with the feature (we need to find the commit of the merge of the feature to the main/develop branch).

Multiple approach:
In this case the team decided to have multiple versions to maintain and add features in any version that particular client need.
The team need to create a branch from the minor version of the product to develop the feature. After the feature is done and merged to the minor branch, the feature would be merged to each version is needed. If the team need to fix or change something for this feature in this version, the team would be create a new feature branch from this version branch or fix it in the same version branch.

Advantages:
The ahead approach allow go forward with the product and prevent more bugs.
The ahead approach is more clean, also for the products and the clients.
Both approach allow isolate versions.
Both approach allow combine another strategy, but the ahead approach is more clean if is used originally.
The ahead approach is faster and more effective than multiple.

Disadvantages:
The multiple approach always have more bugs.
Too much merges in multiple approach.
In multiple approach is commonly that the team do backward merges.
Too much branches.
Lazy merge and updates causes disasters and blocks.
Slow development process.
I not recommend multiple approach because cause team stress and a confused product.
Problematic CI/CD (but you can isolated per version and develop).
Deprecated branches still live in repository.
Alive released braches version still live in repository.

Mirrored Branching

This is strategy use a main releasable branch and two more main branches, the develop branch and the hot-fix branch.
Is similar to GitHub flow but with a branch to concentrate the features and a branch to concentrate the fixes. The name is because in a graph the main branch is in a middle and the features branches are in one side and the hot-fixes in the other. All bugs are fixed in branch fixes and for each feature the team open a new branch from develop. After feature done the feature is merged to develop and when features version is done and release, this release is merged to fixes branch. Fixes branch only receive merges from main branch and do merges to main branch. If you need to merge a bug to develop branch, first you need to merge to main.

Advantages:
Isolated features between fixes and release versions.
Easy CI/CD
Less branching
Less merging
Compatible with Pull Requests
More integration version
Easy fixing

Disadvantages:
Could block features versions and releases
Could block fixing.
Lazy fixing merge cause disasters

Conclusion

As final conclusion, I can say that this strategies are only pattern to try to fit your project. No one are a silver bullet, but they can help you to follow best practices and prevent common issues on branching strategies. Are more common mixed strategies or modified strategies to fit each project.

This content is property of Matias Creimerman
Any misuse of this material will be punishable
This work is licensed under a
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License
Creative Commons License