What is the best branching strategy to use when you want to do continuous integration?
I find the topic really interesting since I heavily rely on branches on my daily job.
Hope you find the links interesting.
The answer depends on the size of your team and quality of your source control and the ability to merge correctly complex change sets. For example in full branch source control like CVS or SVN merging can be difficult and you might be better off with the first model, while if using more complex system like IBM ClearCase and with a larger size of team you could be better of with the second model or a combination of the two.
I personally would separate the feature branch model, where each major feature is developed on a separate branch, with task sub-branches for each change done by individual developer. As features stabilize they get merged to trunk, which you keep reasonably stable and passing all regression tests at all times. As you near the end of your release cycle and all feature branches merge, you stabilize and branch of a release system branch on which you only do stability bug fixes and necessary backports, while the trunk is used for development of the next release and you again branch off for new feature branches. And so on.
This way trunk contains always the latest code, but you manage to keep it reasonably stable, creating stable labels (tags) on major changes and feature merges, the feature branches are fast paced development with continuous integration and individual task sub-branches can be often refreshed from the feature branch to keep everyone working on the same feature in sync, while simultaneously not affecting other teams working on different features.
At the same time you have through the history a set of release branches, where you can provide backports, support and bugfixes for your customers who for whatever reason stay on previous versions of your product or even just latest released version. As with the trunk, you do not setup continuous integration on the release branches, they are carefully integrated upon passing all regression tests and other release quality control.
If for some reason two features are co-dependent and need changes done by each other, you can consider to either develop both on the same feature branch or to require the features to regularly merge stable parts of the code to trunk and then refresh changes from trunk to exchange code between trunk branches. Or if you need to isolate those two features from others, you can create a common branch off which you branch those feature branches and which you can use to exchange code between the features.
The above model does not make much sense with teams under 50 developers and source control system without sparse branches and proper merging capability like CVS or SVN, which would just make this whole model a nightmare to setup, manage and integrate.
The way I see it you want to have a limited set of branches where you can focus. Since you want tests, code quality metrics, and many interesting things to run with the builds, having too many reports will probably get you to miss info.
When and what to branch, usually depends on the size of the team and the size of the features being developed. I don't think there is a golden rule. Make sure you use an strategy where you can get feedback early/often, and that includes having quality involved from the very beginning of the features. The quality bit, means that as you are automating as the team develops, if you branch for a large feature set a team is building, you gotta have quality involved in the team as well.
ps Where did you get those approach references? - doesn't feel that those graphs represent all the options
Update 1: Expanding on why I said it isn't a golden rule. Basically for relatively small teams I have found it best using an approach that is a mix. Feature branches are created if it is something long and part of the team will continue adding smaller features.
As long as you understand principles, you can always re-invent the best practices. If you don't understand principles, the best practices will take you that far before falling apart due to some conflicting external requirement.
For best intro into the Mainline Model, read this: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf
Read the link. Once you got the basics, read the following article by venerable Henrik Kniberg. It will help you relate Mainline Model with continuous integration.
http://www.infoq.com/articles/agile-version-control
Dave Farley, an author of Continuous Delivery, referred to Trunk Based Development (TBD) as the cornerstone of Continuous Integration (CI) and Continuous Delivery (CD). He says:
Any form of branching is antithetical to Continuous Integration.
He also says,
Feature Branching is very nice from the perspective of an individual developer but sub-optimal from the perspective of a team. We would all like to be able to ignore what everyone else is doing and get on with our work. Unfortunately, code isn’t like that. Even in very well-factored code-bases with beautiful separation-of-concerns and wonderfully loosely-coupled components, some changes affect other parts of the system.
Trunk Based Development (TBD) is the practice of integrating code changes into the trunk (a.k.a, master, mainline) at least once per day - preferably multiple times per day. Continuous Integration (CI) is a similar practice except that it also involves verifying the code changes using automated tests. The best branching strategy for this is to work directly off the trunk and to perform code reviews through Pair-Programming. If for some reason you can't pair, or you just really want to branch, make sure your branches are short-lived (less than a day).
I work on Trunk, “master” in my GIT repos. I commit to master locally and push immediately, when I am networked, to my central master repo where CI runs. That’s it!
For large features (i.e. ones that take longer than a day), try to break them into small chunks of logic which can be integrated into the trunk without breaking the software. You can also use techniques such as feature-flagging and branching by abstraction which allow you to deploy incomplete work without affecting end users.
I use branch by abstraction, dark-releasing and sometimes feature-flags. What I get in return is fast, definitive (at least to the quality of my testing) feedback.
I think either strategy can be used with continuous development provided you remember one of the key principles that each developer commits to trunk/mainline every day.
http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay
EDIT
I've been doing some reading of this book on CI and the authors make suggest that branching by release is their preferred branching strategy. I have to agree. Branching by feature makes no sense to me when using CI.
I'll try and explain why I'm thinking this way. Say three developers each take a branch to work on a feature. Each feature will take several days or weeks to finish. To ensure the team is continuously integrating they must commit to the main branch at least once a day. As soon as they start doing this they lose the benefit of creating a feature branch. Their changes are no longer separate from all the other developer's changes. That being the case, why bother to create feature branches in the first place?
Using branching by release requires much less merging between branches (always a good thing), ensures that all changes get integrated ASAP and (if done correctly) ensures your code base in always ready to release. The down side to branching by release is that you have to be considerably more careful with changes. E.g. Large refactoring must be done incrementally and if you've already integrated a new feature which you don't want in the next release then it must be hidden using some kind of feature toggling mechanism.
ANOTHER EDIT
There is more than one opinion on this subject. Here is a blog post which is pro feature branching with CI
http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/