A Warning from Finkbeiner
Never do a cp -r on a directory because the CVS/Repository will be
copiedand there will be two pointers to the same directory: the old
one!
CREATE A REPOSITORY
First, you need to create a "CVSROOT" directory which serves as the
repository where all files and directories under version
control are stored. Find a disk (if you're lucky enough to have more
than one!) which has some space... this repository stands the chance
of becoming large.
> mkdir $HOME/CVS_repository
To test this stuff out, I'm making a repository in
/fenway/robishaw/.cvstest
You don't directly access the files in the repository; rather, you
check out your own copy into a working directory and
work on that copy. Once you're done making changes to the working
copy, you commit (or check in) the working copy back into the
repository. The repository then contains the changes which you have
made, as well as recording exactly what you changed, when you changed
it, etc.
There are a few things CVS needs to know and to save time you can just
set environment variables that CVS will look for. Add the following to
your .cshrc file:
#
# CVS stuff.
#
setenv CVSROOT $HOME/CVS_repository
setenv CVSEDITOR emacs
setenv CVSIGNORE '*~'
$CVSROOT/CVSROOT contains all the adminitrative files for CVS, while
the other directories in $CVSROOT contain the user-defined
modules. CVSEDITOR is the editor that is launched when you commit a
file (you will have the chance to add notes about changes made before
committing the file). CVSIGNORE tells CVS not to bother dealing with
any files ending in ~ since they are just backup files made by EMACS.
Now, you're ready to create the repository. However, if you want to
set up your repository so a group can checkout and commit files, YOU
NEED TO TAKE THE STEP IN THE SECTION DIRECTLY BELOW FIRST!!
> cvs init
Now you'll find a CVSROOT directory in $CVSROOT.
WORKING WITH A GROUP
If not, then ignore this. The module directories and certain
administrative files inside the repository should be writable by users
that wish to checkout, edit and commit files in the repository. Other
users who can check out and edit files in your repository also need
write permission to the repository since CVS needs to create lock
files in case more than one of you access CVS simultaneously. This
means that you need to create a UNIX group consisting of the persons
that will be editing the files in a project, and set up the repository
with this group's ID.
First, send an email to central@astro.berkeley.edu and ask them to
create a group with the users that will work on the project.
Once your group is created, you need to set the group ID of the
repository directory:
> chgrp yourgroup $CVSROOT
You also need the repository to be group writable (the repository's
history file and all its module directories must be group writable as
well, but CVS seems to make these group writable regardless). In
addition, you want all the files and directories that will be created
in the repository to have this group ID, so you have to set the group
"sticky bit".
> chmod g+ws $CVSROOT
IMPORT A FILE
Now you're ready to start putting files into CVS. In CVS lingo, we
are going to import these files into the repository. Let's
start simple... suppose you have a file named paper.tex in some
directory. First go to that directory:
> cd /fenway/robishaw/papers/arecibo/
> ls
Makefile eps/ paper.dvi paper.tex
We'd like to import the Makefile and paper.tex into our repository
(these are files that will change. You can make a DVI file
from the TEX file (and you don't directly edit a DVI file), so
there's ZERO sense in importing these to the repository! Also, it
would be a huge waste of space to import PostScript files into the
repository. So, how do we get just these two files into the
repository? Well, we need to pick a module name. Inside the
repository, these files will live in a directory named for this module
and when this module is later checked out a directory with the
module's name will be created in the directory from which you check
the module out. So, here's where it gets sort of stupid, but in this
partcular case necessary: make a backup directory above this one named
bak and move the files and directories you don't want in
the repository to this backup directory:
> mkdir ../bak
> mv eps ../bak
> mv paper.dvi ../bak
Now we're ready to import just the files we want into the repository.
Make the module's name that of the directory you are currently in!
> cvs import -m 'This is the 1st version' arecibo yourname start
N arecibo/paper.tex
N arecibo/Makefile
No conflicts created by this import
Everything worked. (N stands for new file.) The files are in the
repository. Two notes:
1) The -m option lets you add a one-line log message. If you don't use this
option, the editor you've set in $CVSEDITOR will be launched!
2) The last two entries are required but are also higher-level
things that you probably won't need until you're a CVS
master. (yourname is the vendor tag; start is the release tag)
Now that you've created the module, you need to define it in
the administrative file $CVSROOT/CVSROOT/modules! It isn't exactly
necessary and does seem sort of redundant, but it keeps CVS in check.
Here are the 4 necessary steps:
(1) Checkout the modules administrative file from the repository:
> cvs checkout CVSROOT/modules
U CVSROOT/modules
(U stands for updating.)
(2) Add the module to the modules file:
> emacs CVSROOT/modules
(If this is the first time you've edited the modules file, you should
add the following lines:
CVSROOT CVSROOT
modules CVSROOT modules
Add the following:
arecibo arecibo
(3) Commit the changes:
> cvs commit -m'added module arecibo' CVSROOT
cvs commit: Examining CVSROOT
Checking in CVSROOT/modules;
/fenway/robishaw/.cvstest/CVSROOT/modules,v <-- modules
new revision: 1.2; previous revision: 1.1
done
cvs commit: Rebuilding administrative file database
(4) Remove the CVSROOT directory from the current directory... don't
want ot hanging around:
> cvs release -d CVSROOT
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `CVSROOT': y
OK. Now we are ready to check out the arecibo directory, but we don't
want to overwrite it!! So, we want to remove the original
source directory! Sounds dangerous, and it is, so you may want to
make a backup:
> cd ..
> mv arecibo dead
Now we type:
> cvs checkout arecibo
cvs checkout: Updating arecibo
U arecibo/Makefile
U arecibo/paper.tex
There's the arecibo directory. Notice there is now a CVS direcotory
in the arecibo directory... this stores administrative files that you
should not edit!
Check the files and if they look fine, go ahead and delete the source
directory:
> rm -fr dead
You can now move back the files you were not importing to CVS:
> mv bak/* arecibo
> rmdir bak
Of course, if you're about to start from scratch, it makes a wicked
lot of sense to just make an empty directory structure and import the
parent directory as a module into the repository! Then you can use
add to add new files and directories as they appear! Boy, that
would save the big headache above, but sometimes you've already got a
big directory structure in existence! N.B. You would still need to
remove the directory structure after importing it into the repository
and you would also need to update the CVSROOT/modules file!
CHECK OUT A MODULE
If a module exists in the repository, all of the files in the module
can be checked out into a working directory:
> cvs checkout modulename
You could check out specific files as well:
> cvs checkout modulename/filename
Now you're free to edit the files in the working directory.
CHECK IN (COMMIT) A FILE
Now you've edited a file in a working directory. If you're happy,
first make sure that nobody else has changed the file!! You make sure
all changes that have been committed are updated with:
> cvs update
Now we can commit our changes to the repository:
> cvs commit -m 'Log entry goes here so emacs won't open!' filename
If you leave out the -m option, the $CVSEDITOR will launch. If you
don't specify a filename, all the files in the working directory will
be examined.
ADD A FILE
Suppose you've created a new file that was not imported with the
module into the repository. You can add a new file or directory to a
module with the add command.
When using add, you must go to the directory that the file or
directory to be added lives in! It is not a recursive command so 'cvs
add foo/bar' will fail! Instead:
> cd foo
> cvs add bar
cvs add: scheduling file `bar' for addition
cvs add: use 'cvs commit' to add this file permanently
You now need to commit this file into the repository:
> cvs commit -m 'adding bar' bar
In order to use add, the files to be added must already exist in the
directory! If you want to add a whole new directory hierarchy to the
repository, you should use import!
FILE HISTORY
To examine the history of a file you can use the log command:
> cvs log paper.tex
Or you can use the annotate command to show a
line-by-line history of your file... every revision will be
shown.
> cvs annotate paper.tex
This could be a little lengthy for a 3000 line paper or program, so
you might want to look at the differences between two revisions
instead using the diff command:
> cvs diff -r 1.3 -r 1.6 paper.tex
This will show you all the differences between the 3rd and 6th
revisions of the paper.
REMOVE A FILE
You will change your directory structure and add or delete files. You
still may want to retrieve a copy of old versions of a file that no
longer exists. So if you want to remove a file but still be able to
retrieve old revisions:
(1) Make sure there are no uncommitted modifications to the file!
> cvs update
(2) Remove the file from the working directory:
> rm file
(3) Tell CVS you are going to remove the file:
> cvs remove file
(4) Commit the file, actually removing the file from the repository:
> cvs commit -m'Removed unneeded files' file
(You can do steps (2) and (3) simultaneously by using a -f flag when
you call remove: cvs remove -f file )
The file gets moved to the Attic directory in the repository, where it
might be pulled out and looked at some other day!
!!!!
erences between any two revisions With two `-j revision' flags, the update (and checkout) command can merge the differences between any two revisions into your working file.
$ cvs update -j 1.5 -j 1.3 backend.c
will undo all changes made between revision 1.3 and 1.5. Note the order of the revisions! If you try to use this option when operating on multiple files, remember that the numeric revisions will probably be very different between the various files. You almost always use symbolic tags rather than revision numbers when operating on multiple files.
Specifying two `-j' options can also undo file removals or additions. For example, suppose you have a file named `file1' which existed as revision 1.1, and you then removed it (thus adding a dead revision 1.2). Now suppose you want to add it again, with the same contents it had previously. Here is how to do it:
$ cvs update -j 1.2 -j 1.1 file1
U file1
$ cvs commit -m test
Checking in file1;
/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
new revision: 1.3; previous revision: 1.2
done
$
!!!!!!!!
RELEASE A MODULE
When you are finished with all the changes you wanted to make to a
module, you could "release" the module. That is, you could delete the
working directory for the module but keep the module and files in the
repository so that they can be checked out later. This is equivalent
to just deleting the working directory, but this is a little safer
since CVS checks to see if you have committed changes and makes a note
in the history file that you have abandoned this checked out module.
> cvs release -d arecibo
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `arecibo/': y
The module still lives in the CVS repository and all of the files in
the module are safe and sound. This just removes the working
directory!
WARNING! release has a very serious side-effect! If
there are files or directories, maybe PostScript images you didn't
want to import into the repository, that are in a module directory and
you release the module, CVS WILL remove these file and
directories!! This is very dangerous. Think before you release a
module! It won't hurt to just keep it hanging around. CVS will warn
you about files it does not recognize with question marks:
> cvs release -d arecibo/
? eps
? paper.dvi
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `arecibo/': n
** `release' aborted by user choice.
SHORTCUTS
The CVS commands have convenient shortcuts to save some typing:
cvs ci (=checkin = commit)
cvs co (=checkout)
cvs upd (=update)
cvs rm (=remove)
cvs rel (=release)
cvs ann (=annotate)
EMACS & CVS
If you are using EMACS, there are bindings that run CVS operations:
C-x v v : commit
C-x v u : revert to last version
C-x v l : show history
C-x v = : compare with last version
C-x v g : annotate
If the screen splits into two regions, get back to single screen from
split screen, C-x 1.
There are more options under the Version Control menu (which is
under the Tools menu).
OTHER STUFF...
If you need to move or rename a file or directory in CVS, you'd better
check the CVS User's Manual . You can also learn about branching
and remote repositories. Then make a homepage so I can read about it.
Here is a Guide to CVS commands with examples.
SAMPLE SESSION
Add CVS environment variables to .cshrc file:
#
# CVS stuff.
#
setenv CVSROOT /fenway/robishaw/.cvstest
setenv CVSEDITOR emacs
setenv CVSIGNORE '*~'
Make a CVS repository:
> mkdir $CVSROOT
Change the group ID:
> chgrp robi $CVSROOT
Set the group permission to writable and sticky:
> chmod g+ws $CVSROOT
Make the repository:
> cvs init
A directory full of stuff called arecibo exists. I want to make
a module called arecibo but I don't want all the stuff in the
directory to live in the module! So go to the directory just above
arecibo rename the directory something else:
> mv arecibo tmp
Make an empty directory called arecibo:
> mkdir arecibo
(Yes, you could have just moved everything in arecibo to some
other empty directory: 12 to one...)
Go to the arecibo directory:
> cd arecibo
Now we want to import the arecibo module:
> cvs import -m'Creating Arecibo module' arecibo robishaw start
No conflicts created by this import
Now we remove the source directory,
> cd ..
> rmdir arecibo
Before we go any further, we should define this module in the modules
administrative file:
> cvs co CVSROOT/modules
U CVSROOT/modules
> emacs CVSROOT/modules
Add the module name and the working directory (the first two lines
below need to be added if not there):
CVSROOT CVSROOT
modules CVSROOT modules # Now you can check out modules (vs. CVSROOT/modules!)
arecibo arecibo
Now commit the modules module and release CVSROOT from your working directory:
> cvs ci -m'Added arecibo module' CVSROOT
cvs commit: Examining CVSROOT
Checking in CVSROOT/modules;
/fenway/robishaw/.cvstest/CVSROOT/modules,v <-- modules
new revision: 1.2; previous revision: 1.1
done
cvs commit: Rebuilding administrative file database
> cvs rel -d CVSROOT
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `CVSROOT': y
Next, check out the module areciboas a working directory:
> cvs co arecibo
cvs checkout: Updating arecibo
Now we want to move the files we're going to keep in the repository to
the working directory:
> mv tmp/Makefile arecibo
> mv tmp/lgs3.tex arecibo
Add them to the repository and commit them:
> cd arecibo
> cvs add Makefile
cvs add: scheduling file `Makefile' for addition
cvs add: use 'cvs commit' to add this file permanently
> cvs ci -m'Adding Makefile' Makefile
cvs commit: Examining .
RCS file: /fenway/robishaw/.cvstest/arecibo/Makefile,v
done
Checking in Makefile;
/fenway/robishaw/.cvstest/arecibo/Makefile,v <-- Makefile
initial revision: 1.1
done
> cvs add lgs3.tex
cvs add: scheduling file `lgs3.tex' for addition
cvs add: use 'cvs commit' to add this file permanently
> cvs ci -m'Adding lgs3.tex' lgs3.tex
cvs commit: Examining .
RCS file: /fenway/robishaw/.cvstest/arecibo/lgs3.tex,v
done
Checking in lgs3.tex;
/fenway/robishaw/.cvstest/arecibo/lgs3.tex,v <-- lgs3.tex
initial revision: 1.1
done
Now move the rest of the directories and files that you wish to store
in this working directory (but are not planning on checking into the
repository) to this working directory and remove the temporary directory:
> mv ../tmp/* .
> rmdir ../tmp
See what the log looks like for one of the files:
> cvs log lgs3.tex
RCS file: /fenway/robishaw/.cvstest/arecibo/lgs3.tex,v
Working file: lgs3.tex
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1; selected revisions: 1
description:
----------------------------
revision 1.1
date: 2001/11/07 06:57:51; author: robishaw; state: Exp;
Adding lgs3.tex
============================================================================
Edit the lgs3.tex file...
> emacs lgs3.tex
Make sure nobody else has changed this file!
> cvs update
cvs update: Updating .
M lgs3.tex
? eps
? lgs3.log
? lgs3.aux
? lgs3.dvi
(CVS is confused by a directory named eps and the other lgs3
files since they are not stored in the repository! We don't really
want them in there taking up space, so no hay un problemo.)
Now commit the changes we made:
> cvs ci -m'Added a comment to lgs3.tex' lgs3.tex
Checking in lgs3.tex;
/fenway/robishaw/.cvstest/arecibo/lgs3.tex,v <-- lgs3.tex
new revision: 1.2; previous revision: 1.1
done
Let's see how the log file looks now:
> cvs log lgs3.tex
RCS file: /fenway/robishaw/.cvstest/arecibo/lgs3.tex,v
Working file: lgs3.tex
head: 1.2
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 2; selected revisions: 2
description:
----------------------------
revision 1.2
date: 2001/11/07 07:07:05; author: robishaw; state: Exp; lines: +1 -0
Added a comment to lgs3.tex
----------------------------
revision 1.1
date: 2001/11/07 06:57:51; author: robishaw; state: Exp;
Adding lgs3.tex
============================================================================
Now you could look for where you made the revision by typing:
> cvs ann lgs3.tex
That's a lot of lines to look through. So look at just the difference
between revisions 1.1 and 1.2:
> cvs diff -r 1.1 -r 1.2 lgs3.tex
Index: lgs3.tex
===================================================================
RCS file: /fenway/robishaw/.cvstest/arecibo/lgs3.tex,v
retrieving revision 1.1
retrieving revision 1.2
diff -r1.1 -r1.2
9a10
> % I am a comment in this program.
BACK