cvs - Concurrent Version System



Introduction

cvs, the Concurrent Version System, is an integral part of OpenBSD's development and most other things related to OpenBSD (as well as Open Source.)

There's heaps of documentation regarding cvs so browse those things if you need more in depth material. These notes came out of personal problems deciphering the existing notes for my needs.

Introduced here is the process by which I was able to get something up and running on my machines.

Fortunately, OpenBSD comes with CVS client and server built together with the system, therefore we do not have to worry about how to install it and can get straight into setting up a basic server and then start working with it.

[2002-06. In the midst of creating this document, testing, my experimental server died with a failed hard-disk. I had hoped to reorganise the text to make it 'clearer?' but that may never happen. Being that the LCD screen was already shot, and we are in the middle of the South Pacific Ocean, it may not get fixed. In the meantime i hope that these notes serves you in your learning of CVS and OpenBSD.]

Configuring a Server

The whole point of CVS is to share a common set of resources, and since I'm offline most of the time (ie. not on the Internet) I couldn't experiment without 1st getting up a server. Once figured out, it isn't that difficult after all.

The stages for configuring a server are:-

Specifying and starting a repository

We decide the location for our repository (/usr/local/CVSREPOSITORY) just to make sure that we don't confuse things. To configure the location to store the CVS repository, we use the 'init' command.

bash$ cvs -d /usr/local/CVSREPOSITORY init

This command generates the required configuration and reference files, and can be checked by looking at the files now stored into /usr/local/CVSREPOSITORY and the control directory /usr/local/CVSREPOSITORY/CVSROOT

bash$ cd /usr/local/CVSREPOSITORY

bash$ ls

CVSROOT

bash$ cd CVSROOT

bash$ ls

Of course, the user (if not root) must have write access.

Files in CVSROOT are used by cvs for administration purposes, but for our purposes tells us that we have been successful this far.

Setting access privileges

To hopefully limit uninvited users from whacking your repository, the next step is to specify a means for controlling write access privileges to your repository. We will achieve this (for the local user) through group privileges.

1. Create a group for CVS use (e.g. group cvs.) In this group we will include local users who we will allow write access to the repository.

bash$ su -

bash# groupadd cvs

bash# usermod -G cvs user1

bash# usermod -G cvs user2

2. Change the repository's group ownership and permissions to allow rwx access to the new group.

bash$ cd /usr/local/CVSREPOSITORY

bash$ chgrp -R cvs .

bash$ chmod ug+rwx . CVSROOT

Now, all users in the group 'cvs' have full access to the repository (i.e. they can create new projects and get files from the repository.)

The password-authenticating server

I wanted to play with the environment of accessing the CVS across the Internet, so I went ahead and configured the password-authentication server. This allows my WinXP machine to share with the server, and also a few other guys I work with to access my repository from their Linux boxes.

To configure the server we need to ensure the cvs port is specified and configure inetd to monitor/service the port.

Make sure there is a line in the /etc/services file that specifies cvspserver is referenced at port 2401.

Edit the file: /etc/services to include the following line.

cvspserver         2401/tcp

Edit the /etc/inetd.conf file to include the following line.

cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/usr/local/CVSREPOSITORY pserver

Now, we just need to restart the inetd server and our CVS server will be listening.

bash# kill -HUP `cat /var/run/inetd.pid`

Creating special password access to the server is the next topic, but for the purpose of getting a system up and running, we'll continue with the current configuration. Without any additional work, CVS will authenticate users from your /etc/passwd file. This limits the number of developers to those with accounts on your system, but this is ok for a start.

Accessing the Server

Continuing our discussion, we will take a look at accessing the materials in the Repository.

Using a sample configuration for a server:

Server: nomoanet.to
Repository: /usr/local/CVSREPOSITORY

Accessing the Repository

The general command format for accessing/using the repository is:

bash$ cvs REPOSITORY command

Where the REPOSITORY is a reference to the desired repository of the following form.

If using a 'local' repository then we can use
"-d /usr/local/CVSREPOSITORY".

If you are accessing an external repository then
"-d :pserver:samt@externalhost.com:/usr/local/CVSREPOSITORY".

Of course, you want to use your own user-id and host.

To simplify your work, we set the environment variable $CVSROOT to the REPOSITORY you wish to use (of course if you use more than one repository you may not want to do this.) There are three methods that I've looked at, but for the beginning you can simply use Option 1 (local directory.)

Option 1: For a local repository

bash$ export CVSROOT=/usr/local/CVSREPOSITORY

