CVS Coding Conventions

When to commit

Never commit code to the trunk (i.e., mainline) that is not fully tested. If you must commit incomplete code, use branches.

Tagging releases

All LimeWire releases are tagged in the following format:

<beta|prod>-<release>-<platform>

"Release" does not have an decimal points, as CVS does not allow them. "Platform" usually means the Java variant, e.g., "java118". Example release tags include "alpha-06-java118" and "prod-14-java13".

Tagging major changes

If you commit a significant change that affects several files, you should tag the trunk before and after the merge. This allows developers to review your changes and undo them if necessary. The tag before the commit should be called "X-before" where "X" is some descriptive string. The tag after the commit should be "X-after". For example, an optimization to the FileManager might result in the tags "faster-filemanager-before" and "faster-filemanager-after".

In the past, we have reversed these tag names, e.g., "before-faster-filemanager" and "after-faster-filemanager". The newer convention is better because it allows one to more easily group all tags related to a single change. This benefit will be more clear after the discussion of branch tags.

Using branches

If you have to make a significant change that may require multiple rounds of testing and refinement, you should use a CVS branch. This is especially important if you plan on sharing incomplete code with another developer. Your branch should have a descriptive name, e.g., "faster-filemanager".

Here's how you make a branch with name X:

  1. Tag the trunk with "cvs tag X-branch-point". This is not strictly required by CVS, but it makes it easier to see what changes you have made on your branch and what changes have been made on the mainline.
  2. Actually create the branch with "cvs tag -b X-branch".
  3. Change to the branch with "cvs update -r X-branch".

At this point all your files have "sticky tags" and you can commit to the branch without fear of modifying the repository. Make sure, however, that CVS lists these sticky tags when you commit.

If you want to see the changes you've made on the branch, type "cvs diff -BbuNr X-branch-point". Note that simply typing "cvs diff -BbuNr X-branch" will not work; that's why we took the time to make the extra tag in step (1) above. If you want to see the changes made on the trunk since you branched, type "cvs diff -BbuNr X-branch-point -r HEAD".

When you're all done with the branch, you need to merge to the trunk:

  1. Change to the trunk with "cvs update -A".
  2. Tag before your change with "cvs tag X-before", as described above.
  3. Actually merge by executing "cvs update -j X-branch". Do not simply copy files from your branch, as changes made to the trunk may be lost!
  4. Resolve any merge conflicts, compile, test, and debug.
  5. Verify that the merge looks fine by executing "cvs diff".
  6. Commit your code with "cvs commit". Use the comment "Merge from X-branch" for your commit. This makes it easier for developers to track the history of a file, as CVS does not record merges internally.
  7. Tag after your change with "cvs tag X-after", as described above.

Now your branch should be retired; do not use it any more.

Fancy merging

The above section describes simple merging. For most situations, this is sufficient. If you wish to do anything fancier with CVS, be aware of the following "gotchas":

  • Avoid multiple merges from one branch to another. Basically you must tag the "source branch" and do a selective merge using these tags.
  • Avoid merging from the trunk to a branch. This is possible, but it makes merging from the branch back to the trunk difficult. It often requires writing some scripts to make things work.

If people need to do these kinds of merges, we will have to develop tagging conventions. Historically, we have used some variation of "X-mergeN" for such merges, but we have not been consistent.