CVS Considered Harmful

Posted 16 Jul 2002 at 14:52 UTC by lindsey Share This

Good programming calls for good organization -- including naming of files and directories. But the popular source-code management tool, CVS, makes that difficult.

Good programmers have good practices: when things start to smell funny, they improve the design of the existing code until it smells right. They can't always anticipate every design consequence and future design needs, but they can react to them to keep the code clean.

Refactoring like this requires flexibility -- sometimes code needs to be moved out to be its own method/function. Sometimes the work of a class/module is split across lots of classes, and a new class needs to be created. Well organized code lives in clearly-named files within a meaningful directory hierarchy -- in fact, the coding conventions of some languages require specific file and directory names. To move some classes into a new package, or to clarify the name of an existing class, files must be renamed and moved within directories.

Failure to name and organize code is a pitiable mistake, which causes wasted time and reduced enjoyment for anyone who works on the code later. But, unfortunately, CVS, the leading distributed source-code management tool makes this task difficult. Through the CVS interface, directories cannot be removed entirely; files can only be renamed by removing one file and copying its contents to another new file -- thus losing the revision history of the old file. Thus, to use CVS is to lose a critical capability to respond to future insight -- to refactor names within code modules.

The deficiencies of CVS are straightforward; it needs

  • a cvs mv command to rename and relocate directories and files within the cvs tree, and
  • support for really removing directories

The task to add these capabilities would be nontrivial -- the internal structure that CVS uses to store files and directories does not distinguish between the contents/history of a file and its name. Further, "empty" directories are used to store the skeletons of removed files which can be checked out later. And the algorithm/protocol for merging existing, distributed working copies with renamed/relocated files from the repository must be developed. These are interesting, yet accessible technical challenges for any careful programmer.

Nevertheless, these technical challenges -- which are great -- should not prevent CVS from providing this critical service to its thousands of normal users. By simply improving this one tool in a critical way, the quality of open-source development everywhere can be improved; alternately, newer, more flexible tools should be made backwards-compatible for the graceful replacement of CVS. Anybody want a project?

Show me the code, posted 16 Jul 2002 at 15:13 UTC by Zaitcev » (Master)

I can understand gripes about file renaming (this is why bk has such feature), but the author completely fails to substantiate his anger against the directories.

More important, if the author thinks that some features are important, it's up to him/her to implement them. Developer's personal itch and all that...

Tell us something new..., posted 16 Jul 2002 at 15:38 UTC by egnor » (Journeyer)

It's well known that this is a major deficiency of CVS, and it's usually the first item on the feature list of all ten million CVS replacements out there. Adding proper "rename" capability to CVS is close to impossible (or it would have been done long ago), though you might look at Meta- CVS.

Making Subversion (or arch or Vesta or PRCS or MyFavoriteVersionSystem) backward compatible with CVS is a laudable goal but has plenty of issues. Feel free to start working on a conversion utility or supporting someone else's effort, I'm sure we would all appreciate it.

Right about CVS; alternatives exists, posted 16 Jul 2002 at 16:35 UTC by lmb » (Master)

Backwards compatibility isn't always a good thing. Especially not when it results in too much cruft; and the CVS format has severe disadvantages; you point out a few, none atomic updates etc being further ones.

Using Subversion, arch, BitKeeper is probably the easier choice, except that people don't always feel enough pain to do the switch over, as all known quirks in CVS have (sometimes ugly) work-arounds.

I think that at least BitKeeper can import CVS changes, and writing a simple converter shell script for any of these - if you don't try to deduce the grouping of commits, which is hard enough with CVS, as it is really file based - shouldn't be too much work if you really want to; probably on a timescale measured in hours.

Diffs are hard to read when re-naming files, posted 16 Jul 2002 at 16:47 UTC by tjansen » (Journeyer)

Even with a SCM tool that supports moving files you should not do it unless it is really neccessary. The problem is that moving files (or shuffling code) makes it really hard to read or revert the changes, port fixes etc. Support in CVS for moving would help a little bit, but even better is to avoid it.

