← Other Branching Strategies

Single Latest Version

The Single Latest Version approach to the scalable git branching model is common for teams working on web applications where only a single version is maintained - the most recently deployed codebase.

Branch Types

Every branch type below documents:

Main Branch

As our only service line, the main branch (or trunk) represents the most recently deployed code. For any new work, it is safe to use main as the base branch.

Feature Branches

These represent the basic unit of business work that can be included in a release. Most feature branches are based on the main branch, but they may also be based on other feature branches, and they may include infrastructure branches.

Depending on the project, bugs may be treated as features or they may be treated as sub-tasks for a particular feature. The examples provided allow for both, but bugs reported in a feature branch should be based on the feature(s) they originate from.

Sub-feature Branches

Often, features can be broken down into smaller tasks to be worked by different engineers and tracked within your ticketing system. If features are large enough to be broken down further, these branches may be used to have a more granular visibility into work, allowing for easier reviews, simpler testing, and even small experiments.

Release Candidates

When features are ready to release, they are bundled into a release candidate. For the most part, this is merging the features together into a branch for deployment and testing, keeping them separate from main in case production needs a hot fix or a feature needs to be pulled from the release.

Do not resolve merge conflicts from merging two features into a release candidate when creating the release candidate; instead, create an integration branch.

Bugs found in a release candidate should be fixed within the originating branch, or an integration branch that contains the features that caused the bug. Bug fixes should not be branched from the release candidate if at all possible; doing so will hinder the ability to rebuild the release candidate if a feature needs to be removed.

If a feature needs to be removed from a release candidate, rather than trying to revert commits, a fresh release candidate should be made from the features still preserved.

Integration branches

Sometimes, two features are targetted for the same release but have conflicts with each other. Whether found via merge conflicts or from bugs resulting from conflicting logic, integration branches are used for resolving integration issues.

Less-common branch types

The following branch types are not used in all projects.

Hotfixes

Some projects, when discovering an issue in production, have a need to track fixes separately from a standard feature and release candidate process. Hotfix branches act as a combination of Feature and Release Candidates; they have developer changes, but may be treated as a release candidate for testing and releases.

Infrastructure branches

Some projects do not track technical investments, such as refactoring and additional shared components, as features. When not tracked, engineers should put shared infrastructure in one of these infrastructure branches. Engineers may add an infrastructure branch as a base for their features; the shared commits between the infrastructure will reach main when the first feature that includes it is released.

Standard processes

Most engineers should be used to creating a feature branch from main, and a sub-feature branch from the feature branch. When any base branch is updated, engineers should update the downstream branch, keeping it up-to-date.

Releases

Once a release candidate is approved to go to production:

Re-integrating integration branches

If all but one of the base branches of an integration branch is merged to main, the integration branch may be merged into its other base. This will resolve merge conflicts between the released features and the unreleased features without needing to re-do the conflict resolution.

Automation and Branch policies

Footnotes

  1. You can’t have a branch named both “feature/ABC-1234” and “feature/ABC-1234/ABC-1237”. That’s because, given the branch “feature/ABC-1234” exists, at .git/refs/heads/feature/ABC-1234 there is a file that contains the commit hash for the branch. Since file systems don’t allow a file to also be a folder, you wouldn’t be able to have .git/refs/heads/feature/ABC-1234/ABC-1237, meaning you can’t have “feature/ABC-1234/ABC-1237”. 2