The information here is based on CVS versions 1.9 and 1.10.5 and later.
Notes to emacs users: the emacs Tools/Version Control (or vc) pulldown has CVS commands: it's well worth checking out. And, see the Preliminaries section for a handy addition to your .emacs file.
If you'd like to update your CVS workspace remotely, see Nanbor Wang's   CVSup  page.
Please email me any corrections or suggestions!
Contents:
The CVSROOT
environment variable listed below is . If you
want to use CVS from within emacs, you'll have to restart it from a
shell that has CVSROOT
defined.
Emacs users might want to add (setq vc-follow-symlinks t) to your .emacs file to instruct emacs to follow symlinks to version-controlled plain files.
For lack of a better place to put the following, I'll put it here. It's a good idea to insert a CVS/RCS keyword string at the top of every file that you place under CVS control. This includes source files, Makefiles, config files, etc. It will embed in the file a concise record of the filename, last update time, revision number, and last user who updated it. For C++ files, the keyword string is:
// $Id$It's not necessary to fill in the fields of the keyword string, or modify them when you edit a file that already has one. CVS does that automatically when you checkout or update the file.
On Unix systems, you might want to create a file called .cvsrc
in your home directory with the following contents:
co -P
update -P
That will cause CVS to prune empty directories on checkout or update.
setenv CVSROOT /project/cvs-repository
####
site-specific location
setenv ACE_ROOT `pwd`
#### to set the ACE_ROOT
environment
cvs checkout ACE_wrappers
% ln -s config-sunos5.5.h ace/config.h
% ln -s platform_sunos5_sunc++.GNU include/makeinclude/platform_macros.GNU
CVSROOT
.)You can use the CVS client under Windows NT to keep a local repository of ACE. To set it up, follow these steps:
Alternatively, WinCVS provides a graphical front-end on Windows. NOTE: if you use WinCVS, beware that it enables read-only checkout by default. So be sure not to check out that way if you want to edit files.
Thanks to Steve Huston for that note.
d:\utilities\cvs;D:\utilities\gnuwin32\b18\H-i386-cygwin32\bin
LOGNAME =
usernameCVSROOT = ace.cs.wustl.edu:/project/cvs-repository
For an alternative approach that uses CVS pserver instead of rsh, please see Darrell's CVS pserver page for Win32.
ChangeLogTag: date name <email address>
In all examples below, ChangeLog
refers to appropriate
ChangeLog.
% cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" file(s)/directori(es) ChangeLog
C-x v v
(vc-next-action) to check the file or directory
in
C-c C-c
to finish checkin
% cvs update ACE_wrappers
cvs will print out a line for each directory that it enters
(by default, it will recurse through the directory tree; to
disable this and only update one directory, add -l
after update
).
cvs will print out a line for each file that differs from what is in the repository. This first character indicates the file status:
U
the file was brought up-to-date, so
now it agrees with what is in the repository
P
same as U
, except used by CVS server
when it sends a patch instead of the entire file
M
the file is modified in your
workspace with respect to the repository; without any
other message, it means that the file was not modified
by this update operation. If changes were
successfully merged (without conflict), then cvs will
note on the previous lines.
C
the file needs to be updated, but a
conflict was detected. The file now
contains the differences, demarcated with
<<<<<<<
and
>>>>>>>
. The
unmodified file was moved to .#file.revision.
You'll need to edit the file to resolve the
differences. I get a lot of false positives on files
that I know I didn't modify locally: for those cases,
I just remove the file and rerun update.
A
or R
The file has been
added or removed
to/from your workspace, but the add or
remove has not yet been committed.
?
the file is private to your
workspace: it does not exist in the repository
% cvs -n update .
The -q option to update suppresses the ``Updating'' message for each directory:To get the status of the current directory (recursively) with respect to the repository:%cvs -nq update .
% cvs status .
To get the status of a single file with respect to the repository,
with symbolic tags displayed:
% cvs status -v file
To show local (in current workspace) changes to one or more files,
relative to the versions that they were checked out from:
% cvs diff file(s)/directori(es)
To show local (in current workspace) changes to one or more files,
relative to the latest versions in the repository:
% cvs diff -rHEAD file(s)/directori(es)
% cvs add file . . . % cvs commit file . . .
Binary files require the -kb
option to cvs add
:
% cvs add -kb file . . . % cvs commit file . . .
add
operation, -kb
can be applied using cvs admin -kb
.Removing files is similar, except the cvs remove command is used instead of the add command:
% cvs remove file . . . % cvs commit file . . .
An add of an empty directory doesn't require a commit.
Removing a directory is more problematic. There is no CVS command to remove (or rename) a directory: it has to be done behind CVS' back, directly in the repository. This is by design; a CVS command can't be used to irrevocably destroy information. Therefore, never remove a directory. You can safely remove all of the files in it, using the above steps. To just remove a directory from a workspace (without removing it from the repository): first, remove the directory and all of its files using usual OS commands. Second, run
% cvs update -P directory-path
% cvs checkout -c
IMPORTANT: if a subdirectory is added to ACE, it
must be added to the list of known modules in
$CVSROOT/CVSROOT/modules
! If you don't want to edit that
file, please tell David. The
CVSROOT
files are under RCS control. emacs' VC tools
handle them the same way that they handle CVS-controlled files. So,
you can check them out and back in with C-x v v
.
To add an entirely new module:
$CVSROOT/CVSROOT/modules
, as
mentioned above.
$CVSROOT
, owned by the appropriate
group and with sufficient (probably group write+setuid) permissions.
cvs checkout new module name
C-u C-x v aThanks to James Hu <jxh@cs.wustl.edu> for this useful tidbit.
To set a specific host address in your ChangeLog entries, add a line
like this to your ~/.emacs
:
(setq mail-host-address "cs.wustl.edu")
To set a specific name in your ChangeLog entries, add a line like
this to your ~/.emacs
:
(setq user-full-name "my full name")Otherwise, CVS uses the name (GECOS field) from your passwd entry.
% cvs tag tag .
To retrieve an old revision of a file, use the -r option to cvs update:
% cvs update -rtag fileThe revision tags of a file can be viewed with the cvs log command.
Or, to retrieve the file and/or directory versions as of a certain date and time, use the -D option to cvs update, for example:
% cvs update -D "last Saturday" OS.{h,i,cpp}NOTE: The -r and -D options are ``sticky''; they will apply to the file(s)/directories until overwritten with another revision tag or date, or until disabled. They are disabled by using the update -A option, which also checks out the latest revision:
% cvs update -A file
To change the log message for a particular revision of a file:
% cvs admin -mrevision:"new message" file
C-x v u
(vc-revert-buffer). Or from the shell, you could remove the
file and update it with cvs update file
.
% cvs update -jafter_change -jbefore_change fileFor example, if the version containing the version you want to revert is 4.10, then, after_change should be
4.10
and before_change should be
4.9
.NOTE: this doesn't seem to work with CVS version 1.10.
Make sure the patch succeeded (if you are not reverting a change you made long time ago, most likely it will succeed) before checking in the reverted version.
Also make sure the you add a ChangeLog entry explaining why you reverted the change.
-r
option. It's all done in the user's workspace:
Add ChangeLog entry containing: Renamed OLD to NEW % mv OLD NEW % cvs remove OLD % cvs add NEW % cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" OLD NEW ChangeLog
% cd $CVSROOT/MODULE % mv OLD,v NEW,v
While the first method is the safest, it has the distinct disadvantage of hindering access of old versions. If that's not a problem for a particular file, then it is the preferred approach. As Carlos would probably say if you asked him, ``it's the right thing to do.''
If easy access to old versions is desired, I would use the third approach: copy the history file in the repository.
% cvs rtag -b branch_tag module(s) % cvs checkout -r branch_tag module(s)It's not necessary to checkout all the files in a directory or module on the branch, but it's probably the easiest and least confusing approach in the long run. Note that it's usually tricky to tag individual files on a branch because CVS won't be able to identify which module they're in. By way of example, to checkout just
ace/OS.h
on a branch, you'd have to do
this, assuming that you're already in the ace
directory:
% cd .. % cvs rtag -b branch_tag ace/OS.h % cvs checkout -r branch_tag ace/OS.h % cd aceThis can be done after modifying files, and CVS will retain your modifications. However, if you don't trust CVS, it's best to backup your files first.
Checkouts on a branch are sticky, and will apply until the head
version of the file(s) have been checked out with the -A
option to cvs update
. Presumably, this will be done
after merging the branch to the main trunk. See the
Old file revisions section of this
page for similar discussion of sticky tags.
To merge an entire branch to the main trunk, use the -j
(for join) option to cvs checkout
. That just
merges in your workspace; the repository can then be updated from the
workspace using commit
as usual:
Add ChangeLog entry containing: merged branch_tag % cvs checkout -P -Aj branch_tag file(s)/directori(es) % cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" file(s)/directori(es) ChangeLog(The
-A
is needed if you are in the workspace that has
the checkouts on the branch. It updates the workspace to the latest
versions on the main trunk. So, don't use it if
you want to keep working on the branch.)To merge any changes on the main trunk to a branch, the first time:
Add ChangeLog entry containing: merged main trunk changes % cvs update -jHEAD file(s)/directori(es) % cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" file(s)/directori(es) ChangeLog % cvs tag merged_foo_branch file(s)/directori(es)AFTER MERGING, APPLY A LABEL TO THE SOURCE BRANCH, as shown above. For example, if you merged from the main trunk to a branch, apply a new label to the main trunk. You can use that label later to merge any subsequent changes on the main trunk. The
cvs
info pages have a good example of this.
Briefly:
Add ChangeLog entry containing: merged main trunk changes % cvs update -jmerged_foo_branch -jHEAD file(s)/directori(es) % cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" file(s)/directori(es) ChangeLog % cvs tag merged_foo_branch_again file(s)/directori(es)Note that any files created on the branch won't be visible on the main trunk, even after the merge. I'm not sure of right way to take care of this, but I follow these steps for each file created on the branch:
Add ChangeLog entry containing: merged branch_tag % cvs update -Aj branch_tag file % cvs commit -m "ChangeLogTag: `head -1 ChangeLog`" file ChangeLog
In general, deleting branch tags is not recommended. But it's often
necessary, especially when getting started with branches. The
-d
option to cvs rtag
can be used to delete
a branch tag.
The use of a branch for maintaining a release is illustrated in the section on the ACE release bug-fix branch.
An easy way to access a remote repository is via rsh. These steps ought to get you going:
.rhosts
file on the remote machine
of a user that can access the repository.
CVSROOT
environment variable to:remote user@remote host:remote repository
If you have ssh on your client machine, you can use ssh instead of
rsh. Just set your CVS_RSH
environment variable to
ssh
. You don't need to add an .rhosts
entry with ssh, so it's the best alternative for remote repository
access.
Another way to access to remote cvs repository is to run cvs in
client-server mode. To use this feature, first check if you have your
HOME
environment variable set properly. Then, set your
CVSROOT
to:
:pserver:your_user_id@ace.cs.wustl.edu:/project/cvs-repository
Then, do a cvs login as
% cvs login
Type in your password when CVS prompts you to enter your password.
This will create a file call ".cvspass
" in your home
directory (as defined by $HOME
) that contains the
encripted password for the server. You can now perform regular CVS
operation directly.
Notice: It's not difficult to decode the passwords in
.cvspass
file. Therefore, never use cvs in client-server
mode in a unsafe environment. (Where others can read your .cvspass
file.)
To speed up client-server mode operations, it might help to use
the cvs
-z
option. It requires that
gzip
be on your search path on both the client and
server. An example use is:
% cvs -z 1 update
Thanks to Nanbor Wang and Darrell Brunsch for figuring out and providing this documentation for cvs client-server mode.
To use cvs export, either a date or revision
tag must be specified. It's usually a good idea to tag the sources
with a revision tag and use that. So, the steps would be:
% cd root of directory tree % cvs tag tag . % cd staging directory % cvs export -r tag % find . -print | cpio -o -H tar | gzip -9 > tar filenameTo tag and create a release in the form of a gzip'ped tar file from a user's workspace:
% cd root of directory tree % cvs tag tag . % find . -name CVS -prune -o -print | cpio -o -H tar | gzip -9 > tar filenameThe relative advantage of the first, export approach is that you will be sure that only CVS-controlled files will be released. However, it requires the extra step and creation of the staging area.
This extra step is one reason why we don't currently stage releases of ACE. Instead, they are built from Doug's personal workspace. That workspace is visible on the web, so that ACE users can track the very latest changes without any explicit action by Doug. If we were to stage it, to make any change visible would require an explicit move to the staging area.
There's now a ``frozen'' ACE in /project/cvs-repository/ACE_wrappers-frozen/. It contains the latest official release of ACE.
There are complete g++ 2.7.2.1 and Sun C++ 4.2 builds in the build directory below the directory noted above. To use one of these builds, set or prepend to these environment variables:
Compiler | set WRAPPER_ROOT to: | prepend to LD_LIBRARY_PATH: |
---|---|---|
g++ | /project/cvs-repository/ACE_wrappers-frozen/build/SunOS5_g++ | /project/cvs-repository/ACE_wrappers-frozen/build/SunOS5_g++/ace |
Sun C++ | /project/cvs-repository/ACE_wrappers-frozen/build/SunOS5_sunc++-4.2 | /project/cvs-repository/ACE_wrappers-frozen/build/SunOS5_sunc++-4.2/ace |
The ``main line'' CVS branch will (continue to) be the ``new features''
branch. If you want the very latest and greatest ACE at all times, no
changes to the use of your workspace are required. Just
cvs update
it as usual.
Bug fixes to the official release will go on a branch. For the ACE 4.2 release, for example, this branch is name ACE-4_2. (CVS does not allow periods in branch names or any other tags.) To use it, do this in your workspace:
% cd .. % cvs checkout -r ACE-4_2 ACE_wrappersFrom that point on, all updates and commits in that workspace will be from/to the ACE-4_2 branch.
cvs update: conflict: foo is modified but no longer in the repository
U bar- That might indicate that file foo was renamed to bar. If so, foo should be removed from the current workspace. (And that warning will not reoccur for the workspace, because its CVS will have removed foo from the workspace entries and checked out bar.)
cvs update: [time] waiting for user's lock in repository- Check for lock files and directories in the
$CVSROOT/CVSROOT
and lock files anywhere in the$CVSROOT
hierarchy. Remove ones that no longer appear to be in use and retry. Lock files and directories have names starting with ``.#'', I think.
- Why does a file in the repository not have group and/or other read permission?
- Because it didn't have those permissions when it was added to the repository. To fix it, those permissions can be added to the ,v file in the repository. To avoid it, those permissions should be added to the file before it is created/committed the first time.
- Why does CVS keep removing group/and or other read permission from a file in my workspace?
- Because your umask is something like 7 or 77. Change it to something like 22. If you don't want to change it for everything, then alias cvs; in t/csh:
%alias cvs '(umask 22; \cvs \!*)'
Also, the file will have to have mode 644 before you commit it. So if your editor removes group/other read permission, you'll have to ``fix'' that as well.
- I modified Makefile in my workspace so I don't build static or shared ACE libraries. But, I forgot about it and commited the modified Makefile to the repository. Help?
- You'll have to correct the Makefile and commit your corrections.
Instead of modifying your makefile, try these commands to build the ACE static and shared libraries, respectively:
% makestatic_libs_only=1
% makeshared_libs_only=1
Back to David L. Levine's home page.
Last modified 11:15:16 CDT 30 September 2002.
[an error occurred while processing this directive]
[an error occurred while processing this directive]