[p4] Branching strategy for major.minor.patch versioning
Rick Macdonald
rickmacd at shaw.ca
Thu Sep 20 11:14:51 PDT 2007
I'm trying to sort out the branching strategy required for the typical
3-node version numbering of "major.minor.patch", where we are obligated
to support some number of active major and minor releases. "Major"
implies possible incompatibilities or even different results, where
"minor" mostly means feature additions but still source and binary
compatible, and patch implies stabilizing bugfixes. The code in question
is hundreds of libraries, each versioned separately, and linked together
(using only 5 or 10 at once) to create a batch executable to perform a
data processing flow.
Currently, we use just two nodes, which kinda sorta either rolls minor
and patches together, or minor and major together. The idea is to make
the distinction by assessing the amount of risk to the user in the
change: does it increase or decrease stability? For example, compare
making the user of 2.2 change from 2.2->2.3 for a simple bugfix versus
2.2->4.0 for a new feature. Upgrading to the major version 4 to get a
new feature exposes the 2.2 user to other major changes, but this is
somewhat preferable if the new change itself is destabilizing anyway and
therefore not appropriate as a point change to 2.x.
My natural thought for major.minor.patch is that each major release
needs it's own accumulation branch, with a release stabilization branch
for each minor version. My interpretation is that this is what Laura has
in her book as well (Chapter 7, pages 183-185). I've drawn the actual
releases (1.0.0, 1.0.2, etc) as branches because that's what I do for
convenient automated builds, but they could be labels or just changelist
numbers. Regardless, they are to be considered snapshots and never
actually updated once released.
1.0.0 1.0.1 1.1.0 2.0.0 2.1.0
/ / / / /
/-1.0------- /-1.1---- /-2.0---- /-2.1------
/ / / /
/-1-------------------------- /-2-----------------------
/ /
--main--------------------------------------------------------
A bugfix done to the 1.0 stabilization branch to release 1.0.2 would
have these integrations if everybody needed the same bugfix:
-1.0 to 1
-1 to 1.1 to release 1.1.1
-1 to main
-main to 2 (or 1 to 2?)
-2 to 2.0 to release 2.0.1
-2 to 2.1 to release 2.1.1
That's a lot of integrations, but it seems clear to me.
A new feature added to the major version 1 branch would create
stabilization branch 1.2 and release 1.2.0, and have these integrations:
-1 to main
-main to 2 (or 1 to 2?)
Stabilization branch 2.2 and release 2.2.0 would be created.
I've had the following suggestion, which is that the minor version
accumulation can be in the mainline:
1.0.0 1.0.1 1.1.0 2.0.0 2.1.0
/ / / / /
/-1.0--------- /-1.1---- /-2.0---- /-2.1
/ / / /
--main--------------------------------------------------------
A bugfix done to the 1.0 stabilization branch to release 1.0.2 would
have these integrations:
-1.0 main
-main to 1.1 to release 1.1.1 (or 1.0 to 1.1?)
-main to 2.0 to release 2.0.1 (or 1.1 to 2.0?)
-main to 2.1 to release 2.1.1 (or 2.0 to 2.1?)
Fewer integrations to get the same additional 3 releases. But is it a
reasonable thing to do? The problem that I have is when adding a new
feature (new minor version) to the major version 1. The only place where
the accumulated code _maybe_ exists for major version 1 is at the head
of the 1.1 branch. I say _maybe_, because if 1.1 was created before the
1.0 bugfix 1.0.1, there is no policy that says the 1.0.1 fix had to be
integrated to 1.1 to release 1.1.1. We're trying to wean people off
these old versions, after all. Still, one could create 1.2 from 1.1,
and integrate it to the mainline. Similarly, one could create 2.2 from
2.01 and then merge the new feature into it from main (or from 1.2?). My
take on this is that it's not reasonable to create 1.2.0 with a new
feature knowingly leaving out previous bug fixes. One would probably
have to go back and do the integrations that you thought you were saving
by having fewer branches. If you never add a new minor version to the
old release, you may end up ahead.
Is anything like this feasible to reduce integrating changes through so
many branches? Due to the promise of a stable production environment and
consistent results, we have to support any release used in production
for some time (could be measured in years).
I view a 2-node version system as a compromise between complexity (for
programmers and users) and the benefits of the extra level of
change-type distinction.
...RickM...
More information about the perforce-user
mailing list