#===============================================================================
# Author: Kris Monsen
# Date  : 02/02/2000
# @(#) $Id: cvs_tutorial.txt,v 2.6 2001/12/19 22:54:40 monsen Exp $
#===============================================================================

			CVS TUTORIAL
		
CVS has many commands.  You can check the "man" page (man cvs) to see
the details on all of them.   The ones most commonly used are:

    cvs checkout <db>		Check out copy of database <db>

    cvs add <file>		Add a file to the database
				Need to do a "cvs commit" afterwards.
				Note: it's a good idea to do:
				  cvs update -A
				before doing any "cvs add".

    cvs add <dir>		Add a directory to the database
	
    cvs commit <file>		Commit the changes made to a file
				into the database.

    cvs update -A [file]	Retrieve the latest version of <file>
    cvs update -r <rev> <file>	Retrieve version <rev> of <file>
    cvs -n update -A [file]	See what files have been changed
    				(e.g., by other people) or what files
				you have modified.  (-n means don't
				actually retrieve the files).

    cvs remove <file>		Remove file from database for anyone
    				checking out the latest versions.
				Doesn't actually remove all versions--
				just makes it so that you don't get
				the file when you do "cvs update -A".
				First, must remove the file from your
				local directory.  Afterwards, need to
				do a "cvs commit".

    cvs diff <file>		Show the differences (changes you have
    				made to the file).
    cvs diff -r <rev> <file>	Compare <file> with another version.

    cvs log <file>		Print out the log messages for all
    				the "committed" versions of the file(s).

    cvs tag <file> ...		Create a symbolic "tag" marking the current
    cvs tag <dir> ...		version you have in each of the files (or
                                directory hierarchy). This is what you use
				to create a "release".

    cvs stat <file> ...		Show cvs status for list of files.

    For ALL CVS commands, if you leave off the file or directory name,
    then cvs will apply the command to the current directory (and all
    directories below it).


To get familiar with these commands try the following:

1. Create a temporary directory:
	% mkdir $HOME/tmp
	% cd $HOME/tmp

2. Run the setup script:
	% make_cvs_tutorial
   This command makes and populates a directory called "db" in the current
   directory.  This directory will act as the central CVS database -- all
   CVS commands in this tutorial will act upon files under this directory,
   but you will not do anything here yourself.

3. Set up your environment:
	% setenv CVSROOT $HOME/tmp/db
   Normally, you will not need to do this step: the CVSROOT variable
   will be set up for you in your .cshrc startup file to be
   the conventional $HOME/project.

4. Check out your own version of the source code database "foo" in a 
   location of your choice (e.g., $HOME/tmp/project):
	% mkdir <location_of_your_choice>
	% cd <location_of_your_choice>
	% cvs checkout foo

   This step will create a directory tree under 'foo'.  Each directory
   will contain:
	- sub-directories (CVS supports hierarchy)
	- files under revision control
	- a directory named 'CVS' that cvs uses to keep track of what
	  you have checked out.  Never delete or make any changes to it.

5. Go into foo/src and edit the file foo.c
   (for example, change the number of loop iterations.)

6. Now check the differences you made:
	% cvs diff foo.c
   Note that since there is only one file in this directory, you could
   simply leave off the "foo.c".  Then "cvs diff" will show you the
   differences for all modified files in this directory.

7. Commit the changes you made to the file ("check them into"
   the database):
   	% cvs commit foo.c
   This command will bring up an editor window to allow you to record
   a log message for the changes you made.  It doesn't have to be long,
   but it is very important that you give some description of what you
   did and why.

8. Check the message log for this file:
	% cvs log foo.c

9. Make one more edit to the file.  Then have cvs print the differences,
   first with the latest file:
   	% cvs diff foo.c
   then with the older version:
   	% cvs diff -r 1.1 foo.c

10. Commit the changes.  Check the log again.

