Quick guide on CVS in STAR


Quick menu


General layout and CVS areas in STAR

STAR uses CVS, the Concurrent Version control System, to manage the STAR software repositories. The current repository in use in STAR are:

STAR offline repository $CVSROOT/asps/
This repository contains most of the STAR software used for data reconstruction, simulation and analysis. All codes in this category are subject to nightly builds.
STAR offline generic code repository $CVSROOT/offline/ This area contains a mix of (a) a set of test codes and Makers which are not yet ready for inclusion under StRoot (b) project specific codes such as xrootd, the data carousel (c) the paper area containing raw materials for STAR notes and published papers documentation (d) a generic user area.
STAR online repository $CVSROOT/online/ Is an area containing codes for detector sub-systems and aimed to be used online, but this area typically do not contain shared codes such as OnlTools (aka Online Plots or PPlots).
STAR login and script areas



Several areas contains scripts and configurations used for support of STAR's global login, general production related scripts and CGI or analysis related supported commands and configurations.
STAR ROOT pacthes $CVSROOT/root/
Areas contains patches for ROOT in support of STAR software.


One should never ever go to, browse in, touch, edit, or otherwise interfere with a CVS repository itself. Use the web browser, do a CVS checkout of the software of interest, make your changes and commit.

$CVSROOT/ current value is /afs/rhic.bnl.gov/star/packages/repository. Access in write mode to STAR's CVS repository is hence subject to AFS ACL in addition of the CVS Karma mechanism. Only STAR authenticated users have write access.


Access control -- Karma!

The STAR offline CVS repository employs an access control mechanism that allows only authorized accounts to modify parts of the hierarchy. Authorization control is for commits only; everyone can check out any part of the repository as far as you have access to AFS.

