Linux in a NutshellLinux in a NutshellSearch this book

Chapter 15. CVS

Contents:

Basic Concepts
CVS Command Format
Common Global Options
Gotchas
CVS Administrator Reference
CVS User Reference

The Concurrent Versions System (CVS) is the most popular revision control system among users of free and open source software. It is particularly appropriate for highly distributed projects, with developers working on many different computer systems and even in different parts of the world.

This chapter is based on CVS Version 1.11.2.

15.1. Basic Concepts

To accommodate large projects using a hierarchy of several directories, CVS defines the concepts repository and sandbox.

The repository (also called an archive) is the centralized storage area that stores the projects' files. It is managed by the version control system and the repository administrator, and contains information required to reconstruct historical versions of the files in a project. An administrator sets up and controls the repository using the procedures and commands described later in Section 15.5.

A sandbox (also called a working directory) contains copies of versions of files from the repository. New development occurs in sandboxes, and any number of sandboxes may be created from a single repository. The sandboxes are independent of one another and may contain files from different stages of the development of the same project. Users set up and control sandboxes using the procedures and commands found in the later Section 15.6.

In a typical interaction with CVS, a developer checks out the most current code from the repository, makes changes, tests the results, and then commits those changes back to the repository when they are deemed satisfactory.

15.1.1. Locking and Merging

Some systems, such as RCS (Revision Control System) and the older SCCS (Source Code Control System), use a locking model that coordinates the efforts of multiple developers by serializing file modifications. This was described at the beginning of the previous chapter. The locking model is pessimistic: it assumes that conflicts must be avoided. Serialization of file modifications through locks prevents conflicts. But it is cumbersome to have to lock files for editing when bug-hunting. Often, developers will circumvent the lock mechanism to keep working, which is an invitation to trouble.

To handle work by multiple developers on a single file, CVS uses a merging model that allows everyone to have access to the files at all times and supports concurrent development. The merging model is optimistic: it assumes that conflicts are not common and that when they do occur, it usually isn't difficult to resolve them.

CVS is capable of operating under a locking model via the -L and -l options to the admin command. Also, CVS has special commands (edit and watch) for those who want additional development coordination support. CVS uses locks internally to prevent corruption when multiple people are accessing the repository simultaneously, but this is different from the user-visible locks of the locking model.

15.1.2. Conflicts and Merging

In the event that two developers commit changes to the same version of a file, CVS automatically defers the commit of the second committer's file. The second committer then issues the cvs update command, which merges the first committer's changes into the local file. In many cases, the changes are in different areas of the file, and the merge is successful. However, if both developers have made changes to the same area of the file, the second to commit will have to resolve the conflict. This involves examining the problematic areas of the file and selecting among the multiple versions or making changes that resolve the conflict.

CVS detects only textual conflicts, but conflict resolution is concerned with keeping the project as a whole logically consistent. Therefore, conflict resolution sometimes involves changing files other than the one CVS complained about.

For example, if one developer adds a parameter to a function definition, it may be necessary for all the calls to that function to be modified to pass the additional parameter. This is a logical conflict, so its detection and resolution is the job of the developers (with support from tools like compilers and debuggers); CVS won't notice the problem.

In any merge situation, whether or not there was a conflict, the second developer to commit will often want to retest the resulting version of the project because it has changed since the original commit. Once it passes the test, the developer will need to recommit the file.

15.1.3. Tagging

CVS tracks file versions by revision number, which can be used to retrieve a particular revision from the repository. In addition, it is possible to create symbolic tags so that a group of files (or an entire project) can be referred to by a single identifier even when the revision numbers of the files are not the same (which is most often the case). This capability is often used to keep track of released versions or other important project milestones.

For example, the symbolic tag hello-1_0 might refer to revision number 1.3 of hello.c and revision number 1.1 of Makefile (symbolic tags are created with the tag and rtag commands).

15.1.4. Branching

The simplest form of development is linear development, in which there is a succession of revisions to a file, each derived from the prior revision. Many projects can get by with a completely linear development process, but larger projects (as measured by number of files, number of developers, and/or size of the user community) often run into maintenance issues that require additional capabilities. Sometimes it is desirable to do some speculative development while the main line of development continues uninterrupted. Other times, bugs in the currently released version must be fixed while work on the next version is already underway. In both of these cases, the solution is to create a branch (or fork) from an appropriate point in the development of the project. If, at a future point, some or all of the changes on the branch are needed on the main line of development (or elsewhere), they can be merged together (joined).

Branches are forked with the tag -b command; they are joined with the update -j command.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.