At Relevanz, we use CVS in the following way:

  1. There is a CVS repository called mb which contains the _product_. mb stands for Marketing Bright, our initial product. This codebase is what we use and re-use for every project we embark on. Ongoing product development happens in this repo as well.
  2. The mb repo is organized by modules, with each top-level folder constituting a module. Check out jakarta-commons' CVS. We have a similar CVS structure.

    There can be dependencies between modules. These are explicitly defined in the module's Maven project.xml file. These dependencies are resolved at build-time.

  3. A project that involves professional services/customization (find me one that doesn't) has its own CVS repository. A project has dependencies on modules depending on the project scope. These are also declared in the project's Maven project.xml file.
  4. In cases where the project needs to redefine/re-implement existing classes, then the developer will mimic the same directory structure of the file that needs to be forked, and introduce it to the project's CVS structure. For example, if a file in the mb repository with directory structure /mb/core/src/java/foo/bar/StringUtils.java needs to be forked. This will become /acme/core/src/java/foo/bar/StringUtils.java, where acme is the name of the project forking StringUtils.java.

    Note that the name of the file does not change. We handle this seeming conflict at build-time, by replacing mb repository's version with the customized version. Sounds HACKish? Yeah, coz it is. The alternative, though, is to create a branch on the file, and we tried that initially but it just didn't work out…