Skip to content

Branching strategy for repositories

Introduction to branching strategies

Branching strategies are essential for managing the development workflow in a version control system. They help teams collaborate on code, manage features, fix bugs, and prepare for releases in an organized manner. A well-defined branching strategy ensures that the codebase remains stable and that new features and fixes can be integrated smoothly.

There are two mainstream branching strategies in git and many lesser known strategies.

GitHub Flow

GitHub Flow is a simple and powerful branching strategy. It is widely used by GitHub and many open source projects.

  • Mainline Development on main: The main branch always contains the latest production-ready code.
  • Feature Branches: Work on new features or fixes is done in separate branches. These branches are merged into main via pull requests.
  • Continuous Delivery: This strategy works well for continuous delivery, allowing for frequent and small releases.
  • Single Release Focus: GitHub Flow does not have a built-in way to manage or maintain old releases, and it only allows working on a single release at a time.

Git Flow

Git Flow is a more complex and comprehensive branching strategy introduced by software developer Vincent Driessen in 2010. It provides greater control over when features and code are released. Fundamentally, Git flow involves isolating your work into different types of Git branches.

  • Development on development Branch: The development branch is used for ongoing development and integration of new features.
  • Main Branch for Releases: The main branch only contains released code that is production-ready.
  • Support for Old Releases: Git Flow supports maintaining old releases, allowing for bug fixes and security updates on previous versions.
  • Multiple Release Development: This strategy supports development on multiple releases simultaneously, providing flexibility for larger projects.

Choosing a branching strategy for PSS®X

The branching strategy of PSS®X is following Git Flow Workflow and GitHub Flow depending on project type.

Projects under application and modules project groups use git flow while all other projects use github flow.

The most important reason for this is the desire to keep the release of the DDD layers under control.

Please remember if you do not have a good reason to go with Git Flow, then start with GitHub Flow. It is a far simpler model and if you end up needing Git Flow later, it is easy to convert.

Principles

The following principles should we consider while developing PSS®X modules; The PSS®X application may follow another branching strategy in addition to the release branch described below.

  • Isolation Until Finalized : Work product is relatively isolated from other changes that are irrelevant until one of two conditions: the other changes are finalized and approved, or the other changes are recognized as prerequisites.

  • Multiple Bases : Because changes are isolated, we keep a concept of multiple bases on any kind of integration branch.

  • Immediate Downstream Propagation : As soon as changes are made, they get propagated downstream to anything based on it. This keeps the changes from being isolated, and keeps branches fresh despite the longer lifetimes.

  • No branch is sacred : No permanent branches exist in this strategy; every branch type has a clear way to start it and end it.

  • Move infrastructure out : Because everything stays isolated until a release, if developers aren’t careful, infrastructure changes don’t make it to other developers, or even other features by the same developer.

“Release Candidate Branches” strategy emerges as a dynamic framework that strikes a harmonious chord between collaboration, stability, and incremental releases. The strategy centers on creating dedicated branches, known as release candidate branches, that serve as the focal point for feature integration and comprehensive testing. These branches provide a controlled environment where disparate features merge and undergo rigorous validation before making their way to production.

Understanding basics

Git Flow describes a set of rules to guide developers in their day-to-day operations. The primary focus lies in the definition of several branches to manage features, releases, and hotfixes separately.

Here are the key components and workflows of GitFlow:

Main branches

  • Main Branch (main):

    • The main branch contains the production-ready code.
    • Only stable releases are merged into this branch.
    • Tags are used to mark release versions (e.g., v1.0.0, v2.1.0).
  • Development Branch (development):

    • The development branch is used for ongoing development.
    • It contains the latest delivered development changes for the next release.
    • New features and fixes are integrated into this branch.

Supporting branches

  • Feature Branches (feature/*):

    • Used to develop new features.
    • Created from the development, release, main, infrastructure or hotfix branches.
    • Merged back into development or release candidate once the feature is complete.
    • Naming convention: feature/feature-name.
  • Release Branches (release/*):

    • Used to prepare for a new production release.
    • Created from the development branch when the release is feature-complete.
    • Allows for final testing and bug fixing.
    • Merged into both main and development after release.
    • Naming convention: release/x.y.z or release/next.
  • Release Candidate Branches (release/rc*):

    • Used to test release candidates before the final release. No work should be done directly on a release candidate. The release scope can be expanded or narrowed based on data from control gates.
    • Created from the release branch.
    • Allows for thorough testing and validation of the release candidate.
    • Merged back into the release branch after successful testing.
    • Naming convention: rc/x.y.z.
  • Hotfix Branches (hotfix/*):

    • Used to quickly address critical bugs in the production code. They act as a feature and release candidate as one, and are intended for quick individual fixes
    • Created from the main or release branches.
    • Merged back into both main and development after the fix is applied.
    • Naming convention: hotfix/x.y.z or hotfix/next.
  • Infrastructure (infrastructure/*):

    • Used to address specific needs of the development team, such as framework updates, database changes, etc., that have cross-cutting concerns.
    • Usually created from the development branch.
    • Allows for thorough testing and validation of infrastructure changes.
    • Merged back into the development branch after successful testing.
    • Naming convention: infrastructure/x.y.z.
  • Integration (integration/*):

    • Used for multiple features that have overlapping functionality, especially in cases of merge conflicts.
    • Allows for thorough testing and validation of integration changes.
    • Naming convention: integration/change-description (e.g., integration/framework-update).

The Main Flow

This is a basic summary of the whole flow, with more detailed information in the relevant sections

  1. The developer creates a feature branch from a service branch (main, development, release etc..) , infrastructure branch, another feature branch (prerequisite feature), or integration branch if multiple branches are required.

  2. The developer makes all changes necessary for their feature in the feature branch. Unit tests can run on the feature branch directly to test the feature in isolation.

  3. The developer merges the feature branch into the development or release candidate branch targeted for the feature if there are no conflicts. If there are conflicts, the developer needs to make an integration branch and merge that into the release candidate

  4. If further changes need to be made on the feature, such as bug fixes unrelated to another feature, the changes should be done on the original branch and merged again into the release candidate.

  5. When the release candidate is approved and is merged into a service line (note that if things are done right, this should be a fast-forward merge), the feature branch (and any infrastructure or integration branches that were in the service line) should be deleted from the remote. Other outstanding release candidate branches should be populated immediately with the service line updates if they were based on the release candidate.

Switching Over

Starting out with a branching strategy is easiest, but only happens so often. The reality is that this process is pretty easy to adopt: we can start with a single branch (such as our old development branch) and treat it as infrastructure.

Whenever you need to adopt, simply do the following;

git checkout development
git checkout -b infrastructure
git push --set-upstream origin infrastructure