Tutorial:Using CVS

From NCSU EDA Wiki
Jump to: navigation, search

CVS (Concurrent Versions System) is an open-source system for facilitating versioning of data when multiple users are working on the same project. Although it is intended primarily for software development, we recommend using it with Cadence design projects as well. This page details the practices that should be adopted in order to use CVS with Cadence most effectively.

Usage Policies and Maintenance

In order to allow the most freedom in viewing and using design-data created by other group member, we suggest the following policies:

  • Anyone is free to create directories in the repository. Consult other group members for tips on the most logical location in the repository.
  • Users are free to check-out other users' code. It's not advisable to commit any changes, however, without consulting the author.


Getting Started with CVS

First, find the path-name to your repository. If you do not have a repository, see Creating a Repository below. Next, add the following line to your .mycshrc file:

setenv CVSROOT [repository path]

On Solaris machines, you will also need to type the following command to add cvs to your path (not necessary on Linux machines):

add rcstools

Creating a Repository

If you have not yet created your repository, then create an empty directory with the path you chose above, follow the setup steps above, and then execute the following command once and only once:

cvs init

This will create the necessary files in the repository for all group members to use the repository.

Documentation

For more information, type "man cvs", or check out the following CVS PDF-file references (NCSU login required):

Using Private Source Directories

Private source directories are where all users should do their work for the project. These directories are created by cvs using the directions below. They can usually be identified by the fact that they always contain a subdirectory called "CVS".

Creating a Private Source Directory

To create a private source directory, use the "ceckout" command (abbreviated "co"):

cvs co [path]

Note that path must be the full path. For example, if you want to check out the file mylib/mycell/layout/layout.cdb you would type "cvs co mylib/mycell/layout/layout.cdb", and creates three nested private source directories (mylib, mylib/mycell, and mylib/mycell/layout) in the current working directory.

You cannot checkout files that have not yet been added to the repository. See Adding and Importing New Files and Directories below to add new files.

Updating a Private Source Directory

The "update" command allows us to see if other people have modified the repository. To update the contents of a private source directory, change to that directory and use the command

cvs update

Generally, one of four things happens to each file when using this command:

  1. If no changes have been made to the file (by you or anyone else), nothing happens
  2. If you made changes to the file, you would see the file name printed with an "M" (modified) in front of it. For example, "M layout.cdb".
  3. If someone else made changes to this file and committed them to the repository AND if you made no changes yourself, the contents of the file would be updated and the name would be printed with a "U" (updated) in front of it. For example, "U layout.cdb".
  4. If someone else made changes to this file and committed them to the repository AND you made changes as well, the file would be merged. You would see the message "Merging differences between [rev1] and [rev2] into [filename]". If the files were merged successfully, then the file name would be printed with an "M" (merged) in front of it. If there were problems during the merge, then the filename would be printed with a "C" (conflicts) in front of it. See fixing conflicts below. Generally, only text files can be merged successfully, so this feature seldom is useful with Cadence designs.

Note that if you want to "force" an update of a file that you modified (to throw away any changes you have made), you can do so with the "clean" option:

cvs update -C [filename]

Committing Changes

Once you've made changes to a file, you can "commit" (abbreviated "ci") them with the command

cvs ci -m "[log message]" [filename]

The message doen't have to be much, just enough to make life easy if you or someone else needs to fix conflicts later. Note that if you omit filename, all files in the current directory and subdirectory will be committed.

Adding New Files and Directories

It's easiest to add new files and directories to the repository from an existing private source directory. Simply create the new file/directory and type

cvs add -m "[description of file]" [file/directory name]

If the file you want to add is a binary file, then you will need to use the option "-kb" (as in "cvs add -kb ...")

New directories will be added immediately to the repository, but new files won't actually be added until you use the command "cvs ci" to commit them.

Importing New Files and Directories

If you want to add a large number of files with one command, you can do so by changing to the root of the directory tree that you want to import and typing

cvs import -m "[message]" [repository directory] [branch tag] [revision tag] 

By convention the message is always "Imported Sources", the branch tag is something to identify your site (like "ncsu") and the revision tag is an identifier of your choice, something like "mylib_0" or whatever (presumably, if you ever imported these sources again, you would bump up the revision tag to something like "mylib_1").


Fixing Conflicts

