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