Version Control Guidance – Alternative Branching Strategies
This is a new series covering out-of-band version control and branching guidance and discussions, for content that is not (yet) part of the product documentation. We will update this post and add a link to the new branching strategies concepts and common branching strategies when available.
Adapt your branching process for inevitable ‘blips’
Blip - (noun) - an unexpected, minor, and typically temporary deviation from a general trend.
Even with the best project planning and intentions, the stakeholders may ask your development teams to change course. Be it a temporary change in priorities, failure to meet a deadline or a change in direction, you need to be able to handle these ‘blips’ as they happen and, importantly, deal with their consequences in the longer term.
Remember, all you need to guarantee you can repeat a build is a changeset because it is immutable. Labels and branches are just conveniences. Use them to your advantage to handle blips in your process and to simplify the support and delivery of your software.
Whether you have a simple main branch strategy or an advanced ‘main, servicing, hotfix, feature’ branching strategy, the process is the same:
- Analyze the new requirement and do not panic
While the team may be panicking over how to deal with the blip, keep a steady head and remember your strategy. Ensure that the person controlling your branching is involved in this analysis. The person who has control over branches in your source control system will likely have a good understanding of which procedures they follow, the exact state of the system, and the release vehicles. They will be able to provide invaluable ‘matter of fact’ input.
- Branch only if necessary
Once you understand the requirements, you may find that is unnecessary to create another branch, if however, you do need a new branch, then it is important to understand how branching options. Visual Studio allows you to branch by Changeset, Date, Label, Latest Version or Workspace Version.
Figure – Branch from version using Date
We generally recommend you get a confident understanding of your requirement and branch by Changeset.
- Remove the branch
If you needed to create a branch, your ultimate goal will likely be to get the code from the branch back into your normal operating branch or branches to mitigate any long-term consequences. Try to be understanding but firm in working towards this goal. Temporary and numerous branches cause confusion and overhead for the team.
Please also refer to the Using Feature Toggles as an Alternative to Development or Feature Branches article, for more information on feature toggling.
Feature Toggling is a useful technique for toggling features on and off to determine whether a software feature is available at run time. These may be UI features visible by the end user or simply code itself driving functionality. There are several names and nicknames for this technique that include flags, toggles and switches, and various implementation strategies that include both build and run time. For the purpose of this guidance we will discuss run time feature toggling, which involves the hiding or showing of features during run time. Most of the time the implementation involves a configuration file where the toggles are set. We can combine this with the wrapping of UI elements or classes, and thus control the visibility of the various features. Some implementations leverage a data driven approach where we maintain feature toggle state in a database.
- You need to release features frequently and continuously.
- You need to be able to enable and disable features on the fly.
- You need to selectively enable/disable features to a specific audience or set of users
- Make use of “Canaries” to release and evaluate features with a selected audience.
- Ensure you do not leak features inadvertently to the wrong audience or enable features that are not ready.
There are several advantages for implementing feature toggling. One simple advantage is yanking or rolling back a feature becomes easy and done on the fly, and without an entire recompilation and redeployment ceremony.
With the advent of continuous delivery, software releases are happening very frequently, and many features complete at different times, and can span multiple sprints. Often this requires complex branching and merging strategies to coordinate the various feature development activities. This can lead to reduced velocity and increased merge conflicts. The further the various branches drift from each other, the worse the merging exercises will become. With feature toggling, in general, we can expect to use less branches since we can have a single codebase contain both features that are done, as well as features still under development. Everyone can safely integrate to Main continuously and in general without worry of destabilizing the code base.
Another advantage to feature toggling is the ability to do so called “A/B”, “canary”, and various other scenarios where you may want to test features on only a certain segment of your audience or customers. Many popular online social networking applications leverage these techniques to roll out new features selectively to their audiences. You can gradually open the feature up to more and more of your user base as you get the success you desire during this type of roll out. Of course, you can also roll back features quickly if things do not go so well.
Of course, with any technology choice, there are pros and cons. One disadvantage to feature toggling is you must ensure you do not accidentally forget to wrap the features appropriately, and thus inadvertently make a feature visible before it is ready. Feature toggling also requires upfront planning and some technical overhead on implementation of a strategy.
Inadvertent disclosure is another potential risk. There can be situations where the live code base contains features still under development. Crafty end users may view these feature in plain sight simply by looking at your source. This might give a competitor or a user visibility into what features are coming in your product. This might cause you to implement cryptic naming for your various features if this is an issue for your product.
You also need to ensure you are testing scenarios for the feature being both on and off, which of course involves some overhead.
Techniques and Practices
You can leverage some common techniques to ensure you optimize your feature toggling approach. One of the key tenets of feature toggling, as well as a typical best practice in building software in general, is to ensure your developers are writing code as modular as possible. For example, you may have method or function where you implement several features simultaneously via nested if/else clauses. This does not line up well with isolating features. Ensure you are compartmentalizing your features as much as possible.
Adopt naming conventions and consistency to ensure the feature toggling techniques are consistent throughout your codebase. Also, if security is an issue, ensure you are naming your features appropriately for obfuscation of the feature. It is very important to keep in mind scenarios where end users are able to view pre-release features or features that you want to hide in source code. Clever users may derive the meaning of hidden features by following loose naming conventions. If this is important to your scenario, you must weigh the risks and determine a strategy.
You will want to ensure you do appropriate smoke testing both with feature toggles on as well as off for your various features. The essential idea is to understand how your application behaves for each of the feature states. Obviously depending on the exact scenario, there may or may not be nuances for specific features.
In some cases you can eventually deprecate the feature flag from your code base, while in other cases you may want to leave the ability to toggle on and off the feature after is it in production a while. This is a preference decision, but in general a clean-up of features implemented long ago can help keep the codebase tidy.
There are various open source tools available for implementing feature toggling. Some companies employ their own custom-built implementation. Depending on the type of application you are building, may determine the appropriate technology to leverage. For example in an ASP.NET application, you may wrap UI elements, and drive the toggles via a configuration file.
At Microsoft, the team responsible for implementing Visual Studio Online (also called Team Foundation Service) employs feature toggles. The implementation used in this scenario is a custom-built solution that leverages a data driven approach combined with a REST based service for toggling on and off features. This enables this team to maintain feature toggle state in a database. With this approach, this team achieves the benefits described in this guidance.
This guidance is not recommending one technology or tool over another at this point. Here is a starter to look at: Feature Toggle libraries for .NET
Continuous delivery relies on automation of build, testing and deployment. Change is continuous, frequent and merge operations more challenging as merge conflicts often require manual intervention. It is recommended to avoid branching and rely on other strategies, such as feature toggling (page 20), when considering continuous integration.
- You have only one major release, supported and shipped to customer using the main branch.
- You have short featuredevelopment cycles.
- You need to release features frequently and continuously.
- Labels, when used as bookmarks, are mutable (can be changed) and there is no history of changes made to labels.
- Peruse Team Foundation Server Permissions and consider protecting the administration of labels.
- Avoid cherry picking which complicates tracking of changes and subsequent merge operations.
If you are looking for a continuous build and deployment pipeline, we recommend that you peruse the Building a Release Pipeline with Team Foundation Server guide.
When using feature toggling, we can adopt the main only branching strategy, enabling and disabling features by toggling them on or off as shown. The main branch becomes the trusted source for the automation pipeline.
Figure – Continuous integration: Feature toggling
Release isolation is feasible if you use branches as snapshot archives only and lock the branches down appropriately.
Figure – Continuous integration: Feature toggling with release isolation
If you opt for the use of feature isolation, it is important to keep the scope of each feature small and the duration short. By making the feature branches short-lived, the merge operations and potential impact are as small as possible. Restrict the lifespan of a feature branch to hours, rather than days, and delete the feature branch as soon you merge (RI) it with the main branch.
Figure – Continuous integration: Feature isolation
Please send candid feedback!
We need your candid feedback. Here are some ways to connect with us:
- Add a comment below.
- Contact us on our blog.
- Version Control (ex Branching and Merging) Guide
- Branching Strategies
- Version Control Guidance – Frequently Asked Questions
A special thank you to everyone who laid the foundation this and other version control guidance: Anil Chandr Lingam, Bijan Javidi, Bill Heys, Bob Jacobs, Brian Minisi, Clementino de Mendonca, Daniel Manson, Jahangeer Mohammed, James Pickell, Jansson Lennart, Jelle Druyts, Jens Suessmeyer, Krithika Sambamoorthy, Lennart Jansson, Mathias Olausson, Matt Velloso, Matthew Mitrik, Michael Fourie, Micheal Learned, Neno Loje, Oliver Hilgers, Sin Min Lee, Stefan Mieth, Taavi Koosaar, Tony Whitter, Willy-Peter Schaub, and the ALM Community.