This is an old revision of the document!


A summary of the CVS problems that are hurting us yet may not be immediately obvious to the casual observer.

CVS doesn't record when a branch began. You have to use heuristics to guess exactly when it was. CVS itself doesn't know either, and avoids the problem by simply duplicating the entire branch contents.

Consider vendor branch imports. Begin with a rev 1.1.1.1, 1.1.1.2 and 1.1.1.3 import. If you then edit the file on the mainline, then rev 1.2 is created. CVS records this as a delta from 1.1.1.1 → 1.2. It never records where 1.2 actually came from. It might have been 1.1.1.2 or (most likely) 1.1.1.3. If you'd checked out an older revision when you did the commit, cvs wouldn't have warned you and would have just used 1.1.1.2 as the base even though 1.1.1.3 existed and had later code.

This is mostly harmless, until you try and reconstruct the history. Things that mechanically parse the repo will guess solely based on the date. And it is just that, a guess.

This is both the reason why we go to great lengths to avoid touching vendor branch code (stop the duplication of rcs deltas), and never put files back on the vendor branch - there would be no way to ever guess that the mainline existed based solely on a 'date' spec.

If 1.5 is HEAD, and we create RELENG_7, then a “magic” tag is created - RELENG_7: 1.5.0.2. (“Magic” is another term for “illegal” in a RCS file. Since RCS won't have created it, then cvs knows that it must have.) This means that commits to RELENG_7 will have deltas in 1.5.2.x. (remove the illegal .0. and shift up).

This is fine.. suppose there are commits on the branch, and 1.5.2.1 is the top of RELENG_7 when we release. Then RELENG_7_0_RELEASE will be 1.5.2.1. It is obvious that this is on the branch.

However. If no commits took place, RELENG_7_0_RELEASE can't be tagged as '1.5.0.2' because there isn't really a corresponding rcs revision. So the tag gets put on the 1.5 instead. How is one supposed to tell for sure if “1.5” is a mainline or a branch revision? CVS repository parsers guess this using heuristics. They won't know our convention that “RELENG_7_0_RELEASE” really happened on “RELENG_7”

It is more complicated than that because now we create release branches. RELENG_7_0 would be branched from RELENG_7, and RELENG_7_0_0_RELEASE would be on RELENG_7_0. Except that we didn't do that in the past. Before RELENG_4_4_0_RELEASE or so, this intermediate branch didn't exist.

Plenty has been said about this already.

CVS might be helping us “get by”, but every time we touch a branch, vendor code, import, etc, we have lost a little more information.

Sooner or later, we will have to change. The longer we leave it, the bigger the mess is that cvs leaves us.

I have trouble remembering what was branched from what back in 1999 in order to correct the guesses that the cvs repo parsers come up with. Because of the ambiguous quirks above, they usually get it wrong.

Do you remember if RELENG_5_0_RELEASE was really from HEAD or RELENG_5? When was RELENG_5 created? Before 5.3 or 5.4? Did we have RELENG_4_3? or did we start doing that with RELENG_4_4? The cvs2xxx tools all got this wrong.

  • versioncontrol/vcscvsproblems.1198812882.txt.gz
  • Last modified: 2007/12/28 03:34
  • by PeterWemm