BUY THIS BOOK

Safari Books Online

What is this?

Looking to Reprint this content?


Essential CVS
Essential CVS By Jennifer Vesperman
June 2003
Pages: 336

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: What Is CVS?
CVS is a version tracking system. It maintains records of files throughout their development, allows retrieval of any stored version of a file, and supports production of multiple versions. CVS enables multiple developers to work simultaneously on a single file without loss of data. Each developer works on her own copy of a file, and all changes are later merged into a single master copy. CVS can be integrated with bug-tracking and feature-tracking systems, and it provides features that can assist a project manager by tracking changes to a project over time.
CVS can be used in many environments for many purposes. It is used for maintaining configuration files, mail aliases, source code, FAQ files, art, music, articles, essays, and books. Some system administrators keep everything in the /etc directory under CVS in order to track system configuration changes over time. CVS is also used to store and automatically publish content to web sites and FTP servers.
CVS follows the Unix ethos of small programs doing what they do well. The RCS (Revision Control System) program handles revision control of single files, so CVS uses RCS to store file data. CVS adds features to RCS, most notably the abilities to work over collections of files, and to work out of a repository that may be local or remote.
Version control is the process of recording and retrieving changes in a project. A version control system can enable you to retrieve an old version to fix bugs or update features, branch development to allow the project to progress along multiple tracks simultaneously, and generate reports that show the changes between any two arbitrary stages of a project.
Most version control systems store notes with each change, and many provide tools that allow a project leader to analyze the changes. Most also include the ability to retrieve differences between arbitrary versions of files, which makes it easier to create patches or locate bugs.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is a Versioning System?
Version control is the process of recording and retrieving changes in a project. A version control system can enable you to retrieve an old version to fix bugs or update features, branch development to allow the project to progress along multiple tracks simultaneously, and generate reports that show the changes between any two arbitrary stages of a project.
Most version control systems store notes with each change, and many provide tools that allow a project leader to analyze the changes. Most also include the ability to retrieve differences between arbitrary versions of files, which makes it easier to create patches or locate bugs.
The benefits of a version control system such as CVS include:
  • Any stored revision of a file can be retrieved to be viewed or changed.
  • The differences between any two revisions can be displayed.
  • Patches can be created automatically.
  • Multiple developers can work simultaneously on the same project or file without loss of data.
  • The project can be branched to allow simultaneous development along varied tracks. These branches can be merged back into the main line of development.
  • Distributed development is supported across large or small networks. (CVS offers a variety of authentication mechanisms.)
Using version control for a project requires some extra work on an ongoing basis. In addition, previous versions of files, or records of changes to the various files in a project, occupy disk space that you might otherwise use for something else. However, the features that a good version control system makes available are well worth the investment of time and disk space. For example, without version control, project backups typically are timestamped copies of an entire project, hopefully stored together in a logical fashion. Version control provides organized storage and retrieval of the complete record of project changes, rather than whichever copies someone gets a chance to make.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
CVS in the Field
CVS records file changes during a project's development. Project files are added to the repository as they are created, and developers check out a personal sandbox — a personal copy of the project's files — to work from. Each developer works in her own sandbox and regularly commits her changes to the repository. Developers also update the contents of their sandboxes regularly to ensure that changes to the repository are reflected in each sandbox.
The term project can take on many different meanings. The stereotypical CVS project is a programming project in which files contain source code for the various programs written as part of the project. But that's a narrow view of what a CVS project can be. CVS can be used in many other settings as well, as the next few sections demonstrate.
CVS can store configuration files, mail aliases, domain records, and other files for which changes should be tracked. Import the files (or all of /etc) into a repository and require administrators to check them out into a sandbox to make changes. Commit the files back to the repository and export the changes to the server. If the changes fail, rolling back to the previous state is easy.
Multiple servers with varied but similar configurations can be maintained using different branches of the same files. Changes to any given branch can be merged into other branches selectively.
Every change made through CVS is recorded in a file history, along with the username of the person making the change, the date the change was made, and any notes recorded with the change. All this information can help, for example, when trying to spot which change to which configuration file broke the mail server.
Both the CVS server and the client run on all Unix and Linux operating systems. Third-party graphical clients are available for Unix, Linux, Windows, and Macintosh systems, and for the Java runtime environment. The CVSNT CVS server is available for Windows NT or later. This makes CVS particularly useful for cross-platform environments.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: CVS Quickstart Guide
To help you get up to speed quickly using CVS, this chapter explains the most common CVS operations. The commands and examples in this chapter are based on standard situations and cover only the most common options. Future chapters go further in depth on each topic covered in this chapter.
The examples and instructions in this chapter are based on the Unix/Linux command-line CVS client. Most graphical clients use the CVS command names for their menu options and buttons, so if you're using a graphical client you should be able to follow this chapter reasonably easily. Graphical clients and clients for operating systems other than Unix/Linux are described in Appendix A.
You may not need to read all of this chapter; follow these guidelines:
  • If you're working on an existing project that is already stored in CVS, skip the early sections and start at Section 2.5.
  • If CVS is already installed and running, with a repository available for your project, go straight to Section 2.3.
