oreilly.comSafari Books Online.Conferences.


The Top Ten Subversion Tips for CVS Users

by Brian W. Fitzpatrick, coauthor of Version Control with Subversion

The primary mission of the Subversion project is to "provide a compelling replacement for CVS." One of its secondary missions is to provide a user interface similar to CVS's, so that switching to Subversion will be painless for CVS users.

So, if you learn Subversion's new features, you're ready to start using it, right?

Almost. Although the interfaces are similar, there are some important differences. Subversion has some features that CVS either lacks or offers differently; plus, there's the need to unlearn some of the bad habits that CVS has instilled in you.

With that, I give you the top ten Subversion tips for CVS users. The first six tips address bad CVS habits; the last four address good Subversion habits.

1. Use status to find out your ... status

In CVS, if you want to see what has changed in your working copy, odds are that you run cvs update. This command shows you the status of the files in your working copy, but it also updates your CVS working copy to the latest revision of the repository*. This not only requires a round-trip to the server, but also may change files in your working copy. Finding out what you've changed locally is different from finding out what has changed in the repository, but CVS mixes the two.**

With Subversion, if you want to find out what you've modified, you run svn status. This command compares the files in your working copy with those in the Subversion administrative areas (those pesky .svn directories), thus avoiding the necessity of a network round-trip:

  $ svn status 
  D      fish.c
  A      shrimp.c
  M      anemone.c

Note that fish.c is scheduled for deletion, shrimp.c is scheduled for addition, and anemone.c has been modified.

Now, by default, svn status shows only the files that are interesting (like those that have been added, modified, or deleted). If you want to see information about all the files in your working copy, pass the --verbose switch:

  $ svn status --verbose
                  44        23    sally     README
                  44        30    sally     INSTALL
                  44        35    harry     trout.c
  D               44        19    ira       fish.c
  A                0         ?     ?        shrimp.c
  M                0         ?     ?        anemone.c
                  44        36    harry     things/rocks.txt

The first column remains the same, but the second shows the working revision of the item. The third and fourth columns show the revision in which the item last changed, and who changed it.

If you want to know which files will be updated the next time you run svn update, use the --show-updates switch to svn status:

  $ svn status --show-updates --verbose
         *        44        23    sally     README
                  44        30    sally     INSTALL
         *        44        35    harry     trout.c
  D               44        19    ira       fish.c
  A                0         ?     ?        shrimp.c
  M      *        44        32    sally     anemone.c
                  44        36    harry     things/rocks.txt

You can see that the files that will be updated are marked with a *.

* Unless you pass CVS the -n switch.

** CVS has a status command, but it's not very useful.

2. Remember, you can move things around

I've seen people spend hours in meetings working out the directory structure and file placement of a project they are preparing to create in their CVS repository--and anyone who's ever tried to move a directory or a file in CVS knows why: CVS doesn't allow you to move anything around in the repository!* With Subversion, you can move files and directories with wild abandon:

  $ svn move foo.c bar.c
  A         bar.c
  D         foo.c

Now bar.c has been scheduled to be added and foo.c has been scheduled for deletion. (This is how Subversion represents a move. svn commit will send your changes to the server.)

You can even move files and directories on the server by using URLs:

  $ svn move -m "Move a file" \

That will immediately move foo.c to bar.c on the server.

* Unless, of course, you shell into your repository and start moving and copying things around by hand, but this totally hoses your repository history.

3. Tag and branch by copying

In CVS, you have cvs tag, cvs tag -b, cvs rtag, and cvs rtag -b for creating tags and branches. In Subversion, everything is done as a copy:

  $ svn copy -m "Tag rc1 rel." \

You've created a tag of your main line of development (referred to as trunk in Subversion terms). If you want to create a branch instead, copy the trunk line of development into the branches directory--it's just that easy. And in Subversion, tagging and branching are fast too.

In Subversion, tags and branches are just copied paths in the repository tree. By convention, tags live under /tags and branches live under /branches.

CVS has to modify each individual file that you tag in the repository; depending on the size of your repository, this could take a very long time. Subversion, on the other hand, needs only to copy a single directory node, which not only is really fast but also takes very little space in your repository--no matter how many files are involved in the branch or tag. The Subversion community calls 'em "cheap copies" for good reason!

You're not limited to tagging all files in the same revision in Subversion: If you need to make a "mixed-revision" tag or branch, you can always copy a working copy to a URL:

$ svn copy -m "Mixed branch." .

See Branching and Merging for an extensive description of how to branch and tag.

4. "Revert" instead of "delete and update"

If you've ever made changes to a file in your CVS working copy that you wanted to undo without committing, you probably did something like this to rectify the situation:

  $ rm I-made-a-boo-boo.txt
  $ cvs up I-made-a-boo-boo.txt
  U  I-made-a-boo-boo.txt

And that, aside from requiring two separate operations, required a trip to the server to get the unblemished file (which, by the way, may not be the original file you were working on but rather a newer version). Subversion, however, stores a pristine copy of each file in the .svn directory, so you can just do this:

  $ svn revert I-made-a-boo-boo.txt
  Reverted 'I-made-a-boo-boo.txt'

That comes in especially handy if you don't have a Net connection at the time.

5. Don't fear your version control system

By default, CVS translates line endings (from CR [Unix] to CRLF [Windows] and back) and expands keywords (like $Id$) in your files. This is very handy until you commit a binary file to your CVS repository and CVS, in a fit of helpfulness, turns your file into tapioca pudding.

Subversion will never ever ever do anything to your data unless you ask it to.

Let's say that together now:


You can add any binary file to your Subversion repository and not have to do anything special to have Subversion not destroy your file. However, if you add a text file (a .java file or .c file, for example), you may want Subversion to automatically handle end-of-line translation for you. This is done using Subversion properties.

In this case, you will set the svn:eol-style property to native:

  $ svn propset svn:eol-style native halibut.c

and then commit your change.

You can teach your Subversion client to add certain properties to your files automatically--see the section on Automatic Properties and their configuration for more information.

Pages: 1, 2

Next Pagearrow

Sponsored by: