CVS FAQ

Welcome to the CVS FAQ.

Rules for adding new answers:

  • Please read through the Cederqvist, the questions below, and their answers carefully before adding new answers.
  • Please keep in mind that this is a list of Frequently Asked Questions, not a general problem-solving forum. If you don't know the answer to a question, please do not add it here. You should probably be asking on the info-cvs@nongnu.org mailing list, instead.
  • If you have a question and its answer, but you aren't sure that your question is frequently asked, please ask about it on the info-cvs@nongnu.org mailing list before adding the answer here, or discuss it on this page's talk page.
  • If you still think you have a new answer appropriate for this FAQ, add it to the end of the appropriate section or, if you aren't sure where it should go, to the New Answers section at the end of this page.

dental insurance

Getting Help with CVS

This category describes some of the other CVS resources available. If you can't find your answer in this FAQ, you might try one of them.

Is commercial support or consulting available for CVS?

The Commercial Support page contains a partial list of companies offering professional technical support, consulting, and/or training for CVS on a commercial basis.

Getting Started

This is a section for beginner users just getting started installing and/or configuring CVS.

What the &*%$ is a Cederqvist?

"The Cederqvist" is the nickname for the CVS manual written by Per Cederqvist et al. There is a copy online 1 and a copy in the wiki: CVS--Concurrent Versions System v1.12.12.1.

Creating a project

Here are the steps that I took.

  1. Installed CVS software
  2. Established /usr/local/cvs-rep
  3. Set environment var CVSROOT="/usr/local/cvs-rep"
  4. cvs init
  5. cvs import /home/someuser/newsourcedir <-- I'm having troubles with this command. I need to know how to instantiate the new directory so that I can start the cvs.Essay

Try to stay away from the esoteric cvs import command that should be used to import external code trees only. The simplest way to start a new directory in the root of the repository is:

$ cvs -d $CVSROOT co -l .

This will create a copy of the root of the repository only. Create your directory and add it:

$ mkdir DIR
$ cvs add DIR

Now cd to DIR and add new files and directories recursively.

Q: I have initialized cvs with cvs init. I checked it with "cvs version", which responds me "CVS 1.11.5 (client/server)". But when I use cvs -d $CVSROOT co -l, the cvs responds: "must specify at least one module or directory."

$ echo $CVSROOT
/usr/local/cvs-rep

What should I do?

A: I think you're forgetting the "." in the command suggested. I did the same thing until I realized that I wasn't using the "." which specifies the current directory. So the command is:

cvs -d $CVSROOT co -l .

Q: I tried to setup the project with import too. But I was surprised that it created a branch 1.1.1.1 with the vendor_tag as branch tag and a release_tag src.txt 1.1 "initial import" src.txt 1.1.1.1. I do not want this. I would like to import all sources in a directory with 1.1 "initial revision".Research Paper

Is it possible to remove the unwanted (vendor) branch tag and release tag? Import is easy, since it's imports (recursively) all files into cvs. Add does not do this. Or is there any other method?

A: (pending)

Q: I have almost the same problem

  1. I've created a repository using cvs -d <path of the rep> init
  2. I steped over the directory that I wanted to add to the rep and I've used the following command: cvs -d <path of the rep> import -m <tag1> <tag2> <tag3>

When I execute this command it returns a coredump and finish the process...

Can anybody help me with this?

A: (pending)

I mistyped an import command. Can I remove the mislaid project before I try again?

Removing projects this way is discouraged but a bad import is a valid reason for doing this. `cd' into the repository and `rm -rf <project name>'. Of course, you should be absolutely sure you're done with the project before you delete it, especially if you don't have a backup.

cvs add - how do I know which files are new?

Is there an easy way to find out which files have been added to a working directory/sandbox since the last checkout was done? What I am telling the users of CVS is to use the cvs add command, each time they add a new file (e.g. a HTML file), but sometimes they forget to do so (which is very dangerous) or they really want to add all new files at the end before the commit is done. tks. Uwe uwe.geercken@web.de

The command:

 cvs -n update

will compare your local disk to the repository and tell you which files have changed (locally or in the repository) and which files are new. Files that cvs doesn't yet know about are marked with a '?' so you could use the following command to find them:

cvs -n update | grep '^?'

I would also make use of the -q argument to suppress any extra verbiage. Here is a filter I use to remove spaces and the leading "?".

cvs -qn update | grep '^?' | tr -d '^?' | tr -d "[:space:]

"

Another neat trick is to use awk to do automate your check-ins. I call the following script from within a Makefile. I just call `make add` and all my new files get added.

--Makefile--

add:
    ${PWD}/add_new.sh

--add_new.sh--

#!/bin/sh
#Script which filters list f new files and submits them to cvs
cvs -qn update | grep ^? | awk '{print $2}' |\
    awk 'BEGIN {FS="/"};
        { for (i = 1; i < NF; ++i) print "cd " $i 
          filelist = (filelist " " $NF) }
        END{ print "cvs -d $CVSROOT add " filelist }' | sh

Yes, nice grep. But how do you manage this at windows 2000? Try to install cygwin and move your project to any place under /var... It works fine to me.

How do I add a branch to a branch ("sub-branch")?

$ cvs checkout project      # get a local copy of your project
$ cvs tag -b superbranch    # create a branch, called "superbranch",
$                           # from your working copy
$ cvs update -r superbranch # start using the new "superbranch" branch
$ cvs tag -b subbranch      # create a branch, called "subbranch", from
$                           # your working copy
$ cvs update -r subbranch   # start using the new "subbranch" branch

How can I change the name of a branch?

I created a new branch and accidentally gave it the wrong name. Is there any way to change it?

To create the new name for the branch:

cvs admin -n <newbranchname>:<oldbranchname>

I usually leave the old name in the files, at least for awhile, since branches without _any_ names are quite a bit harder to recreate tags for, but if you are confident you know what you are doing, the following can be used after the above to delete the old tag from the files (you may want to use cvs log to verify creation of the new branch name before attempting this):

cvs admin -n <oldbranchname>

Another question related to the same topic: How could I rename a branch tag(HEAD) when I have the same name on the CVS tag(HEAD) as well on a given source file. Here is the vendor branch 1.1.1 has symbolic name(HEAD) at the same time CVS tag(HEAD) is pointing to 1.6 Term Paper

Working file: vdgate.cpp head: 1.6 branch: locks: strict access list: symbolic names:

       v200: 1.2.0.2
       v100: 1.1.1.1
       HEAD: 1.1.1

Trying the following cvs admin command adds BR_HEAD symbolic name but it gets the 1.6 revision instead of renaming the HEAD:1.1.1. Any help on getting this rename done is much appreciated.

cvs admin -n BR_HEAD:HEAD vdgate.cpp

Working file: vdgate.cpp head: 1.6 branch: locks: strict access list: symbolic names:

       BR_HEAD: 1.6
       v200: 1.2.0.2
       v100: 1.1.1.1
       HEAD: 1.1.1

How do I remove a directory?

Directories are not versioned in CVS and, thus, cannot be removed.

You can fake it by always using the -Pd options to checkout and update, perhaps in your ~/.cvsrc. This will cause empty directories not to be checked out and, thus, appear to have been removed once all of the files in them have been checked out.

Source Configuration Management Best Practices

There are several good, general-purpose, free documents on this subject.

Take a look at Arbitrage Conspiracy and http://www.sanchivi.com/cm/cvs-bestpractices/. This document is also available as browsable html from The Linux Documentation Project, as well as several other formats.

Other good, general purpose SCM best practices information can be found at the Assembling Configuration Management Environments (ACME) Project and the Configuration Management Yellow Pages.Thesis

What is the best branching practice to use with CVS?

It is generally said on the mailing list that "it less painful if development is done on the trunk and releases are branched for maintenance. This way, the merge-backs are fewer when main development is going on. You will have to merge fixes from the maintenance branches to the main trunk after a release but this is less of a headache because these are generally smaller and easier to manage than merging all the changes that would be made on a development branch." Sherk

But the correct branching practice also depends on the way you want to develop, so you should also consult documentation that discusses code management branching in a general way, such as Streamed Lines: Branching Patterns for Parallel Software Development .

CVS Best Practices specifically deals with other good practices for CVS use beyond branching and merging.

Other good, general purpose SCM best practices information can be found at the Assembling Configuration Management Environments (ACME) Project and the Configuration Management Yellow Pages.

What is the submit/assemble mechanism

The submit/assemble mechanism (aka. release/integrate mechanism) is a two-step handoff procedure between one phase of production to the next (e.g. developers -> release integrators). It involves creating inventories of file versions that are eligible for inclusion in the next phase, computing a manifest (or bill of materials) from these inventories, and using the manifest to control checkouts.

General Repository Administration

This category is intended for questions and answers involving the administration of CVS repositories, not including network access.

How do I relocate a repository?

Repositories can simply be renamed to a new location. For instance, `/cvsroot' could be renamed to `/home/cvs/newcvsroot': e.g. `mv /cvsroot /home/cvs/newcvsroot'.

This also means tarring the root and unpacking it on another machine is sufficient to move it to the new machine.

In both these cases you should disable repository access during the move so that users do not commit changes to the original repository during or after the move.

It is generally wise to make all of your users release their workspaces before the move if you plan on changing the $CVSROOT used to access it. The alternative to making all of your users commit and release their workspaces can be providing them with a script which redirects their workspaces to use the new root.

Is there a way to completely remove a project from the repository?

It's discouraged, but there are valid reasons to want to do this - a bad import, for example. `cd' into the repository and `rm -rf <project name>'. Of course, you should be absolutely sure you're done with the project before you delete it, especially if you don't have a backup.

Why are new files and directories being created with the wrong group on the server?

If the files are being created owned by your default group and you'd rather they be created owned by the same group that owns the parent directory, try setting the "setgid" bit on all directories under $CVSROOT ('chmod -R g+s $CVSROOT'). This enables BSD style new file and directory ownership.

How do I control list or read access within the repository?

CVS per se does not have a built-in authorization model like other SCM products (Perforce, Subversion). However there are several good options to solve the general problem of controlling read/list access to CVS resources on the server.

1) If you can live with coarse grained read access control at the CVSROOT level, you can use the CVSROOT/readers file. The file contains a list of all CVS users with read-only permissions on the repository. However this works at the CVSROOT level only not modules or file/dirs.

2) You could use UNIX permissions at the module/dir/file level. For example you could set the directory ownership within a CVSROOT to allow read access to a specific UNIX group. This gives you some control but for large repositories it means more administration and tracking permissions can be tricky. In addition the UNIX permission model can not distinguish between list versus a read operation. It cannot help you with controlling read access to CVS branches for instance.

3) Commercial tools like WANdisco's Enterprise Edition provide a complete RBAC (Role based access control) model for CVS. Access control can be as fine grained as you want. Branches can be access controlled just the same way files and directories are. You can define hierarchical sub-groups/roles to inherit access. For more information look at WANdisco ACL Model. WANdisco also offers a free version of their CVS security product.

What needs to be done to use file system Access Control Lists (ACLs) within the repository?

0. Set LockDir in $CVSROOT/CVSROOT/config
1. Initialize repository ACLs   
   a. Do not use default ACLs
   b. Set directory ACLs
      i. Make readable and executable for those that need checkout privileges
      ii. Make writable for those that need checkin privileges
   c. Set file ACLs
      i. Make readable for those that need checkout privileges
      ii. Make unwritable (for safety)
      iii. Make executable if checked out file is to be executable
2. Create a loginfo script that will:   
   a. set repository file ACLs:
      i. inherit ACLs from parent directory
      ii. inherit ACL executable bits from original file
      iii. turn off ACL write bits
   b. set new directory ACLs:
      i. inherit ACLs from parent directory

Is it possible to version directories with CVS?

Directories in CVS are not version controlled. Consistently passing the '-P' option to checkout, for instance in your .cvsrc file, is a workaround for this. ~

It is possible to version control at the directory level in CVS. Take a look at the CVSPermissions toolkit available at http://www.magic-cauldron.com/cm/cvspermissions/cvspermissions.html.

CVSPermissions does *not* provide directory versioning, as the previous comment suggests. It provides directory-level permissions. While useful, that's *not* the same thing!

Is it possible to define more than one LocalKeyword in the CVSROOT/config?

Better check 2, before answering.

Binary Files

This category is for questions and answers about how CVS deals with binary files.

Can I set cvs to treat all files as binary by default?

I know about the -kb (or -ko?) options. They are nice and useful. However, I'm still using Appgen, where all the code is stored in binary database files. I would like CVS to treat all files by default as binary files. Is this easy to accomplish?

In the $CVSROOT/CVSROOT directory there is a file called cvswrappers. You can add filename matchers here to describe how cvs should treat the files. For example, to tell cvs that all files should be binary just add the following line:

* -k 'b'

What binary file formats can CVS handle?

CVS can handle any binary format, but you have to let CVS know it is a binary file by setting the RCS keyword mode to '-kb'. If you already have a revision checked in you may have to force an extra commit after setting the keyword substitution mode.

It is worth knowing that sometimes very large binary files can cause slowdown and even stoppage of the server. In these cases, it might be worthwhile to delete revisions on the server end, but you should be very sure you know what you are doing before trying.

See the Cederqvist (CVS Manual) for more.

It seems CVS can't handle binary files very well. CVS can only point out whether two binary files differ, but not how they differ.

CVS handles binary files just fine. Not being able to detail the context of how 2 binary files differ is not a shortcoming of CVS. To do a meaningful diff (one that shows the context of the diff), the tool must understand the specific binary format that it is dealing with. I do not know of any revision control systems that do context diffs for binary files, unless they call separate programs that understand the binary format of the file. Systems that do this kind of thing are not general revision control systems (like you use for managing source code). Rather, they focus on one area, like documentation, and are usually quite expensive.

CVS will not allow you to mark a file to not have line endings changed. While a file may be "text" and all the usual text utilities work with it, the line endings may be significant (For example, files intended to be sent to a raw terminal). CVS does not currently support this.

Can you use CVS with Rational Rose for controlling models?

Rational recommends treating all Rose files as binary even though they are text. The reason being is that they don't publish how to modify them. We started out treating them as text but CVS did a merge and corrupted the files.

We do use CVS to store Rose files but we do two things:

  1. We indicate that the files are binary (-kb) when we commit 2) we publish when these files have been checked out on a web page so people know when NOT to modify them because CVS provides no way to lock another user from modifying a file while you are.

We have similarly had a lot of difficulty with CVS and Rose models. Rose is tightly integrated with our code, so when developers need to branch & merge, we have to be _very_ careful with the Rose Files.

What we've found is that, if you remove all diagrams from your rose models, it _is_ possible to merge model files (just like any other kind of text files). I can't say for certain that it will always work, but we haven't had any trouble with it thus far. Of course Rational could change the model format (again) tomorrow and this could break - but it works at present. Of course, this isn't an option for you if you rely heavily on diagrams, but luckily for us, we don't.

One other thing we do to make merges easier is to break the .mdl files down into small .cat files - so there's less chance that 2 people will be working on the same part of the model at the same time.

One other idea that might be worth pursuing is as follows: I understand there are freely available tools for importing and exporting rose models as XML files. If this is the case, it would be worth looking for a good XML diff utility. Using these tools, we could avoid .mdl and .cat files altogether and simply store the XML files in CVS.

How do I recover a text file accidentally marked as binary?

Use cvs admin -kkv file to change the file attribute to text in CVS, then cvs update -A file to sync up local file with the repository.

Networked Repositories (Client/Server CVS)

This category is intended for questions and answers involving remote CVS servers and problems accessing them via CVS clients.

Is CVS secure?

CVS has the potential for security holes, like any software. Used behind a secure firewall, CVS should be very safe from outside attackers, but would still be vulnerable to insiders if they had access to an exploit before it was documented and fixed by the CVS community.

CVS does not get thorough security audits though, by the nature of open source, it gets fairly thorough peer-review and any attempt to create simple Trojan-horses or back-doors should be noticed immediately. Instead of explicit security audits, CVS relies on administrators concerned with security to use tools such as SSH as an access method and standard operating system users, groups, permissions, and ACLs to restrict the tool's access to sensitive information. Piggy-backing CVS on top of such powerfully secure and frequently and thoroughly audited tools makes it very secure, or at least as secure as the SSH implementation and operating system you choose.

Derek 10:10, 27 Jul 2005 (EDT)

DON'T use CVS in :local: mode with a server on a network drive!!!

This has to do with the file locking method CVS uses and the way many network shares cache remote file data and can result in severe data loss.

Incompatible and broken NFS implementations are also known to cause severe data loss by writing random null bytes into archive files. Using NFS to access a CVS repository is not recommended!

The alternative is to use :pserver: or :ext: with SSH as an access method.

If you still must try this and encounter problems, don't come crying to us.

If you still must try this and do manage to solve any of these problems, well-written patches and workaround advice are happily accepted at bug-cvs@nongnu.org. Derek 12:32, 25 Jul 2005 (EDT)

CVS local with Samba repository commit error

Please see before proceeding with this advice. Derek 12:32, 25 Jul 2005 (EDT)

Using cvs on windows with a repository which is located on a SAMBA server may cause a problem when a user tries to commit a file owned by another user. The error message provided by cvs would read like this:

l:\project> cvs commit file
Checking in file;
r:/repository/file,v  <--  file
new revision: 1.2; previous revision: 1.1
cvs aborted: cannot rename file h:/repository/,file, to h:/repository/file,v: File exists

The following excerpt from the smb.conf manpage explains the problem and provides the solution:

delete readonly (S)
This parameter allows readonly files to be deleted. This is not normal DOS semantics, but is allowed by UNIX.
This option may be useful for running applications such as rcs, where UNIX file ownership prevents changing file permissions, and DOS semantics prevent deletion of a read only file.
Default:
delete readonly = No
Example:
delete readonly = Yes

This problem was successfully solved by adding the option delete readonly = Yes to the definition of the file space service which contains the repository.

How do I install a CVS pserver under Mac OS X?

Installing CVS on Mac OS X differs slightly, but in key ways, from the default installations listed in the CVS documentation. The overview:

  • password authentication happens with netinfo
  • services in OS X are scheduled through netinfo, not through /etc/services
  • the environment inherited by the inetd-launched cvs can cause errors (which the cvs documentation does not correctly diagnose.) these errors look like:
cvs server: cannot open /var/root/.cvsignore: Permission denied
cvs [server aborted]: can't chdir(/var/root): Permission denied

All of the above issues are easily solved, however, but i was unable to find them all in one place, so i added this cookbook faq entry. Here's the walkthrough, in 5 easy steps:

  1. ensure you've got cvs installed.
    • Apple supplies a version of cvs. It is not part of the standard OS X installation, but is installed from either the XTools CD (if supplied) or by downloading the latest version of XTools from developer.apple.com/tools/xcode/.
  2. add the cvs pserver service with netinfo tools. type the following into a terminal:
    niutil -create . /services/cvspserver
    niutil -createprop . /services/cvspserver port 2401
    niutil -createprop . /services/cvspserver protocol tcp
  3. append the following to your /etc/inetd.conf file. the launching of the command from a subprocess (env) solves the error often seen above:replace /cvsroot with the path to your $CVSROOT:
    cvspserver stream tcp     nowait root  /usr/bin/env env -i /usr/bin/cvs -f --allow-root=/cvsroot pserver
  4. restart inetd:
    kill -s HUP `ps cax | grep inetd | awk '{ print $1 }'`

    and that should be it. you can now login with:

    cvs -d :pserver:user@hostname:/cvsroot

    with appropriate user, hostname, and cvsroots for your particular install.

Nicely put!

I only answer 1):

  • The CVS-binary is distributed as part of Apple Developer Tools, accessible from developer area on apple.com.
  • The complete dev-tool file is ~250-300 MB.

/Wilmer T

under item 3, according to inetd.conf in Jaguar OS X 10.2.x and newer:

# Mac OS 10.2 and forward uses xinetd instead of the traditional inetd.
# See xinetd.conf(5) if you need to add a service to run out of xinetd.

Having set up a cvspserver entry in /etc/xinetd.d as below

service cvspserver
{
        disable         = no
        socket_type     = stream
        wait            = no
        protocol        = tcp
        user            = root
        passenv         =
        server          = /usr/bin/cvs
        server_args     = -f --allow-root=/cvsroot pserver
}

where /cvsroot is the location of your repository as per the previous example, it starts up & is running according to

/sbin/service --list

but trying to login as above results in the following:

3 phile% cvs -d :pserver:phile@philsg5:/cvsroot login
(Logging in to phile@philsg5)
CVS password:
cvs aborted: authorization failed: server philsg5 rejected access

Any suggestions?

For installing cvs pserver under Mac OS X 10.4 (Tiger) and later, here's what seems to work:

You'll need to create a launchd control file, call it cvspserver.plist, and put it in /Library/LaunchDaemons:

 <plist
version="1.0"> <dict>        <key>Label</key>
        <string>com.apple.cvspserver</string>
        <key>UserName</key>
        <string>cvs</string>
        <key>Program</key>
        <string>/usr/bin/cvs</string>
        <key>ProgramArguments</key>
        <array>
                <string>cvs</string>
                <string>-f</string>
                <string>--allow-root=/Users/cvs</string>
                <string>pserver</string>
        </array>
        <key>Sockets</key>
        <dict>
                <key>Listeners</key>
                <dict>
                        <key>SockPassive</key>
                        <true/>
                        <key>SockServiceName</key>
                        <string>cvspserver</string>
                        <key>SockType</key>
                        <string>SOCK_STREAM</string>
                </dict>
        </dict>
        <key>inetdCompatibility</key>
        <dict>
                <key>Wait</key>
                <false/>
        </dict>
</dict> </plist>

(this was pulled together from various sources, the best being man launchd.plist and an article on launchd from afp548.com.

Change the "/Users/cvs" string above to your $CVSHOME, of course.

You may also want the UserName key to have a value of root rather than cvs (there may be no cvs user on the system, in which case you will get "launchd: com.apple.cvspserver: getpwnam("cvs") failed" messages in /var/log/system).

Then,

$ sudo launchctl load /Library/LaunchDaemons/cvspserver.plist

and you're up and running.

Under Tiger, cvs doesn't seem to be able to use system user/password info, so you'll have to create a password file in the CVSROOT like this (mutatis mutandis):

$ cd ~cvs # CVSHOME
$ cd CVSROOT
$ sudo htpasswd -c passwd <first user>
Type new password:
Retype new password:
$

and then use

$ sudo htpasswd passwd <other user>

etc. to add new users. If anyone has a clue about how to get cvs to use the built-in user/password database, I'd sure love to hear it.

More Information on Installing CVS on Mac OS X

For starters, here's the CVS page on the Apple developer site: developer.apple.com/opensource/cvs.html

Finally, this page gives a pretty good overview on using CVS locally and over the network: developer.apple.com/internet/opensource/cvsoverview.html

SSH CVS is much simpler to configure (and more secure) than pserver cvs. Current versions of Eclipse can do SSH CVS without any plugins. Set up a CVS server on Mac OSX in 4 steps and 4 minutes: http://bratton.com/?p=5

How do i generate a passwd file in $CVSROOT/CVSROOT?

Please see the Cederqvist for information on the format of the CVSROOT/passwd file.

My favorite method for generating crypted passwords is using the Perl crypt function:

perl -e 'print crypt "password", "sa"' >>$CVSROOT/CVSROOT/passwd

Where "sa" is the salt, or an arbitrary two character string which is used to encrypt the password. You will of course have to subsequently edit the passwd file to get the generated crypted password string into the proper location.

Another method you can use is to cut and paste the password from a UNIX passwd file, but this probably won't work if you are using "shadowed" passwords. Derek 12:32, 25 Jul 2005 (EDT)

Please also note that, if using multiple repositories e.g. for security reasons, each repository must provide its own password file in $CVSROOT/CVSROOT/passwd. A randomized generation of the salt to provide the password string is suggested here: http://www.faqs.org/docs/ldev/0130091154_201.htm.

Also note here, though, that the example provides a general user access as third field of the password row that is generated (for more on that, see the Cederqvist).

/Wilmer T

htpasswd command should be used to generated passwd file in the $CVSROOT/CVSROOT directory.

htpasswd is the default built in command in linux. To create passwd file and storing userrname and encrypted passwd in the file. htpasswd -c passwd userA return prompts for password for userA and Re-Type confirmation. To add more username's in the passwd file use the following command.

SYNTAX : htpasswd -b <PASSWD FILE> <USERNAME> <PASSWORD>
EXAMPLE: htpasswd -b passwd userB userB htpasswd -b passwd userC userC

One single repository and several platforms

Hi, We want to use CVS, and we have 3 different platforms: Linux, Solaris and Windows. The CVS repository and the /home/users will be on LINUX, and will be mounted on Solaris via NFS, and on Windows via Samba. I have several questions:

  1. I have installed the CVS solaris package 1.11.1 for Solaris 2.8, CVS 1.11.1.p1 for Linux, and want to install CVS 1.11.1 on WindowsNT. Are these versions are compatible or should I build cvs 1.11.1.p1 for all these systems?
  2. So our Solaris developers will update the CVS Linux repository using CVS Solaris software, our Linux developers will update the same Linux repository using CVS Linux Software, and our windows developers will update the same repository using CVS Windows software. Could that create conflicts (in the sens for exemple that these CVS updates the repository on different way)
  3. Is there a CVS client/server configuration to perform in this case, or it should works fine only by using the local CVS with the mounted cvs repository?

Thanks a lot Virginie

Hi, I think the best way to use CVS in your case is to set up a client/server configuration. You can also use Wincvs to access to the Repository (graphical cvs GUI on PC/Windows). We have projects with several (local or not) platforms that acces to a Unix repository and we are using to use client/server access on a CVS repository. Catherine

I am faced with a similar situation and what concerns me most is the issue of case-sensitivity. Our software product runs on both 16-bit and 32-bit versions of Windows and, to ensure compatibility all around, we actually run some machines under Windows 3.1 code. We actually do have UPPER.CAS ;-) file systems, and so we do have SHOUT.ING filenames. And it's fairly easy for a single file to be worked-with on one computer that uppercases names and then worked-with by one that understands mixed-case. What I want to make sure of is, that CVS will not somehow interpret those files to be different!

Furthermore, the repository will reside on a Red Hat Linux system; the native filesystem there is ext3, of course, and that's case-sensitive. What I would like to be able to do, I think, is to somehow specify on a repository-basis or better yet a project-basis that "these file-names are case-insensitive." I'm trying to figure this issue out before bringing CVS on-line here. A definitive response is rather urgently needed by me on this point and I'd love to get e-mails anytime (soon!) to answer this question for me.

How do I access a CVS repository using SSH?

Using SSH as a connection method to a CVS repository is exactly like using RSH. See the "Remote Repository" section of the Cederqvist. Note that SSH must be set up properly to connect without asking for a password and may break if you have login scripts which generate text when they run. Failing this, you COULD possibly set up an SSH tunnel for a CVS pserver connection but this is fraught with complications. I mention this only because some people seem to like to try anyhow.

Derek 12:58, 25 Jul 2005 (EDT)

See also: CVS--Concurrent Versions System v1.12.12.1: The Repository.

Setting up an SSH tunnel to a pserver CVS repository is actually fairly simple and there are a variety of reasons you may need or choose to do this. You will need to have a shell account on the host with the CVS repository in order to tunnel with SSH. Probably the most simple command to start the tunnel is: ssh -L 2401:remote.cvs.repository.host:2401 -g shellaccount@remote.cvs.repository.host. If, after establishing your tunnel, your attempts to use "localhost:2401" in your CVSROOT value don't work, you may need to use your local hostname instead of "localhost". Try running hostname in a local shell to see what it returns, and use that value.

As long as you remain logged in, anyone connecting to your local host on port 2401 will be accessing the pserver repository at the host "remote.cvs.repository.host" via your SSH tunnel. I think that leaving off that "-g" flag will only allow you to contact your local port from your box, rather than allowing remote hosts to contact your box on that port. So, unless you want your box to relay traffic from other hosts across your tunnel, you should probably leave the "-g" off. Some implementations of CVS clients (MacCVS Pro, one of my otherwise personal favorite CVS clients, comes to mind) do not support SSH connections directly at all, so if you wish to have the security and compression that SSH provides, this manner of tunneling may be your only option.

One additional note, when doing SSH port forwarding to a pserver CVS repository, using the -z option in CVS is not generally wise (and is unnecessary since SSH can provide compression already) as this can sometimes cause binary files to be mangled in the transfer. :(

I had a hard time going through the relevant documentation and actually getting things to work. Just a short cut answer that might work for people: set the CVS_RSH environment variable to "ssh". For bash this would be

export CVS_RSH="ssh"

set CVSROOT similar to using rsh

export CVSROOT=":ext:username@remotehost:/path/to/cvsroot"

And you're set. -Rushabh

If you use Emacs you may find that the simple CVS_RSH="ssh" settings do not work; for example, Emacs's C-x v = (vc-diff) command may contain garbled output. To work around this problem, set CVS_RSH=$HOME/bin/ssh4cvs instead, where $HOME/bin/ssh4cvs contains the following shell script:

#! /bin/sh
# Arrange so that ssh's stderr is never stdout,
# by interposing a "cat" process between ssh's
# stderr and our stderr.  Why bother?  Because
# ssh puts stderr into nonblocking mode, and
# CVS (which uses stdio for stdout) gets confused
# if stdout and stderr are the same file.
# See:
# http://lists.gnu.org/archive/html/bug-cvs/2002-08/msg00032.html
exec 3>&1
exit `((ssh "$@" 2>&1 >&3; echo $? >&4) | cat -u >&2) 4>&1`

For more details about ssh4cvs, please see http://lists.gnu.org/archive/html/bug-cvs/2004-09/msg00005.html.

Maybe this can be useful for someone. When the SSH is asking for password it is possible to connect and use wincvs (at least the version 1.3) if you make the following: go to menu "Admin" and select the option "Preferences". In the oppened window, select the tab "CVS". At this point, select the option "Enable CVS console (open TTY)". The important thing is, if you are using protocol :ext: you can not use the login command. The checkout, update and the other commands can be used and in each time you try to execute them, one terminal window will open and you can put your password. That is it.

How do I set up a CVS server for access via SSH?

Each developer needs a shell account on the server which he or she can access via SSH and needs to be able to run CVS in local mode once logged into the server. See CVS--Concurrent Versions System v1.12.12.1: The Repository.

Derek 12:58, 25 Jul 2005 (EDT)

There is a description of how to set up anonymous CVS access via ssh at http://kitenet.net/programs/sshcvs/.

A single "cvs" account which can only do "cvs server" commands. Requires ssh2 in sshd.

How do I access an internal CVS server via an SSH gateway?

This is only for cases where you cannot tunnel without a key. You can port-forward via an ssh external-facing host, which doesn't have cvs. You will require shell access on both machines, as well as an account in the CVS passwd file.

There is a good description of the process at http://gentoo-wiki.com/HOWTO_CVS_Server In summary you need a one line script in your path eg host_ssh:

  1. ! /bin/bash

ssh -t login@host.tld -pNNNN ssh "$@" (you won't need the -port number if it's standard 22)

Then in ~/.bashrc: export CVSROOT=:ext:cvsUsr@internal:/var/lib/cvsd/root export CVS_RSH=host_ssh

This document explains how to set up the keys: http://www-128.ibm.com/developerworks/library/l-keyc.html You set up one key with a passphrase to access the ssh host. scp that across and mv or append it to ~/.ssh/authorized_keys (chmod g-rx,o-rx ~/.ssh as well if you just made it.) Then generate a new key while logged into the ssh host via password. scp this across to the internal cvs host, and save it in the same manner. Now when you exit back to the gateway, you can log ssh to the internal cvs host without a password. This is what enables CVS to log into the internal machine via ssh.

Exiting back you can test the script with host_ssh login@internal ls. You should be asked for the passphrase to the key and then see a list of your shell home account on the internal machine.

A shell function in ~/.bashrc for host_ssh will not work as cvs looks for an executable file (so chmod +x it.)

How do I get CVS pserver working with xinetd?

Create a file called /etc/xinetd.d/cvspserver containing the following settings:

service cvspserver
{
        disable             = no
        socket_type         = stream
        protocol            = tcp
        wait                = no
        user                = root
        passenv             =
        server              = /usr/local/bin/cvs
        server_args         = --allow-root=/usr/local/newrepos pserver
}

Restart xinetd (/etc/init.d/xinetd restart) and you're on your way.

If you have the permissions on your ROOT account set to exclude world access, you may encounter problems unless you add a

env      = HOME=/usr/local/newrepos

or something similar to set the HOME environment variable to a directory where cvs can look for .cvsignore files (among other things).

The more efficient way to accomplish this is by passing the `-f' argument to CVS. Derek 12:58, 25 Jul 2005 (EDT)

In redhat, cvs is located in: /usr/bin/cvs, so you need to change the service to...

service cvspserver
{
        disable             = no
        socket_type         = stream
        protocol            = tcp
        wait                = no
        user                = root
        passenv             =
        server              = /usr/bin/cvs
        server_args         = --allow-root=/usr/local/newrepos pserver
}

--- I worked this out because there was a limit to the number of arguments allowable in inetd. However, it worked so good in practical matters, I still use it. The main reason is you do not have to use root and restart xinetd to add, remove, or diable one or more of the "--allow-root" arguments. It also keeps the IT guys happy that I'm not "su"ing all over the place ;-)

service cvspserver
{
        disable             = no
        socket_type         = stream
        protocol            = tcp
        wait                = no
        user                = root
        passenv             =
        server              = /repos/redirect-cvs
}

and:

#!/bin/sh
#========================================
# redirect-cvs
#========================================
exec /usr/bin/cvs \
     --allow-root=/repos/project_one \
     --allow-root=/repos/project_two \
     --allow-root=/repos/project_three \
     --allow-root=/repos/test_repos \
     pserver

--- On our system, we do not run with the username of "root," but with a limited (designated as nologin) user and group that is dedicated to the purpose. All access to CVS from local users is set up to use "CVSROOT=:fork:/usr/cvsroot" (or whatever), so that access even by local users occurs using the client/server protocol. The repository's permissions are set up so that the repository can't be accessed except by that user/group. And it seems to work.

how to link client and server through GSSAPI

Hi all, to set this up, follow the below steps:

  1. on the cvs server, run kadmind -p username/admin, then add a krb5.keytab for the cvs service by doing the below:
    addprinc -randkey cvs/host.domain
    ktadd cvs/host.domainname
    This will create the keytab file in /etc on the cvs server.
  2. make sure your cvs binary is linked to the gssapi libs by running ldd /usr/bin/cvs
    • If your running a newer version of Red Hat > 7.0, then the default cvs binary should have the krb5 libs linked by default. FreeBSD however ships with krb4, so you'll have to compile krb5 by hand from /usr/ports and then re-compile cvs and link it to the gssapi libs created from ports.
  3. Next obtain a tgt from a client
    1. kinit username
    2. Then cvs co module. You should now see the cvs service ticket on the client when you run "klist". If you do not, start troubleshooting.

Troubleshooting:

  1. Check that your time is in sync on both the server and the client.
  2. On the client make sure your CVSROOT is correct (CVSROOT=:gserver:servername/cvsdir).
  3. On the server make sure inetd or xinetd is configured properely:
    service cvspserver
    {
            disable         = no
            socket_type     = stream
            wait            = no
            user            = root
            server          = /usr/bin/cvs
            server_args     = --allow-root=/cvsdir -T/tmp -f pserver
    }
    

Good Luck Cory Vokey Sr. Systems Administrator ACI/MessagingDirect Edmonton, Alberta Canada

Can 2 CVS servers talk to each other?

Since feature release 1.12.9 or so, CVS has supported "writeproxy" functionality, which allows any number of read-only CVS servers to serve as a proxy for write commands to a central, writable, repository. It is somewhat complicated to set up, but see CVS--Concurrent_Versions_System_v1.12.12.1: The Repository for instructions.

If you were looking for some other functionality, submit a patch!

Derek 12:58, 25 Jul 2005 (EDT)

Does CVS supports PAM for user authentication?

There are several ways.

  1. http://sourceforge.net/projects/cvs-nserver/. It's a bit of a pain to get setup, but works a treat doing LDAP auth via PAM.
  2. The development version of CVS currently supports PAM on an experimental basis and PAM support should be in the next feature release (1.12.2) of CVS if you are willing to build your version from the source and configure using `--enable-pam'.

Support may be shipped in binary versions of CVS if we receive enough positive feedback on the feature.

Ksh and ssh and cvs: cannot find cvs

Anyone trying to run cvs over ssh from ksh? My ssh login from client to server works just fine, without prompting for the password. cvs over ssh fails to find cvs. I am assuming that it doesn't run the .profile or .kshrc and therefore fails to find cvs. Can anyone enlighten me on how I can fix the problem?

When running cvs:

cvs -d :ext:taylor@dwhprod:/home/taylor/cvs checkout -p CVSROOT/modules
ksh: cvs:  not found cvs aborted: end of file from server (consult above messages if any)
  1. export CVS_SERVER=/some/path/cvs on client solved this for me. See CVS--Concurrent_Versions_System_v1.12.12.1:_All_environment_variables_which_affect_CVS. (Note: this worked for CVSNT on Windows too, set CVS_SERVER=/path/to/cvs - no need to edit anything on the server system at all, just locate the path to the cvs executable on the server.)
  2. ssh reads $HOME/.ssh/environment and adds lines of the format 'VARNAME=value' to the environment. I created the environment and set my PATH variable there and was able to checkout with any more problems. The one downside is that variable substitution isn't recognized, so if you enter PATH=$PATH:/usr/local/bin you will literally get '$PATH:/usr/local/bin' back from an echo.

--- I did set the PATH etc. in .ssh/environment but it still does not work. Is there any idea about how I can check if these settings are at all honored?

Execution of .ssh/environment is disabled by default at least in OpenSSH. Have a look in the SSH server config file /etc/ssh/sshd_config and change the line

 #PermitUserEnvironment no
 PermitUserEnvironment yes

I'm using CVS_RSH=ssh. Is the whole session encrypted or just the authorization?

When you connect through SSH, you encrypt _all_ the data. This is this way because then, the only way to access the repository is the SSH protocol, and it is used for authorization and for transferring the files as well. You can test this by closing all the ports on that a computer listens except the corresponding to the SSH connections (TCP 22). You can do that with an intermediate firewall or simply closing the port in the CVS server computer. The try to work with the CVS. You will see than you can still work.

Basics: Does cvs support IPv6 connections?

Yes, it does. On any platform where pserver is supported, configure it in the same way as an IPv4 service.

Mirror Repositories

Is it posssible to set up CVS repository mirrors?

Yes.

CVS was designed and first implemented over 20 years ago, for the type of networks that existed 20 years ago. Networks today (even slow ones) are much better, so mirrored repositories are generally not required to solve performance problems. Mirrored repositories are used to:

  1. save on bandwidth across dial up lines
  2. set up read-only CVS mirrors for non-developers
  3. allow a laptop to be used "offline" and still allow diff/revert to previous version

Often people look for a mirror solution when the problem exists elsewhere, see this thread for more information

  1. Open Source / Free solutions:
    1. For read-only mirrors, see the CVSup project.
    2. For multiple proxies that perform read operations locally but proxy write connections through to a central write server, see CVS--Concurrent Versions System v1.12.12.1: The Repository.
    3. For combined CVS, Access Control, Audit, Write Proxies, Repository Synchronisation, Read Only Repositories on Linux/Windows/Mac/Solaris/HPUX see CVSNT 2.5.04
  2. Commercial solutions (in alphabetical order):
    1. CVS Professional Multi Site with Audit, Access Control and Repository Replication - by the same people who provide the open source Linux/Winodws/Mac/Unix CVSNT - March Hare Software USA - UK - Australia
    2. Wandisco - which wraps CVS in such a way to handle mirroring and allow writes against an arbitrary number of mirror servers, see the CVS Replicator at wandisco cvs page. It allows creation of true multisite CVS without changes to CVS clients or servers. It is specially designed for offsite, geographically split team. WAN latencies can be reduced to 0 with the rotating quorum feature. You can also see the the following threads: thread on info-cvs and thread on cmcrossroads.

How do I set up a CVS server for access via ext or pserver on Windows

Use CVSNT. I haven't been able to get the Linux command line for inetd to work on Windows, so CVSNT is pretty much the only option. Download at http://www.cvsnt.com. Installation guides at http://www.cvsnt.com/wiki and http://www.devguy.com/fp/cfgmgmt/cvs/cvs_admin_nt.htm.

The Cygwin tool kit, available from http://cygwin.com, also implements inetd and sshd for windows, but it is still fairly complex to use it to set up a CVS server.

Date not available when in Eclipse 3.0.1 when comparing with revision

The date is showing "Not Available" when I compare with revision on all files checked in from my Eclipse 3.0.1. My CVS 1.12.9 is running on a linux Debian system. When I manually look into the files in the cvs repository, the tags are there with correct date and time. Have anyone experienced this?

here we go: cvs server versions < 1.12.9 returned the date in "cvs log" commands like this:

yyyy/MM/dd HH:mm:ss zzz

versions >= 1.12.9 are returning the date like this:

yyyy-MM-dd HH:mm:ss zzz

eclipse (<= version 3.0.2) doesn't understand this new format, but e.g. eclipse 3.1 is available to handle this format. so you have 3 solutions:

  1. update eclipse to version 3.1
  2. downgrade cvs to a version < 1.12.9 3.)
  3. you "backport" the bugfix from version 3.1 to 3.0.2 modify the file: plugins/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/LogListener.java (attached to this mail). The "bug" is in a method of the file "DateUtil.java". Move this method to LogListener.java and implement it like this:
    /**
     * Converts a time stamp as sent from a cvs server for a "log"
     * command into a <code>Date</code>.
     */
    private Date convertFromLogTime(String modTime) {
        String timestampFormat = LOG_TIMESTAMP_FORMAT;
        // Compatibility for older cvs version (pre 1.12.9)
        if (modTime.length() > 4 && modTime.charAt(4) == '/')
            timestampFormat = LOG_TIMESTAMP_FORMAT_OLD;
    
        SimpleDateFormat format = new SimpleDateFormat
            (timestampFormat, LOG_TIMESTAMP_LOCALE);
        try {
            return format.parse(modTime);
        } catch (ParseException e) {
            // fallback is to return null
            return null;
        }
    }

    the file DateUtil.java isn't needed anymore then. regards, mr.bienzle

Why is the "TZ" environment variable ignored?

This will happen when you are using remote such as :pserver when you are on the same machine as the repositary. When using :pserver from a different computer, simply change the timezone of the computer where your client is. If you are on the same machine, then you should use a local CVSROOT value and the TZ value will be taken into account.

TZ=EST cvs -d /home/cvs log file1  # Works (Timezone taken into account)
TZ=EST cvs -d :pserver:localhost:/home/cvs log file1  # Does *NOT* Work (Timezone ignored)

This is true for version 1.12.13 and might be thru for other versions as well.

Branching and Merging

Branching and Merging seem to be the source of a lot of confusion. Here are some common questions and their answers.

How do I replace branch A with the contents of branch B?

Scenario: you have a branch (by "branch" we are also referring to HEAD), branch A, and a revision B (which could be a branch tag, or a non-branch tag). You want to make branch A appear to be identical to revision B. You don't want to merge the changes from the branch, but completely overwrite the trunk with the branch.

This is quite simple to accomplish, using CVS's merge command (yes, I know you just said you didn't want to merge, please read on). You just update to the target branch (the one that will receive the updates), then merge from the source branch, using this syntax:

cvs update -rTARGET_BRANCH # or cvs update -A if target is HEAD
cvs update -jTARGET_BRANCH -jSOURCE_REVISION

then commit.

Remark: Remember to use option '-d' to bring new directories into branch A alongside the modifications to existing files, i.e.,

cvs update -jTARGET_BRANCH -jSOURCE_REVISION -d

if the source branch contains new directories.

Example (all examples assume a clean checkout, with the current working directory as the base directory of the project):

  • Replace the HEAD with the contents of BRANCH_X:
cvs update -A
cvs update -jHEAD -jBRANCH_X
cvs commit
  • Replace BRANCH_B with the contents of BRANCH_A:
cvs update -r BRANCH_B
cvs update -j BRANCH_B -jBRANCH_A
cvs commit
  • You have released a version, say rev 1.4, and tagged it with REV_1_4 (not a branch tag). You have been making changes on the trunk, adding new features. For some reason (business requirements have significantly changed, the code is utter garbage, whatever) you need to scrap that work, and start from rev 1.4 again:
cvs update -A
cvs update -j HEAD -jREV_1_4
cvs commit

Note that this will not delete any intervening revisions - those are still in the repository in case you ever need to refer to them again.

  • Similar to the previous scenario, but you want to revert to revision 1.1 on all files:
cvs update -A
cvs update -j HEAD -j 1.1
cvs commit

For a detailed explanation on how this works, see CVS Merging Details

That's great, but I only want to do this for a few files

Simple: in the 'update -j -j' command, specify which files you want copied, as in:

cvs update -A
cvs update -j HEAD -j REV_1_4 file1 file2 file3 file4 ... fileN

Only the files specified will be copied. All other files will be unaffected.

If you only need to copy one or two files, then you can simply combine update's -p and -r options. Suppose you want to copy files a and b from the trunk to a branch REV_1_4. As above, first make the branch the working revision:

cvs update -A

then for each file, issue the command

cvs update -p -rREV_1_4 file>file

--Jhyslop 16:22, 28 Oct 2005 (EDT)

Common Error Messages

Many error messages are listed in CVS--Concurrent Versions System v1.12.12.1: Troubleshooting.

Here are some of the more common ones:

`cvs login: authorization failed: server xxx rejected access to /devel/test'

Read the "Troubleshooting" section of the Cederqvist carefully, particularly CVS--Concurrent Versions System v1.12.12.1: Troubleshooting.

-- Derek 13:32, 25 Jul 2005 (EDT)

I just resolved a truly entertaining case on Linux where authorization failed for some users in some directories, yet not for other directories or for the failing directories and other users. The reason turned out to be line-ending conventions in CVS/Root and CVS/Repository in the affected directories. In the problem ones, these files ended with a CR/LF pair (0x0D 0x0A) instead of only a linefeed (0x0A). Since cvs was trying to log in to /devel/testCR instead of /devel/test, it flunked the authorization. The solution was to edit the appropriate files and remove the spurious carriage returns. I still don't know how they got in there, but I suspect a combination of a DOS/Lose editor and Samba.

-- Charles Shapiro

Similar problems as described above may bappen if there's something wrong with the CVSROOT/passwd file. Re-running cvspasswd (and so setting a new password) doesn't help in these cases. Cleaning the passwd file fixed it.

Seems there's a problem with unprintable chars (ie. CR/LF problem again).

-- nekrad 19:37, 16 Dec 2005 (CET)

`cvs server: cannot open /root/.cvsignore:access denied'

This is a *very* common common problem. Read the "Troubleshooting" section of the Cederqvist (CVS Manual). Pay special attention to the subsection titled, Trouble making a connection to a CVS server.

`Missing hostname in CVSROOT.'

You are running a version of CVS prior to 1.11.1 and have forgotton to place a colon after the hostname in your CVSROOT value.

E.g.: `:ext:me@foo.org/cvshome', rather than the required: `:ext:me@foo.org:/cvshome'

`binary files differ' cvs commit failure on Solaris 5.7

This message, in conjunction with a failure to commit a binary file, has to do with a problem with /bin/diff on Solaris and a hardcoded path to this diff utility in rcsdiff.

The solution is to upgrade to a more recent version of CVS. CVS hasn't used external rcs programs since release 1.9, which is over 5 years old.

failed to create lock directory for '/cvsroot/project/subdirectory'

Update fails with message:

failed to create lock directory for '/cvsroot/project/subdirectory'

Solution: On SysV systems (e.g. Linux) directories are created with the creator group id. If you find this can be solved temporarily using:

chgrp -R cvs_group_name cvs_root_directory

(where cvs_group_name cvs_root_directory have your project specific values) then you you may find it useful to set the SGID bit on the parent directory. You can do this using:

chmod g+s cvs_root_directory

This will ensure that newly created directories inherit their group id from the parent directory rather than the group id of the creator.

cvs aborted: can't chdir(username): No such file or directory

On the Windows platform, various CVS commands display the following error message when executed from the native command line:

cvs aborted: can't chdir(<username>): No such file or directory

The message occurs after the command seems to have done some work. Executing the command repeatedly may eventually get all of the work done. For example, when trying to commit three changes, the first change may get committed before the command aborts. Executing the command three or four times finally gets all of the changes committed. Executing the same commands from within WinCVS (even the exact same commands using the the "Command Line" option) works OK.

If this occurs, check to see if there is a HOME environment variable set. The documentation indicates that CVS uses this on the Unix platform, but it probably checks for it on all platforms. In our case, the HOME environment variable was probably set by a network login script, which is why the directory it was trying to change to was the user's login ID ("username").

To resolve the problem, remove the HOME environment variable:

set HOME=

Hopefully this will save someone else a lot of time tracking this one down - I could not find anything similar in any of the newsgroups or elsewhere.

`No such file or directory', with chroot & checkout

It turns out that cvs absolutely needs a /dev/null to be able to checkout files. This will affect you if your running a cvs:pserver under a chrooted environment on linux atleast. So remember to make a dummy "/dev/null".

Hi, sorry. i didn't get it really. i already have /dev/null, but it still doesn't work.

My problem:

  • cvs 1.11.14 running on linux
  • repository on my home directory
  • i want to check it out in a fat32 partition on the same computer.
    cvs checkout: cannot open CVS/Entries.Log: No such file or directory
    cvs [checkout aborted]: cannot open CVS/Root: No such file or directory

When i try to to check it out on my own home directory it works!

thanks, Peter

cvs aborted: your apparent username (xxxxx) is unknown to this system

This happens under Windows only with release 1.11.2 of CVS. Use a newer release.

CVS.EXE aborted: could not find out home directory

If you are working in Windows you must set %HOME% variable. Type the command, `set HOME=D:\CVS\MYPROJECT', at a shell prompt, or add this line to your environment settings available via right clicking "My Computer" and selecting "Properties". Once set, the `.cvspass' file will be stored in directory %HOME%.

With some older versions, fixing the above may cause the following error to appear: .

cvs aborted: cannot rename file h:/repository/,file, to h:/repository/file,v: File exists

Please see .

cvs add: <filename> added independently by second party

This means that someone else added a file of the same name in the same location from another workspace. You can move your copy out of the way and update to pull down the new version of the file, then merge it with your own copy.

Derek 15:00, 25 Jul 2005 (EDT)

I've experienced this issue when enforcing Java Coding Standards using Websphere Studio and CVSNT. For instance, another programmer checks in categoryNode.java. Well, according to Java Coding Standards, classes should start with an upper case letter, so the file name should be CategoryNode.java. However, CVSNT, probably because it's running on Windows, thinks the file name is still the same, although WSAD is aware of the change and insists the file is new. The work-around is a two-step process:
1. Rename categoryNode.java to NewCategoryNode.java. Commit all changes. categoryNode.java will be removed.
2. Rename NewCategoryNode.java to CategoryNode.java. Commit all changes. Done.

--Tschrader 17:11, 6 Feb 2006 (EST)

Or:

  1. Rename categoryNode.java to CategoryNode.java.
  2. Commit the removal of the old file (categoryNode.java)
  3. Then commit the new renamed file (CategoryNode.java)

--Esge Moos 10-04-2007

cvs login: failed to open <HOME>/.cvspass for reading: No such file or directory

This problem is fixed in CVS versions 1.11.2 and later.

The workaround, if you don't wish to upgrade your CVS version as the CVS developers recommend, is to create an empty ~/.cvspass file then try again. On UNIX systems, something like touch ~/.cvspass does the trick. On Windows, some program like notepad should help.

cvs aborted: Failed to create temporary file: No such file or directory

I could not find the root cause of this error message when trying to commit changes. My TMPDIR environment variable was not set. CVS error message should in my opinion give more information (such as what file cvs is unable to create).

I found 2 simple ways to work around the error message by:

  • setting TMPDIR environment variable (example: export TMPDIR=/tmp)
  • by using cvs global option -T to specify temp dir (example: cvs -T /tmp commit ...)

cvs aborted: end of file from server (consult above messages if any)

This is an extremely common error message, but is rarely CVS's problem. It occurs when the CVS client's underlying transport mechanism manages to connect to the CVS server but retrieves no data.

If you are encountering this problem, first consult CVS--Concurrent Versions System v1.12.12.1: Troubleshooting, for instructions on how to verify that your underlying transport mechanism is set up correctly. Common problems include:

  • inetd or xinetd not set up correctly.
  • Rate limiting in inetd and xinetd.
  • Number of users limited in inetd or xinetd.
  • sshd not set up correctly.

There are a few rare combinations of CVS clients and servers which can cause this problem when the server is otherwise set up correctly. If you verify that your transport is set up correctly and you are still encountering this problem, try making sure you are running the most recent versions of the CVS client and server. If anything, upgrading the server should solve the problem.

Derek 15:21, 25 Jul 2005 (EDT)

connection refused

Please see: CVS--Concurrent Versions System v1.12.12.1: Troubleshooting.

cvs aborted: unrecognized auth response from 192.168.1.3: cvs: ...

inetd, xinetd, ssh, or whatever is calling the CVS server with incorrect command line options. Please see: CVS--Concurrent Versions System v1.12.12.1: Troubleshooting.

cvs update: move away `foo/bar.c'; it is in the way

  1. Read the following threads:
    1. http://lists.gnu.org/archive/html/info-cvs/2001-03/msg00163.html
    2. http://lists.gnu.org/archive/html/info-cvs/2001-04/msg00566.html
  2. Check foo/CVS/Entries.
  3. Check CVS/Entries (i.e. 'foo' is probably missing).

cvs commit: sticky tag 'XXX' for file 'file' is not a branch

When committing, you get the above error message.

This means that the file you are trying to check in was checked out with a sticky tag, but that tag was not a branch. You can only check in files if there is no sticky tag, or of the sticky tag is a branch tag.

To fix this problem, you have to clear the sticky tag:

cvs update -A

or if the file is on a branch,

cvs update -r branch_tag

You can then commit the file.

Jhyslop 12:57, 20 Dec 2005 (EST)

Specific Platforms (Operating Systems)

This category is intended for questions about using CVS on specific platforms. There is a list of platforms CVS has compiled on successfully in the INSTALL file in the top level of the CVS source distribution. If you get CVS to compile on a platform not in the list, please send a report to bug-cvs@gnu.org including the version of CVS you compiled, the operating system name and version of the machine you compiled it on, and the short architecture description (CPU type) of the machine. For UNIX-like OSs, please submit the output of `uname -a'.

RedHat Professional 8.0?

Is there a CVS build for Redhat Linux 8.0 Professional or can I use the CVS builds for RedHat 7.x?

There is a version of CVS 1.11.2 distributed with RedHat 8.0. You should be able to use that rather than downloading a binary, but the 7.3 binary should work just fine.

Windows Clients and UNIX Servers?

Windows clients generally work with UNIX CVS servers accessed via the :pserver: method or via SSH. Some common problems include:

  • Due to case insensitivity, it is possible, though uncommon, to have two files which get checked out on UNIX which look like a single file under Windows.
  • If you use two subdirectory names in one directory which differ only in case, the Windows box will get big problems on checkout and update. Even if one subdirectory is empty while the other is not (and you use -Pd options), you will get "cvs update: move away `foo/bar.c'; it is in the way" messages frequently. This is because the Windows CVS client does not find out that these are different directories, thus, the CVS/ subdirectory of one directory will be overwritten with the CVS/ directory of the other. It seems to be pure luck which one gets overwritten with with one.
  • Don't use the same workspace under Windows and UNIX via a network share or whatever. CVS performs OS dependant line ending conversions and this will confuse it. Use separate checkouts on Windows and on UNIX.

Windows NT / 2000 / XP?

There is a Windows version of the CVS server available from: http://www.cvsnt.org/

A client GUI which runs on Windows, Mac Classic, Mac OS X, and the Gnome windowing manager under UNIX is available from http://www.wincvs.org/ and the client GUI project is hosted on sourceforge: http://sourceforge.net/projects/cvsgui/.

A Java client is available from http://www.jcvs.org/.

The standard CVS source releases can usually be compiled on Windows using MS Visual C 5.0 or later. See the INSTALL file in the CVS source distribution for more information.

I use the CVS client fine under Cygwin (www.cygwin.com) on Windows 2000.

Instructions for a command line version of CVS are available at http://www.splike.com/howtos/cvs.html.

I am left with the impression that the "cygwin" package has a number of other useful goodies, like SSH support, which are commonplace in Unix but hard to find in Windows. I myself do not fully understand what all of the Windows-client possibilities are (yet), nor how (e.g.) WinCVS might interact with Cygwin and/or the lack thereof.

Sun Solaris

Q: Will CVS run on Solaris 2.7?

A: Sure, download the source or binaries from http://ftp.cvshome.org or try one of the binary packages available from http://sunfreeware.com or binaries from scoruri live (though sunfreeware.com usually seems to lag a few versions behind cvshome.org) Links for CVS binaries for 7 and 8:

2.7: http://www.sunfreeware.com/programlistsparc7.html#cvs

2.8: http://www.sunfreeware.com/programlistsparc8.html#cvs

Also, since Solaris is binary backward-compatible, 2.5.1 and 2.6 binaries should work fine on 2.7 and 2.8.

Q: I have download cvs-1.10.7-sol7-sparc-local.gz from http://sunfreeware.com and unziped it by gzip. But I don't know how to install it to the system. Where can'i get the guidance.

A: To install the latest (as of this writing) cvs from Sunfreeware:

wget ftp://ftp.sunfreeware.com/pub/freeware/sparc/8/cvs-1.11.22-sol8-sparc-local.gz
pkgadd -d cvs-1.11.22-sol8-sparc-local.gz

VMS?

CVS is known to compile and run under VMS. Only some very old VMS binaries are available via the cvshome.org FTP site.

Patches are still cooked up and applied for VMS, so newer versions of CVS should compile and run, at least on some VMS machines. Please search the bug-cvs mailing list archive for more information.

AIX installation?

Can CVS be setup on AIX 5.1 on an RS/6000 model 43p? If so are there any special considerations or OS specific download? We are using Websphere Development from an XP environment. If CVS would work more reliably, or be easier to use under Windows, I could do that.

Mac OS X?

Setting up a CVS server on Mac OSX in 4 steps and 4 minutes: http://bratton.com/?p=5

Other Questions and Unsorted Questions with answers

Where do I download CVS from?

See http://www.nongnu.org/cvs/#downloading for sources.

Binaries are currently not available, but should be restored soon. Please feel free to submit links to binaries to bug-cvs@nongnu.org for mirroring at the above FTP site.

How do I delete revisions from an archive?

You probably don't really want to delete revisions from an archive, but lets break it down:

If you just made some changes that are breaking your build, you probably want to back out your changes. Backing out changes is one of the things CVS is good at and cases like these are one of the reasons people use CVS. You can "remove" the changes you made between any two revisions while keeping a log of the fact and retaining the ability to recover the changes later. This is covered in the Branching and merging section of the Cederqvist (CVS Manual).

If you really want to delete a revision, it can be done, but it is discouraged as it can break old builds and cause other problems. Look up the `admin' command in the Cederqvist and particularly the `-o' option, but keep in mind that once you delete a revision this way it is never coming back.

Is there any tool for command line client to see the version tree in text form (short!) without seeing entire log?

  • For wincvs one is there (button); for jcvs also there must be something.
  • Eclipse has a graph view (CVS Repository Exploring perspective)
  • The following command line tool generates image files with branching and tagging information: http://www.akhphd.au.dk/~bertho/cvsgraph/
  • I've written a script to do this. It's reasonably quick but currently doesn't handle branches too well - but does show them. If you want a copy then email me at andrew.fry7@ntlworld.com.

Why is CVS running so slowly?

This can happen for any number of reasons, but usually it's because you are making too many demands on your server resources. Increasing memory on the repository server and removing other programs which take up CPU time can help. You can get up to a tenfold speed increase by using a temporary file system (/tmp) on a RAM disk (in memory).

When a large number of concurrent users are accessing a CVS server simulateously, that can cause a large number of CVS processes to be forked. Each CVS process can consume memory equal to ~ 2-3X the largest file size the CVS command is trying to process. This can cause issues like SWAP space becoming too low or too much CPU load being placed on the system. You can offload a large CVS repository by creating multiple active replicas using commercial tool like WANdisco CVS Replicator. This tool can effectively allow you to scale horizontally by clustering multiple machines to act as one virtual repository. Thus you can share CVS traffic across multiple machines with strong fault tolerance guarantees. You can even use a hardware load balancer tool to spray CVS load equally across machines much like a web server farm. For more information visit the WANdisco web site.

Also make sure that there is some free space (around 700-800 MB) on your CVS server machine.

Is there a way to list modules and files on the server from the client?

The 1.12.x (feature) series of CVS releases and CVSNT both support the cvs ls command.

For older versions of CVS, several workarounds exist:

  • 'cvs co -c' and 'cvs co -s' will cat the CVSROOT/modules file. This is a viable workaround, but the modules file must be maintained and is not versioned. There are several scripts and patches floating around that do similar things. I believe 'cvsls' is the name of one of them. Try searching the mail archives, the web, and cvshome.org for more.
  • cvs rdiff -s -D 01/01/1971 -r $rev $mcode will list all of the files in the repository. You can prune it to get just the modules.
  • cvs history -c -a -l | awk '{sub(/4.*/,"",$8); print $8;}' | sort -u
  • You can create a CVS directory, and add the files Repository with a single `.' in it and an Entries with a blank line, then run "cvs update -dp" which very quickly ouputs the module names to stderr. A script to do this may be obtained by running cvs -d :pserver:anonymous@bothie.sharedaemon.org:/home/public/bodo/cvs/public co bothie-utils/cvsmodls.

I've wrapped a bash script around the above suggestions using cvs history & awk. Used in a directory under CVS control it'll list the modules in the current repository and the -d option lets you specify an alternative CVSROOT.

<nowiki>
#! /bin/bash
if [ $1 = '-h' ]
then
    echo "Usage: cvsmodules [-h] [-d cvsroot]     list CVS modules"
    echo "    -h           display this help and exit"
    echo "    -d CVS_root  Overrides \$CVSROOT or CVS/Root as the root of the CVS tree."
    echo
    echo "Provide a list of modules in the repository for the current directory or "
    echo "a specified repository."
elif [ $1 = '-d' ]
then
    cvs -d$2 history -c -a -l | awk '{sub(/[/].*/,"",$8); print $8;}' | sort -u
else
    cvs history -c -a -l | awk '{sub(/[/].*/,"",$8); print $8;}' | sort -u
fi
</nowiki>

I just use this one-liner... yes it does show the root but I don't mind.

<nowiki>
cvs history -a | awk -F= '{print $2}' | sort -u | uniq
</nowiki>

Another script to do the same:

<nowiki>
#!/bin/ksh
myname=`basename $0`
usage="\nUsage: $myname [-h] [-a] [-d cvsroot] list CVS projects\n-h\t\tdisplay this help and exit.\n-a\t\tdisplay all projects (not just top-level).\n-d cvsroot\tOverrides \$CVSROOT as the root of the CVS tree.\n"
optroot=$CVSROOT
display="TOP"

while getopts d:ah OPT
do
  case $OPT in
    d) optroot=$OPTARG ;;
    a) display="ALL" ;;
    h)
       echo $usage
       exit 0 ;;
    \?)
       echo $usage
       exit 1 ;;
  esac
done
echo
if [[ $display = "ALL" ]]
then
  cvs -d $optroot rlog -h -N . 2>&1 | awk '$3=="Logging" {if($NF !~ /.*Attic$/ && $NF != ".") {for(i=4; i
<NF; ++i) {printf("%s ", $i)} print $NF; next}} $3=="failed" || $3=="aborted]:" {print $0}'
else

 cvs -d $optroot rlog -h -N . 2>&1 | awk '$3=="Logging" {if($NF != "." && $0 !~ /\//) {for(i=4; i

<NF; ++i) {printf("%s ", $i)} print $NF; next}} $3=="failed" || $3=="aborted]:" {print $0}' fi echo

</nowiki>

Can I preserve the sticky bit or set uid or set group id bit within the CVS Repository?

CVS has some code which attempts such things, as well as preserving some special files (symlinks, device nodes, etc.), but it was notoriously buggy and has been disabled for quite awhile. You can try enabling PRESERVE_PERMISSIONS in options.h and recompiling, but you'll probably have to fix some bugs.

The usual suggested work around is to set those bits as part of your build process, from your Makefile, for example.

Can I plug an alternate 'diff'ing utility into CVS?

I'm using APPGEN which if you don't know about don't worry. Suffice to say all the code is stored in a database so it's possible for files to be textually different but not functionally so. There's a built-in diff command (dbdiff) that I would like CVS to use when comparing files instead of traditional diff. CVS is no use to me if I can't do this. Anyone know if it can be easily done?

Again, not really.  There's been some talk about developing in this direction, but as far as I know no real work has been done in this area yet.  If you have time to work on this, please volunteer!

The Subversion project (as of version 1.0) supports arbitrary diff commands besides the default (unified diff).

If you are only concerned about the diff tool used in the merging process, WinCVS, and thus, possibly, MacCVS and gCVS has a facility for using external visual diff tools to help resolve conflicts during merges.

For Windows NT, I created a Windows command-line script that will invoke a different "diff" utility - in this case "WDiff".

Source of file "wd.bat":

@REM "diff" file and earlier revision using "wdiff"
@if not .%1 == . if not .%2 == . goto ok
@echo -------------------------------------------------------------------------
@echo wd - invoke WDiff to compare latest revision with earlier revision
@echo Usage:
@echo    wd {file.ext} {rev}
@echo    wd {package/file.ext} {rev}
@echo    wd {package\file.ext} {rev}
@echo       use either forward slashes or backslashes in package specification
@echo       "rev" can be either a specific revision number or a symbolic tag
@echo Examples:
@echo    wd overview.html
@echo    wd com/ourcompany/Parameter.java 1.1
goto end
:ok
cvs update -p -r %2 %1 > c:\temp\wdiff.tmp
wdiff32 c:\temp\wdiff.tmp %1
:end

Can CVS version links?

Not really.  There's some buggy and disabled code (search for PRESERVE_PERMISSIONS in the mailing list archives) which you might try and fix if you were motivated.

The usual suggested workaround is to make creation of links part of your build process (in a script or Makefile or the like) and version the files that create them.

Rolling back the repository based on a date

Here is what you need to do if you want to revert the changes in you repository back two days:

  1. Check out the HEAD: cvs co <module> or cvs up
  2. Create a tag based on the date, you could also create a remote tag if you want the rest of the world to know about it. The -D can be any date format that CVS will reconize. e.g. cvs tag -D "2 days ago" two_days_ago or cvs rtag -D "2 days ago" two_days_ago project
  3. Clear the sticky bits: cvs up -A.
  4. Do the reverse join: cvs up -j HEAD -j two_days_ago
  5. Update after you do the join: cvs up.
  6. Commit the changes: cvs ci.

If you need to revert changes on a branch, create the start and end tags as above, but also specify the `-r' option to tag or rtag.

Here is another method:

This does exactly what the above does, but uses external diff/patch rather than CVS's internal diff3, so you will get *.rej files on merge conflicts instead of conflict markers inside the file.

  1. if you did not previously tag the version you want to revert to, do so retroactively using the date options to rtag (as shown above)
  2. cvs commit -m "botched" (this commit, after you execute he following tag, command gives you a name to use in generating the reverse diffs and also gives you a backup in case you forgot to check in some changes you don't want to revert)
  3. cvs tag NEWTAG (substitute an appropriate tag such as BOTCH001)
  4. cvs diff -u -r NEWTAG -r OLDTAG |patch -p0
  5. cvs commit -m "after reverting to OLDTAG" (so most recent version in archive won't be a botched version
  6. cvs tag TAGxxxx

Another potentially dangerous method of trying to revert (using bash) is:

for i in $files; do cvs update -p -r OLDTAG $i > $i; done

If one of the files listed in $files was never added to cvs with "cvs add", it will be silently replaced with a zero length file. This is particularly dangerous because it erases the very files you don't have backups of in cvs.

Operations on old versions are easier if you tag after every commit; a design flaw of CVS is that it versions individual files rather than collections of files. A script like this (call it tagit) can generate automatically increasing tag numbers.

#!/bin/bash
tag=`cat tagno`; let tag=$tag+1; echo $tag >tagno
tagno=`printf "TAG%04d" $tat`
cvs tag $tagname
echo $tagname

As of feature release 1.12.12, each commit is automatically tagged with a commit ID and these commit IDs are displayed by cvs status and cvs log, though there is still no way to refer to these commit IDs directly via -r arguments to checkout, update, and so on.

Export: I want to export sources overwriting existing files in the target directory

Unfortunately, export isn't very good at this by its nature. Since it doesn't save meta data about the exported files, even if it was willing to overwrite the files, it wouldn't notice and remove deleted files.

Your best bet is either to use checkout/update (see Keeping an checked out copy in the Cederqvist (CVS manual)) or export to a new directory name then quickly move the old directory out of the way and move the new one into its place.

#! /bin/sh
cvs export -Dnow -dnewcopy module
mv module module.old
mv newcopy module
rm -rf module.old

Derek 16:23, 25 Jul 2005 (EDT)

Thank you very much for your tip. We have come upon something that fits out needs in the meantime: we wrapped the export command into a script that does the export into a temporary directory, then copying/creating the source entries and directories one by one by comparing the target directory to the temporary directory. We move away the existing entries to something like <old-entry>.save_old thus giving us some kind of an additional safety feature where we can check what has been patced lately.

Permission settings on checked out files

As far as I can see permission settings of the checked out files and the CVS directories in the working directories are based on the users' umasks. We want to share a working directory between users belonging to a certain group (that means write access to group for the CVS subdirectories - especially the Entries file). On the other hand we only want individual write access to the checked out files. Is there a possibility to get these permission settings automatically from cvs?

CVS doesn't want to override the users umask as a default.

As far as other permissions are concerned, CVS will preserve the 'x' bit of files as they are checked into the repository, but the information isn't versioned. The 'watch' (and associated) commands, the $CVSREAD environment variable and the global '-r' flag can be used to manipulate them in limited ways.

Sharing working directories can cause problems and isn't recommended. Read up in the manual on the loginfo admin file and, "Keeping a checked out copy" for alternatives to this technique. You might also search the mailing list archives for more information on this topic.

In the Cederqvist (for CVS 1.11.2) in Sec. 15, I see "CVS also ignores file permissions and ownerships." So, in other words, CVS stores file contents, not properties?

In WINCVS version 1.0.6, there is no option of permissions settings on checked out files. But I think it is very important with the developer point of view. Unable to get anything about this in internet.

You will be READ ONLY files if a "cvs watch" is set. This is CVS's way for reminding you to do a cvs edit on the files. You can do a "cvs watch off" to disable - check with "cvs watchers". Otherwise it is down to the users umask in their sandbox / or whether they've specifically requested a ro copy.

How can I use CVS from inside my corporate proxy server?

As of CVS release 1.12.7, CVS supports connecting via HTTP proxies using "connection options" with a syntax like
<nowiki>:pserver;proxy=

<proxyserver>;proxyport= <portnum>:</nowiki>

See CVS--Concurrent Versions System v1.12.12.1: The Repository
A work-around for older CVS versions
  • Download and build a simple HTTP proxy command line tool, such as corkscrew.
  • Write a wrapper shell script /usr/local/bin/mytunnel. Substitute the HTTP_PROXY_HOST, HTTP_PROXY_PORT symbols according to the corporate environment and CVS_SERVER, CVS_PORT, CVS_ROOT with the CVS server details.
    <nowiki>
    #! /bin/bash
    if [ $# -eq 0 ] ; then
        set -- ${CVS_SERVER} ${CVS_PORT}
    fi
    exec corkscrew ${HTTP_PROXY_HOST} ${HTTP_PROXY_PORT} "$@"
    </nowiki>
  • Run the netcat tool in the listening mode paired with the above wrapper script.
    <nowiki>
    while : ; do nc -l -p ${CVS_PORT} -e /usr/local/bin/mytunnel ; done
    </nowiki>
  • In another terminal, run the cvs client in pserver mode against localhost:
    <nowiki>
    touch ~/.cvspass
    mkdir ~/CHECKOUT && cd ~/CHECKOUT
    CVSROOT=":pserver:anonymous@localhost:${CVS_ROOT}"
    cvs login
    cvs co -c
    cvs co .
    </nowiki>
CVS via SSH
The following is for cvs via ssh see this site http://proxytunnel.sourceforge.net/
I should add that many proxys I've tried do alow you to use port 22 (ssh), so ignore the setting up a ssh server on port 443, and set the ssh-client to use 22.
ViewCVS scrapping
I have written a little utility called cvsgrab that uses the ViewCVS web interface for a repository to checkout all the files in it. You can get it from http://cvsgrab.sourceforge.net cvsgrab is useful for people who want to checkout anonymously files from a cvs repository, and cannot use the ssh solution because ssh requires you to be a registered developer in the project.
-Ludovic
WinCVS
In WINCVS (version 1.0.6), there is an option "preferences". There is a tab of "proxy" in that option. The user can specify the Host name or IP of the proxy as well as port number for the proxy for CVS.
  1. Download whttpstunnel (search on google)
  2. run it
  3. for local port (22), for proxy (your proxy IP address or name) for port (your proxy port) for remote host (cvs-ssh.sourceforge.net) port (443)
  4. Click start
  5. Run Pageant (just like the docs say on the sourceforge site).
  6. Run WinCVS (if you are not using version 1.3.17.2 your dialogs might be different)
  7. From Menus Pick Admin->Preferences Auth is "ssh", Settings... set to c:\putty\plink.exe (or where ever you installed that)
    1. Host Address (normally you'd set this to cvs-ssh.sourceforge.net but in this case you are going through the tunnel so set it to "localhost"
    2. Username, your sourceforge user name CVSROOT would normally be username@cvs-ssh.sourceforge.net:/cvsroot/projname but again we are going through the tunnel so it's "username@localhost:/cvsroot/projname"
  8. Select a folder, right click and pick "checkout" and type in just the project name under "module name and path on server"
It worked for me (horray!) :-)

What is the status of UTF-8 sourcecode in CVS?

We're producing Java code containing swedish characters on Windows 2000. The file is saved in UTF-8 which means that the special characters are saved as two byes (e.g. hex 81 E5 for one character). CVS complains, stating that characters 0x00-0x20, 0x80-0xFF are escape characters, when adding the file to CVS. When commiting and checking out the file again, it seems as if there is no problem, but can I be sure? Does CVS handle these escape characters differently from other characters (i.e. bytes)?

We are programming various websites in japanese, chinese, korean and english we use cvs to handle website development. so far we had never problems with char-sets. so i can say its stable with sjis, utf-8, big-5 ...

checkout module without leading directory names

is this possible to checkout or export without the leading folder information? i would like something: cd $CHK_DIR cvs checkout module1 and instead of having a module1 folder, i would like to have only the content of it.

thx

Dear User, Use the following command to checkout the module without leading directory names cvs co -d <DIRECTORY> <MODULE>

For example:

cvs co -d cvstest help/userguide/index.html

index.html file will be checked out and file will be present under cvstest directory. I hope this is clear.

Dear User, If you want to the file and not the cvs details then use the following command:

cvs co -p <repository filename> > <filename>
cvs co -p source/common/AString.java > Test.java

The above command checkout the latest AString.java and store the contents in Test.java (Note: there will not be any cvs details for Test.java).

where do I find pcl_cvs, an emacs client for CVS?

download pcl_cvs from ftp://rum.cs.yale.edu/pub/monnier/pcl-cvs from the README: PCL-CVS is a front-end to CVS. It integrates the most frequently used CVS commands into emacs. For VC users, PCL-CVS can be thought of as a VC-dired specially designed for CVS. PCL-CVS is not a replacement for VC and is supposed to interact well with it. It provides a global view of your project and allows execution of cvs commands on several files at a time.

PCL-CVS is a now a standard package in Emacs 21.1 (and later versions). See the `PCL-CVS' submenu of the `Tools' menu, or try `M-x cvs-examine'.

Can I lock a file when I check out it? I'm working in local net.

I'm working in local net. When I check out a file, can I lock it? Thanks.

You could set the "sticky tag" by checking out a version explicitely, e.g.:

cvs update -r 1.4 myfile.c

This would set the file myfile.c read-only in the repository. To commit changes of this file later, you need to remove the sticky tag again. Do so by using:

cvs update -A myfile.c

Keep in mind, that everybody else can remove the sticky tag as well to commit his/her changes, plus on normal checkout nobody would notice the sticky tag (thus starting modifications and then may be disappointed about the whole). A good idea is to notify the other developers about not changing the file, and using the sticky tag in addition to that (e.g. for those who ignored the notification or forgot about).

Locking files

We are using CVS 1.10 and we have problems locking files. For example, if a user (A) locks a file named test.txt, and another user (B) tries to unlock the same file (test.txt), CVS removes the lock allowing the user B to edit the file without problems, and the user A lost the lock. Dou you have an idea, how can we fix this?

Hi.. I am using 1.11.1 . Try locking twice the tree. First 1.1.1.1 version and then create a tag@ 1.1. then lock that version

Error in Win32 version; hash.c.312: findnode:

The error given is

cvs: hash.c.312: findnode: Assertion 'key != ((void *)0)' failed.
cvs aborted: received abort signal cvs commit: saving log message in C:\DOCUME~1\username\LOCALS~1\Temp\

This is caused by a file being committed where there is already a version in the repository, where the capitalisation is different. To solve, rename the version being committed to the original filename, or delete the original from the repository. I think it may be possible for the clash to occur even if the original was removed from the repository, and a manual delete within the source tree may be necessary.

How do you move files in the repository w/o losing history?

There is no tidy way to do this in CVS. See http://subversion.tigris.org for a CVS-like version control system that *does* support renaming.

For the non-tidy CVS workaround, see CVS--Concurrent Versions System v1.12.12.1: Adding, removing, and renaming files and directories

How to copy sources from branch to main trunk?

I have imported sources to the vendor branch and want to copy them to trunk without suggested merging.

Why? Just merge it.

A not cvs manner would be to:

  1. update to the branch
  2. copy the branch sources in another newly created empty directory
  3. update to the main trunk
  4. copy the sources from the directory containing the branch sources (see point 2 in the maint trunk local directory
  5. check the functionalities of the main trunk with the copied files
  6. if it works tag the main trunk to a new tag for .. that is a manual merge ;)

Need script to move from Design Sync Rev Control to CVS

The best I can suggest is attempting to adapt the pvcs2rcs script distributed with CVS.

Updating an old branch

Does anyone know how I can update an old branch release? I checkout that branch and want to update 1 jar file and then commit it and update that branch. But it CVS tells me that I must remove sticky tabs before I can commit. If I remove the sticky tabs, I loose the code from that branch.

Thank You

You can commit against a branch tag, but not a "normal" tag. The solution therefore is to branch when you make a release and commit against that.

How do I delete a tag?

CVS--Concurrent Versions System v1.12.12.1: Revisions

Can I rename a MODULE?

It can be aliased with a new name using the modules file.

It can also simply be renamed in the repository, though this invalidates any checked out workspaces. The easiest way to work around this is to have all users check in their work first then rename the modules, then allow the users to check it out with the new name.

And who knows what happens to the history of the module in this case?

History of individual files in the module is preserved, using either the module alias or renaming the top level directory. What isn't preserved is the path created on checkout. Ie, cvs co orig-module would check out files under the local directory "orig-module", whereas the new cvs co new-module would check out by default under the local directory "new-module", for _all_ versions of the project, using tags created before or after the module was renamed.

Similar things happen if you rename subdirectories, but the effects are more likely to break a build. For example, if, before the rename:

$ cvs co -rrelease_1_0 module
U project/olddir/file1
...

and after the rename:

$ cvs co -rrelease_1_0 module
U project/newdir/file1
...

Then a Makefile in the project directory may still expect to find files in olddir and refuse to build release 1.0 of the project.

Also, see CVS--Concurrent Versions System v1.12.12.1: Adding, removing, and renaming files and directories and CVS--Concurrent Versions System v1.12.12.1: Adding, removing, and renaming files and directories.

How do I backup and restore complete CVS repository?

CVS--Concurrent Versions System v1.12.12.1: The Repository

How do I extract the change history on a branch?

Option 1.
In our project we have similar setup and also had the desire to see a "change history" just on a branch boundary. Therfore we used the cvs diff like follows:
<nowiki>
cvs -q diff --brief -r branch1_start -r branch1_end | grep -i "^index"
</nowiki>
This script analyzes the output of the cvs rlog and filters out the changes made in a specified period.
Option 2.
Run the following script.
<nowiki>
#! /bin/sh

REALCVSROOT="/export/home/cvs"

function usage() {
    cat >&2 <<-EOT
Usage: `basename $0` BRANCH MODULE ["DATE_RANGE"]
Where
        BRANCH is the branch name or "MAIN" for the main branch or "any"
        for changes on any branch within the given date range.
        MODULE is the full path of CVS directory or file name.
        "DATE_RANGE" is the date range, see examples below.
	
If no time zones are specified, the local time zone is assumed.  Note that 
CVS logs and ViewCVS show time in GMT.

Dates can be specified in free format, but the stricter the better,
i.e. 

        diffbr MAIN niti/Makefile "1998-10-03 2:55 GMT<1998-10-03 2:55 GMT"
        diffbr r3_72 niti/src "Apr 15 19:56:11 EDT 2003<"
        diffbr any niti/src/weaver/wvnamed.cc now

To obtain the latest revision, use "now" as the date range.  For the 
last revision before the given date, supply the respective date only.

For information on other date range formats, see info cvs.


EOT
    exit 1
}

function getrlog() {
	set -e
	case "${DATES}" in
	  ("")
	    cvs rlog -N "${branchspec}" "${MODULE}"
	    ;;
	  (*)
	    case "${branchspec}" in
	      ("")
	        cvs rlog -N -d "${DATES}" "${MODULE}"
		;;
	      (*)
	        cvs rlog -N "${branchspec}" -d "${DATES}" "${MODULE}"
		;;
	    esac
	    ;;
	esac
	set +e
}
export -f getrlog

function getrange() {
	gawk '
		/^cvs rlog: warning: no rev/ { skip=1 } 
		/^RCS file:/ { file=$3 } 
		/^total revisions:/ { selrevs=$6 } 
		/^revision / { if (!lastrev) lastrev=$2; firstrev=$2 } 
		/^====/ { 
		    lastdigit = \
		    	gensub(/^(([0-9]+\.)*)([0-9]+)\.([0-9]+)$/, "\\4", 
				"g", firstrev);
			
		    digitbeforelast = \
		    	gensub(/^(([0-9]+\.)*)([0-9]+)\.([0-9]+)$/, "\\3", 
				"g", firstrev);
			
		    firstdigits = \
		    	gensub(/^(([0-9]+\.)*)([0-9]+)\.([0-9]+)$/, "\\1", 
				"g", firstrev);

		    if (lastdigit != "") {
			lastdigit_less1 = strtonum(lastdigit) - 1;

			if ((lastdigit_less1 == 0) && (firstdigits != "")) {
			    firstrev = \
			    	gensub(/^(.*)\.$/, "\\1", "g", firstdigits);
			} else {
			    # When firstdigits is empty, the MAIN trunk is
			    # inspected and the branch point is emptiness.
			    # We''ll be using cvs rdiff -r 1.0 -r 1.X to
			    # produce the whole revision 1.X.
			    firstrev = firstdigits \
			    	"" digitbeforelast "." lastdigit_less1;
			}
		    } else {
		        # signal an error
		    	firstrev = "";
		    }
		    
		    if (!skip && selrevs) 
			print file, firstrev, lastrev; 
		
		    skip = 0; 
		    selrevs = "";
		    lastrev = "";
		    firstrev = "";
		    }
		'
}
export -f getrange

function getdiff() {
	while read file firstr lastr; do
		f="${file#${REALCVSROOT}/}"
		f="${f%,v}"
		echo "+ cvs rdiff -r ${firstr} -r ${lastr} ${f}" >&2
		set -e
		cvs rdiff -r ${firstr} -r ${lastr} ${f} \
		    | gawk '
			NR == 4 { 
			    print gensub(/^(.*)\/Attic\/([^\/]+) /, "\\1/\\2", 1)
			    next
			}
			{ print }
		    '
		set +e
	    done
}
export -f getdiff

MODULE="${2}"
case "${MODULE}" in
  ("")
    usage
    ;;
esac

DATES="${3}"

BRANCH="${1}"

case "${BRANCH}" in
  ("")
    usage
    ;;
  ("MAIN")
    branchspec="-b"
    ;;
  ("MAIN.")
    branchspec="-r"
    ;;
  ("HEAD" | "HEAD.")
    echo "HEAD is not a branch name, did you mean MAIN?" >&2
    exit 1
    ;;
  ("any")
    case "${DATES}" in
      ("")
        echo "The \"any\" branch specifier requires the date range" >&2
	exit 1
	;;
    esac
    branchspec=""
    ;;
  (*)
    branchspec="-r${BRANCH}"
    ;;
esac
export branchspec

getrlog | getrange | getdiff
</nowiki>
If I remember correctly, I needed to set up the REALCVSROOT configuration variable because the cvs output contained the absolute path of a symlinked CVS root. (http://ei.homeip.net/svn/scripts/diffbr?view=markup)

Add projects from one CVS repository to another

Looking for a way to remove the code from one repository on an NT CVS server and load the data (without losing the history etc.) into another CVS repository on a Linux Server. Also Backup and Recovery of the main repositiry (incase the merge stuffs up etc.). Have not found any answer on the FAQ so far.

I have done this from Windows (using cvsnt) to linux. It is simple - just archive the repository directory using e.g. winzip, transfer it to the Unix system and unpack it. Would be a little more complicated if you have lots of users, you need to migrate these too.

file already exists version 1.1

This message will be thrown when then there is already a version in the repository and you again try to do cvs add <filename>. Assume a file A.java under source directory. now under source directory say user A done cvs add of A.java and checked in the file now the version of A.java is 1.1. Now without knowing this if user B does the cvs add A.java this message "file already exists version 1.1" will be thrown. Best possible thing user B can do is that do cvs update A.java and see the difference ( cvs diff ) and do cvs ci A.java which now will hold the version 1.2.

Hope this clears the doubt.

cvs update -r tag:date doesn't work

Starting at least at CVS feature release 1.12.12, CVS handles a -r branch:date format, like the format that has long been accepted by the -j options to checkout and update, just about anywhere it used to accept a tag.

Previous to 1.12.12, many commands, including update, accepted -r branch -D date

It still doesn't work.

xv40opt02> /grid/common/pkgs/cvs/v1.12.13/bin/cvs -v

Concurrent Versions System (CVS) 1.12.13 (client/server)

Copyright (C) 2005 Free Software Foundation, Inc.

Senior active maintainers include Larry Jones, Derek R. Price, and Mark D. Baushke. Please see the AUTHORS and README files from the CVS distribution kit for a complete list of contributors and copyrights.

CVS may be copied only under the terms of the GNU General Public License, a copy of which can be found with the CVS distribution kit.

Specify the --help option for further information about CVS xv40opt02> xv40opt02> /grid/common/pkgs/cvs/v1.12.13/bin/cvs diff -r RE_BRANCH_XAE_62:"1 day ago" Makefile cvs aborted: tag `RE_BRANCH_XAE_62:1 day ago' must not contain the characters `$,.:;@' xv40opt02>

How can I exclude subdirectories on a checkout of a module?

There are two ways that this can be done. The more straightforward way is to type it on a command line, the other way is to create an alias in your modules file.

So, let's consider a module named my_module that has subdirectories a through f. We can use the command 'cvs co !my_module/b !my_module/d my_module to checkout the module and exclude the b and d subdirectories on checkout.

For the same thing in the modules file, you will create an alias. Something like:

my_module_abridged -a !my_module/b !my_module/d my_module

Then use "cvs co my_module_abridged" to get the abridged version of the module.

(I tried it in version 1.10 of CVS. I don't know what the earliest revision of CVS to have this capability is. I expect more recent revisions to have it too.)

to exclude *all* subdirectories while checking out a module use the following command

cvs co -l <module name>

assume in the repository you are having a directory hierarchy as mentioned below

my_module/a
my_module/b
my_module/c
my_module/d

i.e under my_module directory 4 ( a,b,c,d ) subdirectories are present.

execute cvs co -l my_module to ignore subdirectories checkout ( a,b,c,d )

thanks

How do I get a date based diff on a branch?

Starting with CVS 1.12.12 or so, the -r option or any CVS command will accept a branch:date format.

Previously, I found that the following worked for me:

  1. cvs co -r {branch name} -D {date} {module}
  2. cd {module}
  3. cvs tag {new tag name}
  4. cvs rdiff -r {tag name from step 3} -r {branch name} {module}

cvs --help co tells me that this is an unaccpetable way to use the co command. Therefore, this may not work for you. I'm using CVS on Windows via Cygwin.

How do I undelete a file?

Follow the instructions for backing out changes in the manual using tags or, if you know the name of the file to be undeleted, just cvs add filename.

How do I add a directory tree without using `cvs import'?

Assuming the pwd (`.') has already been addded to CVS:

find . ! \( -name CVS -type d -prune \) -exec cvs add {} \;
cvs ci

Can the modules file contain names with spaces ? (I am transfering from another VC-tool)

You can refer to a module name with spaces in quotation marks using command line. for example:

$  cvs -d /home/cvs/Directory checkout "Module Name with spaces"

How do I lock file not to be edited by anyone else on CVS?

Despite being used to working this way with PVCS or MS Visual Source Safe, or whatever, you really shouldn't need to do this when working with text files in CVS.

Really. I'm not kidding. Go read through the manual slowly.

No, really. I mean it. It works. Try it for awhile.


I really did mean it, but if you still feel the need to insist, perhaps for working with binary files, the cvs edit and cvs watch series of commands mimic this behavior using and advisory locking model.

The rcslock script distributed in CVS's contrib directory may also be installed on the commitinfo commit hook and used to provide an enforced locking model. Again, I don't recommend it except possibly when dealing with binary files.

Derek 21:50, 25 Jul 2005 (EDT)

keeping 'cvs up -d' with modules persistant

If you have a very large project kept in the CVS repository, and you want to be able to have views of that project, you would have to make use of the CVSROOT/modules feature.

This is good for the initial checkout of a module. The problem is later on, when you are activly working with a checked out module, that 'cvs update' will not bring new directories added to that module, and 'cvs update -d' will bring the full project tree, and will not be limited to the directories defined in CVS/modules.

The below patch which I use, makes the modules work in a 'sticky' notation. After checking out a tree with 'cvs co <module>' the subsequent 'cvs update -d' will use the module information to decide what directories belong to this module.

I tested this patch on cvs-1.11.2 and cvs-1.11.9.

diff -u /home/ortal/src/cvs-1.11.2/src/add.c ./add.c
--- /home/ortal/src/cvs-1.11.2/src/add.c        Tue Feb  6 17:29:43 2001
+++ ./add.c     Sun Aug  4 17:01:39 2002
@@ -174,6 +174,21 @@
           special-case this.  */
        if (found_slash)
        {
+           /* Get the module name */
+           char *update_dir, *filedir, *p;
+           filedir = xstrdup (argv5);
+           p = last_component (filedir);
+           if (p == filedir)
+           {
+               update_dir = "";
+           }
+           else
+           {
+               p6 = '\0';
+               update_dir = filedir;
+           }
+           module_name = read_module_name(update_dir, update_dir);
+
            repository = Name_Repository (NULL, NULL);
            send_a_repository ("", repository, "");
            free (repository);
   @@ -245,6 +260,7 @@
                rcsdir = xmalloc (strlen (repository) + strlen (p) + 5);
                sprintf (rcsdir, "%s/%s", repository, p);
+               module_name = read_module_name(".", ".");
                Create_Admin (p, argv7, rcsdir, tag, date,
                              nonbranch, 0, 1);
@@ -807,7 +823,10 @@
 #ifdef SERVER_SUPPORT
     if (!server_active)
 #endif
+    {
+       module_name = read_module_name(repository, repository);
         Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1);
+    }
     if (tag)
        free (tag);
     if (date)
diff -u /home/ortal/src/cvs-1.11.2/src/client.c ./client.c
--- /home/ortal/src/cvs-1.11.2/src/client.c     Thu Aug  9 23:27:26 2001
+++ ./client.c  Sun Aug  4 17:01:39 2002
@@ -137,6 +137,7 @@
 static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *,
                                int, int, struct hostent *));
+char *module_name = NULL;
 /* We need to keep track of the list of directories we've sent to the
    server.  This list, along with the current CVSROOT, will help us
    decide which command-line arguments to send.  */
@@ -3068,6 +3069,14 @@
        module_argv8 = xstrdup (argv9);
     module_argv10 = NULL;
+    /* First arg should be the module name. */
+    if (argc < 1)
+    {
+       error(0, 0, "No module name given");
+       return;
+    }
+
+    module_name = xstrdup(argv11);
     for (i = 0; i < argc; ++i)
        send_arg (argv12);
     send_a_repository ("", current_parsed_root->directory, "");
diff -u /home/ortal/src/cvs-1.11.2/src/create_adm.c ./create_adm.c
--- /home/ortal/src/cvs-1.11.2/src/create_adm.c Tue Jan  9 15:59:59 2001
+++ ./create_adm.c      Sun Aug  4 17:01:39 2002
@@ -169,6 +169,35 @@
     WriteTag (dir, tag, date, nonbranch, update_dir, repository);
 #ifdef SERVER_SUPPORT
+    if (!server_active && module_name)
+    {
+       /* Create the ModuleName file */
+       if (dir != NULL)
+           (void) sprintf (tmp, "%s/%s", dir, CVSADM_MODULE_NAME);
+       else
+           (void) strcpy (tmp, CVSADM_MODULE_NAME);
+       fout = CVS_FOPEN (tmp, "w+");
+       if (fout == NULL)
+       {
+           if (update_dir13 == '\0')
+               error (1, errno, "cannot open %s", tmp);
+           else
+           {
+               error (1, errno, "cannot open %s/%s", update_dir,
+                   CVSADM_MODULE_NAME);
+           }
+       }
+       fprintf(fout, "%s\n", module_name);
+       if (fclose (fout) == EOF)
+       {
+           if (update_dir14 == '\0')
+               error (1, errno, "cannot close %s", tmp);
+           else
+               error (1, errno, "cannot close %s/%s", update_dir,
+                   CVSADM_ENT);
+       }
+    }
+
     if (server_active && dotemplate)
     {
        server_template (update_dir, repository);
diff -u /home/ortal/src/cvs-1.11.2/src/cvs.h ./cvs.h
--- /home/ortal/src/cvs-1.11.2/src/cvs.h        Fri Aug 24 20:47:02 2001
+++ ./cvs.h     Sun Aug  4 17:01:39 2002
@@ -123,6 +123,7 @@
 #define CVSADM_ENTLOG   "CVS/Entries.Log"
 #define CVSADM_ENTSTAT  "CVS/Entries.Static"
 #define CVSADM_REP      "CVS/Repository."
+#define CVSADM_MODULE_NAME "CVS/Module."
 #define CVSADM_ROOT     "CVS/Root."
 #define CVSADM_CIPROG   "CVS/Checkin.prog"
 #define CVSADM_UPROG    "CVS/Update.prog"
@@ -140,6 +141,7 @@
 #define CVSADM_ENTLOG  "CVS/Entries.Log"
 #define        CVSADM_ENTSTAT  "CVS/Entries.Static"
 #define        CVSADM_REP      "CVS/Repository"
+#define CVSADM_MODULE_NAME "CVS/Module"
 #define        CVSADM_ROOT     "CVS/Root"
 #define        CVSADM_CIPROG   "CVS/Checkin.prog"
 #define        CVSADM_UPROG    "CVS/Update.prog"
@@ -366,6 +368,7 @@
 extern int use_editor;
 extern int cvswrite;
 extern mode_t cvsumask;
+extern char *module_name;
@@ -445,6 +448,8 @@
 void tm_to_internet PROTO ((char *, const struct tm *));
 char *Name_Repository PROTO((char *dir, char *update_dir));
+char * read_module_name PROTO((char *dir, char *update_dir));
+
 char *Short_Repository PROTO((char *repository));
 void Sanitize_Repository_Name PROTO((char *repository));
diff -u /home/ortal/src/cvs-1.11.2/src/ignore.c ./ignore.c
--- /home/ortal/src/cvs-1.11.2/src/ignore.c     Wed Apr  4 18:52:55 2001
+++ ./ignore.c  Sun Aug  4 17:01:39 2002
@@ -325,7 +325,7 @@
     char *name;
 {
     /* Make sure we've got the space for the entry.  */
-    if (dir_ign_current <= dir_ign_max)
+    if (dir_ign_current >= dir_ign_max)
     {
        dir_ign_max += IGN_GROW;
        dir_ign_list =
diff -u /home/ortal/src/cvs-1.11.2/src/logmsg.c ./logmsg.c
--- /home/ortal/src/cvs-1.11.2/src/logmsg.c     Fri Sep 14 20:12:10 2001
+++ ./logmsg.c  Sun Aug  4 17:01:39 2002
@@ -261,7 +261,7 @@
        }
     }
-    (void) fprintf (fp,
+    (void) fprintf (fp, "\n"
   "%s----------------------------------------------------------------------\n",
                    CVSEDITPREFIX);
     (void) fprintf (fp,
diff -u /home/ortal/src/cvs-1.11.2/src/modules.c ./modules.c
--- /home/ortal/src/cvs-1.11.2/src/modules.c    Fri Jun 22 00:23:09 2001
+++ ./modules.c Sun Aug  4 17:01:39 2002
@@ -162,7 +162,13 @@
     /* if this is a directory to ignore, add it to that list */
     if (mname15 == '!' && mname16 != '\0')
     {
-       ign_dir_add (mname+1);
+       char *file = xmalloc (strlen (current_parsed_root->directory)
+           + strlen (mname) + 1);
+       (void) sprintf (file, "%s/%s", current_parsed_root->directory,
+           mname + 1);
+
+       ign_dir_add (file);
+       free(file);
        goto do_module_return;
     }
diff -u /home/ortal/src/cvs-1.11.2/src/repos.c ./repos.c
--- /home/ortal/src/cvs-1.11.2/src/repos.c      Tue Jan  9 15:59:59 2001
+++ ./repos.c   Sun Aug  4 17:01:39 2002
@@ -10,6 +10,45 @@
 #include "cvs.h"
 #include "getline.h"
+char *
+read_module_name (dir, update_dir)
+    char *dir;
+    char *update_dir;
+{
+    FILE *fpin;
+    char *mname = NULL;
+    size_t mname_allocated = 0;
+    char *tmp;
+    char *cp;
+
+    if (dir != NULL)
+    {
+       tmp = xmalloc (strlen (dir) + sizeof (CVSADM_MODULE_NAME) + 10);
+       (void) sprintf (tmp, "%s/%s", dir, CVSADM_MODULE_NAME);
+    }
+    else
+       tmp = xstrdup (CVSADM_MODULE_NAME);
+
+    fpin = CVS_FOPEN (tmp, "r");
+
+    if (fpin == NULL)
+        return NULL;
+
+    if (getline (&mname, &mname_allocated, fpin) < 0)
+    {
+       /* FIXME: should be checking for end of file separately.  */
+       error (1, errno, "cannot read %s", tmp);
+    }
+    if (fclose (fpin) < 0)
+       error (0, errno, "cannot close %s", tmp);
+    free (tmp);
+
+    if ((cp = strrchr (mname, '\n')) != NULL)
+       *cp = '\0';                     /* strip the newline */
+
+    return mname;
+}
+
 /* Determine the name of the RCS repository for directory DIR in the
    current working directory, or for the current working directory
    itself if DIR is NULL.  Returns the name in a newly-malloc'd
diff -u /home/ortal/src/cvs-1.11.2/src/server.c ./server.c
--- /home/ortal/src/cvs-1.11.2/src/server.c     Tue Mar 19 21:15:45 2002
+++ ./server.c  Sun Aug  4 17:01:39 2002
@@ -3692,6 +3692,27 @@
     do_cvs_command ("admin", admin);
 }
+/* Null callback for do_module() of serve_module_name(). */
+static int
+serve_module_name_cb (int argc, char *argv17, char *where,
+    char *mwhere, char *mfile, int shorten, int local_specified,
+    char *omodule, char *msg)
+{
+}
+
+static void
+serve_module_name (arg)
+    char *arg;
+{
+    DBM *db;
+    module_name = xstrdup(arg);
+    /* Parse the module in order to build ignore list based on the module. */
+    db = open_module ();
+    do_module(db, arg, CHECKOUT, "Updating", serve_module_name_cb,
+       NULL, 0, 0, 0, 1, NULL);
+
+    close_module (db);
+}
 static void
 serve_history (arg)
     char *arg;
@@ -4816,6 +4837,7 @@
   REQ_LINE("rannotate", serve_rannotate, 0),
   REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
   REQ_LINE("version", serve_version, RQ_ROOTLESS),
+  REQ_LINE("module-name", serve_module_name, 0),
   REQ_LINE(NULL, NULL, 0)
 #undef REQ_LINE
diff -u /home/ortal/src/cvs-1.11.2/src/status.c ./status.c
--- /home/ortal/src/cvs-1.11.2/src/status.c     Tue Jan  9 15:59:59 2001
+++ ./status.c  Sun Aug  4 17:01:39 2002
@@ -78,6 +78,18 @@
        if (local)
            send_arg("-l");
+       /* Read the module name. We assume that we are located inside
+       * the repository.
+       */
+       module_name = read_module_name(".", ".");
+       if (supported_request ("module-name") && module_name)
+       {
+           /* Send module name to server. */
+           send_to_server ("module-name ", 0);
+           send_to_server (module_name, 0);
+           send_to_server ("\012", 1);
+       }
+
        /* For a while, we tried setting SEND_NO_CONTENTS here so this
           could be a fast operation.  That prevents the
           server from updating our timestamp if the timestamp is
@@ -287,6 +299,14 @@
        }
        else if (!really_quiet)
            cvs_output ("   Sticky Options:\t(none)\n", 0);
+       if (module_name)
+       {
+           cvs_output ("   Module:\t\t", 0);
+           cvs_output (module_name, 0);
+           cvs_output ("\n", 0);
+       }
+       else if (!really_quiet)
+           cvs_output ("   Module:\t\t(none)\n", 0);
     }
     if (long_format && vers->srcfile)
diff -u /home/ortal/src/cvs-1.11.2/src/update.c ./update.c
--- /home/ortal/src/cvs-1.11.2/src/update.c     Sun Jul  8 23:51:46 2001
+++ ./update.c  Sun Aug  4 17:01:39 2002
@@ -278,6 +278,18 @@
            {
                 unsigned int flags = 0;
+               /* Read the module name. We assume that we are located inside
+               * the repository.
+               */
+               module_name = read_module_name(".", ".");
+               if (supported_request ("module-name") && module_name)
+               {
+                   /* Send module name to server. */
+                   send_to_server ("module-name ", 0);
+                   send_to_server (module_name, 0);
+                   send_to_server ("\012", 1);
+               }
+
                /* If the server supports the command "update-patches", that
                   means that it knows how to handle the -u argument to update,
                   which means to send patches instead of complete files.
@@ -895,7 +907,7 @@
     char *update_dir;
     List *entries;
 {
-    if (ignore_directory (update_dir))
+    if (ignore_directory (repository))
     {
        /* print the warm fuzzy message */
        if (!quiet)

Can I switch off line end conversions on text files?

You shouldn't need to as long as you don't share your checked-out workspace between platforms, since the conversion happens on the client end and happens in both directions. i.e., if you checkout on Windows, commit from Windows and, if you check out on UNIX, commit from UNIX.

What are the differences between CVS version 1.11.x and 1.12.x?

VersionDescription
1.11.xThis is the stable series of CVS releases. Stable releases only contain bug fixes when compared to earlier versions of CVS from the same series.
1.12.xThis is the feature series of CVS releases. Feature releases contain new features in addition to all the bug fixes from the stable releases.

Can I convert an RCS directory into a CVS directory?

Yes. Just move the RCS files directly into your CVS repository.

Where can I find the details of pserver protocol?

The doc/cvsclient.texi file distributed with CVS may be run through makeinfo or texi2html to convert it into many different formats including GNU Info, HTML, and PDF. The GNU Info version is also distributed with CVS, as doc/cvsclient.info*

There is an HTML version online at http://www.elegosoft.com/cvs/cvsclient.html.

How can I deny a commit action in the main branch (trunk) for some specific users or groups?

CVS--Concurrent Versions System v1.12.12.1: Reference manual for Administrative files

In particular, you might want to consider installing the contrib/cvs_acls script distributed with CVS on the commitinfo hook.

Is there a way to list branches in a project?

#!/bin/ksh
myname=`basename $0`
usage="Usage: $myname 18 19 cvsroot project/file
List branches for a CVS project.
-h\t\tdisplay this help and exit.\n-b\t\tonly display branchnames (no tags).
-d cvsroot\tOverrides \$CVSROOT as the root of the CVS
tree.\n"
optroot=$CVSROOT
display="TAGS"

while getopts d:bh OPT
do
  case $OPT in
    d) optroot=$OPTARG ;;
    b) display="NOTAGS" ;;
    h)
       echo $usage
       exit 0 ;;
    \?)
       echo $usage
       exit 1 ;;
  esac
done

while $# -gt 1 
do
  shift
done

branches=$(cvs -d $optroot rlog -h $1 2>/dev/null | grep ": 20*\.0\.21*" | awk -F: '{print $1}' | sort -u)

if "$display" = "TAGS" 
then
  for x in $(echo $branches)
  do
    echo
    echo $x
    cvs -d $optroot history -Ta | grep $x | grep -v :D
  done
else
  echo
  for x in $(echo $branches)
  do
    echo $x
  done
fi
echo

Is there a way to change the versions of files to 2.X?

wrong answer:
you can assign a revision Assigning revisions.
find . -type f |grep -v CVS |xargs cvs commit -r 2.1
But you may want to read a story of woe about doing it "How to go back..."

right answer:
ignore the cvs _revision_ information, it is for CVS's use only. By changing the cvs revision information you may run the risk of breaking assumptions the cvs code has about things being on the 1.x revision set "Re: Updating revision number on a branch." , and no those assumptions are not documented any where.
Use tags ( symbolic names )for the humans, i.e. if you want the set of files in a sand box versioned for 2.1
cvs tag VERSION_2_1
there are some restrictions on the content of a tag name (second paragraph of Tags-Symbolic revisions )

New Answers

New questions with answers should be appended to the appropriate section, or this section if you aren't sure where else to put them. Questions without answers should be asked on the info-cvs@nongnu.org mailing list first. If you have a question and an answer, but aren't sure if the question is frequently asked, please discuss its eligibility on info-cvs@nongnu.org or this page's talk page before adding it here.

If you see a question in this section and have some idea where it should be filed, please feel free to move the question and its answer to the appropriate section of the FAQ.

Category:User Documentation

Derek Price, CVS developer and technical editor of Essential CVS (Essentials line from O'Reilly Press) , and others offer consulting services and training through Ximbiot.