[Development] Branches and time based releases
Lars.Knoll at digia.com
Mon Feb 24 22:11:47 CET 2014
there’s been quite a bit of discussions on both topics lately. I’ll sum up
my thinking in a separate mail, as I think they are to some extent related.
Let’s start with our release cycle. In my opinion (and having seen 15
years of doing Qt releases), our time based releasing model works better
than anything we have been doing before.
Feature based releases is what we did in the past, and I do not want to go
back. It usually meant rather long delays, and we usually never managed to
get more than 1 feature release out per year.
Like anything we could be doing our current model is not perfect and can
still be improved, but since Qt 5.0, we have been getting better with
every release in planning our releases. Our schedules have become more and
more predictable. While 5.0 was delayed by half a year (not surprising
given the circumstances), we were down to 8 weeks for 5.1, and around 2
weeks for 5.2. So we’re getting there and I feel we have a good chance of
releasing 5.3 on time :)
Yes, I am sometimes approving some limited exceptions to the feature
freeze. This is because we don’t live in a perfect world, where we can
simply afford to wait another 6 months for something. Qt has many users
that are waiting for new features, and we need to improve the
competitiveness of our product. 6 months can still be a very long time in
the business we are in. If we could get down to a 3 months cycle that
might be less of an issue, but our infrastructure doesn’t yet support this.
So to sum it up, I believe the release model we currently have works
pretty well, certainly better than anything we have had in the past.
But there is currently still quite a bit of pain involved in creating
releases. Our branch management is one of the reasons as Ossi and others
have pointed out on the releasing mailing list. Currently branching from
dev to stable (and to a lesser extent from stable to release) is always
very difficult. As Ossi pointed out, the fundamental reason behind this is
the fact that we need a two way merge to happen atomically (stable->dev
followed by dev->stable). Ossi nicely explained the issues in his initial
mail to the releasing mailing list. He then proposes a model that would
not imply two way merges at the expense of giving up having one rolling
Thiago pointed out the disadvantage of developers not having one branch
they can track and always get something stable. I personally think this is
not going to be an issue in practice. Finding out how to push a patch into
gerrit is quite a bit harder than figuring out which branch to push a
change to (In addition gerrit 2.8 will then finally solve this by allowing
to retarget a change). I actually can’t think of a person pushing a patch
to gerrit that doesn’t know what our latest minor release is :)
But I have seen how the people trying to handle the dev->stable merge
suffer, and how long time it took us again. Personally I now think that
this cost is not worth paying if we can avoid it at the expense of the
rolling stable branch.
I believe that a model where we only do forward merges would be a lot
easier to maintain for the people involved in branch management and
releasing. And this would imply separate branches for each minor release.
Actually I would propose to go even a slight step further with regards to
the creation of patch level releases (see below).
So here’s what I would propose:
* We have one dev branch for all new development
* We create one branch for each minor release. This branch can be created
atomically from a ‘known as good’ set of changes in qt5.git
* We only do forward merges (5.0 -> 5.1 -> 5.2 -> 5.3 -> ... -> dev). So
currently we would go from 5.3 to dev, once 5.4 gets created 5.3 merges
into 5.4, 5.4 into dev.
* After creating the branch for a new minor release we do a forward merge
from the previous branch before creating the alpha. The advantage here is
that the forward merge is something we know how to handle (it’s done on a
rather regular basis), and we then know we have all changes from the
previous patch level release in the new release.
* The scheme makes it simple and natural to extend the lifetime of a 5.x
branch to as long as required. We can simply decide that a certain branch
will live longer or have an additional release without having to twist our
* To create the actual patch level releases (5.x.y), I would propose that
we create a short-lived branch from 5.x. That branch gets tested, but no
patches get directly committed to it (as opposed to the release branch we
have today). Instead I would propose that the release team creates a list
of P0 bugs that still have to be fixed before we can fix 5.x.y. Fixes for
these bugs get pushed to 5.x and cherry-picked to 5.x.y by the release
team. Like that we can control in a better way what goes into the final
release and no developer has to deal with a release branch. It should also
reduce the risk that other changes go in that again break qt5.git CI or
have other negative side effects.
* For 5.x.0, the branch point from 5.x should probably be around RC time.
* Since the 5.x.y branches then only contain a very small (ideally 0) set
of changes that have been cherry-picked from 5.x, we can safely close that
branch after the release is out. Yes, this implies that there’s no
fast-forward from one release to the next, but I seriously doubt this
would cause problems for anybody in practice.
So this would be my proposal for simplifying our branch handling and
optimising it towards simplifying the creation of releases.
More information about the Development