Option 2: or, for an external pserver repository

bash$ export CVSROOT=:pserver:samt@nomoanet.to:/usr/local/CVSREPOSITORY

Option 3: or, using an external program for authentication/access to repository

bash$ export CVSROOT=:ext:samt@nomoanet.to:/usr/local/CVSREPOSITORY

We don't need to login using the local configuration, because we're already logged into the system (remember the privilege settings we did earlier.) Local users get whatever access privileges our file system gives them.

Logging In (pserver)

To login, we use the "login" command, as shown below:

For external pserver cvs access.

bash$ cvs -d :pserver:samt@nomoanet.to:/usr/local/CVSREPOSITORY login

Logging in to :pserver:samt@nomoanet.to:2401/usr/local/CVSREPOSITORY
CVS password:

or, we can set the environment variable CVSROOT to the REPOSITORY and login:

bash$ export CVSROOT=:pserver:samt@nomoanet.to:/usr/local/CVSREPOSITORY
bash$ cvs login

bash$ Logging in to :pserver:samt@nomoanet.to:2401/usr/local/CVSREPOSITORY
CVS Password:

We're now into the repository

SSH for secured communications

When accessing external CVS repositories, communications is through insecure systems. You can improve the security of your access (passwords, information, etc) by using SSH as the communications methodology. Do this by setting the $CVS_RSH variable.

bash$ export CVS_RSH=ssh

Your communications with the CVS server can now be using the more secure ssh system. To specify that we want to use the CVS_RSH system, we have to use the :ext: method for accessing the server.

bash$ export CVSROOT=:ext:samt@nomoanet.to:/usr/local/CVSREPOSITORY

Starting a New Project

Starting a new project is through "import".

cvs import -m "log message" project_name vendortag releasetag

To show the flexibility of this configuration, we'll even begin by accessing the server externally. I produce the files for this website on a WindowsXP, Cygwin laptop and I have been sharing it among different closed LANs here in Tonga. I want to import it onto this new CVS system.

WindowsXP/Cygwin Laptop

bash$ export CVSROOT=:pserver:samt@nomoanet.to:/usr/local/CVSREPOSITORY
bash$ cvs login

(Logging in to samt@nomoanet.to)
CVS password:

bash$ pwd

/cygdrive/c/My Documents/My Websites/nomoa.com

bash$ cvs import -m "1st Import into CVS Tree" nomoa.com samt START

I nomoa.com/CVS
N nomoa.com/index.html
N nomoa.com/nomoa.css
cvs server: Importing /usr/local/CVSREPOSITORY/nomoa.com/bsd

[ ... stuff left out ... ]

cvs server: Importing /usr/local/CVSREPOSITORY/nomoa.com/_notes
N nomoa.com/_notes/dwSiteColumnsMe.xml

No conflicts created by this import

Voila! We have now successfully placed our first files into the CVS repository.

"import" loads all files from the current directory (/cygdrive/c/My Documents/My Websites/nomoa.com) onto the CVS server.

Equally important for the novice (i am) is the project_name. The project_name becomes the directory name that will be used by CVS to identify/store your files on the server (likewise that will be the directory it creates when extracting the files from the server.)

To check that the project has been started, check the server directory /usr/local/CVSREPOSITORY and you should now have an extra directory nomoa.com.

OpenBSD nomoanet.to

bash$ cd /usr/local/CVSREPOSITORY
bash$ ls

CVSROOT    nomoa.com

Take a look inside the nomoa.com directory and you will see copies of the original files.

Checking out the New Project

Before you commit changes to your files to the CVS repository, you have to first obtain (checkout) a copy of the files as the CVS now understands them. The general format for getting a CVS repository (checkout) is:

bash$ cvs checkout project_name

Where project_name is the project name you specified above, or directory name where the CVS now stores the files.

For the insanely paranoid, and you wouldn't be using OpenBSD unless there is some level of paranoia, you should backup your original files. Just as important, note that when you get your CVS copy (checkout) it creates a new sub-directory (by the project name.)

1. Backup your original files

WindowsXP/Cygwin Laptop

bash$ pwd

/cygdrive/c/My Documents/My Websites/nomoa.com

bash$ cd ..
bash$ mv nomoa.com nomoa.com.old
bash$ ls

nomoa.com.old/

2. Checkout your new CVS project

WindowsXP/Cygwin Laptop

bash$ pwd

/cygdrive/c/My Documents/My Websites

bash$ ls

nomoa.com.old/

bash$ cvs checkout nomoa.com

