Source Control with cvs


Source control lets you store and manage multiple versions of your files. It is essential for managing the concurrent work of many developers, and it allows you to track changes to your files over time. It is not specific to C and C++ development; it can be used on files of any type. Source control programs track your changes by storing a history of your files in a central repository. The source control program can use this history to reconstruct any version of the file, which allows you to roll back if you make a mistake.

Modern source control programs allow each user to check out their own local copy of the source. Once you are ready to save your local changes, you can commit the changes back to the repository If you are modifying the most recent version of the file, then you can commit directly, but if someone else has modified the file since you checked it out, then you must merge your changes with the repository changes before submitting. Advanced source control programs also allow you to keep track of isolated code branches and to merge changes to source files across these branches.

There are many options available for source control on UNIX. Some of the most commonly used are SCCS, RCS, CVS, Subversion, and Perforce. SCCS and RCS are restrictive because they only allow you to lock files. This lock allows only a single user at a time to modify each file. CVS evolved from RCS. It also allows locking, but it supports concurrent work on the same file as well. For large projects, this is generally much more useful, as it is possible to merge multiple people’s work on the same file. Subversion is an evolution of CVS but isn’t as widely adopted. Perforce is a commercially available product with robust branching and merging support. This section focuses on CVS (Concurrent Version System), since it is arguably the most popular source control program used on UNIX systems.

Obtaining CVS

You can run the command which cvs to find out if you have CVS preinstalled. If you need to install CVS, you can download the binaries and source from: ftp.gnu.org/non-gnu/cυs/. This chapter gives the basics for using CVS; for more information, there is a central CVS web site at http://www.nongnu.org/cvs/.

Configuring Your Environment and Repository

To use CVS, you will either need to use an existing repository or create a new one. If you need to create a new repository, then you should create a directory for it in a central location on your file system. You could also use a remote server, but setting up remote authentication for a CVS server is beyond the scope of this book.

Once you have decided on a location for your repository you should set the environment variable $CVSROOT to the path for that directory. If you stored your repository locally at /usr/local/cvsdepot/, for example, you would run the following command in csh or tcsh:

 % setenv CVSROOT /usr/local/cvsdepot

If instead you are running ksh or bash, then the commands would be

 $ export CVSROOT=/usr/local/cvsdepot

You will likely want to add this to a start-up script such as your .profile or .login file. Another environment variable that you might want to modify is CVSEDITOR, which specifies which text editor cvs opens when you need to enter a commit message. CVS currently uses vi by default.

You can generate a new repository in your directory by typing the init command:

 $ cvs -d /usr/local/cvsdepot init

This command will generate a directory called CVSROOT inside /usr/local/cvsdepot. The init command initializes the repository, so that you can add projects.

Adding a Project

Once you have a repository established, you will want to add your existing project source files to it. It’s possible to import your repository history from another source control program, but more commonly you will start a new history for your files. To do that, cd to your current source code base directory If you run the cvs import command like

 $ cvs import -m "Imported project files." projectname vendortag releasetag

then cvs will add all of the files in the current directory to a directory in the repository called projectname. The initial version of the files will have the note “Imported project files.” If you have subdirectories in that base directory, then they will also be recursively added, along with their files, to the repository Both a vendortag and a releasetag string must be included. These tags are intended to track multiple releases of third-party code but often go unused. If the import command succeeds, then the source should now be in the repository Once you have carefully verified that you can check out a full copy of the source (see the next section) and made a backup, you might want to remove the old source directory that you imported from, since it will not be under source control.

Checking Out Source Files

Once you have imported your project into the repository each developer will want to check out their own local version of the source to work with. Change directory to where you would like the root directory of your source code to be located and type

 $ cvs checkout projectname

This command will add a directory called projectname and populate it with your source files. Each project directory will have a subdirectory called CVS, which has information that CVS uses to keep track of which version you have of each file.

Working with Files

By default, when you checkout your source files from CVS, they are writable. When you are ready to save your local changes to the repository, you should cd to your project’s root directory You can commit all of the files in that directory and all of its subdirectories by running the command

 $ cvs commit

You can also commit specific files by specifying them as command-line arguments. If you are up to date with the most recent repository version of your modified files, then cvs will bring up an editor asking you to type in a message about the changes that you made to each directory After you exit the editor, it will save your changes back into the repository This makes your version of these files the one that other users will get with a checkout command.

