Overview of contributions branches and tags
To understand the naming conventions for the branches and tags used for Drupal contributions, you should already be familiar with the version numbers for contributions.
There are three types of CVS identifiers now used in the contributions repository:
In addition, there is the HEAD branch, which is the branch that every repository has by default.
All releases of contributions are created based on release tags. These tags determine the specific revisions of each file included in the release. The tag name itself corresponds with the version string for the release. The release tag naming convention is:
[CoreCompatibility]--[Major]-[PatchLevel][-Extra]
- [CoreCompatibility] indicates what release series of core (e.g. 4.7.x, 5.x, or 6.x) the release is compatible with. It uses the same form as the Drupal core branch for that core release series. For example:
DRUPAL-4-7orDRUPAL-5(any value from the complete list of available Drupal core branches). - [Major] is an integer that indicates what major revision of the contribution the release is from. Most of the time, this will be
1to indicate the initial stable release for a given version of core, but occasionally contribution maintainers might provide multiple versions that are all compatibile with the same version of core (e.g. stable and development versions). A maintainer might choose to use major revision0to identify releases from the HEAD development branch that are being ported to a new version of the core API, but which aren't yet stable enough to have their own branch. - [PatchLevel] is an integer that uniquely defines the specific release. The initial release for a given major number is patch level
0and subsequent releases increase the patch level. - [-Extra] (optional) can be used (in rare cases) to specify additional identification for a release. These extra tags may only consist of either
-UNSTABLE,-ALPHA,-BETA, or-RCfollowed by one or more numbers. When adding extra information like -BETA1 or -RC1 the tag must be in upper case. rc1 or beta1 will not be accepted. For example:-BETA1to indicate the first beta release before the specified version.
Some examples of tag names and the corresponding versions they represent should help clarify:
DRUPAL-4-7--1-0- The initial (patch-level 0) stable release (major revision 1) of a module compatible with any version of Drupal core 4.7.*. This would be version 4.7.x-1.0.
DRUPAL-4-7--2-1- An updated (patch-level 1) new-feature release (major revision 2) of a module compatible with any version of Drupal core 4.7.*. this would be version 4.7.x-2.1.
DRUPAL-5--0-1- An updated (patch-level 1) unstable release (major revision 0) of a module that's not done being ported to the 5.x core API. This would be version 5.x-0.1.
DRUPAL-5--1-0- The initial (patch-level 0) stable release (major revision 1) of a module compatible with any version of Drupal core 5.*. This would be version 5.x-1.0.
DRUPAL-6--2-0-BETA1- The first beta of the initial (patch-level 0) release from the second release series (major revision 2) of a module compatible with any version of Drupal core 6.*. This would be version 6.x-2.0-beta1.
Historically, the 'extra' element at the end of version tags allowed nearly arbitrary strings, including lowercase letters, hyphens, and underscore characters. As of 2008-09-16, this is no longer supported and the optional 'extra' element at the end of a version tag must follow the strict rules described above. See issue #252473 for background on this change.
Once a contribution has been ported to a given version of the Drupal core API, the maintainer should create a branch that marks it as compatible with that version. This is not technically required, but is definitely recommended for responsible project maintainers. These initial stable branches are similar to the branch names used by Drupal core branches, with the addition of the module's [Major] version number. For example, the initial release of a module compatible with Drupal 6 should be branched with: DRUPAL-6--1.
The releases corresponding to branches, even "stable" branches, use -dev at the end of their version string to indicate that the code contained within that release is constantly changing and inherently unstable. So, the release pointing to the DRUPAL-6--1 branch would have the version 6.x-1.x-dev.
Historically, the Drupal Contributions repository supported 'partial' branch names like DRUPAL--4-7 and DRUPAL-5, treating them as synonyms for DRUPAL-4-7--1 and DRUPAL-5--1. Starting with the DRUPAL-6 core branch, code in the contributions repository must use fully-named branches, like DRUPAL-6--1 and DRUPAL-6--2.
Development and other branches
If a project maintainer wishes to provide a development branch for a given version of the core API, they would add a branch of the form:
[CoreCompatibility]--[Major]
- [CoreCompatibility] indicates what release series of core the branch is compatible with. This is just like the first part of a release tag (explained above). For example:
DRUPAL-4-7orDRUPAL-5. - [Major] is an integer that indicates what major revision of the contribution the branch represents. In the case of development and other branches, the major version number must be
2or higher, since the default stable branch for a given version of core (e.g.DRUPAL-4-7) corresponds with major revision 1, and by convention, releases with the major revision 0 (if used at all) are always from the CVS HEAD.
Again, some examples of these additional branch names should help clarify:
DRUPAL-5--2- The first additional branch of a module compatible with any version of Drupal core 5.* (by convention, for new feature development) This would be where versions 5.x-2.0, 5.x-2.1, etc. where released from, and the development snapshot release would be called 5.x-2.x-dev.
DRUPAL-6--3- The second additional branch of a module compatible with any version of Drupal core 6.*. Perhaps after a period of developing new features in the 6.x-2.* series of a module, the maintainer decided to create a new stable branch and use that as the new default download of their module. This would be where versions 6.x-3.0, 6.x-3.1, etc. where released from, and the development snapshot release would be called 6.x-3.x-dev.
HEAD branch and how to use it effectively
The HEAD branch is the branch that every repository has by default, when it is created in CVS. In Drupal, the HEAD branch is customarily used for the latest code on the most recent version of Drupal that the project maintainers are working on. It often contains code that is not yet ready for release. There are a few different approaches to how you can use the HEAD branch for your contribution, depending on how closely you want to "chase" the latest changes to the next version of core under development. In general, the first approach is the recommended one, but both have advantages depending on your needs and abilities.
Use it for the "new feature" branch for the current stable core
In this approach, you would only attempt to port your contribution to a new version of core once the API had stabilized and the code freeze was well under way (for example, once the release candidates were already out). Any bug fixes you make in your current stable branch should be committed to HEAD as well. Additionally, new features or any major changes to your code should be developed directly in HEAD. You can tag official releases in HEAD, but identify them as the development series for the previous version of core.
Eventually, you'll decide it is safe to update the module to the next version of core. At this point you should make a new branch for your previously developed features, before you start porting to the latest version of core. Once that branch was created, you would convert your module in HEAD, and when you consider it stable enough for an official release, you would create a new stable branch that was compatible with the new version of core.
For example, during the entire period when the 6.0 core release was being developed, the HEAD of your module would remain compatible with the 5.x core API. Any bugs you fix on the DRUPAL-5 branch would be committed to HEAD, but you would also add new features and do other major changes there. Once you had a set of new features working well enough to release, you would add the DRUPAL-5--2-0 tag to a workspace checked out from HEAD and submit a release node pointing to this tag (which would be version 5.x-2.0). Time goes on, and you add more features, so you create the DRUPAL-5--2-1 tag for the 5.x-2.1 release and so on. At some point, you feel like the 6.x core API is stable enough to port your module to, so you add the DRUPAL-5--2 branch off the end of HEAD so you could continue to make 5.x-2.x releases if you needed to (for example, to fix a security hole in the 5.x-2.2 release). Now, you can update your module, and when it is stable, you add a DRUPAL-6--1 branch and start the whole process over again as the Drupal core 7.x API is developed in the core repository's HEAD branch.
Note: Beware that this example is spanning the period when the --1 was added for the initial stable branch, so don't be confused. DRUPAL-5 is valid for legacy reasons, DRUPAL-6--1 is valid because that's the correct convention going forward, whereas DRUPAL-5--1 and DRUPAL-6 are both invalid.
Keep up with the version of core currently under development
This approach assumes a more active involvement with the development of the next version of Drupal core. Whenever changes are made in the HEAD of core, you would try to update your contribution's HEAD so that it continued to work with the new API or took advantage of the latest feature. In this case, if you wanted to add new features to your contribution that were compatible with the previous version of core, you would make a branch off of your previous stable branch. Bug fixes to the stable branch would be applied to the development branch (if it exists) and HEAD. New features would be applied only to the development branch and HEAD.
Since the core API usually changes a lot during the development cycle for a new version, this approach will often require more work for contribution maintainers. Also, it's less likely that patches for bug fixes against your current stable code would apply to the HEAD version, since you've already modified the code to stay current with the latest changes to core.
Only sync changes to HEAD when you're going to start a new branch
Another viable approach to HEAD is to basically ignore it during most of your development, and only sync the changes back to HEAD when you're ready to create a new branch moving forward. In this case, you always create a branch for whatever release series you want to work on and do most of your work directly in that branch. When you're ready to create a new branch, you first copy the latest versions of the files from your most current branch back to HEAD. Then, you create a new branch from that point and carry on. This has a the nice benefit that you're always working in a branch that is named with exactly what version of the code it's for. By merging changes back into HEAD and branching from there, you prevent CVS's revision numbers from getting insanely long.
Moving HEAD to a new version
When developing new features in HEAD or keeping up with the current version of Drupal core in HEAD, you will face the situation when you need to re-map HEAD to a new major version of your module. For example:
Current development snapshots for HEAD show: 6.x-1.x.
HEAD should be 6.x-2.x now and you still need a separate branch to commit bug fixes for 6.x-1.x.
Due to drupal.org's release system, you can simply create a new branch DRUPAL-6--1 from HEAD. Afterwards, go to the release node that currently points to HEAD, where you now have the option to select DRUPAL-6--1 (6.x-1.x-dev). After changing the CVS branch for this release node, you can create a new release node for HEAD (most probably either for 6.x-2.x or 7.x-1.x in this example).
Important: The CVS branch for HEAD release nodes can only be moved once. It is impossible to revert this change afterwards, so please make sure to select the proper CVS branch.
