I was whipping up some pictures of source code branch and release strategies and I thought maybe I would post them here if anyone was interested. Generally I find that it’s hard to come by good best practice information on this sort of thing for some reason.
There are of course many philosophies on branching strategies and I will make no attempt to properly cover the topic here. Instead I’ll simply submit two strategies that I have seen used successfully.
First some terminology with respect to these pictures and labels. This terminology will not apply to all projects and is only one of many possible ways to cut up your releases, but I know that this can work.
- A new version of the product with a 3 part identifier. A.B defines the major release and C represents a minor release. Each release has an official kit.
- Major release
- A release that consumes a significant scheduled period of time and includes both new features and bug fixes. A major release has a version number like A.B.0 (1.0.0, 1.1.0, 2.0.0, etc).
- Minor release
- A release that generally occurs on an as-needed basis to release bug fixes. In general minor releases should not contain new features (but this is a rule that inevitably will be broken).
The decision about when to increment major releases from 1.x to 2.0 is largely a matter of product management and marketing. Generally any A.B.0 release is going to have exactly the same lifecycle, release process, etc. The .0 release is often saved for major new features, new APIs, breaking APIs, etc but it’s largely a matter of preference.
Below I’m going to describe two branching strategies but they share many common features:
- In general, new feature work for the next major release is integrated on the trunk.
- All minor releases occur off-trunk.
- All patches are built from a branch associated with a specific release.
Strategy A creates a new branch specific to each major release. All work for the next minor release occurs on this branch, so it’s kind of similar to trunk in that regard. Patch branches are created lazily as needed.
Strategy B instead creates a new branch for every minor release. It is sometimes easier to name the branches with Strategy B as they always apply to one release.
In the case where patches are rare, Strategy A will minimize the total number of branches. In the case where patches are frequent (they occur on every release), then Strategy B actually minimizes them by avoiding the maintenance branch.
If you’re willing to omit release-specific patches altogether, there is a simpler (very common open source project) strategy where there is no branch specifically available for per-release patches. In this case, you essentially force users to either wait for the next minor release or use a nightly build which may contain many other features and/or bug fixes. For a lot of projects, this is fine.
Generally however, enterprise customers with your product in production really need the ability to apply a patch specific to a release. And if one customer needs that, many customers need it. It’s possible to manage patches on a per-customer basis but that’s a path to madness and does not scale. You ultimately have to look at cumulative patches and an official patch process. But that’s probably a topic for another post some day.