Your committed files are now also available to other users via the update command. An update copies the most recent version of each file from the repository and replaces your local copy of that file. To update, you can either specify which files you would like to update, or you can run the command

 $ cvs update

which gives you all of the changes in the current directory and in any recursive subdirectory The only files that will be modified by an update are the ones that other users have checked in since you last ran a checkout or an update. cvs will display a special character and the filename for each of the files that are affected by the update. Table 24–4 lists the meaning of each character.

Table 24–4: cvs update Character Flags

Character

Description

?

This file is in your current directory but not in the repository.

A

This file is pending add when you commit.

C

Your changes to this file conflict with the changes from the repository.

M

This file was merged. Either your local changes and the repository changes didn’t conflict, or it’s a file that you have modified and the repository hasn’t.

P

This file has been patched; same as U.

R

This file is pending removal when you commit.

U

This file has been updated or added, and you haven’t modified it locally.

If you have locally modified files that another user has committed since your last update, then cvs update will need to merge your changes with the repository changes. When this is the case, cvs update displays an M before the filename. It will also show an M if you modified a file locally and the repository version hasn’t changed. If you see a line like

 Merging differences between 1.1.1.1 and 1.2 into hello.c

then cvs automatically merged the lines of your hello.c file and the repository version of the hello.c file together. cvs should make a backup of your pre-merge file called .#filename.revision. In the preceding example, it would create a file called .#hello2.c.1.1.1.1. Because the filename starts with a period, you will have to run ls -a to list it.

If you modified the same lines of a text file as another user who already committed to the repository, then cvs can’t automatically merge the results. This is called a conflict. cvs should save a backup of your old file in the same manner as it does for a merge, but in the case of a conflict, you must manually resolve the conflicting lines by editing the file. cvs will place both copies of the conflicting text into the file separated by conflict markers. Conflicting lines in the source file will look like

 <<<<<<< hello.c   printf ("This is one version of the file.\n");   printf ("This is another version of the file.\n") ; >>>>>>> 1.4

You must edit the conflicting file, fix the conflicts, and remove the conflict markers. CVS requires you to modify the file before submitting. Although it’s not advisable, CVS will not prevent you from submitting a file with unresolved conflict markers as long as you have made some modifications.

cvs update has several important command-line options. If you run cvs update with -d, it will tell cvs to create new directories that you don’t have in your local version of the repository You can revert a locally modified file with the -C option. This will overwrite the local file with the copy from the repository (cvs should back the file up in the same manner as it does for merges.) Finally, the -r option allows you to specify a revision that you would like to get. This allows you to pull an old version from a file’s history

The commands we described are the minimum set that you need to know to get up and running in CVS. Table 24–5 includes some additional cvs commands that may be useful to you.

Table 24–5: cvs Commands

Command

Description

add

Adds a file or directory to the repository. Can also undo a remove. Doesn’t take effect until the add is committed to the repository.

admin

Performs administrative and RCS commands. Allows you to lock and unlock files and to delete revision ranges.

checkout

Creates a new local project in the current directory. If one is already there, then it will update the contents, although update is recommended for this instead.

commit

Saves local changes into the repository. Can commit all changed files or you can specify a list. Will ask you for a message to accompany the change.

diff

Compares two revisions of a file and displays the differences. By default it compares the local version with the repository version.

edit

Makes a file that is being watched enabled for write.

log

Displays the log information for the listed files. This includes the location of the RCS file, tags, version authors, and the commit messages.

remove

Removes a file or directory from the repository. Can also undo an uncommitted add. Doesn’t take effect until committed.

status

Shows whether the specified files are up to date or have an unresolved conflict with the repository as well as other revision information.

update

Copies changes that were committed to the repository to the local copy of the source. Can also get a specific version of a file and bring in new directories.

unedit

Cancels an edit command and reverts the file to the depot version.

watch

Causes files to be checked out read-only. A user must run the edit command before modifying these files. Can also set up file status change notifications.

You can get a full list of cvs commands by running

 $ cvs --help-commands




UNIX. The Complete Reference
UNIX: The Complete Reference, Second Edition (Complete Reference Series)
ISBN: 0072263369
EAN: 2147483647
Year: 2006
Pages: 316

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net