developed. Organize your process and tools to make this the simplest case and then deal with the exceptions.
So, rather than starting changes off in their own branch, changes will be applied directly to the stream branch. But we'll use a few guidelines and capabilities to help out. These are not hard and fast rules, but rather guidelines that are to be followed to avoid more drastic circumstances.
- Absorb risky changes into a new stream as early on as possible, preferably before most of the developers have migrated to development in that new stream. This is basically a way of stablizing a development stream early on in its life time, before the impact of instability is large.
- Break up complex features in such a way that the Non-Upward Compatible (NUC) portions of the feature are implemented up front with hooks added so that the rest of the feature can be done as a series of incremental changes. So, for example, if changes are being made to message protocols, these are done early, and preferably in such a way as to respect backward compatibility. The functionality afforded by the changed protocols can be implemented in a series of subsequent changes.
- Track promotion levels against changes, not against file revisions, and the tool will automatically identify promotion violations. A file revision will basically be open for change or closed (change completed). We avoid having to make sure that we promote all of the file revisions of a change in unison - instead, we just promote the change. As well, if we promote a change which depends on another change, either implicitly (e.g. changed the same file) or explicitly (e.g. specified in the change package data as a dependent change), the CM tool will clearly point this out and allow us to deal with it.
- Choose a CM tool that will support automatic baselining and context viewing based on promotion levels of the change. This means that we can set up baselining to work only on sufficiently promoted changes - no need to hold up check-in operations. It also means we can view different promotion levels (e.g. latest checked-in, last night's compile, last system integrated changes, latest verification tested changes, etc.). By view, I mean that we can look at the code, do incremental bug fixes, create system build environments, etc. It also means that we can roll back a change from certain views by simply demoting its promotion level.
- Support check-out (and/or check-in) restrictions. For example, when a stream is close to its final beta release, we may want to restrict changes except for those which fix problems on the release-gating problems list. In some shops we may even want to restrict changes to header files beyond a certain date, again in a product stream specific fashion.
So with all of this in place, we'll proceed to do incremental integration as follows:
- Have developers check-out and change files as necessary, directly in the release stream branch, and only as permitted by any restrictions. Encourage exclusive serial check-out and check-in, but allow parallel check-outs in the same branch (assuming our CM tool will support this), with a reconcile operation on check-in. Where there are explicit change dependencies, have the developer attach these to the change package.
- Have developers "unit" test their changes before checking them in. Here, we refer to the unit of change as opposed to the "module" unit. Also, consider having the developer push checked-in changes to the "ready" state when the change (and associated dependent changes) are all ready for build integration.
- Do nightly (or even more frequent)