cvs server: Updating nomoa.com
U nomoa.com/index.html
U nomoa.com/nomoa.css
cvs server: Updating nomoa.com/_notes

[ ... stuff left out ... ]

bash$ ls

nomoa.com/ nomoa.com.old/

We now have the original version of this project in nomoa.com.old and we also have a CVS working copy of the website at nomoa.com

OpenBSD nomoanet.to

bash$ cd /var/www
bash$ ls

cgi-bin htdocs conf icons logs

bash$ export CVS_RSH=ssh
bash$ export CVSROOT=:ext:samt@nomoanet.to:/usr/local/CVSREPOSITORY
bash$ cvs checkout nomoa.com

samt@nomoanet.to's password:

date time host sshd[19469]: Accepted password for samt from ip-address port 32011 ssh2

cvs server: Updating nomoa.com
cvs server: Updating nomoa.com/_notes
cvs server: Updating nomoa.com/bsd

[ ... stuff left out ... ]

bash$ ls

cgi-bin htdocs conf icons logs nomoa.com

We now have another CVS checkout (work files). This copy is on the OpenBSD machine and can act as the approved website after developments are done on the WindowsXP machine.

Project Updates

To continue the demonstration we will assume that I continue to update this file within the Web site (filename: bsd/cvs.htm) and we now want to look at how we can upload updates to the working files.

Reviewing Changes to a file

There are a number of ways to review whether files on the CVS Repository have changed relative to the working copy.

Which files have changed

"-n update" and "status" give a different summaries of file changes. The "-n" (no change?) before update tells cvs to report what would happen if the update were performed, but not to perform an update.

For example: cvs -n update from the WindowsXP/Cygwin laptop will tell us whether things are different between the current working copy and the material on the Repository.

WindowsXP/Cygwin Laptop

bash$ cd nomoa.com

bash$ cvs -n update

cvs server: Updating .
cvs server: Updating _notes
cvs server: Updating bsd
M bsd/cvs.htm
cvs server: Updating bsd/mmedia
cvs server: Updating bsd/sysadmin
cvs server: Updating mmedia
cvs server: Updating proj
cvs server: Updating python
cvs server: Updating texts

Note the "M" indicates that the file bsd/cvs.htm has been modified on the local copy and out of synch with the Repository copy. Oh, yes, I've continued to make changes to this document as I've tested the examples.

What kind of change has occurred.

The "status" command gives a summary of the current state of a file or directory.

We take a look at the operation on the "development machine" which has new updates not yet uploaded (Windows)

WindowsXP/Cygwin Laptop - Web page development machine

bash$ cd nomoa.com/bsd

bash$ cvs status cvs.htm

Checking in cvs.htm;
/usr/local/CVSREPOSITORY/nomoa.com/bsd/cvs.htm,v <-- cvs.htm
new revision: 1.1; previous revision: 1.1
done
bash-2.05a$ cvs status cvs.htm
===================================================================
File: cvs.htm Status: Locally Modified

Working revision: 1.1
Repository revision: 1.1 /usr/local/CVSREPOSITORY/nomoa.com/bsd/cvs.htm,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)

CVS clearly indicates "Locally Modified" that the contents of the local work files is later (modified) to the current Repository.

OpenBSD nomoanet.to - Web server release machine

bash$ cd nomoa.com/bsd
bash$ cvs status cvs.htm

bsd #cvs status cvs.htm
===================================================================
File: cvs.htm Status: Up-to-date

Working revision: 1.1 Mon Jun 10 04:29:22 2002
Repository revision: 1.1 /usr/local/CVSREPOSITORY/nomoa.com/bsd/cvs.htm,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)

CVS is telling us on the OpenBSD box that the contents are still the same as that in the repository (although we do not know changes have been made on the Windows machine.)

Reviewing Changes

The command for reviewing changes between your working files and the repository is:

bash$ cvs diff -r revision filename

When you omit the 'revision' number, the filename is 'diff'd', compared, to the most recent revision in the Repository.

To review the current changes to cvs.htm to to that in the Repository.

WindowsXP/Cygwin Laptop

bash$ cvs diff cvs.htm

[ ... stuff left out ... ]

This displays the changes between cvs.htm and the copy on the Repository.

We can compare to different versions on the repository (or between different repository versions) by using

bash$ cvs diff -r1.2 cvs.htm

bash$ cvs diff -r1.1 -r1.3 cvs.htm

From the man page:

diff Show differences between files in working directory and source repository, or between two revisions in source repository. (Does not change either repository or working directory.)