If you're not sure whether CVS is already installed and running, read the first part of Section 2.1; it tells you how to check. If you're uncertain about having a repository, try searching for the directory CVSROOT . The repository root is then the directory that CVSROOT is in. The other directories in the top level of the repository are CVS projects.
CVS is client/server software that runs on Unix and Linux platforms. When you install CVS on a Unix/Linux server, you automatically get both server and client software. To access CVS across the network from any Unix/Linux machine, simply install CVS on the machine in question. The server and client software are one and the same.
CVS is available from http://www.cvsgui.org. It is also available as an installation package from many GNU/Linux distributions, including Debian, Red Hat, and SuSE.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing CVS
CVS is client/server software that runs on Unix and Linux platforms. When you install CVS on a Unix/Linux server, you automatically get both server and client software. To access CVS across the network from any Unix/Linux machine, simply install CVS on the machine in question. The server and client software are one and the same.
CVS is available from http://www.cvsgui.org. It is also available as an installation package from many GNU/Linux distributions, including Debian, Red Hat, and SuSE.
If you prefer GUI clients, I recommend a visit to http://www.wincvs.org. There you'll find gCVS, WinCVS, and MacCVS, which are GUI clients for Unix and GNU/Linux, Windows, and Macintosh (pre-OS X), respectively.
If you are a Macintosh user running OS X, you can install the standard Unix CVS server and client.
A Windows-compatible CVS server is available at http://www.cvsnt.org. This server is not identical with the Unix server, but the differences are clearly listed in the FAQ and an installation guide is available on the web site.
If you plan to use the Secure Shell (SSH) protocol to establish secure connections between CVS clients and CVS servers, you'll need to install compatible versions of SSH on your client and server machines. For clients, you may need to find a version of SSH that can be used from the command line. See Section 2.4 for more information on this topic.
The OpenSSH web site (http://www.openssh.com) is a good starting point for information on SSH and SSH clients. You may also want to read SSH, The Secure Shell: The Definitive Guide (O'Reilly) by Daniel J. Barrett, Ph.D. and Richard Silverman. For more than you ever wanted to know, check the SSH FAQ at http://www.employees.org/~satch/ssh/faq/. The Google list of SSH documentation is at http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Documentation/.
Most Unix and Linux systems have an SSH client installed as part of the standard set of programs. Mac OS X also has an SSH client preinstalled. If it is not installed automatically, an SSH client is usually available in your distribution as an optional program.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Building Your First Repository
CVS relies on a file-based database called the CVS repository. The repository needs to be hosted on a machine with sufficient disk space to store your files and all the change data for your projects. The repository should be accessible to all the users from their workstations.
If the repository is on a remote computer, I recommend that users access the repository via SSH. Ensure that the server is running an SSH server and the workstations have a compatible SSH client. For more information on remote repositories and SSH, see Section 2.4 later in this chapter. Chapter 8 contains a full discussion of remote repositories.
For any one project, ensure there is enough disk space for three times the expected final size of that project. If you intend to store binary files, multiply by at least five. After your first project, you'll have a feel for how much space to allow.
A repository can store many projects. If you are creating a repository that may be required to handle several projects of unknown size, estimate what you can and ensure you can add more room later.
A CVS repository is user data, and it should be on a partition that is backed up and won't shut down the machine if it gets full. Repositories are often stored in /cvsroot, /var/lib/cvsroot, /home/cvsroot, or /usr/local/cvsroot. According to the Filesystem Heirarchy Standard (available at http://www.pathname.com/fhs/), the preferred location for a repository is /var/lib/cvsroot.
Another possibility is to put the repository in /cvsroot. This is easiest for users to remember.
Example 2-5 illustrates the steps involved in creating a repository. First, create the repository root directory on the CVS server. In Example 2-5, I create the /var/lib/cvsroot directory.
Example 2-5. Creating a repository
$ mkdir /var/lib/cvsroot
$ chgrp anthill /var/lib/cvsroot
$ ls -la /home
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Importing Projects
When you have created a new repository, you may want to import a project — a related collection of files stored under a single directory. It is possible to store a single file under CVS, but it will also be a project and you will need to store it under its own project directory. CVS needs to be able to create a subdirectory to store metadata about the project.
Before loading a project into CVS, consider the project's structure. If you move a file after it has been created and stored in CVS, CVS treats it as two files: the original in the original location and the new file in the new location. The history of the file is then split into two parts. Decide how you want to structure the source files for a project before you import it into CVS.
If you will eventually want to distribute your project's files across several unrelated directories, it is best to develop the project under a single root directory, then distribute the files as part of the installation script. Chapter 7 describes the issue of project structure in more detail.
If you have binary files or other files that are not plain text, please see the information on binary files in Chapter 3 before adding them to the repository.
Create your initial project directory structure, possibly in /tmp. Once the project is stored in CVS, this initial version can be removed. You won't be using it as a sandbox and the project is duplicated in CVS, so there's no reason to retain it.
Once you have your initial structure, add any initial files you want. Change into the root directory of the project. Then, from within that directory, import the project with the command:
cvs -d repository_path import name_of_project vendor_tag release_tag
            
If the repository is on the local machine, use the full path of the repository directory for the repository path. If the repository is on a remote server, see Section 2.4 for help on specifying the repository path.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Accessing Remote Repositories
There are several ways to access a remote repository. This quickstart guide uses the ext method with the SSH protocol, but if your system administrator gives you different instructions, follow those. Chapter 8 explains the use of remote repositories in detail. The ext and SSH approach uses the ext repository access method, with an SSH client as the program that performs the connection. These are also explained in Chapter 8.
Your first step, at least the first step that I recommend, is to install SSH on the client machine. Make sure that the client-end SSH protocol matches the server's SSH protocol. Set up SSH keys or passwords and test the connection. Using SSH enables you to create a secure connection to the remote repository.
Next, if you're on a Unix or Linux system, set the CVS_RSH environment variable on your client machine to the name of your SSH program, usually ssh or ssh2. Graphical clients that support the ext and SSH approach may have ssh as an authentication type option in the dialog that requests the repository path. Check the documentation for your client.
In WinCVS and gCVS, call up the Preferences dialog under the Admin menu and select "ssh" as the Authentication method under the General tab. In MacCVSX (for OS X), ssh is available under the MacCVSX menu. MacCVS for OS 9 and earlier versions do not support SSH as a standard option. Instead, you can make use of SSH from MacCVS via port tunnelling, as described in Appendix A.
If the repository is on the same machine as the client, the repository path is simply the full path to the repository's root directory. On a remote machine, the repository path takes the form:
[:method:][[[user][:password]@]hostname[:[port]]]/path
            
The method is the protocol used to connect to the repository. To use SSH, use ext as the method. Include the username and the @ if the username on the server differs from the username on the client. If you don't have an SSH key on the host, the system asks you for a password when you try to log in.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Checking Out Files
CVS stores projects and files in a central repository, but you work from a working copy, called a sandbox , in your local directories. You create that sandbox with cvs checkout .
CVS creates the sandbox as a subdirectory of your current working directory. I like to create a directory to contain all my CVS sandboxes, and I use ~/cvs. From whichever directory you want a sandbox created in, run the command:
cvs -d repository_path checkout project_name
            
This command checks out all files for the named project. If your repository is on the local machine, the repository path is the full pathname of the CVS repository. If your repository is on a remote server, see the earlier Section 2.4. Example 2-10 shows a local checkout.
Example 2-10. Local repository checkout
$ mkdir ~/cvs
$ cd ~/cvs
$ cvs -d /var/lib/cvsroot checkout example
cvs checkout: Updating example
U example/file1
U example/file2
The checkout command puts a copy of the project's files and subdirectories into a directory named for the project, created in the current working directory. It also puts some administrative files of its own in a subdirectory of the project directory, called CVS.
You can check out an individual file or subdirectory of a project by replacing project_name with the pathname to the file or directory, from the project's root directory. See Chapter 3 for more information.
CVS stores the repository path as part of the sandbox, so you should never again need to use -d repository_path in commands executed within that sandbox.
If you are checking out a sandbox from a remote repository, the repository path is slightly different than the path shown in the previous example. Example 2-11 shows a checkout from a remote repository.
Example 2-11. Remote repository checkout
$ cvs -d :ext:cvs:/home/cvs checkout cvsbook
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Committing Changes
Once you've checked out project files into a sandbox, you can edit those files with your preferred editor. Changes are not synchronized with the repository until you run the cvs commit command. This command is best run from the root directory of your sandbox, and it must be run from within the sandbox.
Commit to the repository frequently. Rules of thumb for when to commit include "every time the code compiles cleanly" and "every day before lunch and before you leave."
In programming projects with several developers, try to avoid committing code that doesn't compile.
When you commit, CVS examines each directory and subdirectory below the current working directory. It searches for files that it is tracking that have changed, and commits all changes to the repository. See Example 2-12 for an example of committing files. Remember, the repository path is stored in the sandbox, so you don't need to specify the path explicitly in your cvs commit command.
Example 2-12. Committing files
$ cd ~/cvs/example
$ cvs commit
cvs commit: Examining .
If your repository is not on the local machine and your repository server doesn't have your SSH public key, CVS will ask for a password for the remote machine. If the server has the public key, your SSH client can use the private key to authenticate you.
If any files have been changed, CVS opens an editor to allow you to record a change message. By default, the editor is vi, just as when importing a project. Chapter 3 gives instructions on changing your editor.
I strongly recommend meaningful change notes. If you're trying to do a rollback and all you have are messages that say "fixed a few bugs," you won't know which revision to roll back to. See Example 2-13 for an example of a good change note.
Example 2-13. Enter a commit message
CVS:------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with 'CVS:' are removed automatically
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Updating Sandboxes
The cvs update command checks your sandbox against the repository and downloads any changed files to the sandbox. It complements the cvs commit command, which uploads changes from the sandbox to the repository. Use the -d command option to download new directories as well. Example 2-16 shows the use of cvs update.
Example 2-16. Updating the sandbox
$ cvs update -d
cvs update: Updating .
U file2 
cvs update: Updating directory
$ ls
CVS  directory  file1     file2
As with committing, you should not have to specify the repository; it should be stored in the special CVS subdirectory in the sandbox. You must run cvs update from within the sandbox, and it is best to run it from the root directory of the sandbox to ensure that it checks all the subdirectories.
Note that -d means two different things, depending on where it is in the command. Recall that CVS commands take the form:
 cvs [cvs-options] command [command-options]
As a CVS option, -d defines the directory path. As a command option to the update command, -d downloads directories and files. This is explained more in Chapter 3.
As the update command runs, it generates a list of files that are modified. To the immediate left of each filename, you will see a single uppercase letter. Those letters report the status of each file listed, and they have the following meanings:
U filename
Updated successfully. A newer version in the repository has replaced your sandbox version.
A filename
Marked for addition but not yet added to the repository (need to run a cvs commit).
R filename
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Adding Files
To add a file to a project in the repository, first create the file in your sandbox. Be sure to consider your project's structure and place the file in the correct directory. Then, issue the following command from the sandbox directory containing the file:
cvs add filename
            
This command marks the new file for inclusion in the repository. Directories are added with the same command. Files within a directory can't be added until the directory itself is added. A file is only marked for addition when you run cvs add ; it is actually added to the repository when the next cvs commit is run. A directory is added to the repository immediately. Example 2-19 shows a file being created and added to the repository. Remember, the file is not actually stored in the repository until the cvs commit command is run.
Example 2-19. Adding files
$ touch file3
$ cvs add file3
cvs add: scheduling file `file3' for addition
cvs add: use 'cvs commit' to add this file permanently
$ cvs commit
...
Log message editor opens
...
RCS file: /var/lib/cvsroot/example/file3,v
done
Checking in file3;
/var/lib/cvsroot/example/file3,v  <--  file3
initial revision: 1.1
done
If you have binary files or other files that are not plain text, please see the section on binary files in Chapter 3 before adding them to the repository. These files should be added with the -kb command option.
As with committing, an editor window will open asking you to enter a log message describing the files to be added.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Removing Files
To remove a file from the repository, first remove the file from the sandbox directory; then run the following command from the sandbox directory that contained the file:
cvs remove filename
            
The deletion does not take effect until the next cvs commit command is run; the file remains in the repository until then.
Example 2-20 shows a deletion. After the cvs commit is run, CVS doesn't remove the file entirely; it puts it in a special subdirectory in the repository called Attic . This saves the file history and enables the file to be returned to the repository later.
CVS opens an editor so you can record the reason for the file deletion, as it does when you commit changes.
Example 2-20. Removing a file
$ rm file3
$ cvs remove file3
cvs remove: scheduling `file3' for removal
cvs remove: use 'cvs commit' to remove this file permanently
$ cvs commit
...
Log message editor opens
...
Removing file3;" 9L, 308C written
/var/lib/cvsroot/example/file3,v  <--  file3
new revision: delete; previous revision: 1.1
done
CVS does not remove directories from the repository, because doing so would break the change tracking. Use the -P flag to cvs checkout and cvs update to avoid empty directories in your sandbox.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Quick Tips for Success
CVS is a tool for improving project development and system maintainence. Like all tools, there are ways to make your use of it more effective. Here are some tricks for using CVS well:
  • Synchronize the clocks of computers sharing a repository to the same universal time. CVS relies on file timestamps to determine which files have changed.
  • Give each developer his own sandbox, and communicate all file changes through CVS. This maintains change tracking and prevents developers from irretrievably overwriting each other's work.
  • Update frequently, at least before starting work every day, to keep your sandbox current.
  • Commit frequently to keep your repository current. Programmers typically update every time their code compiles cleanly; other people may commit after completing each block of work.
  • Programming teams: use build-management tools and ensure that all files in the build are committed to the repository. Ensure that builds for testing or release come from the repository rather than a sandbox, but allow sandbox builds for programmers to do pre-alpha tests.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Basic Use of CVS
This chapter provides a thorough discussion of the most critical CVS commands and topics. It is designed for end users who will not have to administrate the repository and who will not have to make changes that affect the entire project.
The commands explained in this chapter include checkout, commit, update, release, add, remove, and status. Other topics in this chapter include an explanation of sandboxes, merging, conflicts, binary and special files, keywords, editing files in CVS, and the CVS command syntax.
This chapter assumes that you have installed CVS, set up a repository, and created a project. Instructions for these tasks are in Chapter 2. Chapter 2 also touches on many of the commands in this chapter, but this chapter provides a full explanation of their uses.
CVS stores project data in a repository, but you don't work directly from the repository. You work from a sandbox. A sandbox may be on the same machine as the repository, on a machine on the same local network, or on a machine connected through the Internet or another wide-area network. Figure 3-1 illustrates some of these possibilities.
Figure 3-1: Repository and sandboxes
The sandbox is a directory on a client machine, that contains a copy of a project's files. Sandboxes are usually within a user's home directory. All of a given project's files should be underneath the top directory, but the files may be in as many subdirectories as are desired. Every subdirectory contains a special CVS directory, with metadata files.
If you want to install your project over several directories or outside of your home directory, that should be part of your build or installation script. The sandbox is a place for making changes; it's not a place for running the project.
Sandboxes and repositories do not exist on a one-to-one basis; many sandboxes may share the same repository. To ensure that the repository does not become unstable, the repository locks files that are being changed. (The locks are actually over entire directories.) Occasionally, a developer will get a warning message that the repository is waiting on a lock, as shown in Example 3-1.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
General Information
CVS stores project data in a repository, but you don't work directly from the repository. You work from a sandbox. A sandbox may be on the same machine as the repository, on a machine on the same local network, or on a machine connected through the Internet or another wide-area network. Figure 3-1 illustrates some of these possibilities.
Figure 3-1: Repository and sandboxes
The sandbox is a directory on a client machine, that contains a copy of a project's files. Sandboxes are usually within a user's home directory. All of a given project's files should be underneath the top directory, but the files may be in as many subdirectories as are desired. Every subdirectory contains a special CVS directory, with metadata files.
If you want to install your project over several directories or outside of your home directory, that should be part of your build or installation script. The sandbox is a place for making changes; it's not a place for running the project.
Sandboxes and repositories do not exist on a one-to-one basis; many sandboxes may share the same repository. To ensure that the repository does not become unstable, the repository locks files that are being changed. (The locks are actually over entire directories.) Occasionally, a developer will get a warning message that the repository is waiting on a lock, as shown in Example 3-1.
Example 3-1. Lock message
cvs server: [23:20:43] waiting for jenn's lock in /var/lib/cvs/wizzard/src
This message indicates that CVS is waiting on the other developer's lock in the specified directory. If a CVS process is killed before it's finished tidying up, a lock file may be created and not cleared. If CVS seems to be taking an inordinate amount of time to clear a lock, your repository administrator can clear it manually. Chapter 6 provides instructions and an example of how to do so.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Sandboxes and Repositories
A sandbox is a local copy of a project's files, used to make changes and test work. Each developer should work from her own sandbox on a computer that is convenient to her.
The CVS repository contains the master copies of a project's files and their full histories. The repository may be on the same machine as the sandbox or on a remote machine accessed across a network. The repository is explained more fully in Chapter 6.
Every directory in the sandbox contains a CVS subdirectory. This directory has several files; the most important are Root, Repository, and Entries. The Root file contains the path to the sandbox's repository, the Repository file contains the subpath within the repository that leads to the directory in question, and the Entries file holds metadata about the files in the directory. The CVS subdirectory is explained more fully in Chapter 6.
Files lose their permissions when they are transferred to the repository. CVS normally will check out files with read and write permissions, but it can be configured to check them out as read-only. The person who checks a file out into the sandbox becomes the file's owner.
CVS works on many operating systems, each of which has its own way of recording ownership of files. The repository might not be on the same machine or have the same operating system as the sandbox. These circumstances may cause files to lose their ownerships and group memberships when the files are transferred to the repository, especially if the owning user does not exist on the repository machine. If the sandbox is connected to the repository through a proxy or network tunnel, the existence of appropriate users and groups on intermediate machines can also affect the ownership of files.
Group ownership of files in the repository is important, because CVS prevents users from checking out files they do not have read access to. Chapter 6 explains ownership and security issues with CVS.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Committing Changes to the Repository
Files are edited in the sandbox, but changes to the sandbox have no effect on the repository until they are committed. The cvs commit command uploads changes from the sandbox to the repository. After determining which files need to be changed in the repository, cvs commit opens an editor and expects you to enter a log message.
Section 3.1.3 earlier in this chapter explains how to change the default editor.
The syntax of cvs commit is:
 cvs [cvs-options] commit [command-options] [filename]
cvs commit has only a few options:
-l
Perform a local, nonrecursive commit operation on the current working directory only.
-R
Perform a recursive commit operation on all subdirectories, as well as the current directory (default).
-m message
Provide a log message.
-F filename
Provide a log message from the specified file.
-r revision
Set an updated revision number (not recommended for novice users).
Example 3-3 shows a typical cvs commit. The vertical ellipsis denotes the point at which CVS normally calls the editor. Example 3-4 shows the default text displayed in the editor and the log message for this commit.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Checking File Status
The cvs status command is a quick way to determine which files are up-to-date and which need to be committed or merged.
Files that have not been added to the repository are prefixed with a question mark (?). Files stored in CVS are shown with the filename, the current status, the working (or sandbox) revision, the revision currently stored in the repository and its location in the repository, and the sticky state of the file. Stickiness is explained in Chapter 4.
The syntax of cvs status is:
 cvs [cvs-options] status [command-options] [filename]
The status command has only three options:
-l
Perform local, nonrecursive operation on this directory only.
-R
Perform recursive operation on all subdirectories, as well as the current directory (default).
-v
Use verbose mode (display information about tags as well).
Example 3-5 shows the CVS status report for the wizzard.h file.
Example 3-5. Output from the cvs status command
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  = =  =
File: wizzard.h             Status: Up-to-date
   
   Working revision:    1.5
   Repository revision: 1.5     /var/lib/cvs/wizzard/src/wizzard.h,v
   Sticky Tag:          (none)
   Sticky Date:         (none)
   Sticky Options:      (none)
A file may be in one of the following states:
Up-to-date
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Updating the Sandbox Files from the Repository
The cvs commit command uploads changes from the sandbox to the repository; cvs update downloads changes from the repository to the sandbox. The two commands complement each other, and you need to call both to keep the sandbox synchronized with the repository. Use cvs commit when you have changed sandbox files since your last commit; use cvs update when you know that (or wish to check whether) the repository has been changed since you last updated.
cvs update attempts to preserve any changes you have made to your sandbox since you last synchronized it with the repository. These changes will be merged into the files retrieved from the repository. If you intend to overwrite your sandbox files with a clean repository copy, use the -C (clean) option in conjunction with any other options. Most often, you will use -C when you want to discard changes, but you can also use the -r (retrieve by revision), -D (retrieve by date), or -A (clear sticky tags) options.
Example 3-6 shows output from cvs update executed with the -d option. The -d option instructs CVS to download new directories from the repository to the sandbox.
Example 3-6. Using cvs update
bash-2.05a$ cvs update -d
cvs server: Updating .
cvs server: Updating doc
cvs server: Updating doc/design
U doc/design/Analysis.rtf
U doc/design/Specification.rtf
cvs server: Updating doc/plan
U doc/plan/Schedule.rtf
cvs server: Updating lib
cvs server: Updating man
cvs server: Updating src
M src/wizzard.h
cvs update displays symbols next to each file it downloads. The symbols report file status, similar to those reported by cvs status. You'll see the following symbols in cvs update command output:
A filename
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Adding Files to the Repository
Use cvs add to add a file or directory to the repository. Using cvs add on a file marks the file as needing to be added when cvs commit is run. Running cvs add on a directory adds the directory to the repository and the CVS subdirectory to the directory.
The Attic and CVS directories are special directories that CVS uses for its own purposes. Do not make a file or directory with these names.
If you attempt to commit and get an error message that includes *PANIC* administration files missing, you may have created a file or directory named CVS. This message means that CVS could not find the Repository file in the CVS subdirectory of the sandbox directory it is trying to commit.
You can use cvs remove to remove a file that has been added but not committed. This removes the marking in the CVS subdirectory and doesn't record the aborted addition in the repository's history. Similarly, you can use cvs add to abort a file removal; it will resurrect the file without recording the aborted removal.
The file or directory to be added must exist within the sandbox, and a directory must not contain a file or subdirectory named CVS.
Files and directories are case-sensitive in the repository. If you are using a CVS client or operating system that is not case-sensitive, you may encounter problems. Avoid using file or directory names that would be the same if case were not an issue.
In the process of adding a file, CVS strips trailing slashes and any special CVS files from the arguments, then checks for name conflicts (including some case-comparison testing). If CVS detects a name conflict, it notifies the user and does not add the file or directory.
cvs add uses the following syntax:
cvs [cvs-options] add [command-options] filename
            
The available options are -k, followed by any of the keyword flags, and
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Removing Files from the Repository
The cvs remove command is used to mark a file as removed in the repository. The file isn't actually removed from the repository; it simply is stored in a special directory called Attic, so that its earlier revisions can be recalled. The file is no longer sent to sandboxes, and it is removed from existing sandboxes at the next cvs update, which displays the message cvs server: filename is no longer in the repository.
A removal must be committed before it affects the repository. If you notice that you accidentally removed a file you need (before you run cvs commit), you can use cvs add to undo the removal and then use cvs update to retrieve the removed file. This process leaves no record in the repository. Similarly, if a file has been added but not committed, cvs remove undoes the addition and leaves no record in the repository.
If someone else modifies a removed file before the removal is committed, the commit will fail and report a conflict. Resolve the conflict by unremoving the file with cvs add, checking the changes with cvs update or cvs diff, and removing the file again if desired. I strongly recommend speaking with the person who modified the file before you resolve such a conflict, lest you remove a file that should be retained.
To use cvs remove on a file, the file must not exist in the sandbox or you must call the cvs remove command with -f. Usually, I delete the file from the sandbox before running cvs remove.
The syntax for cvs remove is:
cvs [cvs-options] remove [command-options] filename
            
cvs remove has the following options:
-f
Delete the file from the sandbox.
-l
Perform a local, nonrecursive operation on this directory only.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Moving Files or Directories
There is no CVS command designed specifically to move a file or file directory. In fact, CVS's design doesn't accomodate such moves. However, you can work around this limitation using a combination of CVS commands, or by altering the repository using operating-system commands. Moving files can make project history difficult to track, because then a file's history is recorded across two different files in different locations. Minimize this potential source of confusion by recording the new and old locations with meaningful log messages.
To rename a file or directory at the operating-system level, move it from the old filename to the new filename. For example, use the Unix mv command.
The recommended way to move a file is to use cvs remove followed by cvs add, with messages that state where the file was moved from and to. This method preserves the file's history and allows reversion to earlier versions of the project in its old location. However, the messages stored with the add and remove commands are the only record of the move. Example 3-19 shows this method being used to rename the wizzard.h file.
Example 3-19. Renaming a file
bash-2.05a$ mv wizzard.h config.h
bash-2.05a$ cvs remove wizzard.h
cvs server: scheduling `wizzard.h' for removal
cvs server: use 'cvs commit' to remove this file permanently
bash-2.05a$ cvs add config.h
cvs server: scheduling file `config.h' for addition
cvs server: use 'cvs commit' to add this file permanently
bash-2.05a$ cvs commit
.
.
.
Moving src/wizzard.h to src/config.h
CVS: ---------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with `CVS:' are removed automatically
CVS: 
CVS: Committing in .
CVS: 
CVS: Added Files:
CVS:  config.h 
CVS: Removed Files:
CVS:  wizzard.h 
CVS: ---------------------------------------------------------------------
.
.
.
RCS file: /var/lib/cvs/wizzard/src/config.h,v
done
Checking in config.h;
/var/lib/cvs/wizzard/src/config.h,v  <--  config.h
initial revision: 1.1
done
Removing wizzard.h;
/var/lib/cvs/wizzard/src/wizzard.h,v  <--  wizzard.h
new revision: delete; previous revision: 1.5
done
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Releasing a Sandbox
The cvs release command should be used before you delete a sandbox. CVS first checks whether there are any files with uncommitted changes; then, if all is well, CVS runs cvs unedit on each file to signal that you no longer intend to edit the files, and writes to the history file in the repository to state that the sandbox was released. CVS also reports on files and directories that are not currently stored in the repository.
If there are uncommitted changes, CVS alerts you to the changes and does not release the sandbox. You can use cvs commit to commit the changes, remove the changed files manually, or use cvs update -A to revert to a state where you can release the sandbox (and lose the changed data).
It's not strictly necessary to use cvs release before deleting a sandbox. You can delete a sandbox with no effect on the repository. However, if you get into the habit of using cvs release, you'll remember to use it the one time you do need to run an unedit or when you have made an uncommitted but important change.
The syntax for cvs release is:
cvs [cvs-options] release [-d] directory
            
The only option to cvs release is -d, which deletes the sandbox after checking it for uncommitted changes. You can use cvs release on an entire sandbox or on a subdirectory within the sandbox.
When you execute cvs release, you must specify a directory, but you can use a dot (.) to indicate your current working directory. Example 3-20 shows cvs release being used to release the wizzard sandbox. Note that a dot is used to specify the current working directory as the sandbox to release.
Example 3-20. Using cvs release
bash-2.05a$ cvs release .
cvs server: warning: src/wizzard.h is not (any longer) pertinent
? src/test
? src/test.c
U src/config.h
U src/main.c
You have [0] altered files in this repository.
Are you sure you want to release directory `.': n
** `release' aborted by user choice.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Keywords
CVS recognizes keywords that can be included in any source file other than a binary file. When CVS finds a keyword in a file it is checking out, it expands the keyword to provide metadata about the latest revision of the file. CVS keywords take the following form:
$Keyword$
Example 3-21 shows a file that includes CVS keywords.
Example 3-21. CVS keywords
# Makefile for the Wizzard project
# First created by J Vesperman, 1 September 2002
#
# Current revision $Revision: 1.6 $
# On branch $Name:  $
# Latest change by $Author: chodacki $ on $Date: 2004/04/16 16:15:52 $
   
# Initial declarations
CC=gcc
SUBDIRS = man doc src lib
   
# Declaring phony targets
.PHONY: all clean install
   
all: wizzard
      echo "all: make complete"
   
clean:
      rm -f src/*.o
      rm -f wizzard
      echo "clean: make complete"
   
.
.
.
   
# Log record for Makefile changes:
# $Log: ch03.xml,v $
# Revision 1.6  2004/04/16 16:15:52  chodacki
# sfcleanup fixes
#
# Revision 1.5  2003/07/11 20:00:23  madd
# madd final SC edits
#
# Revision 1.4  2003/07/09 21:31:56  madd
# madd SC edits
#
# Revision 1.3  2003/07/07 21:52:50  madd
# madd SC edits
#
# Revision 1.2  2003/06/27 21:47:43  madd
# madd R2 conversion edits
#
# Revision 1.1  2003/06/26 22:22:10  madd
# Initial revision
#
Example 3-21 shows a makefile. The keywords are expanded when the file is checked out or updated. Example 3-22 shows the resulting expansions.
Example 3-22. Expanded keywords
# Current revision $Revision: 1.6 $
# On branch $Name:  $
# Latest change by $Author: chodacki $ on $Date: 2004/04/16 16:15:52 $
   
# Initial declarations
CC=gcc
SUBDIRS = man doc src lib
   
.
.
.
   
# Log record for Makefile changes:
# $Log: ch03.xml,v $
# Revision 1.6  2004/04/16 16:15:52  chodacki
# sfcleanup fixes
#
# Revision 1.5  2003/07/11 20:00:23  madd
# madd final SC edits
#
# Revision 1.4  2003/07/09 21:31:56  madd
# madd SC edits
#
# Revision 1.3  2003/07/07 21:52:50  madd
# madd SC edits
#
# Revision 1.2  2003/06/27 21:47:43  madd
# madd R2 conversion edits
#
# Revision 1.1  2003/06/26 22:22:10  madd
# Initial revision
#
# Revision 1.2  2002/09/01 06:57:23  jenn
# Initial code in the Makefile.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Binary Files and Wrappers
The default CVS method of handling file conflicts works well for text files, because CVS can determine which lines have changed and add or remove them as appropriate. It doesn't work well on binary files, because such files are not usually built around lines of text separated by carriage returns.
Some files with textual content are not actually text files. Files such as those created by Microsoft Word or OpenOffice should be flagged as binary, because line-by-line merging and keyword expansion could damage the saved data.
CVS doesn't work for device files, symbolic links, or other files that cannot be modified and moved. Rather than trying to store these files in CVS, include the commands to create or connect them in your build scripts.
For binary files, CVS uses a different method of conflict resolution. The two methods CVS has available are MERGE and COPY. MERGE is the default CVS method. COPY instructs CVS to provide the user with both versions of the file if there is a conflict, so the user can blend the changes manually and recommit.
Binary files should be added to CVS using the -kb command option to cvs add. If the expansion mode is not set at the time the file is added, the -kb command option to cvs admin will set the mode retroactively. This informs CVS not to expand keywords, not to modify line endings, and to use the COPY method of conflict resolution. Example 3-23 shows the use of these command options.
Example 3-23. Setting keyword expansion for binary files
bash-2.05a$ cvs add -kb Requirements.doc 
cvs server: scheduling file `Requirements.doc' for addition
cvs server: use 'cvs commit' to add this file permanently
bash-2.05a$ cvs add AcceptanceTest.doc 
cvs server: scheduling file `AcceptanceTest.doc' for addition
cvs server: use 'cvs commit' to add this file permanently
bash-2.05a$ 
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Specifying Default Command Options
If you find yourself regularly using the same options with a command, you can use the .cvsrc file to set default options and minimize your typing. If the .cvsrc file is in your home directory on your client machine, CVS will read the file, look for the CVS command you are currently running, and will run the command with the options specified for that command in the file. To temporarily avoid parsing the .cvsrc file, use the -f CVS option.