11. Create a new file in this directory, called "foo.h".
    Put some #defines in it or something like that.
    We want to add this new file to the database:
    	% cvs add foo.h

    With this command, you have marked the file as being a new database
    file.  CVS will not actually add the file to the database, however,
    until you "commit" it:
    	% cvs commit foo.h

    This step allows you to enter a log message for the file; use this
    message to give a brief description of what the file is (since you're
    not really making any "changes" to it at this point--it's new).

12. Check the "cvs status" of the files you have:
	% cvs stat

13. Remove the file foo.c.  Don't worry--you've already checked in all
    of your changes.  Now do:
    	% cvs update -A
    to get the latest version of all files in this directory.

14. Now check out an *old* version of foo.c:
	% cvs update -r 1.1 foo.c
    then check the "cvs status" of the file:
    	% cvs stat foo.c
    This command's results show that the "Sticky Tag" is set to
    the (old) version you checked out: version 1.1.

15. Make a change to the other file, foo.h.

16. Now check the status of your directory.  You could use:
	% cvs stat
    But a way to get the information in a more concise form is:
    	% cvs -n update -A
    This command says to *pretend* to update to the latest.
    What it should show you is:
		cvs update: Updating .
		U foo.c
		M foo.h
    where the "U" at the front shows that that file needs to be
    updated (i.e., you don't have the latest), and the "M" means that
    you have *modified* the file (i.e., it needs to be "committed").

17. For the purposes of this example, pretend that *someone else*
    (a project teammate) made and committed the changes that you
    just made in steps 6/7 and 9/10.

    Now edit the file "foo.c" again -- remember that this version
    of the file is the *old* file (version 1.1).

18. Now try committing the file:
	% cvs commit foo.c

    CVS will give you an error message saying that you can't commit
    the changes to an *old* version of the file:

cvs commit: sticky tag `1.1' for file `foo.c' is not a branch
cvs [commit aborted]: correct above errors first!

    The "sticky tag" message here actually tells you that *you*
    deliberately checked out a specific version of the file (rather
    than the latest), and that you really don't want to commit
    changes to this file -- otherwise, you'd be creating a "branch"
    off the main source-revision history.  (It is possible to do
    this, but you REALLY don't want to do it.)

    If you had originally checked out the latest with '-A', and 
    someone else subsequently checked in a new file, the message
    would look like:

cvs commit: Up-to-date check failed for `foo.c'
cvs [commit aborted]: correct above errors first!

19. Check the status using the concise form:
	% cvs -n update -A
    CVS should show you:
    		cvs update: Updating .
		C foo.c
		M foo.h
    Here, the "U" has been replaced with a "C", which tells you that
    the changes you have made *conflict* with changes someone else
    has made (and already committed).

    That's ok, though.  CVS can help you "reconcile" the changes
    (combine them).

20. Retrieve the latest version of the file:
	% cvs update -A foo.c
    The message printed out should be something like:
		RCS file: /home/stefan/tmp/db/foo/src/foo.c,v
		retrieving revision 1.1
		retrieving revision 1.3
		Merging differences between 1.1 and 1.3 into foo.c
		M foo.c
    The "Merging" line tells you that CVS tried to merge the changes
    you made with those that the other person made, automatically.
    If it can't do it, it would say that there are "overlapping changes"
    and it leaves marks in the text showing where the overlaps occur.

    Assuming that the merge was successful, check the differences
    to see whether your most recent change is still there:
    	% cvs diff foo.c

21. Commit the changes to foo.h.

22. Let's say that these two files now constitute a "release".
    (You've decided that your code is stable and that others
    can use these versions of this set of files).  Mark these
    files with a symbolic "tag":
    	% cvs tag REL_1_0
    (Without any files or directories after this command,
    it tags all files and directories in the current directory.)

23. Let's say you decide that you don't need the file "foo.h" any more.
    Remove it and tell CVS to mark it as removed for all future "updates":
    	% rm foo.h
    	% cvs remove foo.h
    (CVS will not allow you to "remove" a file from the database until
    you have actually removed the file from the directory yourself.)
    Then, as with "cvs add", you have to do a "cvs commit" to make
    the change permanent.

24. Check your file list: the file is not there any more.
    Try doing a "cvs update -A":  the file foo.h will not be
    checked out into your directory.

25. However, the old versions of the file still exist in the database.
    You can retrieve all of the files marked with the symbolic tag from
    step 22, for example, with a command like:
    	% cvs update -r REL_1_0
    Try it.  This should retrieve the same versions of the files you
    had in step 22.

    Use:
	% cvs stat
    to see that the "Sticky Tag" of REL_1_0 is set on all your files now.
    Before you make any changes to these files it is important to update
    to the latest versions (-A) first.
    (Otherwise, you may need to do the 'merge' step as in 20.)

26. Now, update your directory to the latest set of files again:
	% cvs update -A
    It should print a message like:
    	cvs update: warning: foo.h is not (any longer) pertinent
    and remove the file foo.h from your directory, because it's
    not needed any more (according to your own 'cvs remove').