If you get a message Insufficient karma (yes, it's a weird message) it's an indication you do not have write access to the area you're trying to commit to.

The access list is $CVSROOT/CVSROOT/avail. A line like

  avail 	|jeromel,didenko       |scripts

means that jeromel and didenko can write (that is, modify and add items) to any directory under scripts/.

Note that you will not be able to commit a brand new package to the repository (unless you have a lot of karma) because there will be no entry giving you access to the area you're trying to create. You can create sub-directories under directories you have access to. Please, DO NOT attempt to add packages or directories but send a request to the starsofi list.


Command reference

cvs co module         = check out a copy of 'module' into your working directory
                        (you only need to do this once)
cvs co -r 1.12 module  = check out a copy of 'module' of version 1.12
cvs co -r SL09a module = check out a copy of 'module' that was tagged as SL09a
cvs update           = update all the files in the current directory
cvs -n update        = tells what it would update, but the -n means it doesn't do it
cvs -n update -A     = to get list of what it would update (-n means to not do it)
                       The "-A" is needed if you originally checked out a particular
                       tag - it tells the update to override the tag
cvs commit           = commit all of the files you have changed to the main repository
cvs ci -m "message"  = same as above, but enter explanatory message
cvs add file1        = alert CVS that file1 should be added to the repository at
                       the next 'cvs commit' invocation.
cvs rm  file1        = alert CVS that file1 should be removed from the repository at
                       the next 'cvs commit' invocation.
cvs status -v module = get list of all versions tagged

Whenever you check out, files may appear with a flag. As listed, the meanings are:

U = file was updated in your area
M = file was modified in your area (revisit)
? = cvs doesn't know about it

Advanced Commands/Hints

cvs history -Ta -n module = show all tags on 'module'
cvs diff -r HEAD file1    = show difference between my checked out file1 and the
                            most recent version in CVS
cvs rtag tagname module   = tag 'module' in CVS with 'tagname' 
                            (NOTE: this creates a history entry, the 'cvs tag' command does not)
CVS/Entries               = this file shows you the tag and RCS version of what you checked out

Beyond the quick help

Please see at the bottom of this page for a quick reference card.


Important NOTES for STAR

The below are specific to STAR as we "tag" the whole slew of code regularly. "tags" represents snapshot in time of the whole sate of the repository and tree. In STAR, the CVS tag matches the library release version (for example, SL14b would be tagged SL14b).

Working with a previous version of the code

If you want to check out a certain version of the code, it is not enough to do "starpro" and then "cvs co pams/tpc"!!! The same applies for any specific version of te STAR code you may want to use. Whenever you do a simple "cvs co", you will still get the dev version of pams/tpc.

To check out the a specific version, you must find which one (let's say SL09a) version it is. In our example case, it is SL09a. Then you would do

% cvs co -r SL14b pams/tpc 

Now you must still do

% starver SL14b 

and now you're totally in the environment set for SL09a and code checked out based on this library tag.

Getting history and tags of a particular file

If you want to know what tag has used for a particular file (for example pams/tpc/tpt.F) then you just need to type

% cvs status -v $STAR_ROOT/dev/pams/tpc/tpt/tpt.F 


Other topics / advanced topics

Checking Out a Module for the First Time

To check out something for the first time use a command like this

% cvs co pams/tpc/tss 

CVS will create directories called 'pams/tpc/tfs' in your current working directory and copy all of the files and sub-directories associated with the module 'tfs' into it. All of the remaining CVS commands should be issued from the 'tfs' directory.

Committing Your Changes to the Main Repository

If you have done nothing special when you cvs checkout the code, this process will be straight forward. You can edit any of the files you want in your working directory, and when you are ready to commit your changes to the master repository do,

% cvs commit {filename|*|}

CVS will start an editor (vi, pico or emacs depending on your environment variables EDITOR) and ask you to enter a text that will be stored as part of a history of changes. If this is successful, then your versions of the files will be copied back to the main site so that everyone can access them.  Note that you can also, for a single file, use a form

% cvs commit -m "My relevant message explaining the change" tfs_ini.F

for committing the changed you made to tfs_ini.F and adding at the same time the relevant comment. Please, always think of adding a comment and remember that you are not the only one (or will not be) working on this code and hence, help to other developers as a courtesy is important.

Getting Updates and Merging Changes from Different Users

If someone else changes the files while you are working on your own copy, you must update your copy with the command cvs update to get the new versions. You can chose to update your files at any time. Before committing any files, CVS will check to see if you need to do an update. If you do, CVS prints a message and aborts the commit. If someone else has changed a file that you have also changed, CVS will attempt to merge the new changes into your file. If it is unsuccessful at doing so it will alert you to a 'conflict.'

If there is a conflict, the new file will contain sections that have both your changes and the other persons changes. These sections will be flagged by lines like


The user must then look at the conflicting regions, choose what is correct and edit the file.

Adding New files to an Existing Module

If you create new files, you have to tell CVS to put them into the repository. First do,

% cvs add newfile1 newfile2 

then do a 'cvs commit' (do not forget the initial message / comment). The 'add' command alerts CVS to commit the named files at the next invocation of cvs commit.

Reverting to Old Versions of Files (Tags)

Every time you commit a file to CVS it increments a revision number. The first commit is 1.1 then 1.2 and 1.3 etc... (I don't know if it ever gets to 2.1 by itself though). To revert to an old version of a file you can use the version number as a tag as in

% cvs co -r 1.7 tfs_init.F 

to check out version 1.6 of tfs_init.F.

You could also use the update command

% cvs update -r 1.7 tfs_init.F 

but be careful that you don't commit the old version on top of the current version (jn the above example, you would). To see what version number the current file is do

% cvs status tfs_init.F

You can also revert to files that were tagged as a particular version by the user. For example

% cvs co -r sl97btpc pams/tpc/tfs

would check out all of the files that were tagged by somebody as version sl97btpc. To see what user tags have been created do

% cvs history -Ta -n pams/tpc/tss 

You may also use commands that uses the revision differences (-j for join) and merge them into your current code. Let us say that you have version 1.5 of a code named filename and would like to revert it to version 1.4. What you would need to then is to

% cvs update -j 1.5 -j 1.4 filename
% cvs commit filename

The order of the versions are very important here. What you've asked cvs to do in the above command is to take the difference between versions 1.5 and 1.4 and apply them to your working copy. Because you apply to the current directory the differences between 1.5 to 1.4 (and yu have 1.5 in your current directory) you have effectively asked cvs to apply the changes necessary to revert your code to version 1.4 .

Working with sticky tags

cvs can branch the repository into separate fork in the development until such a time that you are satisfied with it and ready to re-merge. Usually, we do not use this feature in STAR so everyone works from the same code base. Besides, if too many branches are created, re-merging code may create conflict that will take time to sort (see the above note on code conflict while merging).

Sticky tags are used to create branches. To create a branch named BranchName, simply go into a working directory having all code that are in the repository and issue the command:

% cvs tag -b BranchName {Dir|File}

In the above {Dir|File} indicate a choice of either Dir or File: Dir represents the directory tree you would like to update or File a single file you would like to tag (probably not the greatest idea to generate to many branches for each code you have but, noted for consistency).
If unspecified, the whole code tree will be tagged. More generally, you WILL WANT to do this instead

% cvs tag Revisionname  {Dir|File}
% cvs tag -r Revisionname -b BranchName {Dir|File}

What this latest form will do is create a normal tag Revisionname first, then attach the branch named BranchName to that tag. This method may later facilitate merging or seeing differences made since a tagged version (otherwise, you may have a hard time to figure out the changes you made since you created the branch). Note that CVS has a special branch named MAIN which should always correspond to the CVS HEAD (the latest version of the code).

To work with branches, it is simple ...

% cvs co -r BranchName Dir

would checkout the code from the tree Dir  that is in the branch named BranchName into your working directory. From this point on, you have nothing else to do. Just modify your code and cvs commit as usual. By default, the checkout command with a branch specification will create a "sticky tag" in your working directory, that is, cvs will persistently remember that you will be working from that branch. You may alos use "cvs update -r BranchName Dir" for similar effects (you would essentially update your working directory Dir and make it move to the branch BranchName).

** WARNING ***

You may destroy the sticky tag by using the folowing commands

% cvs update -A Dir

If you do this, what you are asking CVS is to update ignoring all sticky tags and updated based on the the MAIN branch. The command will remove all 'stickyness' of your working directory. Further commit will then go into the MAIN branch (or CVS HEAD). If you want to ensure you commit in the branch you intended, you will need to specify the branch name in your commit command as follows

% cvs commit -r BranchName Dir

Before discussing merging ...

Hint #1
: It was noted that the most convenient way to create a sticky tag (or branch) is to use a regular tag and a branch tag combination (second set of commands in our cvs tag example above). This is because when you will be ready to remerge, you may find that you need to merge several branches together and those create conflicts you may have a  hard time to sort out.  You may be able to resolve those conflicts by issuing cvs diff commands with the tag revision Branchrevision  where you branched in the first place

% cvs diff -r Revisionname -b BranchName {Dir|File}
will do that for you. But if you did NOT create a tag and branched from CVS HEAD, it will not be easy to make differences with the "base" you started with when you branched out (since CVS HEAD keeps changing).

You may also try to fix conflicts by generating differences by using cvs diff as below:
% cvs diff -c -r BranchName1 -r Branchname2 >diffs.log
and inspecting what you got. If you are the only person to modify those codes though, the advantage will be minimal.

One branch merging

Now, imagine you are satified with your changes and want to remerge them into MAIN. Then the fun begins ... An easy way to do this (if there has not been any other code divergence in MAIN hence no potential additional conflicts) would be to do this

% cvs update -j BranchName Dir

where Dir here is the location of code you want to update by "joining" the branch BranchName to it. If no conflict appears, you are set to go (with a cvs commit and voila! the code is remerged).

Two branches merging

Generally, if you want to merge two branches together, here are a few examples. Using checkout on a brand new directory tree ...

% cvs checkout -j BranchName1 -j BranchName2 {Dir|File}

this command will locate the differences between BranchName1 and BranchName2. Of the lines that are different between them, the lines in BranchName2 will be patched, or merged, into the latest revision on the main trunk of {Dir|File}. Any conflicts must be manually resolved by editting the file and verifying everything compiles and run properly.

Two branch merged into a third

Even more optimistic, you may remerge two branches into yet a third different branch. Here is an example building on the above

% cvs checkout -r BranchToMergeTo -j BranchName1 -j BranchName2 {Dir|File}

However, file that were created between BranchName1 and BranchName2 do not get created automatically.

Hint #2: When working with branches. cvs status is your friend. See why in the example below

% cvs status StRoot/StiPxl/StiPxlChairs.cxx
File: StiPxlChairs.cxx  Status: Up-to-date

   Working revision:    1.1     Sat Feb  1 19:19:34 2014
   Repository revision: 1.1     /afs/rhic.bnl.gov/star/packages/repository/StRoot/StiPxl/StiPxlChairs.cxx,v
   Sticky Tag:          StiHFT_1b (branch: 1.1.4)
   Sticky Date:         (none)
   Sticky Options:      (none)

In the above example, it is clear that the code checkout in the workig directory Dir = StRoot HAS a sticky tag StiHFT_1b . In contrast, the same command in a directory without a sticky tag would show 

% cvs status StRoot/StiPxl/StiPxlChairs.cxx
File: StiPxlChairs.cxx  Status: Up-to-date

   Working revision:    1.1     Sat Feb  1 19:19:34 2014
   Repository revision: 1.1     /afs/rhic.bnl.gov/star/packages/repository/StRoot/StiPxl/StiPxlChairs.cxx,v
   Sticky Tag:          (none)
   Sticky Date:         (none)
   Sticky Options:      (none)

Sticky Tag: (none) cannot be clearer.


Creating a new module

The following command issued either from an empty directory or a directory containing (ONLY!) the material you want added to the new module

% cvs import -m "Message" repo_name tag_name tag_name  

will create a new module called repo_name containing all the files in your directory. The repo_name can be just a directory name if the module sits at the top of the repository, or a path if the module lives down in the repository directory tree. The tag_name is the initially assigned tag (eg. 'V1.0').

Be aware that in STAR, you may be able to add a new repository to CVS but you will not be able to add files to it until you are granted appropriate karma. This additional step keeps STAR's CVS repository clean as the layout presented at the beginning of this document should be followed.



Other CVS information and resources