Notes on setting things up

Here are some notes I took on how to setup a CVS repository for stable/devel concurrent releases, including a script to merge changes in a regular way. These notes may be useful to other people learning CVS. Or they may just turn out to be useful to me later to understand what I did.

I made a fake project called super-hello. Were it to be completed,
this project would knock gnu-hello out as the premier hello application
available on the Internet. For now, it's just a few files to play

	> ls -lR pre-import-super-hello/
	total 3
	-rw-r--r--   1 jallen   students       55 Feb 15 22:28 Makefile
	-rw-r--r--   1 jallen   students       26 Feb 15 22:26 README
	-rw-r--r--   1 jallen   students       95 Feb 15 22:27 hello.c

Then I made a new repository to play in. The SourceForge guys
already did this for us on This will
be a local repository, that one is a remote one. Hopefully the
differences won't be too important.

	> cvs -d /home/jra/practice/newrepos init

Now, I set the CVSROOT variable:

	> export CVSROOT=/home/jra/practice/newrepos 

Now, I'll import super-hello.

	> cd pre-import-super-hello
	> cvs import supoer-hello $LOGNAME start

Now, I want to check out a copy of it. We want this copy in a directory
called main, since there are no branches yet.

	> cd ..
	> cvs co -d main super-import

Now, we make a root tag for the branch:

	> cd main
	> cvs tag v_1_0_x_root
	cvs tag: Tagging .
	T Makefile
	T hello.c

The next step is to make the branch:

	> cvs tag -b v_1_0_x     
	cvs tag: Tagging .
	T Makefile
	T hello.c

The final step is to make a merge base tag, which will be used by the
merge script to find the most recently merged stuff. By (my) convention,
merge base tags are the name of the branch, followed by a "_m" and
a serial number. This base one will be v_1_0_x_m0, then.

We want to tag to only go on the branch, so we need to check out the
branch now. We put it into a directory called stable, since changes
made onto this branch are supposed to be the little bugfix
ones, and changes on the main branch are for new development.

	> cd ..
	> cvs co -d stable -r v_1_0_x super-hello

The result is that I now have two copies of the stuff, one under
main/ and one under stable/.

Now for the merge base tag:

	> cd stable
	> cvs tag v_1_0_x_m0

Now we are ready to start hacking. Make a change to stable and
check it in:

	> vi README
	> cvs ci

To merge the change over to main, use the merge-changes program
from the dev-tools module:

	> cd ..	(to workspace directory)
	> cvs co dev-tools
		(this module is checked into the Cricket project's repository)
	> cd stable
	> ../dev-tools/merge-changes	(you could add dev-tools to $PATH)
	<output goes here>

You need to be in either the main or stable directory when you
run merge-changes. It assumes your directory structure will be
like this:

	workspace/ 	(this can actually be named anything)

merge-changes will not work unless your main tree is up-to-date
and there are no uncommited changes. This is because the last step
to merge-changes is a checkin, and it wouldn't be good for it to
commit stuff you were still working on.

If merge-changes makes a conflict when it's doing the merge, it will
abort the commit, and make you clean up the mess. You will need to
commit the fixed merge yourself.

Bugs: If there were no changes, merge-changes will still make
the new tag. It should probably be more careful about this.

Setting up commit-email

To setup commit email, first get a copy of the module called

	> cd ..  (to workspace directory)
	> cvs co CVSROOT

Caution: No one but the project administrator should be messing
with these files. They are very sensitive to goofed up changes.

Now, write a script which takes the info from the CVS system
and formats it nicely. Mine is called format-log, and it's checked
into the Cricket repository under the CVSROOT module. Put your script
under the CVSROOT directory you just made, and add it:

	> cp /tmp/fetch-log .
	> cvs add fetch-log

Now, you need to tell CVS that it should de-RCSify format-log
after you commit it. So, add this line to checkoutlist:

	format-log      Could not check out format-log.

Now, tell CVS to use your script to format a log message and
send it upon every checkin. Add this line to the loginfo file:

	ALL $CVSROOT/CVSROOT/format-log '%{sVv}' 
		| /usr/lib/sendmail -t

It should all be on one line.

Finally, check in your changes:

	> cvs ci

If there are any errors in your format-log script, you should see
them now. Remember, your script will be run in the context of
the remote machine, with the privledges of the user doing the commit.
If Perl is installed in /usr/local/bin on your test machine, but in
/usr/bin on the CVS server, then you'll be very sad and bash your head
against a wall for a long time. Not that I did that. :)