Table of Contents
Newsgroups: comp.software.config-mgmt Date: 1998/05/10
I'm putting together a mini-HOWTO for CVS that focuses on how an individual might set up a CVS repository for maintaining an Internet-style project. The mini-HOWTO covers creating the repository, starting a project, the edit cycle, tagging releases, and making releases.
This is a final draft of the mini-HOWTO and I'd like to get your comments on it if you can spare a moment.
Thanks,
-- Ken
$Id: CVS-mini-HOWTO,v 1.3 1998/05/10 15:38:06 ken Exp $
CVS mini-HOWTO
Ken MacLeod <ken@bitsko.slc.ut.us>
INSTALLATION
There's no special setup required to build and install, it's a typical 'net software install, and all the setup happens afterward. Install RCS first, then CVS. Installing in your home directory is OK.
Pick an empty directory to be your CVSROOT and set the `CVSROOT' environment variable to point there. This can be in your home directory to start and you can move projects to a seperate account when you're ready to make them publicly available.
Run `cvs init'. This will create the directory if you didn't
already, and create a subdirectory `
$CVSROOT/CVSROOT' to contain
log files and other admin files. As you create or import projects
they'll each go into their own subdirectory under `$CVSROOT', and
they will all be ordinary RCS files, feel free to look around (but
don't touch :-).
See the info section “Repository”, and “Creating a repository” under it for more details.
STARTING A NEW PROJECT
Because renaming files and moving them between directories is somewhat inconvenient, the first thing you do when you start a new project should be to think through your file organization. It is not impossible to rename or move files, but it does increase the potential for confusion and CVS does have some quirks particularly in the area of renaming directories. — in “Starting a project with CVS”
[The rest of this section is copied from info, “Creating a directory tree from a number of files.” I'll use a project name `GeeWhiz'.]
When you begin using CVS, you will probably already have several
projects that can be put under CVS control. In these cases the
easiest way is to use the `import' command. An example is
probably the easiest way to explain how to use it. If the files
you want to install in CVS reside in `WDIR', and you want them to
appear in the repository as `
$CVSROOT/GeeWhiz', you can do this:
$ cd WDIR $ cvs import -m "Imported sources" GeeWhiz yoyo start
Unless you supply a log message with the `-m' flag, CVS starts an editor and prompts for a message. The string `yoyo' is a "vendor tag", and `start' is a "release tag". They may fill no purpose in this context, but since CVS requires them they must be present.
You can now verify that it worked, and remove your original source directory.
$ cd .. $ mv WDIR WDIR.orig $ cvs checkout GeeWhiz $ ls -R GeeWhiz $ rm -r WDIR.orig
Erasing the original sources is a good idea, to make sure that you do not accidentally edit them in WDIR, bypassing CVS. Of course, it would be wise to make sure that you have a backup of the sources before you remove them.
WHAT NOT TO ARCHIVE
Your repository does not need to have anything in it that you, the author, can regenerate on your machine. This includes `Makefile's from `Makefile.in', `configure', formatted docs, etc. All of these files will be generated when you create a release.
A TYPICAL EDIT CYCLE
A typical edit cycle starts with a checkout, goes through several commits as you make snapshots, and will most often end with releasing and deleting the project directory before starting on the next cycle. I'll leave tagged snapshots to a later section and focus on basic editing here.
CVS will use the project name as the directory name where you'll do your edits:
$ cvs checkout GeeWhiz
CVS will check out your project and you can begin editing right away. CVS doesn't “lock” files like RCS and SCCS do, so you don't have to lock a file before editing it. You'll notice that there are `CVS' directories in your project, this is where CVS tracks adds and removes of files and other admin info, you'll probably want to make sure your scripts ignore these directories.
You add files and directories using the `cvs add' command. You must create the directories and files first, and then add them with `cvs add NAME'. Add the directories first and then files inside the directories. You remove files and directories with the `cvs remove NAME' command, removing all files first if you want to remove the directory. CVS will simply record adds and removes until you commit your changes, it doesn't actually modify the repository at this point.
You can commit your changes at any time using `cvs commit', CVS
will start your editor and ask you for a change description, if
you've made changes in several directories it will ask you again
for each directory, you can redit the comment for each directory
or you can exit your editor and type `
!' to use the same comment
for all remaining directories.
I usually make changes in small batches and commit them as I finish a round of edits. I also try to make sure that I've tested somewhat before I commit, that way if I need to quickly export a copy there's a pretty good chance of it working.
As you are making changes, the `cvs diff' command will give you the diff between your current working copy and the copy that you last committed or originally checked out (i.e. if you're working with others, by default it won't show their changes). I do this often to double check my NEWS and ChangeLog. You can also use tags (described below) to show the diff from previous versions.
When you are finished with a new version of your project and have committed your changes, you can release and delete your work area by running the `cvs release' command in the parent directory of your work area:
$ cd .. $ cvs release -d GeeWhiz You have [0] altered files in this repository. Are you sure you want to release (and delete) module `GeeWhiz': y
CVS will display files it doesn't know about (leftovers or
intermediate files) and ask you for confirmation before deleting
the directory. I prefer to release and delete the project
directories between versions just so I know this happens. If you
notice anything unusual, just answer `n' and nothing will be
touched. (You can also use the `
-n' option to check first.)
** WARNING **
Answering `y' *will* delete the entire directory, even if there are modified files, unknown files, or that file you just spent six hours creating and forgot to add.
I always do a `make clean' before releasing so there are no
suspect files and I look for `
[0] altered files' before releasing.
See also “A sample session” in the “Overview” section of info.
TAGGING RELEASES
When you commit a batch of changes, CVS doesn't do anything special to record the fact except create new revisions of the individual files. You could view the log of commits and diff or export based on the date of commits, or you can do it the easy way and `tag' after each commit or the final commit. Tagging a project tags all the files at the current, or specified, revision together, not just modified files.
Version numbering is apparently a very personal thing, everyone
seems to have their own idea of what makes up a good release
number, including betas and developer snapshots. That's OK. You
can tag your revisions with any label you want as long as it fits
CVS's syntax: Tag names can contain uppercase and lowercase letters,
digits, `-', and `_'. They must start with a letter, and sorry,
no dots (`
.') :-( Personally, I use `_' instead of dot and I
start with an `r' for lack of anything better, i.e. `r1_2' for
version `1.2'.
You can have more than one tag on a revision. You can tag a revision as `r2_4snap1', release it to a few people, come back later and add a tag `r2_4beta1' and release it to a lot more people, and then finally add a tag `r2_4' when you release it to the public. As I'm nearing a release, I will use `r2_4d1', `r2_4d2', `r2_4d3', etc. as I go through my release steps (below), and when everything builds without fail, I tag it with the final release tag and do one final build with the new tag.
Use the `rtag' command tag the latest revision of your project:
$ cvs rtag r2_4d3 GeeWhiz cvs rtag: Tagging GeeWhiz
Use the `-r' option to add another tag on top of an existing tag:
$ cvs rtag -rr2_4d3 r2_4 GeeWhiz cvs rtag: Tagging GeeWhiz
Always use the `-r' option to add another tag, so that you know for sure that you're not accidentally adding any more recently committed files since you last tested.
If you tag a release and then find that you still have an error (before you make it available, of course), you can delete the tag using:
$ cvs rtag -d r2_4 GeeWhiz cvs rtag: Untagging GeeWhiz
If you mistype a tag, or otherwise want to rename a tag, first add the new tag using `-r' with the old tag, and then delete the old tag:
$ cvs rtag -rold_tag new_tag GeeWhiz cvs rtag: Tagging GeeWhiz $ cvs rtag -d old_tag GeeWhiz cvs rtag: Untagging GeeWhiz
RELEASE STEPS
Releasing your project is going to vary a lot depending on how you create release files, how you handle putting revision numbers in your files, how you make your project available to others, and how you announce updates. A lot can, and probably should, be scripted to reduce errors, but leave yourself some checkpoints that you do manually so you can watch logs and catch errors.
My preferred way of making releases is to “freeze” my changes and “start into the release process”. Basically, if nothing goes wrong in the release process then my most recently committed changes will be my release, if there are any errors then I make the change and re-commit, starting the whole cycle again. For minor releases I've found this takes about 15 minutes, for major releases it can be 45 minutes or more, depending on how many errors my users don't have to find for me. :-)
Here are the steps I typically take, starting just before the freeze:
run `make dist', or whatever you need to create the distribution for your package
==> I have a script `make-rel' for these last three steps that also edits in the version numbers based on the tag.
http://bitsko.slc.ut.us/~ken/make-rel/
create binaries if you do that sort of thing
==> I have a script `make-rpm' that creates RPMs from the source tar file.
SUMMARY OF COMMANDS
$CVSROOT Points to the repository where all CVS (RCS) files are kept.
cvs init Creates the repository and initializes the admin files.
cvs import -m "Imported sources" MODULE yoyo start Creates the initial baseline of MODULE. `-m' is the initial comment (otherwise you will be prompted), `yoyo' is a vendor tag and `start' is the initial tag
cvs checkout MODULE Checkout MODULE for editing. CVS does not lock out other people from editing.
cvs add DIRECTORY cvs add FILE Schedules a directory or file to be added to the repository on the next commit. You must add each of the files in the directory after you add the directory (i.e. adding the directory doesn't add the files underneath it). The directory or files must exist before you run this command.
cvs remove FILE cvs remove DIRECTORY Schedules a file or a directory to be declared not to be part of the project when they are committed (i.e. you can still retrieve them as part of older revisions, they are not deleted from the repository). The files or directory must already be removed before you run this command.
cvs commit Commit all changes that have been made since the last commit or checkout. You will be placed in an editor to supply a change description.
cvs diff Display differences between the current work area and the last commit or checkout.
cvs release -d MODULE Release and delete the work area. WARNING: Be careful with this command, you can delete uncommitted files. Run this command in the parent directory of your work area.
cvs rtag TAG MODULE Apply a new tag TAG to the most recent commited change to MODULE. Tags must start with a letter and contain only letters, digits, `-' and `_'.
cvs rtag -rOLDTAG TAG MODULE Add a new tag TAG to the same OLDTAG revisions in MODULE.
cvs rtag -d TAG MODULE Delete TAG from MODULE.
cvs export -r TAG MODULE Export a copy of MODULE using TAG.