The Agile, the Fragile, and the Iron Fist of Branching Strategies
Effective branching strategies help maintain order in the chaos, streamlining the delivery of code from development to production.
Join the DZone community and get the full member experience.
Join For FreeWhether you love it or hate it, Git has proven to be the nearly ubiquitous method engineering organizations employ to ship code today. However, when you’re just getting started and building your team, you may be thinking about which strategy is the right one for you to choose based on your current and future needs.
We recently wrote a longer article about effective branching strategies, and the considerations involved when selecting your branching strategy of choice. However, we still believe it could be useful to dive in more deeply into the underlying philosophy for each branching strategy, to help you decide what code shipping strategy is the right one for your engineering team.
To make a very rough generalization, we can largely split branching strategies into those that are more agile in nature and those that are more structured. Each is employed to provide either more rapid delivery or greater control, if we were to think about them in a very generic way. Below we’ll dive into the most common strategies, from the structured to the agile, their benefits and what they’re best suited for. Hopefully this will help make the decisions regarding what can work best for you and your teams, and whether you need to rethink your branching strategy altogether.
Structured Strategies
Release Branching
This strategy is well-suited for large teams and projects that require long-term support for multiple versions. It’s no surprise then that both Microsoft and the Apache Software Foundation often employ release branching as their strategy of choice. (For those who aren’t familiar, the Apache Software Foundation is best known for hosting numerous open-source projects. The way they work is: Each major release has a dedicated branch where bug fixes and patches are applied while development continues on separate branches).
TL;DR
- In this strategy, a separate branch is created for each major release version, where bug fixes and patches are applied to the release branch.
- New features are developed in separate branches.
When to Use It
Release branching is best suited for projects that require stable release maintenance while continuing development on other branches. This is because it offers a controlled and structured approach to managing releases, along with greater stability. Another situation where this strategy is used is in large projects with frequent releases (e.g. games) — the release branches isolate features scheduled for the upcoming release from ones that are not.
Advantages: The release branching strategy’s greatest advantage is that it provides strong isolation between releases, allowing clarity in multiple versions support, and scheduling and coordination of release cycles in large scale projects.
Disadvantages: This strategy creates numerous long lived branches, which complicates code management — it creates a need for complex merges to make sure code written in one branch (e.g., a bug fix) propagates into the other branches correctly. Use this strategy only where needed.
GitFlow
GitFlow is a variation on the release branching strategy, that also defines additional long lived branches for different purposes. It was conceived in 2010 by Vincent Driessen.
TL;DR
- It consists of a "develop" branch for ongoing development and a "master" branch for stable releases (we’ll call it ‘main’ from this point on to align with the more modern terminology).
- Additional branches are used for feature development, bug fixing, and release preparation. These branches are deleted once they are merged to “develop” and “main”.
The Way It Works
GitFlow uses a central repository approach with two long lived branches: 'main' for production and 'develop' for integrating features. Additional temporary branches are created for isolating new feature developments and for preparing production releases. After a feature is developed on a feature branch, it's merged into the 'develop' branch.
When a release is ready, a release branch is created off 'develop', which is then merged into the 'main' and 'develop' branches, when the release is complete.
When to Use It
GitFlow was commonly used (and still is, in some places) in projects with a scheduled release cycle. Teams working on software that has major scheduled releases, like operating system distributions, often use this strategy to add greater control and stability to the project.
Advantages: Clear separation of under-development code and production; streamlined release management.
Disadvantages: Bad fit for CI/CD processes; a complex workflow with multiple branch types and merging strategies.
The Agile Strategies
Feature Branching
Feature branching enables parallel development, isolation, and collaboration among developers. It places the emphasis on agility, collaboration, and shorter feedback loops, which is why it is one of the more popular branching strategies employed with many development teams, including well-known engineering organizations like Atlassian.
TL;DR
- In the Feature Branching Workflow, developers create a branch for each new feature.
- The 'main' branch contains the official project history, and feature branches are used to develop new features outside of the main project.
- When a feature is complete, it's merged back into the main branch.
- Different instances of this flow are known as ‘Github Flow’ where code is pushed to production upon its merge and ‘Gitlab Flow’ which schedules code for release across one or more staging branches.
When to Use It
Due to its flexibility, this strategy is suitable for teams of all sizes, although it should be noted that it can become complex for larger teams if branch management is not done properly. This is oftentimes the go-to strategy of choice for those who want both agility with some semblance of control and isolation.
Advantages: This strategy is great for collaboration as each feature branch allows developers to work on new features without disturbing or impacting the main branch, which is kept production ready. Yet on the collaboration side, changes can be shared and discussed before being merged into the main code base.
Disadvantages: Probably its biggest downside is that it can lead to "merge hell" if not managed properly. This tends to happen when many branches are created and worked on concurrently, making the merging process a complicated and time-consuming task.
Trunk-Based Development
Trunk-Based Development allows agility, large-scale collaboration and fast-paced development. This strategy is common in organizations that practice continuous integration and deployment, and is used in conjunction with feature flags (with tools like LaunchDarkly). It is often used by large consumer-facing companies such as Google, Meta and Netflix.
TL;DR
- Trunk-Based Development is a branching strategy where all developers work on a single branch, usually the main branch or "trunk."
- Short-lived feature branches are created, but they're merged into 'main' as soon as possible — usually before the developed feature is complete.
- Continuous integration tests are run to ensure 'main' is always in a releasable state.
- Feature flags or toggles are used to enable or disable unfinished or experimental features.
When to Use It
This strategy is useful in organizations that prioritize continuous integration and deployment, over isolation or control. While enabling velocity, this does require discipline to keep the main branch always in a releasable state so that unstable code is not inadvertently pushed to production. In large companies like Meta and Google, this is the only viable strategy — as any branch that splits off main falls hopelessly behind extremely quickly, making merging back an impossible task.
Advantages: This strategy encourages regular code integration, decreases the complexity of merging changes, and supports continuous integration and deployment practices.
Disadvantages: The constant integration can lead to problems if not done carefully. This format requires strong release engineering to support it, and additional feature flags/toggles tooling to ensure experimental and unfinished features aren’t released at large without proper controls.
While it may appear that the more “agile” approaches have similar principles, they prioritize different aspects of the engineering workflow. The Feature Branch workflow allows more flexibility in terms of when deployments happen; Trunk-Based Development emphasizes regular code integration and continuous delivery.
How to Choose Your Strategy
Some of the key factors to consider when selecting or changing the branch strategy for your engineering organization are:
- Release frequency
- Risk tolerance
- Project complexity
- Team size
Regardless of the strategy you employ, the version control system you choose should provide the following:
- Fast branching and updates
- Flexibility
- Ease of resolving conflicts
- Real-time collaboration
The next generation of cloud-native version control systems should focus on all of these elements to ensure that modern engineering can deliver fast and stay safe. There is also a need for better automation of processes like merges and conflict resolution; these may be greatly improved in the near-term by leveraging new generative AI tools, which promise to free us from mundane and frustrating tasks — but this deserves a separate article.
Published at DZone with permission of Sasha Medvedovsky. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments