CVS is used at the Keck observatory to retrieve and replace changes to observatory software.
There are numerous functions of which CVS is capable. The following
sections attempt to present those functions in increasing complexity. Thus
the first section will be that which most users will find useful. If you
find that you are attempting something
beyond the 'basics' then it is probably addressed in one of the addtional
major sections.
There is a tkcvs gui based interface to CVS which is a future topic.
This page does not currently address tkcvs as there are issues involved
when using it from a remote site (not on the Keck intranet). However, once
you are familiar with the command line based CVS interface, as described
herein, you will find tkcvs very convenient for manipulating files at Keck
(I urge the instrument specialists to use tkcvs).
Most of the examples in this section refer to 'test.doc' which is a file contained in the instrument ~/cvs_test_dir directory for all instruments (or will be in the near future). The intent is that you, the reader, can perform the examples as you read them.
This document does not attempt to define all variations of all CVS commands. Once you have learned the basics for a CVS command you can use the '-H' option to view the variations for a given command. For instance:
cvs commit -H
would display the various command options for the commit command which
is discussed in the next section.
The following is a tutorial example which allows you to manipulate the test file, test.doc.
We will assume that the file is contained in a directory which is 'known' to CVS. One can usually determine if this is true by noting if a subdirectory called CVS exists (refer to section 2).
First one must descend into the directory containing the file to be modified. Again we make an assumuption, which is that the reader has logged into an instrument account so as to manipulate an instrument specific file.
cd ~/cvs_test_dir [we assume the directory is in CVS]
Prior to modifying an existing file one would normally determine if the file has been modified by someone else. For this example we will assume that the file is currently upto date and we will simply perform the appropriate CVS command (handling differences and merging are discussed in other sections).
cvs -n update test.doc [determine if the file is upto date]
If the file is upto date then there will be no CVS message and the command prompt will simply return.
If the file is not known to CVS then the response will be:
? test.doc
in which case you need to add the file to CVS as described in section 1.2.
If CVS returns any other response to the 'update' command then the file is not upto date, however we will ignore this, as it is just a test file, so we will proceed with file modifications.
Modify the test.doc with your favorite editor. I suggest you add a new line to the bottom of the file which includes your initials and the date.
Now we will direct CVS to store the modified file:
cvs commit -m"modfied during tutorial" test.doc
If you do not add the remark with the '-m' option then CVS will pop-up a 'vi' edit session. I typically use the command line option for single line mods and use the vi session for any long explanations. If the commit command is successful then CVS will respond with something similar to:
RCS
file: /usr/local/cvsroot/k2nirc/cvs_test_dir/test.doc,v
done
Checking in test.doc;
/usr/local/cvsroot/k2nirc/cvs_test_dir/test.doc,v <-- test.doc
initial revision: 1.1
done
Note that a new revision number will be generated for each committed change to the file. You can experiment with this if you want by either adding yet another line or modifying the line you did add, then doing another commit.
The only other important note, in regards to the commit command, is
that issuing the command without an explicit filename will cause all modified
files in the directory to be committed. Of course all of those files will
then have the same comment, which is sometimes appropriate when making
a change to several files in support of a new instrument feature or some
such, however it is advisable to ensure that files will not be committed
that are being modified and tested by someone else within that same directory.
cvs add <newfile>
The add command in itself is insufficient for adding a file to a CVS
repository. In fact, the file is only noted within the context of the local
directory and the repository has not been alterated. Granted if you perform
an update (refer to section 1.3) the status for the file will indicate
that it has been added, where correct interpretation of that status will
indicate that the file has not yet been committed. Hence the next step
is to commit the file as defined in section 1.1 above. This is a test directory
so it is okay for you to perform the commit, in addition, we will investigate
removing files in section 1.6.
1.3 Update command - updating to the most recent version of a file or reverting to an older version
One of the most important features of CVS is the ability for many people to modify a given file from any number of different accounts (hence the C meaning concurrent). The implication is that a given file in any of those accounts may not be upto date, that is, a newer version may exist in the CVS repository. The CVS command to retrieve any version of a file is update. The update command also provides status on the current state of a single file or all files in a directory. By default update will retrieve the latest version of a file provided that the local file is an unmodified older version.
We will go through several editting sessions in order to investigate
the various status messages that can be generated with update.
The report only form of the update command is:
cvs -n update
This will show the current state of all files in a directory (multiple status lines with the status of one file per line).
To see the current state of a single file, the file name is appended to the update command. For instance:
cvs -n update test.doc
will display the current state of test.doc.
There are several possibilities for the current state of a file. The following gives the potential statuses for a file. We will investigate each of these possibilities.
?
test.doc
[the file is not in cvs]
M test.doc
[the local copy of the file has been modified]
A test.doc
[the file has been added to CVS but not commited]
U test.doc
[the local copy is old]
C test.doc
[a conflict of modifications has occurred and the file needs correcting]
To test the update commands response to a file that is not in CVS simply 'touch junk' then 'cvs -n update'. The response for the new file should be:
? junk
Now edit test.doc again and add a line. The result from 'cvs -n update' will be:
M test.doc
The 'M' status tag indicates that the local version of a file has been modified since it was last committed.
To investigate the 'A' status of a file it is necessary to create a new file and issue the add command for that file (as was done in section 1.2). Create a new file called junk then enter 'cvs add junk'. Once again issue the update command and observe the status of:
A junk
To undo the add we will issue the remove command which is discussed in section 1.6. For now simply 'rm' the file and then enter the command as shown.
cvs remove -m"removing temporary file" junk
To cause the 'U' status tag to occur we must modify a file from within another context. We will do this from another directory which will be a shadow directory to cvs_test_dir, that is, its CVS link will be to cvs_test_dir such that the new directory will contain the same files as cvs_test_dir. So change directory to the instrument's home 'cd ~' then 'cd cvs_tutorial'. If the directory 'cvs_tutorial' does not exist then we will create it using the checkout command (described in section 1.7). To perform the checkout you must change directories to the instrument account's home 'cd ~' then issue the checkout command as shown below. Note that you must replace <instr> with the account name and, the format of the checkout command depends upon whether or not you are on a Keck headquarters computer.
If you need to checkout cvs_tutorial on a Keck headquarters computer then enter:
cvs -d <instr>@apua:/usr/local/cvsroot checkout -d cvs_tutorial <instr>/cvs_test_dir
If you need to checkout cvs_tutorial on a Keck summit computer or other remote site then enter:
cvs -d <instr>@apua.keck.hawaii.edu:/usr/local/cvsroot checkout -d cvs_tutorial <instr>/cvs_test_dir
If the checkout fails then you will have jump to section 1.7 before proceeding.
Assuming the cvs_tutorial directory exists then cd into that directory and modify test.doc (append your favorite line). Commit the file as discussed in section 1.1. Now change directories to ~/cvs_test_dir again and enter the CVS update command again 'cvs -n update'. The status should be:
U test.doc
The 'U' status tag indicates that a local file has not been modified since the last time it was committed and that a newer version of that file exists in the repository.
To cause the 'C' status tag to occur please modify the local copy of test.doc (in cvs_test_dir) with your second most favorite line. If you enter the update command again, but without the '-n' option, then the file will be modified by CVS and response should be:
C test.doc
The 'C' status tag indicates that there is a conflict between the local version of a file and the latest version in the repository. A file with a conflict cannot be committed until the conflict is resolved by the user. Edit the file and look at the lines added by CVS in order to indicate the nature of the conflict. You should see something similar to:
<<<<<<<
test.doc
my second favorite line
=======
my favorite line
>>>>>>> 1.11
In order to commit a conflicting file you must first edit it and resolve
the conflict by hand (merge the changes). The file will not be accepted
by CVS until the lines containing the '>>>>>>>' are removed, as a minimum.
For this example we will assume we want to retrieve the original version of test.doc. So enter:
cvs update -r1.1 test.doc
When you use the '-r' option you create what is called a 'sticky' tag.
A sticky tag precludes you from modifying and committing a file without
performing a few contortions.
cvs update -A test.doc
Please update test.doc to the most recent version, if you have not already
done so, as it will be needed in subsequent sections.
The CVS difference command is 'diff'. The difference command defaults to diff'ing the file with the one in the repository that has the version number from which the local copy was obtained. Thus if someone else has made changes and updated the repository, for a file you are diff'ing, then by default you will not be informed of those differences. If you want to see differences between the local copy and the most recent version in CVS then you must use the '-rHEAD' option of the diff command. I typically do this as standard practice so that I can determine whether or not I want to merge or overwrite changes. This is done as follow:
cvs diff -rHEAD test.doc
If the file is upto date (in this case it is if you just completed section 1.1 above) then no status is generated and the shell prompt returns.
To test the CVS diff command response when the local copy has been modifed and not yet committed, re-edit test.doc and make a change such as appending a line with the word 'test' (or whatever) then re-issue the diff command. The response will be something like:
Index:
test.doc
===================================================================
RCS file: /usr/local/cvsroot/k2nirc/cvs_test_dir/test.doc,v
retrieving revision 1.1
diff -r1.1 test.doc
9c9
<
---
> test
Now delete the most recent change and diff again to ensure the files are identical. Alternatively, you can delete test.doc and do 'cvs update test.doc', which will recreate test.doc from the last version commited. Note that update is discussed in a section 1.3 above.
To test the case where there is a newer version in CVS than in the local directory we will modify test.doc for another directory. Change directory to ~/cvs_tutorial. Hopefully this directory has been created for the instrument in which you are working (this was done in section 1.3.1 above). If not then please change directory to the home directory 'cd ~' and enter one of the following checkout commands (described in section 2.?) . You must substitute the instrument for <instr> in the following checkout command(s). Also the command depends upon whether or not you are on a Keck summit computer (or remote site) or on a Keck headquarters computer. From hq you would enter:
cvs -d <instr>@apua:/usr/local/cvsroot checkout -d cvs_tutorial <instr>/cvs_test_dir
otherwise you would enter:
cvs -d <instr>@apua.keck.hawii.edu:/usr/local/cvsroot checkout -d cvs_tutorial <instr>/cvs_test_dir
The result will be a new directory called cvs_tutorial which is linked to the same CVS repository as cvs_test_dir.
Now descend into the directory 'cd cvs_tutorial'.
If it was necessary to checkout the cvs_tutorial then ensure that test.doc is current, delete the file 'rm test.doc' then use the CVS update command 'cvs update -A test.doc'.
Now modify the file by again adding a line then commit that change as
discussed in section 1 above.
Return to ~/cvs_test_dir and again issue the diff command. This time
the response will be something like:
===================================================================
RCS file: /usr/local/cvsroot/k2nirc/cvs_test_dir/test.doc,v
retrieving revision 1.2
retrieving revision 1.1
diff -r1.2 -r1.1
10c10
< *
---
>
The 'less than' and 'greater than' symbols are relevant to the CVS version of a file such that 'less than' means the local file has something less than the CVS version.
Now try the diff command without the '-rHEAD' option. The result will
be that no differences are indicated. This is because the local file will
be compared with the version from which it was derived (the version before
the latest modification). Remember that this is the default as it can sometimes
have significant implications.
There are several reasons for use of the log command. Some of those reasons are: when a new version of a file does not function as expected; when merging; when attempting to find an older version of a file; before updating a file to the most current version; and sometimes when confused about the results from a diff command.
The log command is straight forward:
cvs
log test.doc
cvs remove -m"<comment>" <filename>
If you recall, in section 1.3.1 we used remove to delete the file 'junk' which was added during the update command examples.
The lack of use of the remove command has occassionally caused problems at the observatory. For instance a problem can arise if a file is modified and moved to another directory, but not removed from CVS. If the original directory occurs earlier in the user's search path then the next CVS update in the original directory will cause the older version to be restored such that it is found and used.
When CVS removes a file it actually places that file in the 'attic'. Thus a remove mistake is not catastrophic.
TBC
Other than the initial checkout, the command is often used when new
subdirectories are added to an already existing CVS subtree, and other
users wish to udate their directories with the new subdirectories.
Assume the file is myfile.
The command to issue is:
cvs -n update myfile
7.1) If the file is known
and not modified
there will be no response and the command will simply terminate
7.2) If the file is known
and has been modified
the response will be:
M myfile
7.3) If the file is known
and has been modified by someone else from another account the response
will be:
U myfile
in this case caution is required when modifying the file (see section 9 below - conflicts and merging )
7.4) If the file is not known
the response will be:
? myfile
in this case the file must be added to CVS, if it is not a temporary file (see section 8 below - Adding a new file ).
If the directory has
a subdirectory called CVS then it is most likely so.
If you enter the following
CVS command from within a directory:
cvs -n update
then the response depends upon whether or not the directory is in CVS as depicted in the following.
6.1) If the directory
is not known to CVS then the response will be:
cvs update: No CVSROOT specified! Please use the `-d' option
cvs [update aborted]: or set the CVSROOT environment variable.
6.2) If the directory is
known to CVS then the response will indicate the status of the files in
the directory,
where nothing is generated for an 'upto date' file, and other files will
have a leading 'M',. 'U', or '?'.
All subdirectories will also be traversed, with statuses being generated
for each file. An unknown subdirectory
will result in a status with a leading '?'.
2.4 Adding a new directory into CVS
13) Where's this CVS repository?
If you look in the ~lris/bin directory, there is a subdirectory called CVS that contains 3 files:
a) Root
(master root of CVS repository, usually kics@hana:/usr/local/cvsroot)
b) Repository
(The CVS repository for keeping track of manuka's ~lris/bin area)
points to kics@hana:/cvsroot/lris/summit/bin
c) Entries
(list of all files & revisions in the repository)
95% of the time you won't have to worry or know about this -- so this is FYI only.
cvs
update -r 1.16 file.c
cvs
update -f
OR
cvs
update -A myfile
cvs update -d
cvs admin -o1.3 drvAbDf1.c
(the "o" is for "outdates")
rm
nogoodfile
cvs remove nogoodfile
cvs commit -m"remove it " nogoodfile
cvs
diff -D1-oct-97
(or use -R for revisions)
cvs -v
cd
~nirc
cvs
-d kics@hana:/usr/local/cvsroot checkout -d nircp3dev kss/nircp3dev
(where -d is for 'directory output specifiction')
truss -f -t open -t stat cvs tag dcs-3-0
where -f for fork; -t to
look for calls to open and stat and the command is d is 'cvs tag...'
cd
~
cvs -d kics@hana:/usr/local/cvsroot
checkout CVSROOT
cd CVSROOT
vi modules
... add the module ! (like an alias, e.g.,'core', 'ire_common')
cvs commit
-m"bla bla bla" modules
then go back
and try to cvs checkout that module
<echock/kroot/kss/dcs/key/data>
touch met_cake_config
<echock/kroot/kss/dcs/key/data>
cvs -n up
cvs update: Updating
.
cvs [update aborted]:
could not find desired version 1.2 in /usr/local/kcvsroot/kss/dcs/key/data/met_cake_config,v
<echock/kroot/kss/dcs/key/data>
pwd
(note vsn
1.2 was removed)
<echock/kroot/kss/dcs/key/data>
more CVS/Entries
/Makefile/1.2/Sat
Apr 4 01:36:41 1998//
/Makefile.Host/1.1/Fri
Feb 6 08:30:37 1998//
/aut2_cake_config/1.3/Wed
Oct 1 09:36:50 1997//
/dcs2_cake_config/1.116/Sat
Apr 4 01:36:43 1998//
/dcs2_header_info/1.8/Sat
Apr 4 01:36:44 1998//
/met_cake_config/1.2/Sat
Apr 4 01:59:39 1998//
D
cd mytree-totag
cvs
tag myrel-3-0
Therefore, if later on you need to revert to pure "3-0", just make a new directory and checkout the nircp3 module w/ the tag "myrel-3-0".
[This is the opposite of DCS. DCS uses 'sticky tags' to prevent inadvertent update (w/ the latest) into a released/closed-off directory. If you set a sticky tag, this will only let you update into that directory using the tagged versions. DCS is the opposite because it has separate development/release areas. To be more restrictive in a directory and set sticky tag, do:
cvs
update -r myrel-3-0
cvs
tag -lF -r 1.2 dcs-2-12 k1mountNfs
T k1mountNfs
[cvs will return this output, 'T'agged]
(where "-l" is local-only,
"-F" forced a retag (otherwise will get error),
"-r" is reviision
you want tagged (the latest) and "dcs-2-12" is the tag)
cvs
-d kics@hana:/usr/local/cvsroot checkout -A dcs