If someone committed changes to a repository file that you were editing, the changes need to be merged. If you already know that someone has been editing your file, you can find out how many differences there are with the "diff" command:

cvs diff [filename]

This command is identical to the normal UNIX "diff" command, except that it retrieves the most up-to-date revision from the repository for the second file. Note that this operation is not very useful for binary files.

Otherwise, if you have arrived at this point because you used "cvs update" and had conflicts, then CVS automatically prints the results of the "diff" into the source file, with the characters ">>>>>>>", "=======", and "<<<<<<<" to delineate the differences. See "merging files" below.

Rolling Back to a Previous Version

If the changes are too much to deal with, then perhaps it's best to just roll back to an earlier revision. To do this, first figure out the revision number that you want with the command

cvs log [filename]

Scan through the log entries and find the revision number that you want (something like 1.7, for example). Then use the following command to retrieve that revision in your private source directory:

cvs update -p -r [revision number] [filename] > [filename]

The "-p" option pipes the file to standard out, which is then redirected into the file. This approach may seem verbose, but it avoids setting a "sticky tag", which we just don't want to have to deal with right now. Once you've looked the file over, you can commit the changes as before, making this old revision the new, most recent revision.

cvs commit [filename]

Merging Files

Merging files is where the real benefit of CVS comes from. If someone else made changes to the file you were editing, you don't have to throw them out. Instead you can use the merging mechanism to help you merge the changes. To understand how to merge files, it helps to understand the "cvs status" command. This command reports the status of any given file as one of the following:

  • Up-to-date - This file matches the most recent repository revision.
  • Locally Modified - You have modified this file, and no one else has committed any changes. You are free to commit this file, if you like.
  • Needs Patch - You have not modified this file, but someone else has committed changes. Use "cvs update" to bring this file up-to-date.
  • Needs Merge - You have modified this file, but someone else has committed changes. Use "cvs update" to merge this file. Read on.

If the status is "Needs Merge", then the file needs to be merged with the most up-to-date repository copy with the "cvs update" command. After this command is issued, the status will be changed to one of the two possibilities below.

  • Locally Modified - If you and the other person did not modify the same lines of the file, then CVS recognizes this fact and merges the changes automatically. While this is happening, you will see a message that reads "Merging differences between rev1 and rev2 into filename", and the filename would be printed with an "M" (merged) in front of it. The status is changed to "Locally Modified" indicating that you are free to commit this file to the repository. To be safe, a backup copy of your original file is saved as ".#filename.revision". Once you've verified that the merge was ok, you can commit the merged file with "cvs ci" and delete the backup copy.
  • File had conflicts on merge - If both you and the other person modified the same lines of the file, then there will be conflicts. CVS merges the files but adds the lines with ">>>>>>>", "=======", and "<<<<<<<" to denote the conflicts. While this is happening, you will see the same message that reads "Merging differences between rev1 and rev2 into filename", along with an additional message that reads "cvs update: conflicts found in filename". Also, the filename would be printed with a "C" (conflicts) in front of it. As above, a backup copy of your original file is saved as ".#filename.revision". You'll have to go through and find all of the characters and merge the changes manually. Once you've got everything merged to your satisfaction, you can commit the merged file with "cvs ci" and delete the backup copy.

If all this merging business seems too complicated, remember that you are completely free at this point to clobber the other person's edits by simply copying the .#filename.revision backup file to filename and checking it in (although the person who made those edits probably won't be very happy).


Repository Administration

Managing Repository Size

Since all technology information is being kept in the repository, There is a danger of the repository becoming far too large. We can keep the size down by selectively making versions of certain files "obsolete". This is done with the "cvs admin -o" command, as described in section A.6.1 page 88 of the CVS Manual.

Another thing to keep track of is the log of all commits, which can be found in CVSROOT/updatelog. This file can get quite large over time, and so it's good to truncate it once in a while.

Handling Binary Files

As described above under Adding New Files and Directories, binary files should be added with the "-kb" option to avoid keyword substitution (which would corrupt the file whenever it is checked in, as illustrated in chapter 9 of the CVS Manual). If you want to check to see if a binary file has been added to the repository correctly, you can do this in one of two ways:

  • Use cvs status to check the status of the file. Text files should show Sticky Options as "(none)", while binary files should show "-kb".
  • Use cvs log to list the revision history of the file. Text files should show keyword substitution as "kv", while binary files should show "b".