Uploading a modified file

The command for updating the repository, sending files to the repository, is 'commit' and follows the form:

bash$ cvs commit file

As we continue to work on this document (cvs.htm) we make changes on our development machine (WindowsXP/Cygwin) and update to the repository.

bash$ cvs commit cvs.htm

Checking in cvs.htm;
/usr/local/CVSREPOSITORY/nomoa.com/bsd/cvs.htm,v <-- cvs.htm
new revision: 1.2; previous revision: 1.1
done

Notice that CVS keeps an internal revision number for your files. Do not worry about these numbers, they are internal to CVS's administration and are not related to the versioning you may choose for releasing your code.

Downloading Updates

The fastest way to update all your working files to the current version on the repository is to use the update command.

bash$ cvs update

From the man page:

Bring your working directory up to date with changes from the repository. Merges are performed automatically when possible; a warning is issued if manual resolution is required for conflicting changes. (Changes working directory; does not change repository.)

Example:

I want to update the current working files on the OpenBSD machine.

OpenBSD nomoanet.to

bash# pwd
bash# /var/www
bash# cd nomoa.com
bash# cvs update
cvs update: Updating .
cvs update: Updating _notes
cvs update: Updating bsd
U bsd/cvs.htm
cvs update: Updating bsd/mmedia
cvs update: Updating bsd/sysadmin
cvs update: Updating mmedia
cvs update: Updating proj
cvs update: Updating python
cvs update: Updating texts

The 'update' command prints a summary that includes saying that the nomoa.com/bsd/cvs.htm file has been 'Updated' from the repository. In this example, no other files were 'Updated'

Project Releases

The really neat feature of CVS that took forever to find, was how they do that product release thing. Controlling binary distributions of source code, without bloating the source code with CVS administration files (such as directory/CVS.) Essentially the approach is:

Tag the point in the CVS

Placing a 'tag' in the CVS allows us to trace back to the point from whence the release is linked. The form for 'taging' the CVS is:

bash$ cvs -q tag NAME_FOR_RELEASE

Some basic rules for the Tag name is to:

For example, to make a release of our nomoa.com website we can do the followin:

bash$ cvs -q tag CDROM_RELEASE_1_0

Export the Tagged version

Once the CVS is marked, tag'd, we can export using the "-d" option to export into a directory named differently from the CVS project name. The format is:

bash$ cvs -q export -r (revision to use) -d project-revision project

From this example of the export command we can already see that we can use any 'revision' in the CVS, such as -D now, or -D tomorrow. To follow our example we can continue with:

bash$ cvs -q export -r CDROM_RELEASE_1_0 -d nomoa.com-1.0 nomoa.com

Of course, this is a good time for a reminder on the GNU-Style convention on names with a stem and major.minor.patch numbering. Summarised the naming convention is:

  1. project name
  2. dash
  3. major version number "dot" minor version number "dot" level number
  4. dot
  5. "src" or "bin" (optional)
  6. dot or dash (dot preferred)
  7. binary type and options (optional)
  8. archiving and compression extensions

As shown in our example above, this leads to

  1. nomoa.com
  2. -
  3. 1.0
  4. .
  5. tar.gz

Archive the Directory

Now we have a new release directory (nomoa.com-1.0cdr) without the CVS administration files we merely package the files for distribution.

bash$ tar -cvf nomoa.com-1.0.tar nomoa.com-1.0.tar
bash$ gzip nomoa.com-1.0.tar
bash$ ls nomoa.com-*
nomoa.com-1.0.tar      nomoa.com-1.0.tar.gz

There we have the beginnings of releasing our source code like the professionals (aka. real programmers.)

Related References

Fogel, Karl Franz. Open Source Development with CVS (CoriolisOpen Press, Scottsdale, 1999)

Purdy, Gregor N. CVS Pocket Reference (O'Reilly & Associates, Sebastopol, 2000)

Author and Copyright

Copyright (c) 2000/1/2 Samiuela LV Taufa. All Rights Reserved.

I reserve the right to be totally incorrect even at the best advice of betters. In other words, I'm probably wrong in enough places for you to call me an idiot, but don't 'cause you'll hurt my sensibilities, just tell me where I went wrong and I'll try again.

You are permitted and encouraged to use this guide for fun or for profit as you see fit. If you republish this work in what-ever form, it would be nice (though not enforceable) to be credited.

cvs Concurrent Version System

Copyright  © 2000/1/2 NoMoa.COM All rights reserved.