Branching Diagram

Note that 1.8.1 need not branch until Firefox 2 ships, since nothing else is contending for the 1.8 branch.

Note also that Gecko 1.9 has not yet branched as of September 6th 2007 and so this diagram is somewhat out of date. Also note that the commits to the trunk require approval, and the trunk is being frozen on September 6th 2007.

Again, the main purpose of the trunk is to continuously integrate new work, to maximize QA coverage and minimize regression check-in windows

Mistakes will be made, but planned landings with back-out options will minimize (not eliminate) distributed discomfort

How to land changes once for both places

We will extend CVS commitinfo and bonsai to automate synchronization of files between trunk and the 1.8 branch

The synchronization can be specified for source repository subtrees such as browser, mail, xpfe, toolkit, extensions/inspector, etc.

Exception lists per directory may be supported if necessary

Developers are expected to test appropriately to avoid breaking trunk or 1.8 branch

All Firefox 2 changes will land on the trunk as well as the 1.8 branch

Some Firefox 2 code will need to be #ifdef MOZILLA_1_8_BRANCH to cope with API or bug-compatibility skew between trunk and branch

Some Firefox 3 changes will be needed by Gecko 1.9 back end changes (e.g. for XUL box layout standardization) -- these must be #ifndef MOZILLA_1_8_BRANCH

The MOZILLA_1_8_BRANCH macro will be defined for C++ and XUL on the branch

After Firefox 2 ships, #ifdefs testing this macro will be purged from the trunk

We'll use an automatic unifdef program to avoid fat-finger errors

A Dialog, or FAQ

Q: Why not just develop Firefox 2 on the 1.8 branch and leave the trunk alone?

A: We'll end up with a big-bang landing as happened with the Aviary 1.0 branch. Also, we are more likely to end up with a bugfix or change to the branch pulling all of Gecko over from the trunk, as happened during Aviary 1.0. And mainly, we must keep enough community QA on the trunk so that it does not regress badly, jeopardizing Firefox 3.

Q: What's wrong with big-bang landings, and what do you mean by regression checkin window?

A: Study up on libpr0n and Aviary 1.0 branch landings (among others), and search bugzilla for the regression keyword. In any sufficiently complex C/C++ codebase with test coverage achieved mostly through open-source community testing, too often the only way to gain traction on hard bugs is to identify when they first appeared.

Q: Hmm, then why not avoid merging and big bangs altogether, and share the trunk between Firefox 2 and Gecko 1.9 work for as long as possible?

A: We want to test Firefox 2 alphas and nightlies soon, to make sure nothing breaks by moving a front-end feature to the 1.8 branch. Working only on the trunk might lead to Firefox 2 depending on a trunk-only bugfix or feature. We will provide trunk alphas and nightly builds too, of course (with appropriate code names for the executable).

Q: Ok, but I hate #ifdefs. Why not just merge to the trunk when landing on the branch, and update both trunk and branch with Firefox 2 changes?

A: Merging is painful and error-prone. This has two effects:

Painful: people avoid merging or forget to do it, leading to more bugs and costlier recovery work to resynchronize.

Error-prone: hand-merging and re-reading cvs diff output is hard on fingers and eyes, leading to yet more bugs.

By keeping all versions present in the tip revision, using #ifdefs, we make the costs of API divergence clear to all. And really, the goal here is not pretty code, it is significant time savings to hundreds of developers and thousands of testers in reduced bugs from avoiding conflicts and merging in favor of #ifdefs.

Q: Shouldn't those who change APIs bear the cost of adding #ifdefs?

A: Yes, and with module owner and peer review of the affected API-client files as usual. No one gets a free lunch on either side of an API, at the expense of the folks on the other side:

If you change an API on the trunk, you need to keep the 1.8 branch of the #ifdef working (add the #ifdefs as needed, with review).

If you break an unfrozen API on the branch with drivers' prior approval, you need to keep the trunk working too.

This cost is a tax, and what you tax, you get less of. It should have the effect of minimizing, ordering, and rationalizing API changes so that we don't have too many, and so that no one gets stuck with his neighbor's tax bill. We will be developing a more detailed plan of action for API preservation and evolution, details TBD.

Q: What's an example of API or bug-compatibility skew where #ifdefs might be required in front-end sources?

A: Fixing window targeting to support better tabbed browsing is one example. A hack-fix only for Firefox could be made to the 1.8 branch, to minimize risk. Meanwhile, to avoid duplication of effort and excess bug habitat, we would like to fix window targeting on the trunk by unifying embedding and XUL-app APIs and implementation, which probably means incompatible API changes.

Another example: XUL box layout standardization may break compatibility at a few edge cases, requiring #ifdefs in toolkit or other front-end XUL sources.

Q: What about the Firefox 2 work already under way on the trunk?

A: It can land on the branch at a stability point its owners are happy with, and thereafter be updated by synchronized checkins from one CVS working tree.

Q: When will the CVS commitinfo, bonsai, or other changes be done?

A: We will work hard to get these done now, the week of 12-Dec-2005, and follow up next week to make sure they're ready for prime time.