Developing Programmers .com

Local Search:



This site is optimized for standards so you can use any standards compliant browser:

Valid XHTML 1.0 Transitional
Valid CSS!
(RSS) RSS Feed

Web Search:
Google


Thursday, 24 November, 2005

CVS and Subversion: Combined Tutorial  

In this tutorial I will teach the basics of two configuration management / revision control systems: CVS and Subversion.

The reason I’m teaching the two together is because both are popular and they are both similar (since Subversion was designed to be an easy replacement for CVS). So we can kill two birds with one stone.

If you’re not sure what configuration management systems like CVS and Subversion are for and why you would want to use one, then you might like to take a peek at a previous article, “What is Configuration Management?“.

I assume in this tutorial that you are working in *nix but most of it should be easy to adapt to the Windows versions of CVS and Subversion. I imagine that sub-directory naming conventions would be the biggest difference.

The Basics

CVS and Subversion both maintain a central “repository”, which is a place where they store all the versions of your project that you want under revision control.

The details of how they work is very different but the basic ideas behind repositories and working copies are remain the same for CVS and Subversion:

  • The repository is kept in a central place like on a server.
  • When you “check out” code, CVS/Subversion fetches a “working copy” of the project from the repository and stores the copy on your computer.
  • You can edit this working copy all you like, or even delete it. The server makes no attempt to keep track of checked out copies and won’t care what you do with your copy unless you try to commit your changes.
  • The checked out copies do keep track of themselves and where you got them from. They do this using additional sub-directories that CVS or Subversion add to your projects directories.
  • When you perform a “commit” operation, CVS/Subversion detects which files you have changed and sends your changes back to the server.

CVS is self contained in one executable program, called “cvs”. You tell it what to do by providing different options, for example “cvs import”, or “cvs commit”. Subversion is also fairly self contained but has two executables: “svn” and “svnadmin”. The “svnadmin” program has all the commands for creating and directly modifying repositories. The “svn” program is purely a client that handles all the day to day operations on an existing repository. Two typical operations are “svnadmin create” and “svn commit”.

The Repository

The repository is the main database where CVS / Subversion stores the “official copy” of your project and all previous revisions.

These examples create CVS / Subversion repositories in your home directory. Both CVS and Subversion offer mechanisms to store the repository on a remote server but we’ll keep it simple for now and you can look up how to set up servers once you’re confident.

Before you start, put together a “test project” to import into the repository. Use an existing project if you like (but don’t trust your only copy of something to a tutorial!). I’ll assume for the sake of the examples that you created a directory called “myproject” containing three text files: A.txt B.txt and C.txt, each containing about eight lines of text. It should be easy enough to adapt the examples to the actual files you chose.

To create a blank repository and then “import” your project to it:

CVS:

    cvs -d /home/me/cvsrepos init
    cd myproject
    cvs -d /home/me/cvsrepos import -m "Imported my project at version 2.6" mycvsproject MYVENDOR VER_2_6

Note that:

  • -d /home/me/cvsrepos gives the path for the repository directory. Putting the repository on a server involves various kinds of special notation here, for example :ext:cvs@myserver.com:/home/cvs/myrepository. See the CVS Manual for details.
  • The import command operates on the current directory by default, so change into your project directory first.
  • -m "message" sets the log message for the import
  • mycvsproject tells CVS what directory to put imported files into in the repository. Usually this will match the directory you changed into but you might like to use the chance to pick a better name. I have chosen the name to not clash with the Subversion example below.
  • MYVENDOR is a vendor ID tag; which is used when you’re basing your code on code from another vendor and need to keep the two sets of code “in sync”. It is an advanced feature that you’re unlikely to use right away so for now set it to any value you like.
  • VER_2_6 is an initial “tag” to be set, a symbolic name for this version of the project. A version number might be appropriate or just a phrase like IMPORTED_VERSION.

Subversion:

    svnadmin create /home/me/svnrepos
    cd myproject
    svn import . file:///home/me/svnrepos/trunk/mysvnproject --message 'Imported my project at version 2.6'

