All examples below will trace actual commands. On the filesystem where they were run, my home directory is /home/einstein/prof/rgb, and I keep all my working directories and CVS root directories in the toplevel directory /home/einstein/prof/rgb/Src. I would recommend doing something similar for your personal CVS root directory, although for shared projects you may wish to use a shared project filesystem instead.
CVS tends to be picky about using absolute pathnames in some commands and contexts. Be aware of this if you attempt to use relative paths or variables place of an absolute path in a CVS command. All CVS commands are to be entered from the prompt of your linux shell in a tty window such as an xterm as it is a "command line tool".
There are two general categories of CVS root directories (recall), personal (for private projects) and for shared projects. We do each one in turn. Remember, change the actual path(s) to point to YOUR toplevel source/project directory.
cvs -d /home/einstein/prof/rgb/Src/CVSROOT init
This creates the named directory and makes it into a "CVS root directory", which basically means that it creates a directory structure and a bunch of files you'll most likely never need to look at directly.
We'll create a CVS root for "dieharder", a project that will be worked on by several people.
cvs -d /home/einstein/prof/rgb/Src/DIEHARDER init
This creates the named directory and makes it into a "CVS root directory", which basically means that it creates a directory structure and a bunch of files you'll most likely never need to look at directly. However, in this case you have more work to do! Some of this work must be done as root or by your LAN administrator.
Now change to the directory immediately above the CVS root directory, e.g. /home/einstein/prof/rgb/Src in this example and set the perms (Unix permissions) on the CVS root directory as follows:
rgb@ganesh|B:1480>chgrp -R dieharder DIEHARDER rgb@ganesh|B:1481>chmod g+s DIEHARDER rgb@ganesh|B:1481>chmod g+s DIEHARDER/CVSROOT
The first causes the entire project to be group accessible to members of dieharder. The next two are very important -- they permit team member A to be able to make changes to files that belong to team member B in this directory! You can optionally turn off all access (including read-only access) for people who are not the owner or not in the group:
although I generally don't recommend this unless the project is really private, e.g. a shared collection of resources (including quiz images) for some class.
rgb@ganesh|B:1487>chmod -R o-x DIEHARDER rgb@ganesh|B:1488>chmod -R o-r DIEHARDER
Finally, check your work:
You should see something like this where of course the names will all be different for your project.
rgb@ganesh|B:1497>ls -al DIEHARDER total 24 drwxrws--- 3 rgb dieharder 4096 Feb 8 12:07 . drwxr-xr-x 275 rgb smmsp 16384 Feb 8 12:07 .. drwxrws--- 3 rgb dieharder 4096 Feb 8 12:08 CVSROOT
Some unix filesystems support Access Control Lists (ACLs). These permit fine grained control over who can access any given file or directory. ACLs do not require root privileges in order to set up what amounts to a "group".
I have figured this out, since we do use the Andrews File System (AFS) on the major campus student clients. However, it is pretty complex and I'm going to omit a step-by-step in this first draft. If you really need it and cannot figure it out on your own or with locally provided documentation, write me and I'll add it in the next major revision.
There are three general approaches we'll define for setting your CVS root.
Permanently set your CVSROOT environment variable to point to your personal CVS root directory created as above. This will make all CVS commands entered without an explicit root defined refer by default to it.
If your shell is bash, put the following into e.g. your .bashrc (and logout and login again) or enter them by hand at a shell prompt:
Modify all the paths of course to reflect the actual paths to the CVS root directory you created following the instructions above.
CVSROOT=~rgb/Src/CVSROOT export CVSROOT
If it is csh or tcsh put the following into .cshrc or .tcshrc ditto:
Note that I will not generally repeat future examples for both bash and tcsh/csh -- I will assume that you know how to add environment variables for your shell and are smart enough to logout and login again or source the init file before trying to use the new variable.
setenv CVSROOT ~rgb/Src/CVSROOT
If you only use CVS for one shared project or any number of personal projects, you can point CVSROOT to this root and forget it. If you work on several shared projects, you'll have to specify the correct CVS root for the project for every CVS command you enter in association with the project. This is done as follows:
(for the dieharder project's shared CVS root) where args... refers to the actual cvs command and its arguments (see below). We already used this syntax above with the "init" command to create the CVS root directory in the first place.
cvs -d /home/einstein/prof/rgb/Src/DIEHARDER args...
Experienced unix users may want to create suitable aliases per project, such as (bash):
and then use e.g. "cvsd" in place of cvs in all cvs command associated with the project.
alias cvsd='/usr/bin/cvs -d /home/einstein/prof/rgb/Src/DIEHARDER'
Specifying a CVS root in this way will only work if you are working on a system where (in the example) /home/einstein/prof/rgb (my home directory) is NFS mounted, which pretty much means a trusted system in the Duke Physics Department LAN. Similar considerations will hold for any CVS root directory that you own or participate in a project under -- if you want to use it using the commands above, you have to be "local" to the actual CVS root directory to do so.
Sometimes, however, you'll want to be able to access the project from faraway -- a system at home or a laptop that is not a trusted part of the department LAN and does not mount the filesystem on which the CVS root directory resides.
There is a way to do this via a "cvs server" that is used by (for example) sourceforge to provide both authenticated and anonymous access. However, it requires all sorts of root access and is somewhat dubious from a security point of view. If you really need/want this, find another HOWTO or other documentation (google will help) as it is beyond the scope of this mini-HOWTO. The following presumes that you and other project members have an account on a system that mounts the CVS root, which might be one or more LAN clients with NFS access or a dedicated project server with only a local mount. In particular, since I am security conscious, the instructions below presume that you have (possibly only) ssh (s(ecure )sh(ell)) access to a system that mounts the CVS project root.
This howto does not discuss how to set up ssh for e.g. passwordless access as that is described elsewhere. If you are unfamiliar with ssh and using e.g. ssh-keygen to generate suitable key, you will have to learn a bit about this in order to use the remote CVS feature described herein.
First, on the remote client (for example, your laptop) set the following defaults in your shell. If this isn't the correct path to ssh on your system, change it. For bash:
CVS_RSH = /usr/bin/ssh export CVS_RSH
If it is csh or tcsh:
setenv CVS_RSH /usr/bin/ssh
Now use the following as your CVS root path:
where "ganesh.phy.duke.edu" should be the name of any system where the path is valid to which you have ssh access. As before (and with the same syntax) you may wish to create a suitable alias such as cvsd.
cvs -d :ext:ganesh.phy.duke.edu:/home/einstein/prof/rgb/Src/DIEHARDER args...
When you run this, you will either be prompted for a password on the remote system/account (where the actual CVS directory is accessible) or will transparently do all CVS transactions over the network if you've set up ssh to permit remote shell commands without a password.
Two possibilities exist. You are creating a new CVS-based project from absolute scratch, or you are putting an existing project under CVS control. The steps are similar, but we'll provide a template/example for each.
Make an empty "starter" directory for the project. This will only exist for a moment and them be thrown away when we create a CVS archive of the directory/project and check it out.
Recall that /home/einstein/prof/rgb/Src is my preferred toplevel working/source directory. Change this to yours. Change diehard to the name of your own project. Use the CVS root appropriate to your own project. If it is personal and CVSROOT is defined in your environment, you don't need the "-d /home..." part, or you can use an alias such as cvsd for it is it is already defined for your current shell.
rgb@ganesh|B:1501>cd /home/einstein/prof/rgb/Src rgb@ganesh|B:1502>mkdir dieharder rgb@ganesh|B:1503>cd dieharder rgb@ganesh|B:1504>cvs -d /home/einstein/prof/rgb/Src/DIEHARDER import -m "Create dieharder project" dieharder dieharder start No conflicts created by this import
This created an archive named "dieharder" in your CVS root directory for the project:
Note that the new dieharder archive directory is created with the default perms for the CVS root itself. Anyone in the dieharder group can check out or commit changes to dieharder.
rgb@ganesh|B:1507>ll /home/einstein/prof/rgb/Src/DIEHARDER total 28 drwxrws--- 4 rgb dieharder 4096 Feb 8 13:34 . drwxr-xr-x 276 rgb smmsp 16384 Feb 8 13:33 .. drwxrws--- 3 rgb dieharder 4096 Feb 8 12:08 CVSROOT drwxrwsr-x 2 rgb dieharder 4096 Feb 8 13:34 dieharder
We now have to get RID of the empty starter directory and check out the actual CVS working directory:
Note that dieharder is not, actually, empty any longer. It contains a directory called "CVS". This indicates that the dieharder project working directory is "under CVS control". You are now ready to begin to add files, edit files, commit changes within this directory (next section).
rgb@ganesh|B:1510>cd /home/einstein/prof/rgb/Src rgb@ganesh|B:1511>rm -rf dieharder rgb@ganesh|B:1512>cvs -d /home/einstein/prof/rgb/Src/DIEHARDER checkout dieharder cvs checkout: Updating dieharder rgb@ganesh|B:1515>ls -al dieharder total 24 drwxr-xr-x 3 rgb smmsp 4096 Feb 8 13:45 . drwxr-xr-x 276 rgb smmsp 16384 Feb 8 13:45 .. drwxr-xr-x 2 rgb smmsp 4096 Feb 8 13:45 CVS
If you really are a CVS novice reading this document, chances are good that you already have a large number of projects that are not under CVS control but should be. Suppose, for example, that "dieharder" was something that I wrote on my own without CVS but now I want to put it under CVS control to work on it with somebody else. Or, that I recently lost a dieharder source file that I had invested fifty hours of work in and that I'm putting the whole project under CVS so I never ever again have to reconstruct all that work. Or, that I'm working on dieharder for somebody else and want to be able to generate a timestamped history of everything I do to the sources so they will pay me.
Now it goes something like this. Enter your project directory and clean it up. Everything in this directory is about to be added to a CVS archive. If the project involves things like object files, binaries, dvi files, or other data objects that are derived from sources and perhaps a Makefile, there is no point in putting them under CVS control. The sources (e.g. *.c, *.tex) and Makefile itself and any figures or images all do need to be under CVS control, though. So clean it up.
For a programming project involving make, this will often mean that you need to run "make clean". In other cases you'll have to remove unwanted files by hand. Be Careful! Your project is not yet under CVS control and if you accidentally delete a critical file you are just screwed. To avoid being screwed, consider making a complete backup copy with e.g. cp -rp dieharder dieharder.backup before beginning.
Once it is clean, something like:
imports the entire project directory tree including all subdirectories and turns it into a CVS archive in the project or default CVS root directory.
rgb@ganesh|B:1531>cd /home/einstein/prof/rgb/Src/dieharder rgb@ganesh|B:1532>cvs -d /home/einstein/prof/rgb/Src/DIEHARDER import \ -m "dieharder already exists but is going under CVS control" \ dieharder dieharder start N dieharder/Btest.c N dieharder/COPYING N dieharder/Makefile N dieharder/NOTES N dieharder/Ntest.c N dieharder/README .... N dieharder/Xtest.c cvs import: Importing /home/einstein/prof/rgb/Src/DIEHARDER/dieharder/CRUFT cvs import: Importing /home/einstein/prof/rgb/Src/DIEHARDER/dieharder/doc N dieharder/doc/SP800-22b.pdf N dieharder/doc/cern_stats.pdf N dieharder/doc/diehard_tests.txt N dieharder/doc/fnal_prob.pdf N dieharder/doc/goodness_of_fit_nr.pdf N dieharder/doc/tests.txt No conflicts created by this import
Note that the "\" character at the end of the lines above is a line continuation character, added just so you can see the entire line. Note also that we used several options to the "import" command: -m "message" is the initial message logged as the file is created. The "dieharder dieharder start" are required "repository vendortag releasetag" arguments that are almost never actually used, although the "start" tag would be useful if you ever wanted to check out the original version just the way you imported it. By common convention one uses "directoryname directoryname start" since nobody I know has any idea what a "vendortag" is good for.
Now remove the original. It is not under CVS control, and we'll never ever again work with it. However, you might want to save the backup created above for a few weeks until you are absolutely certain that there is nothing in your original work that didn't make it into CVS. CVS can sometimes omit files of certain types depending on how it was built.
Then check out the project to create a new working directory, this one under CVS control.
rgb@ganesh|B:1533>cd .. rgb@ganesh|B:1534>rm -rf dieharder rgb@ganesh|B:1535>cvs -d /home/einstein/prof/rgb/Src/DIEHARDER checkout dieharder cvs checkout: Updating dieharder U dieharder/Btest.c U dieharder/COPYING U dieharder/CVS_Mini_HOWTO ... U dieharder/work.c cvs checkout: Updating dieharder/CRUFT cvs checkout: Updating dieharder/doc U dieharder/doc/SP800-22b.pdf U dieharder/doc/cern_stats.pdf U dieharder/doc/diehard_tests.txt U dieharder/doc/fnal_prob.pdf U dieharder/doc/goodness_of_fit_nr.pdf U dieharder/doc/tests.txt
Note the "U", which stands for "update" from the current archived image of the associated document. Note also that the working directories all contain subdirectories named "CVS". This indicates that the dieharder project working directory tree (every subdirectory branch of it) is "under CVS control". You are now ready to begin to add new files, edit old files, commit changes to either one within this working directory (next section).