Contributing source code changes with command-line CVS

Contributing your changes into CVS

To commit your changes to a file into the shared repository, type:

cvs commit -m "Type your changes message here" filename

If you do not include a description of your change to the file, you will be prompted to add it by invoking your file editor before CVS can complete the commit action.

To commit your changes to all files in a directory and any subdirectories:

cd top_directory_to_commit
cvs commit -m "Type your change message here"

All commits are logged automatically and posted to the project's cvs mailing list.

Adding files/directories

To add a new file to the CVS repository after you have first created and edited it in your working directory, type:

cvs add filename

Then follow up with the "cvs commit filename" command. If you do not first add the file, CVS does not recognize it.

If you have cvs write permissions, you can add subdirectories to your project's source tree using the "cvs add" command. To move existing files into a new subdirectory you must first copy or move the files to the new location, use the "cvs add" command to add to the repository in the new location and then commit the files using the "cvs commit" command. To remove the files from their previous location, make sure the files are no longer physically in that directory on your local drive, then use the "cvs remove" command and commit using the "cvs commit" command to remove them from the repository.

NOTE: Naming directories for CVS should be done with caution. The CVS repository is accessible by users on varying operating systems, some of which cannot read certain characters in directory names. While .,~, /, \ and other characters may be legal characters for directory names in your operating system, someone else who needs to access your directory may not be able to use your file organization schema. To avoid conflict with other users, you should use only the following characters in your directory names:

a-z, A-Z 0-9 and _(underscore)

Adding other characters will render your directory names unreadable by users on other operating systems.

Working with files

Between checking files out of the project repository and checking them back in, CVS has virtually nothing to do with how files are used in the project environment or build process. That is governed by the project owner and other external factors unique to the project.

When you make changes to existing files, you must edit your working copies of these files in a file editor on your local machine using your file editor of choice. None of the changes you make to your working files has any effect on the project's source repository or on other developers' work until you check in (that is, do a cvs commit) your modified versions of files.

More about "What CVS is not."

About file types

The information provided in this document about CVS commands and actions assumes that the project files you are working with are text files. It is possible to include binary files in version control with CVS, although there are some special issues.

More about Handling binary files in CVS.

Keeping your working files up to date with the repository

If you want to look before you leap, you can get a list of all files in your local directory not up to date with the project repository by using the following command:

cvs -qn update

Files in the affected directory or directories are listed with their current status indicated as follows:

To go ahead and actually perform an update to make your working directory up to sync with the repository, the command is:

cvs update

You can also update individual files by adding the filename to the command.

Or, to include any new directories when updating, do:

cvs update -d

Comparing your working files to the repository

Another way to determine whether all of your working files are in sync with the latest versions in the repository is with the command:

cvstatus

or for status on individual files:

cvs status filename

This comparison may return one of the following messages:

Locally modified
You have edited the file, and not yet committed your changes.
Locally Added
You have added the file with `add', and not yet committed your changes.
Locally Removed
You have removed the file with `remove', and not yet committed your changes.
Needs Checkout
Someone else has committed a newer revision to the repository. The name is slightly misleading; you will ordinarily use `update' rather than `checkout' to get that newer revision.
Needs Patch
Like Needs Checkout, but the CVS server will send a patch rather than the entire file. Sending a patch or sending an entire file accomplishes the same thing.
Needs Merge
Someone else has committed a newer revision to the repository, and you have also made modifications to the file.
File had conflicts on merge
This is like Locally Modified, except that a previous `update' command gave a conflict and CVS could not resolve the changes made. If you have not already done so, you need to resolve the conflict.
Unknown
CVS doesn't know anything about this file. For example, you have created a new file and have not run `cvs add'.

In general, a good rule of thumb is to make sure your working files are up to date with the repository just before you commit your changes to a file. The reason for this is that sometimes your commit may be unsuccessful, for example, you may be trying to commit from the wrong directory or perhaps another developer has committed changes to that same file after you checked it out of the repository or last updated it. Trying to commit your changes to an older version of the same file often causes conflicts when CVS tries to merge these. The result of your commit attempt under such circumstances is a somewhat daunting failure message about "dying gasps" from CVS. (Unfortunately, you don't find this out until after you've gone through the process of mentally composing and entering a pithy change log message.)

To see the differences between your copy of a file and the latest version in the repository:

cvs diff filename

More about comparing your work with the project repository

Comparing versions of files before you commit (diff)

Perhaps you want to see the changes another developer has made to the same file before you commit your own changes. For example, suppose you are committing some very complex changes which you anticipate may conflict with another developer's work.

In this case, a workable solution is to save off your working file under a different name (something like: "filename-new"). Then you can run the "cvs update" command and compare the latest version from the repository with your file before committing your changes. You can even compare the two files side-by-side using the following diff command:

diff -y filename filename-new

Merging your changes with other developers' changes

By giving the "cvs update" command, you are essentially telling CVS to merge the latest versions of files from the repository into your working copies.

Sometimes, however, other modifications made to a file since you last updated do not mesh well with your version. Or, you've made changes that conflict with the repository version. CVS makes every attempt to resolve such conflicts automatically when you update and commit, but sometimes it cannot resolve everything. Conflicts within the file must be resolved by hand.

Resolving merge conflicts

To resolve merge conflicts, open the file in your file editor. Look for lines or sections marked by >>>>>> and <<<<<<<</B>. When CVS cannot resolve a conflict, it includes both verions of the affected line or sections inthe file, with the latest version usually first. Your task is to delete the unwanted lines, along with the lines containing the conflict symbols and revisions numbers. Then you can save the file and commit again.

Revision history and reverting

Beyond the usefulness of being able to review a file's modification history using the "cvs log" command, those earlier file revisions can actually be restored as the most current revision (that is, restored to the "repository head") by the process of reverting. This becomes a particularly useful option if you need to return to an earlier point in a file's evolution for whatever reason, somewhat like being able to turn back the clock. When development projects experience broken builds or other problems, this becomes one of the most useful and powerful features of version control.

A word of caution: it's easy to get confused by the terminology of "revisions" versus "versions." Revisions are specific updates to individual files, such 1.1, 1.2, 1.3. When you run the "cvs log filename" command, the results are all of that particular file's revision numbers. By contrast, versions are sets of file revisions that are tagged and named at a certain point in time. The confusion occurs because versions are sometimes named similarly to file revisions (1.0, 1.1, 1.2 etc.). But versions do not have to be named this way; they can be any set of characters the Project Owner designates, and probably should use a different numbering scheme.

First, before you attempting to do any reverting, it's recommended that you examine the differences between the file version currently at the head of the repository and the version you want to revert to. The command to do this is:

cvs diff -c -r version# -r version# filename

This enables you to compare the two files before attempting to revert. The order for the file versions in this command is not critical, as long as you know can distinguish between the two versions.

The command to revert requires strict observance in ordering the version numbers, however. Assuming you want to revert from a later version to an earlier version, the command is:

cvs update -j later_version# -j earlier_version# filename

Because there is more than one method for reverting, see also:
More about reverting
More about revision history

You should also know that reverting may result in "sticky tag" errors. These can be resolved using the following update command with a special switch:

cvs update -dAP

(What are sticky tag errors?)

More CVS help: Managing project files and directories with command line CVS