Making Changes in the CVS

In this conclusion to a three-part series on the Concurrent Versions System (CVS), you’ll learn how to commit changes and add and remove files. This article is excerpted from chapter two of Essential CVS, Second Edition, written by Jennifer Vesperman (O’Reilly; ISBN: 0596527039). Copyright © 2007 O’Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O’Reilly Media.

Committing Changes


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.” Speak to your project manager about the preferred working style, or read Chapter 7 for ideas.

In programming projects with several developers, try to avoid committing code that doesn’t compile, unless your project manager tells you that your project is using a different working style.

When you commit, CVS examines each directory and subdirectory under 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 that 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 asks 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. It’s much easier to use CVS if the server has the public key.

Keeping a public key on the server is a security decision: it’s much more convenient to use CVS if you don’t have to keep typing in your password, but it also means that if an intruder has access to your shell, he can gain access to the data stored in the repository. I keep my desktop’s public key on the server, but not my laptop’s. It’s always possible that I’ll lose my laptop, so I don’t want it to have password-free access into our network. The desktop computer is a little bit harder to lose.

SSH is a system of authentication and encryption that relies on a public key and a private key. Only you (or your sandbox computer) should ever know your private key. Anyone (or any computer) can be told your public key, which they use to encrypt messages specifically for you. Your SSH documentation should include instructions for making and storing your private and public keys.


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

Corrected bug #35. ‘hello’ was misspelled as ‘helo’.
CVS: Enter Log. Lines beginning with ‘CVS:’ are removed automatically
CVS: Committing in .
CVS: Modified Files:
CVS:  file1


Example 2-14. Completing the commit

Checking in file1;
/var/lib/cvsroot/example/file1,v <–  file1 new revision: 1.2; previous revision: 1.1 done

Figure 2-7 shows the same commit in gCVS.

If a revision in the repository is more recent than the revision the sandbox was based on, cvs commit fails. Use the cvs update command to merge the changed files; resolve the conflict as shown in the next section, “Updating Sandboxes,” then run cvs commit again. Example 2-15 shows the response to a failed commit.

Figure 2-7.  Committing files in gCVS

Example 2-15. Failed commit response

cvs server: Up-to-date check failed for ‘file2′
cvs [server aborted]: correct above errors first!
cvs commit: saving log message in /tmp/cvst7onmJ

{mospagebreak title=Updating Sandboxes}


Example 2-16. Updating the sandbox

$ cvs update -d
cvs update: Updating .
U file2
cvs update: Updating directory
$ ls
CVS  directory  file1   file2


Note that -d means two different things, depending on where it is in the command. Recall that CVS commands take the following form:

  cvs [cvs-options] command [command-options]

As a CVS option, -d defines the repository path. As a command option to the update command, -d downloads directories that were not previously in the sandbox. This is explained in more detail in Chapter 3.

As the update command runs, it generates a list of files that are modified. To the immediate left of each filename is a single uppercase letter. Those letters report the status of each file listed, and they have the following meanings:

A filename


C filename


M filename

Modified in your working directory. The file in the sandbox is more recent than the repository version, or the sandbox and the repository both had changes that the system could safely merge into your sandbox copy (need to run a cvs commit).

P filename

Patched in the sandbox; similar to U (updated successfully), but in this case CVS sent only the changes, not the entire file.

R filename


U filename


? filename

The file is in your working directory but not in the repository. CVS doesn’t know what to do with it. It’s common to see this marker next to temporary or intermediate files that you haven’t cleaned up.


Figure 2-8 shows the update dialog from gCVS. In the background, at the bottom right, you can see the dialog from a successful update, showing that file1 is modified in the sandbox.

Figure 2-8.  File update with gCVS

If CVS can’t merge a modified file successfully with the copy in the repository, it announces the conflict in the output of cvs update, as shown in Example 2-17. Figure 2-9 shows a conflict in gCVS.

Example 2-17. File conflict

cvs/example$ cvs update
cvs server: Updating .
RCS file: /var/lib/cvsroot/example/file1,v retrieving revision 1.3
retrieving revision 1.4

Merging differences between 1.3 and 1.4 into file1
rcsmerge: warning: conflicts during merge cvs server: conflicts found in file1
C file1

Figure 2-9.  File conflict with gCVS


Example 2-18. Conflict marks

<<<<<<<file 2
This line came from the sandbox.
= = = = = = =
This line came from the repository.
>>>>>>> 1.4

The contents of the original file are stored in .#file.revision in the file’s working directory, and the results of the merge are stored as the original filename.

To resolve the conflict, search the file with the original filename for the pattern of repeated greater-than or less-than symbols. Study the two options for each set of changes, and discuss the changes with the person who committed the previous ver sion of the file. (Use cvs log filename  to find out who committed the previous version; see Chapter 5 for information on cvs log.)

Once you and the previous author have agreed on how the file needs to be changed, edit the file accordingly and remove the conflict markers. Then commit the changed file.

How I Lost Penny’s Changes

The first time I used CVS, I had no idea what I was doing. My coworker sent me to man cvs, which is just a summary of the commands, with no tutorial information. Penny, who I was working with, had never used it either.

We struggled through, until we reached our first conflict. We couldn’t understand why Penny couldn’t commit, and after some time, decided to remove Penny’s existing file and update from the repository. I’m sure we thought CVS must have saved it somehow.

If only we’d updated with Penny’s file still in her sandbox. But we didn’t, and the work she had done was lost.

Penny, if you ever read this, I’m sorry. And now I know what I should have done.

{mospagebreak title=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 that the file is not actually stored in the repository until the cvs commit command is run. Figure 2-10 shows the same file addition in gCVS.

Example 2-19. Adding files

$ touch file3
$ cvs add file3
cvs add: scheduling file `file3′ for addition
$ 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

Figure 2-10.  Adding files with gCVS

If you have binary files or other files that are not plain text, please see the section “Binary Files and Wrappers” in Chapter 3 before adding them to the repository. These files should be added with the -kb command option.

As with committing for other reasons, an editor window will open asking you to enter a log message describing the files to be added.

{mospagebreak title=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


Example 2-20 shows a deletion, and Figure 2-11 shows the same deletion in gCVS. 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 step saves the file history and enables the file to be returned to the repository later.


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


{mospagebreak title=Exporting and Building Projects}

When you’re ready to compile and test a program, to send a book to an editor, or to post a web site to the server, you will want a copy of the project that doesn’t have the CVS administrative files. You could use cvs checkout and remove the CVS subdirectories, but that’s tedious and unnecessary. Use cvs export instead. It works exactly the same as checkout, but doesn’t create the administrative files necessary for a sandbox.

If you need to compile a program, distribute the project’s files, or otherwise modify the results of the export, I recommend using a build tool such as make on the exported project. Unfortunately, the use of make is beyond the scope of this book, but

Figure 2-11.  Removing a file with gCVS

I recommend the article “Introduction to Make” at pub/a/linux/2002/01/31/make_intro.html.

Quick Tips for Success

CVS is a tool for improving project development and system maintenance. Like all tools, there are ways to use it most efficiently:

  • Synchronize the clocks of computers sharing a repository to the same universal time. CVS relies on file timestamps to determine which files have changed. NTP (Network Time Protocol) is a very useful tool for time synchronization.
  • Give each developer his own sandbox, and communicate all file changes through CVS. This method maintains change tracking and prevents developers from irretrievably overwriting each other’s work.
  • Commit frequently to keep your repository current. Programmers typically commit every time their code compiles cleanly; other people may commit after completing each block of work.

chat sex hikayeleri Ensest hikaye