Back - Using CVS with Multiple Developers

Branches and Tags in CVS

One useful feature of CVS, especially when maintaining several releases of a software product at once, is the ability to make branches on the revision tree.

The RCS version numbers have nothing to do with the release numbers of the software product. Therefore, CVS has the tag command which allows you to give a symbolic name to a certain revision of a file. The -v option to the cvs status command allows you to view any tags on a file.

Back to our example, go back to the first developers directory and issue a

cvs update foo.c

to get the current version of foo.c.
Next, we want to release version 1 of our wonderful software product.
To do this, we want to tag all files with the tag release-1.

cvs tag release-1 .

CVS should respond with
cvs tag: Tagging .
T Makefile
T bar.c
T foo.c
T main.c

If some other developer wanted to check out release-1, he would issue the cvs command:

cvs checkout -r release-1 testproj

He would then get the release version, instead of the newest version (if there was one)

Now that we have made a release version, lets pretend we have started working on version 2. Next thing we know, our customers are complaining about a fatal error in version 1. Version 2 may be several months off in the future, and this bug in version 1 needs to be fixed now.

First off, we can remove our two developmental trees from the previous tutorials. There is a simple way to do this using CVS.
Go to the directory where your first testproj directory resides, and issue:

cvs release -d testproj

CVS should respond with
You have [0] altered files in this repository.
Are you sure you want to release (and delete) module `testproj':

To this response: y

The -d option tells cvs release to delete the working copy.
You can now issue this same command for developer 2's directory.

Next we want to create a branch off version 1.
Go back to the original directory where testproj was and issue the command:

cvs rtag -b -r release-1 release-1-patches testproj

CVS should respond with
cvs rtag: Tagging testproj

Next we need a working copy of the branch that was just created.

cvs checkout -r release-1-patches testproj

CVS should respond with
cvs checkout: Updating testproj
U testproj/Makefile
U testproj/bar.c
U testproj/foo.c
U testproj/main.c

You can now fix the bug in version 1. Any changes committed will be committed to the branch and not the main trunk.
Lets say the bug fix is to swap the YOU and TOO printf's in foo.c
Change foo.c accordingly.
[Or copy foo5.c to foo.c]

Next, check back in foo.c: cvs commit -m "Fixed printf bug" foo.c

It is also possible to merge the branch back into the main tree.
To do this, first release the patched version.

cd ..
cvs release -d testproj

Next, used the -j 'branch' option to cvs checkout to merge release-1 and release-1-patches.

cvs checkout -j release-1-patches testproj

CVS should respond with
cvs checkout: Updating testproj
U testproj/Makefile
U testproj/bar.c
U testproj/foo.c
RCS file: /class/'username'/cvsroot/testproj/foo.c,v
retrieving revision 1.3
retrieving revision
Merging differences between 1.3 and into foo.c
U testproj/main.c

If there are any conflicts, they will have to be manually resolved.
After this is done you can now do a

cvs commit -m "Merged patch"

to commit all the files changed by the merge of release-1-patch into the current source tree.

Tutorial: Table of Contents