BTW do you know checkout's and update's -P option?

atomic commits, posted 16 Jul 2002 at 18:48 UTC by atai » (Journeyer)

Meta-CVS seems to address renaming of files and directories. But is it possible to add atomic commits to CVS while remaining compatible with existing repositories?

CVS is so widely used (plus the existing infrastructures widely available) that any improvements on top of CVS should be preferred to switching to another tool, if CVS improvements are possible.

Atomic commits and disconnected operation, posted 16 Jul 2002 at 19:27 UTC by pphaneuf » (Journeyer)

I'd like commits to be atomic, for obvious reasons. Having a commit involving a bazillion files (couldn't do it otherwise) in the Mozilla tree fail in the middle was a rather traumatic experience.

Also, I'd like better disconnected operation. I think arch and BitKeeper are supposed to be better regarding this, but I'm too lazy to switch from CVS at the moment (I do stuff like export a tree and import it into a local CVS tree on my own box as a vendor branch, then using rdiff to send stuff back, slightly annoying, but it works).

Directories are a small issue, as -P mostly takes care of it, and moving files by adding it in its new place while removing it at the same time from the old is just as confusing (regarding logs and history) as systems that explicitly allow moving files, no less and no more.

RCS considered harmful, posted 16 Jul 2002 at 20:49 UTC by braden » (Journeyer)

What would this article be titled if CVS didn't exist? "RCS considered harmful"?

This article is just another pointless complaint about CVS's shortcomings. But none of these shortcomings is the impediment to refactoring it's made out to be.

  • CVS doesn't let you delete directories.

    All this means is that your tree will get cluttered with defunct directories. Even this isn't a big deal; just

    cvs up -P
  • CVS doesn't let you move/rename files.

    So add..remove, and document it in the change log. It's a bit inconvenient, for sure, to have the history distrupted like this. But it's hardly a showstopper. IME, the inconvenience of this operation encourages you to be more deliberate in planning this kind of change. That's a good thing; when refactoring it's often easy to get impulsive and make changes that prove to be inadequate or incorrect.

I'm not at all oblivious to CVS's shortcomings. But it's by far the most heavily-used SCM software available to the Free Software community; and without it we'd be at a real disadvantage. To suggest it is "harmful" is ridiculous.

I look forward to the day when CVS is replaced with some thing that is better. But until then, CVS works. Refactoring isn't about simply being able to play fast and loose with the organization code. Change is good, but it still has to be disciplined. If a SCM makes it difficult to check in undisciplined changes, I'd say it's doing its job.

But here are some things I'd like to see in an SCM:

  • Project-centric versioning.

    From a CVS-colored viewpoint, this would be like versioning branches. This history would track composition of modules from different parts of the repository. So it would be easy to include the same source in multiple projects without maintaining multiple copies in the repository. CVS allows you to compose modules, but doesn't incorporate the composition into a project history. So if you change the modules used in a composition, it becomes very difficult to check out older milestones of your project.

  • Rigorous hand-holding for change log entry.

    Simply: anything that can be added to the process to help guard against shitty change log entries should be added. This boils down to something more interactive than firing up a text editor, as CVS does.

Renaming and moving files in cvs, posted 16 Jul 2002 at 22:57 UTC by neil » (Master)

It's not hard to rename and move files in cvs - you copy the file on the repository to the new location, then cvs remove it from the old. KDE does this all the time. Could it be better? Yes, it'd be better to be able to move and rename with cvs itself. But it could also be worse.

Harmful?, posted 17 Jul 2002 at 05:40 UTC by rasmus » (Master)

Harmful? You're nuts. Without CVS we wouldn't have half the open source software we have today. Most people have learned to work around the various quirks and it certainly is not a harmful tool in any way whatsoever.

Found this, posted 17 Jul 2002 at 07:03 UTC by Marooned » (Apprentice)

