Configuration Management (CM) is crucial to any software project as neglecting it will easily get you in big trouble. It may look like bad luck, but it is not.
A CM-plan will deal with several matters, from simple to decide things, such as naming of releases to more advanced subjects, such as branching strategy. I will talk about the latter today.
There are of course different ideas about what a good branching strategy should be. It is my firm belief that it must be aligned with the subject at hand, namely changes.
If you are not used to looking at different branching strategies, they may all look similar, so how does it matter?
Let me put it this way, if your CM-strategy is not working, you may one day be in a situation like the one I had, where there almost were fist-fights between developers. Luckily, frustration is a more common reaction.
I recommend that you have a simple branching strategy that everyone understands, as long as it works. It does take you a long way and that is probably why so many experienced developers know surprisingly little about CM.
However, when a single main branch, also known as “trunk”, with an occasional branch off from it, does not cut it, it is time to look further.
If you have read Henrik Kniberg’s take on the subject: “Version Control for Multiple Agile Teams”, you may have a different view on this subject than I have.
Henrik’s view is what I would call “team-based” whereas mine is “change-based”.
There are a few things that you should be very aware of. It is not branches that are released, it is configurations. A configuration is a snapshot of the system that includes all the changes applied to the system so far. You typically use release-tags to mark configurations that you release.
Further, you can not state that a branch, such as the trunk, is always releasable. Besides what I just said about branches not being released, as soon as you merge anything new into the “always releasable branch”, the latest version on it, is not tested software anymore.
Let us take a look at the life-cycle of a change. A change springs from a configuration of the system, named or not, but a snapshot of the system at that point in the time. This is called the “baseline” of the change. Work is done on the change at the same time as on other changes.
As time goes by, the difference between the baseline and what is the latest version of the system, increases. Eventually we want merge the change into a release and this increasing divergence will make it harder. To solve that, we incorporate other changes that have been applied since our baseline. This called a “rebase”. Effectively, it moves the starting point of our change forward in time, so to speak.
Typically, you wish to do this on a daily basis, or the burden may be too large. It is your decision on how often it will happen. However, the last rebase is crucial. See below.
A change may get stalled because of technical problems or changing priorities. Anyway, you want your changes to be isolated so you can put them on freeze or deliver them in a later release than planned.
If other changes are on the same branch, they are not isolated from each other which is the main problem with a team based branching strategy, unless a team works only on one change. Not likely, a change should be a job for about 1 – 3 developers, a team is 5-7.
When you reach testing, you probably need an environment to test in. What is interesting about this, is that the number of test environments determine how many changes you can have “hot”. Changes that are “hot” are worked on and can be deployed to a test environment at any time. Changes that are “cold” are just waiting in the wings and may be worked on at a later stage.
Before testing, you should do a rebase to be as close to the rest of the system as possible.
The final phase in our change’s life cycle is the delivery into the release branch. This happens when it is considered done. Potentially, other changes may have come in and your testing, in theory, should start over. But testing is really about balancing risk against cost, so you have to make an educated guess based on how the other changes may interact with your change. If the risk is high, you have to rebase and run the tests again. Note that this is not a consequence of this strategy, it is a consequence of how changes always interact. The strategy just reveals it.
This strategy is aligned with what you wish to control, changes. Not with your team structure or your system structure. This alignment frees you from adding a lot of rules of conduct and policies, everything works naturally when your branches follows the structures of changes.
As for implementing a strategy such as this, you first need to see if your current version control system can cope with it in a practical way. I have used Clear Case but there are other ones that certainly may cope or even do a better job. There will be lots of branches, so remember to have a naming strategy for them.
Secondly, there are only four concepts that every developer needs to understand, it is “change” (we called them “activities”), “baseline”, “rebase” and
Remember that this is the simplest advanced branching strategy there is!