MIT Information Systems

Macintosh Development

[Home] [About Us] [People] [Information Systems]
[Kerberos for Macintosh] [Applications] [Miscellaneous Documentation]

Understanding More CVS

An introduction to advanced concepts of CVS

by Miro Jurisic

Introduction to advanced CVS

Last time we met Alice and Bob, they adopted modify - update - resolve conflicts - commit - repeat as their final model of working with CVS. This model will remain the same as we explore more advanced parts of CVS and additional CVS features.

Tagging: a first look inside a repository

Each revision of each file in the repository is assigned a revision number, which is incremented whenever new changes to the file are commited. Each file starts out with revision number 1.1 when it's first added and commited. The next revision is numbered 1.2, then 1.3, and so forth:

This information is maintained internally by CVS, and in most cases does not concern the developers. However, at some points during the development, the project will be released, and each such release will carry a symbolic version number (1.0a1, 2.5.2d4, 3.0b5r1, etc.). To the developers it is important that they have access to information about which revision of which file became part of each such version of the project. For example, suppose that version 1.0 of SillyBalls is built from revision 1.10 of SillyBalls.c and 1.7 of SillyBalls.h. In order to denote that these revisions of the files belong to the same versions of the project, a developer will tag those revisions with a symbolic name. Later, that symbolic name can be referred to when browsing history of the project, or when referring to old sources.

The only allowable characters in CVS symbolic tags are uppercase and lowercase letters, digits, underscore (_), and hyphen (-). The tag names BASE and HEAD are reserved for internal CVS use. The common way to form tags is to use the project name and the version number, using underscores where appropriate - for example: SillyBalls_1_0, SillyBalls_1_0a1, MacZephyr_2_0f2c3, MacCVS_3_0b5r1.

Tagging is one operation that modifies the repository immediatelly. If your working files have not been commited, the closest repository version is tagged; because of this, it's a good practice to always commit your changes before tagging files.

Branches: parallel development

An immensely useful feature of CVS is that it allows for development of different versions of a project to proceed simultaneously, yet providing for a way to exchange code among them. This is achieved by using branches.

Suppose that Alice and Bob released version 1.0 of SillyBalls, and now while Bob is working on version 1.0.1 which introduces some fixes that they need to release soon, Alice is focusing on some experimental features for version 1.1. The lines of development should look like this:

The way that this is achieved is that Alice creates a new branch in the development of the project, and gives it a symbolic name. Using CVS, she tags her working files with this branch tag, and from there on everything she does on her working files is treated as belonging to that branch, and not to the trunk (the main branch). As the same time, Bob proceeds working on the trunk:

After a while, Bob freezes version 1.0.1 of SillyBalls and releses it. As before, he tags the files with a version tag (SillyBalls_1_0_1), and he proceeds with development, fixing more bugs. Alice realizes that some of the fixes Bob made between 1.0 and 1.0.1 would make it easier for her to work on 1.1, and so she decides to merge those changes into her branch:

It is important that Alice merges sources from the trunk that have been tagged with a symbolic tag; otherwise trying to merge from trunk to the branch again at a later time will not work correctly.

Another week or two, and Bob releases 1.0.2, tagging it as SillyBalls_1_0_2. Alice and Bob agree that they will not make any more 1.0.x versions, and that they will both concetrate on 1.1. Alice, therefore, takes the changes she made on her branch, and merges them into the trunk. Bob updates his files, therefore getting Alice's changes, and now they are both back to working on the trunk, on version 1.1:

Importing and tracking third-party sources

Frequently, a team of developers uses third-party products in their own projects, and they want to track those third party sources in CVS. This is done by using the import feature of CVS to keep version history of the third-party sources, and any modifications made independently of the third-party vendor.

The first time a third-party product is imported into CVS, it is assigned a vendor tag and a release tag. The first import creates a new branch whose tag is the vendor tag, and all sources are tagged with the release tag. Once this is done, the third-party sources can be modified and committed to the repository.

Later, the third-party vendor may release a new version of the product. When the developers want to incorporate the newly released sources into their CVS repository, they need to import the new sources. This import must use the same vendor tag, but a different releaase tag. If any changes have been committed to the sources since the previous import, import will warn that those changes must be merged; otherwise, the new sources will become the default sources.

This way of tracking third-party sources enables CVS to keep track of all revisions of third-party sources that were imported, and all non-vendor modifications made to the sources, while making it easy to apply non-vendor modifications to new vendor releases.

Using importing to start a new project

Importing can also be used to start a new project. This makes use of how importing makes it easy to add many files to the repository at once; using importing this way ignores the ability to perform multiple imports.

When using importing to start a new project, vendor and release tags used are not important.

Questions or comments? Send mail to
Last updated on $Date: 2003/11/18 21:58:25 $
Last modified by $Author: smcguire $