Branching for Success
Source control is a massive benefit to any development – or single developer – working on a non-trivial project. It allows you to manage multiple simultaneous contributions from developers, scroll back time to any previous point, and provides a handy backup in case something goes wrong with a local copy of the code. Any tool that offers so much benefit, however, typically introduces its own complexities into the process. Below we’ll look at one of those complexities – branching schemes. We will focus on Git fairly heavily, but the general concepts should apply to any source control product featuring branch functionality.
Branching schemes are designed to fix a number of problems common to development teams. A few sample benefits of a competent branching scheme are:
- Branches allow developers to work on new features in isolation, reducing the risk of overwriting another developer’s changes.
- Branches allow developers to run experiments, working with wildly varied versions of the underlying source code, without affecting the underlying product.
- Branches allow for quick-and-easy rollback of problematic features (with some caveats).
- Branches allow for isolation of production code, reducing or eliminating the confusion in determining which code has been deployed.
- Branches allow for feature testability, giving QA resources the opportunity to both test features in isolation and in integration scenarios.
One of the first things your development organization should do when selecting a branching scheme is determine which of these considerations is most important, and how your branching scheme addresses each one.
One of the most common branching schemes in use among development organizations is the GITFLOW WORKFLOW. This branching scheme is designed to provide a method to manage the entire development process, using branching to manage releases, feature development, and even production hotfixes. At a very high level, it makes use of the following concepts:
- Code is divided into five types of branches – master, develop, feature, release, and hotfix.
- The master branch contains only the code that is currently deployed to production.
- The develop branch serves as a combined feature branch for the next set of features ready to be deployed to production.
- The feature branches are where most day-to-day development work will take place, with developers completing their features in a separate feature branch before merging it back into develop.
- Release branches are created off the develop branch when enough features have been completed to meet the criteria for the next release. QA for a release is typically conducted on this branch. When a release is approved, the release branch is merged into both master and develop – master to deploy the code to production, and develop to obtain any QA fixes added to the release branch.
- Hotfix branches are created off master in response to a production issue. Once the functionality has been completed and tested, the hotfix is merged to master for deployment as well as develop to ensure that the change is not lost for future development.
The above handles all of the previous criteria discussed. It allows for testing of features in isolation on a feature branch, as well as in an integrated state on the release or develop branches. It allows you to get a clear picture of exactly what is deployed to production via the master branch. It allows developers to work on their own features in isolation, and minimizes merge conflicts by making them the responsibility of the developer performing the merge. And finally, it helps to reduce complexity of code rollbacks, as all development has a clear merge-point where features were introduced into the code base in their entirety. You can read more about the Gitflow Workflow HERE.
One of the common complaints with the Gitflow Workflow is that it makes continuous deployment a pain to manage. For some organizations, having the extra step between the development branch and the deployment branch reduces their desired development velocity. The GitHub Flow follows the following pattern:
- Anything in the ‘master’ branch is deployable
- New development takes place in descriptively-named branches branched off of the master branch
- When the branch is ready, or if the developer wishes feedback, a git pull request is created to review the code
- Pull requests, once approved, are merged into the master branch
- Changes on the master branch can – and should – be deployed immediately
As is probably obvious, this branching scheme prioritizes frequent deployment. That’s not to say irresponsible deployment – all features are still tested and verified before going to the master branch for deployment – but rather a confidence in the team’s development and QA practices that allows for this kind of rapid deployment. You can read more about GitHub Flow HERE.
While Gitflow and GitHub Flow are two of the primary branching schemes used in industry today, they are by no means the only answer to the question of branching schemes. Some organizations, for example, use a modified version of the Gitflow Workflow that has developers forking the base repository and working in their own local copy of the repository, requiring all code to be sent to the master repository via a pull request. Others invert the scheme, using branches to manage simultaneous multi-version development and release schemes – these are most often useful when customizing software for an array of clients. Whatever your desired branching scheme is, odds are there is an organization somewhere using a very similar scheme.
Branching schemes like Gitflow and GitHub Flow are designed to reduce integration and testing concerns among a team of developers working towards a single goal. However, they are not the only potential solutions to the branching question. It is important to do analysis of your development organization and its practices before selecting a branching approach. Using GitHub Flow in an organization dependent upon heavy testing and verification of code may not be advisable, while using the Gitflow Workflow in an organization prioritizing speed of deployment would prove troublesome. The right answer changes for each development team – it is important to simply be aware of the positives and negatives of each approach.