Found this on "./" while browsing.

Found this, posted 17 Jul 2002 at 07:03 UTC by Marooned » (Apprentice)

Found this on "./" while browsing.

.. and thus OpenCM, posted 17 Jul 2002 at 15:49 UTC by todd » (Master)


Ummmm, it is trivial, posted 17 Jul 2002 at 17:27 UTC by imp » (Master)

cd old-location mv new-location cvs rm cd new-location cvs add cvs commit

Geeze, you'd think it was a federal case or something :-). Sure, it is a pain, but hardly readon to brand it harmful. Unuseful, maybe, difficult, sure, but not harmful.

The number of whiners out there seems to be growing every day.

subversion, posted 17 Jul 2002 at 18:00 UTC by hub » (Master)

That is why subversion is being developed. Seriously, once subversion becomes reliable I'll switch to it. In the mean time, I'll just stick to CVS. I one reason for that: freedom. I don't want to give my source code a proprietary source control management system of any sort that will store it in a format I can't decode.

editing the repository directly, posted 19 Jul 2002 at 20:09 UTC by tetron » (Journeyer)

My project ( just recently completely reorganized our CVS repository from a single centralized source tree/build system to one where are independent modules that can be checked out and build independently. We did this by editing the CVS repository directly and simply creating and copying around the files into their new locations. When we were done, we told everyone make a fresh check out the new repository and leave the old one behind. The fact that CVS is very filesystem-centric makes this very easy - the repository itself doesn't keep any metainformation about the structure of what's stored there, it simply uses the filesystem to express this. Do note that RCS files do not (to my knowledge) store the filename within the file, so again editing the repository directly you can easily rename the file with "mv" and not lose any history at all. The biggest problem is that people's existing checkouts will tend to get a bit confused when things start moving around and CVS can't find them anymore, but if you keep your developers appraised of the situation then you should be able to avoid too much trouble.

Of course, if you use a free cvs service *cough*sourceforge*cough* that doesn't let you access the repository directly like this, then you're screwed.

Moving files in CVS?, posted 20 Jul 2002 at 02:29 UTC by vivekv » (Journeyer)

Just curious... what happens to the branches that were created if you manipulate the repository directly? I am sure you can never recover an older version of your software after bunging around the repository. Kinda defeats the very purpose....

Re: Moving files in CVS, posted 20 Jul 2002 at 05:52 UTC by neil » (Master)

vivekv: That's why you cp not mv the files on the repository, then cvs remove the files from the old location. History is preserved on both sides.

Except, of course, posted 20 Jul 2002 at 17:38 UTC by Omnifarious » (Journeyer)

You end up with this new file that has this long history, and gets mysteriously checked out in older revisions. So, that's not the right answer either.

CVS really does have incurable problems, and needs to be replaced.

No Except, posted 21 Jul 2002 at 00:20 UTC by neil » (Master)

You branch old versions before you do reorganizations.

Re: No Except, posted 22 Jul 2002 at 14:18 UTC by jamesh » (Master)

You will still get the mysterious file when checking out an older tag. Consider the following sequence:

  1. Create and check in files A and B in a module.
  2. Tag module.
  3. Copy A,v in the repository to C,v.
  4. cvs rm -f A

If you try to check out the module at the tag you made before the cvs surgery, you will get all three files (all the files have that tag).

In most cases, people just live with this (as they are usually most interested in the tip of the tree), so it isn't that big a deal in practice.

Re: Ummmm, it is trivial, posted 4 Aug 2002 at 03:31 UTC by mickey » (Observer)

ain't that easy. the reason it's hard is that history gets lost this way.
cvs log does not give you the whole picture anymore.
a trick is to move the ,v file to the new place, remove the tags manually in the rcs file and branch diffs. then cvs rm the file in the old place. still, this leaves the new ,v file w/o a link to the old location, whilest preserving the older history, in the form of diffs ang log entries.
ugly ugly ugly

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!

Share this page