Branching practices
In an environment where several developers work at the same code base or several features have to be implemented, then branching will be a topic. I was asked to create a branching guide for my current employer which use TFS as source code repository.
Motivation
In our projects I found the following problems:
- When the developers want to release a new version, not every feature was finished. So they had to deliver unfinished features. To solve that problem, they need to disable the unfinished features by configuration.
- Some features which they had to implement were breaking features. In a such case, they were blocked to deliver new fixes or little features.
- Sometimes they had to produce a hot-fix for the version which was in production. In a such scenario, they had to take manually the labeled version from the repository and build a hot-fix. After that, they had to copy the fixed code into the current code base.
Branching Guide
For those three scenarios branching could minimize the impact. So I described in the branching guide the following patterns to solve our problems:
- Feature-Branch (and Team-Branch)
- Developer-Versions
- Production-Branch
- Feature-Freeze
Feature-Branch
A Feature-Branch is a branch which is created always from the Main-Branch. It’s important to choose the right granularity for a feature. A worst-case-scenario is when you split a feature over several Feature-Branches, so that they become dependent on each other. A good granularity is for example a module or a workflow (several GUIs), something which is self-contained.
With Feature-Branches you have the possibility the use the cherry-picking method. That means, that before you release a new version, you choose by some quality gates (code coverage, code review, documentation, etc.) which Feature-Branches you want to merge back to the Main-Branch.
A special version of a Feature-Branch is the Team-Branch (not visible in the picture). A Team-Branch is a Feature-Branch which will be reused after a completed feature (and reverse integration to the Main-Branch). A Team-Branch will reduce the number of branches and it is assign exactly to one team or team member. It is also important, that on a Team-Branch it is allowed to implement exactly one feature at a time.
Developer-Version
The Developer-Version (in the picture the labels 2.1.2016.1 or 2.1.2016.2) are needed, when you have to create a version of your application or component to deliver it to another team. We had some dependencies of components and for breaking features, all of them were influenced. So we created a Feature-Branch in each component and published for each a Developer-Version. The dependent component could reference that Developer-Version in the corresponding Feature-Branch. A Developer-Version is just for internal use, it isn’t allowed to deliver it to the customer.
Production Branch
The Production-Branch is the representation of the actual delivered version of an application or component. In our situation, it wasn’t possible that there were several versions in production. So, we didn’t need for each release a separate branch, we could reuse a branch – the production branch.
There a two approaches how to refresh the Production-Branch: After the end of the Feature-Freeze, when the new version was shipped. The other possibility is before you create the first hot-fix (refresh with the help of the labeled version).
Feature-Freeze
When you have to create a new version, you have to decide what you will or could deliver. After you merged all good Feature-Branches then the Feature-Freeze begins. During the Feature-Freeze it isn’t allowed to add any features, but it’s allowed to fix the current version. Before the Feature-Freeze ends, you have to release your current version to ship.
When the Feature-Freeze takes a long time, then you have to create Feature-Branches to continue the development for the next version.
Branching and Continuous Integration
Branching and Continuous Integration aren’t the best friends. With Branching you want to isolate the features from each other, but you pay it when you have to merge. Merging is a manual integration of two versions, and it isn’t always fun to do it.
With Continuous Integration you want to prevent a big bang integration. You want to give the developers as early as possible feedback, that the current code is breaking or not.
In our situation, we had Continuous Integration for the Main-Branch, but not for the other branches. I would recommend to add Continuous Integration for the other branches too if they take a longer time. I would recommend also to forward integrate several times to avoid a difficult merge at the end.
Further Reading
2 thoughts on “Branching practices”