Since learning what Torvalds has to say is always enlightening, I wanted to delve into the points he mentioned, because they align pretty closely with the techniques we recommend with Plastic SCM. Obviously, the points apply to Git, Plastic SCM, and any other SCM with good branching support, too.
This is what Linus wrote (I only extracted a fragment, for the complete text, go to http://lkml.org/lkml/2010/9/28/362).
The real problem is that maintainers often pick random - and not at all stable - points for their development to begin with. They just pick some random "this is where Linus -git tree is today", and do their development on top of that. THAT is the problem - they are unaware that there's some nasty bug in that version.
Shooting a moving target
What is Linus talking about? Actually, it’s one of the very well-known issues with trunk development that I described here in the section titled “don’t shoot moving targets!”.
This problem hits “mainline/trunk pattern” followers hard, since they keep updating to “what’s more recent”, probably due to fear of merging. Continuous integration delays the problem, but doesn’t solve it. But this problem can also hit those following a “feature branch” pattern, unless they follow all the rules.
The problem they’re facing is shown in the following picture:
The kernel team uses branches, but what if they’re using the “master” as an integration branch and they’re branching off commits that are not tagged? (As the picture shows).
The problem is that the master branch can be used as an integration point and hence get commits that leave the branch in an intermediate, unstable state. (This is especially true when using fast forward merges on Git, which I don’t really like precisely due to this issue. But I guess Linus must be doing real merges because he DOES know how to use Git. :P) Then you branch from an unstable commit and… you end up in trouble!
Baselines are key
We had exactly the same issue with some teams using Plastic because they failed to understand the importance of baselines. Once your code is stable, tag it, label it, and create branches ONLY from this well-known point!
That’s basically the rule of thumb: create baselines frequently (as many as you can) which of course must be fully tested. (That’s the time-consuming part, since integration is pretty fast nowadays with modern SCMs) and then CREATE BRANCHES ONLY FROM STABLE BASELINES, as the figure shows:
This way if something fails on your task branch (feature branch) you know… it’s your fault!!, because all tests were fine on the baseline -- not just the fast integration ones (like the ones you can run on checkin with continuous integration tools) but also the slow ones that you use to validate a release.
Very easy rule of thumb, great savings!