Note that:

  • /home/me/svnrepos is the path I’ve picked for the Subversion repository.
  • CVS hasn’t “claimed” the “myproject” directory or changed it in any way, so it’s safe to do both imports from the same initial directory.
  • The import command takes two main parameters: source and destination.
  • The destination for an import has several components: the protocol (”file://”), the path to the repository (”/home/me/svnrepos”), and continuing as though it was part of the same path is the directory within the repository where you want the imported sources stored (”/trunk/mysvnproject”). The “trunk” directory isn’t compulsory but is a popular and useful convention for Subversion, as I’ll explain in the section about “tags”.
  • --message sets the log message for the import.
  • There is no initial symbolic import tag or vendor unless you specifically create them after the import. Usually there’s no need for these so early in a project.

Fetching a Working Copy

Now that you’ve imported your project, you don’t technically need the original copy any more. Don’t delete it yet; just move it out of the way or rename it until you’re confident that it’s no longer needed. Note that if you continue working in the original directory your changes will be difficult to put into the repository. This is because the original copy is not set up as a special “working copy”.

A “working copy” is a copy of any directory and its sub-directories, checked out from a repository. It contains not just the files you checked in but also some special “working copy” directories (called “CVS” for CVS and “.svn” for Subversion). These directories contain information about exactly what you checked out: which version and which repository and for Subversion it also keeps a copy of each file (so that comparing with what you checked out does not require more network traffic). The details of what’s in these directories is less important than the fact that CVS/Subversion create them for you when they check out a directory, and that they have to be intact to commit any changes.

To check out a working copy:

CVS:

    cd /home/me
    cvs -d /home/me/cvsrepos checkout mycvsproject

Subversion:

    cd /home/me
    svn checkout file:///home/me/svnrepos/trunk/mysvnproject

Notes for CVS and Subversion:

  • First, change to the directory you want the working copy directory to be placed in.
  • Both CVS and Subversion need to know which repository and which directory within the repository to check out. They each expect the information in their own way.
  • If you wanted to call the working copy directory something different to what it’s called in the project (for example “working-copy-todays-experiment”), just append the name you want for the working copy to the end of the checkout command line.

Working With Working Copies

If you’re not planning to “commit” changes to a working copy, then it’s yours to mess with as you wish. Delete it, change it, remove the CVS or .svn directories, whatever.

If you do plan to commit changes however, then you have to be careful to keep those special working copy directories intact and to make sure CVS/Subversion are kept up to date on files added, deleted or moved/renamed.

Editing Files

Editing an existing file will be noticed automatically. Edit away and CVS/Subversion will notice that it’s changed when you “commit” the changes. You can even ask CVS/Subversion what has changed in a file:

    cvs diff file.txt

or

    svn diff file.txt

Try editing a line in a file in your working copy (perhaps A.txt) and using CVS/Subversion to view what has changed.

Adding Files

If you add a new file, by default it is considered a temporary file that you don’t want in the repository. This works will when you compile a project and leave “.o” and executable files lying around. To tell CVS/Subversion that you want the file added to the repository, create the file first and then use the command:

    cvs add file.txt

or

    svn add file.txt

Try adding a file (perhaps D.txt) to your example working copy.

Note that you don’t need to specify which repository is in use any more: you are typing these commands from a working copy directory so CVS/Subversion can work all that out for itself.

Deleting Files

If you delete a file, CVS/Subversion will assume it was an accident and restore it for you next time you do an update. To tell CVS/Subversion that you really want to delete a file, tell CVS about it or in Subversion just let Subversion delete the file for you: for you:

    rm file.txt
    cvs delete file.txt

or

    svn delete file.txt

Try deleting a file from your working copy. Don’t delete the file you modified or added. Perhaps “B.txt” would be a good choice.

Moving Files

CVS sees a “move” as a delete followed by an add. Subversion can handle them as one smooth operation:

    mv C.txt C2.txt
    cvs delete C.txt
    cvs add C2.txt

or

    svn move C.txt C2.txt

Keeping Up To Date

Working copies can become out of date if another team member checks in some code (or if you commit code from a different working copy; I use this trick to work from home).

To update your working copy with all the latest changes simply run:

    cvs update

or

    svn update

This will fetch changes and tell you which files it updated. If a change occurs in the same place you have made edits then CVS/Subversion will attempt to merge the changes for you. This can be done if the changes are not too near each other in the files. If a merge is determined to be dangerous (because you have both edited the same part of the same file) then you will get an error message and will have to “resolve the conflict” manually.

One easy way to resolve conflicts is to rename your copy of the file, update to fetch their copy, then copy and paste your changes into their copy as you see fit. If you find you are doing this a lot then you will want to look up more sophisticate techniques in the relevant manual (CVS/Subversion). In practice conflicts are uncommon, especially if you only work in one “branch” of a project and you “update” and “commit” regularly.

Remember to update often if you’re working in a group.

Seeing What Has Changed

To check what is different between your working copy and the repository copy, run:

    cvs status

or

    svn status

The output of these commands is rather different, but either way they indicate what is up to date and what is “locally modified”. Read through the output to see if you can identify the file edits, additions and deletions you performed earlier.

Committing Changes

Now it’s time to check in, or “commit” those changes, which makes your changes “official” by creating a new revision in CVS/Subversion.

There is a “right time” to commit changes.

  • Try to hold off a commit if it will have a negative effect on your group: code that doesn’t compile or breaks major parts of the program will annoy others if it’s checked in before you get it working.
  • If your code is working, then check it in as soon as possible. This reduces how much work is involved for you in “updating” your code and also reduces how much others have to worry about in each “update” because less code changes each time.

First change to the directory you want to commit. Commits are recursive by default so the “main” working copy directory is nearly always the best choice.

Second, make sure your working copy is up to date using the relevant “update” command.

Third, make sure you know what has changed, using the relevant “status” command.

Finally, to commit a working copy:

    cvs commit

or

    svn commit

CVS/Subversion will open a text editor (you can configure which editor using environment variables) for you to edit the log message for this commit. Aren’t you glad you checked what had changed before you had to write this?

Save and exit the editor and the changes are committed with the log message you gave.

To view logs for a file, use:

    cvs log file.txt

or

    svn log file.txt

Further Information

Once you get comfortable with the basics, you will almost certainly want to know more about CVS and/or Subversion. For example, you are likely to want to set them running on a server rather than just a local computer. You are also likely to want symbolic “tags” rather than just version numbers, to keep track of which version matches which product release, test edition, etc. In a complex project you will want to look up “branches” and find out how to create them and merge changes from one branch into another (for example, to back-port new security updates to an old version of a program).

For more information about CVS, see the CVS Homepage or the CVS Manual.

For more information about Subversion, see the Subversion Homepage or the Subversion Manual.

CVS and Subversion both have “man” and “info” pages, and both have built in help to remind you of options and commands:

    cvs --help
    cvs --help commit

or

    svn help
    svn help commit

Wrap Up

That’s about it for this tutorial. Hopefully you have picked up the following skills:

  • Specific CVS/Subversion operations:
    • Creating a repository.
    • Importing files.
    • Checking out a working copy.
    • Editing a working copy:
    • Editing files.
    • Adding files.
    • Deleting files.
    • Moving files.
    • Updating a working copy.
    • Checking the status of a working copy.
    • Committing changes to a working copy.
  • A general idea of how revision control works
  • What a repository is
  • What a working copy is

Look out for future articles on setting up CVS/Subversion servers and combining CVS and Subversion with GUIs and web interfaces!

In this thread so far is:

Posted by sarah at 4:19 pm in: Teamwork , Tools , Tutorials (33351 views)

2 Comments

  1. Before commiting, I also sometimes to do a
    cvs diff
    in the directory where I’ll do the commit, to make sure I’m checking in what I think I’m checking in…

    Without a filename, it’ll list changes to all files - exactly what will be commited, line by line.

    Comment by jiri — On 24-11-2005 at 5:09:17 PM

  2. Hi, I am new to CVS, I am updating a specific folder from WinCVS tool, but How to update the particular folder from the CVS in command prompt.

    Comment by Mohan Raj R — On 29-8-2006 at 9:58:53 PM

Please use the DP Forums for further discussion of this topic.