By: Lesego Makaleng – Senior Software Engineer
When starting a project or adding new features to an existing system, many developers skip feature branching by branching off the development or main branches directly, start working, and then merge directly back into development.
This often leads to broken builds, deployment headaches, and wasted time resolving conflicts. A structured Git branching strategy addresses these challenges. By separating feature work, releases, and hotfixes, developers can work in parallel, maintain stability, and deploy confidently without slowing down development.
The following steps outline a workflow that helps developers work safely, collaborate effectively, and deliver features with confidence.
Create Feature Branching from Development
The development branch is the main working branch and serves as the source of truth for the project. It contains the most up-to-date, stable code and acts as the foundation for all new features. It is also the starting point for the base project, ensuring that every new feature or branch is built on a reliable, consistent codebase. Thus, all new work should start from the development branch.
This is achieved by creating feature branches for the different features. This ensures that individual features are isolated, ensuring incomplete changes don’t affect the shared development environment. This strategy further allows multiple developers to work on different features concurrently.
Apply Branch Policies
Branch policies are rules or safeguards applied to git branches to maintain code quality, enforce best practices, and protect the stability of the shared codebase. They define how and when code can be merged, what checks must pass, and who can approve changes. Without branch policies, even a small mistake can break the development branch or introduce unstable features into the project.
Developers Branch from Feature Branches
Once feature branches are created from development, individual developers should branch off from the relevant feature branch for their work. These personal branches provide private space to implement changes, experiment, and iterate without impacting the shared feature branch or the main development branch. Developers push commits to the feature branch regularly, giving visibility to the team and allowing early feedback.
Branching from feature branches rather than directly from development helps teams work in parallel more effectively. It allows multiple developers to contribute to the same feature safely, reduce merge conflicts in the long run, and keeps the development branch stable as a source of truth.
Merge Completed Features Back to Development
Once a feature is complete and tested in its feature branch, it should be merged back into the development branch. This keeps development up to date with finished work while other features continue in isolation. Merging completed features also allows the development branch to be deployed to a dev environment for testing, ensuring that the new feature(s) work well with existing code. This approach maintains stability and reduces the risk of introducing unfinished work into development. It also provides a clear path for tracking progress and preparing features for release.
Create Release Branches
Once it’s time for a feature to be released, release branches are created from the development branch to represent stable versions of the code for environments like test, pre-production, and main. They provide a controlled space to deploy, validate, and finalise features without interfering with ongoing development. Using release branches ensures that new features are only introduced once they are fully tested and approved, and it also creates a predictable deployment process that is easy to manage.
Rollbacks, Hotfixes and Feature Propagation
If a feature causes issues after merging, it can be rolled back by reverting the feature merge rather than individual commits. This keeps the codebase stable and clean.
For critical bugs in test, pre-production, or main environments, hotfix branches provide a controlled way to address issues immediately. Hotfixes are branched directly from the affected release branch, allowing developers to fix urgent problems without waiting for pending features. Once tested, hotfixes are merged back into the release branch and into development to ensure the fix is applied across all relevant environments.
Another positive about this strategy is feature propagation, which allows teams to selectively promote features from development to release branches. For example, if features A and B exist in development, but only feature B is ready for test or pre-production, you can merge feature B into the release branch without promoting feature A. This selective promotion avoids exposing unfinished work and gives teams more control over what reaches each environment.
Using rollbacks, hotfixes, and feature propagation together ensures that development and release branches remain reliable. Teams can quickly fix urgent problems, maintain stability, and deploy confidently, all while ongoing feature work continues safely in isolated branches.
At Integrove, our development teams follow a structured Git branching strategy to ensure code quality, stability, and predictable deployments. By creating feature branches from development, enforcing branch policies, merging completed work systematically, and leveraging release branches, rollbacks, hotfixes, and feature propagation, we can deliver software confidently.
This approach allows us to fix urgent issues quickly and provides flexibility to promote specific features during the agile process, maintaining a reliable codebase across all environments. At Integrove, Git branching is how we maintain stability, accelerate delivery, and instil confidence in every release.
