Maintaining parallel releases simultaneously has implications for how daily development is done. In particular, it makes practically mandatory a discipline that would be recommended anyway: have each commit be a single logical change, and don't mix unrelated changes in the same commit. If a change is too big or too disruptive to do in one commit, break it across N commits, where each commit is a well-partitioned subset of the overall change, and includes nothing unrelated to the overall change.
Here's an example of an ill-thought-out commit:
commit 3b1917a01f8c50e25db0b71edce32357d2645759 Author: J. Random <firstname.lastname@example.org> Date: Sat 2014-06-28 15:53:07 -0500 Fix Issue #1729: warn on change during re-indexing. Make indexing gracefully warn the user when a file is changing as it is being indexed. * ui/repl.py (ChangingFile): New exception class. (DoIndex): Handle new exception. * indexer/index.py (FollowStream): Raise new exception if file changes during indexing. (BuildDir): Unrelatedly, remove some obsolete comments, reformat some code, and fix the error check when creating a directory. Other unrelated cleanups: * www/index.html: Fix some typos, set next release date. ------------------------------------------------------------------------
The problem with it becomes apparent as soon as someone needs to
BuildDir error check fix over to a
branch for an upcoming maintenance release. The porter doesn't want
any of the other changes — for example, perhaps the fix for ticket
#1729 wasn't approved for the maintenance branch at all, and the
index.html tweaks would simply be irrelevant
there. But she cannot easily grab just the
BuildDir change via the version control tool's
merge functionality, because the version control system was told that
that change is logically grouped with all these other unrelated
things. In fact, the problem would become apparent even before the
merge. Merely listing the change for voting would become problematic:
instead of just giving the revision number, the proposer would have to
make a special patch or change branch just to isolate the portion of
the commit being proposed. That would be a lot of work for others to
suffer through, and all because the original committer couldn't be
bothered to break things into logical groups.
In fact, that commit really should have been
four separate commits: one to fix issue
#1729, another to remove obsolete comments and reformat code in
BuildDir, another to fix the error check in
BuildDir, and finally, one to tweak
index.html. The third of those commits would be
the one proposed for the maintenance release branch.
Of course, release stabilization is not the only reason why having each commit be one logical change is desirable. Psychologically, a semantically unified commit is easier to review, and easier to revert if necessary (in some version control systems, reversion is really a special kind of merge anyway). A little up-front discipline on each developer's part can save the project a lot of headache later.
One area where open source projects have historically differed from proprietary projects is in release planning. Proprietary projects usually have firmer deadlines. Sometimes it's because customers were promised that an upgrade would be available by a certain date, because the new release needs to be coordinated with some other effort for marketing purposes, or because the venture capitalists who invested in the whole thing need to see some results before they put in any more funding. Free software projects, on the other hand, are concerned with maintaining a cooperative working atmosphere among many parties, some of them possibly business competitors, and the preservation of the working relationship can trump any single party's deadlines.
Of course, many open source projects are funded by corporations, and are correspondingly by deadline-conscious management. This is in many ways a good thing, but it can cause conflicts between the priorities of those developers who are being paid and those who are volunteering their time. These conflicts often happen around the issue of when and how to schedule releases. The salaried developers who are under pressure will naturally want to just pick a date when the releases will occur, and have everyone's activities fall into line. But the volunteers may have other agendas — perhaps features they want to complete, or some testing they want to have done — that they feel the release should wait on.
There is no general solution to this problem except discussion and compromise, of course. But you can minimize the frequency and degree of friction caused, by decoupling the proposed existence of a given release from the date when it would go out the door. That is, try to steer discussion toward the subject of which releases the project will be making in the near- to medium-term future, and what features will be in them, without at first mentioning anything about dates, except for rough guesses with wide margins of error. By nailing down feature sets early, you reduce the complexity of the discussion centered on any individual release, and therefore improve predictability. This also creates a kind of inertial bias against anyone who proposes to expand the definition of a release by adding new features or other complications. If the release's contents are fairly well defined, the onus is on the proposer to justify the expansion, even though the date of the release may not have been set yet.
An alternative strategy for dealing with the tension between project release timing and corporate needs is for the company to simply make separate interim releases for its customers. As discussed in the section called “The Economics of Open Source”, such releases can be public and open source, and won't do the project any harm as long as they are clearly distinguished from the project's official releases. However, maintaining separate release lines independently from the project comes with its own overhead in tracking changes and porting them back and forth. This technique only works when a company has the resources to dedicate enough people to release management to handle that overhead.
It is crucial, of course, to never present any individual decision as written in stone. In the comments associated with each assignment of a ticket to a specific future release, invite discussion, dissent, and be genuinely willing to be persuaded whenever possible. Never exercise control merely for the sake of exercising control: the more deeply others feel they can participate in the release planning process (see the section called “Share Management Tasks as Well as Technical Tasks”), the easier it will be to persuade them to share your priorities on the issues that really count for you.
The other way the project can lower tensions around release planning is to make releases fairly often. When there's a long time between releases, the importance of any individual release is magnified in everyone's minds; people are that much more crushed when their code doesn't make it in, because they know how long it might be until the next chance. Depending on the complexity of the release process and the nature of your project, somewhere between every three and six months is usually about the right gap between releases, though maintenance lines may put out micro releases a bit faster, if there is demand for them.
 For an alternative approach, you may wish to read Martin Michlmayr's Ph.D. thesis Quality Improvement in Volunteer Free and Open Source Software Projects: Exploring the Impact of Release Management (https://www.cyrius.com/publications/michlmayr-phd.html). It is about using time-based release processes, as opposed to feature-based, in large free software projects. See also https://www.cyrius.com/publications/michlmayr_hunt_probert-release_management.pdf, by Martin Michlmayr, Francis Hunt, and David Probert. Finally, Michlmayr gave a talk at Google on the subject: https://www.youtube.com/watch?v=IKsQsxubuAA.