This article shows how to use a cvs repository to check out a local copy, modify the contents, then check the working copy back into the main repository. It also shows how to control the access to the main repository and how to use ssh for the connection.
I will assume you have already know how to create a repository. In this article I will use the term working to refer to a repository which exists on your local computer. The main repository will exist somewhere else. The working copy is what you check out, modify, then commit back to the main repository. This strategy is common practice and is The Way To Go(tm).
When I started writing this article, I was trying to get access to a cvs repository from another box. I promptly became very confused between cvs and cvsup. cvs is an Concurrent Versions System. Basically, it's a repository. cvsup is a network distribution package for CVS repositories. One is the actual repository. The other deals with distributing that repository.
You use cvsup to update your ports or get your source code.
The main resource for this article is http://cvsbook.red-bean.com/cvsbook.html.
Setting up the cvs server
Most of this section was taken from The Password-Authenticating Server and describes how to configure a cvs server. I will assume the repository is at cvs.example.org. Here's a command I could use for the login to that server:
$ cvs -d :pserver:dan@cvs.example.org:/usr/local/cvs login
I'll come back to the details of this command in a later section. For now, I will deal with the cvs server setup. The reason for showing this command is that it is directing cvs to use the pserver method for logging in. This is by far the most common access method. I'll now describe how to do enable pserver on cvs.example.org. This is accomplished with the following steps:
cvspserver 2401/tcp
cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/usr/local/cvs pserverNote that the example above differs from that found in the URL above because cvs is located in a different location under FreeBSD. Use the above. Not that found in the URL.
# killall -hup inetd
With the above changes, you should be able to connect to the cvs server. Provided any firewall rules allow it. Here's a simple test.
$ telnet cvsup.example.org 2401 Trying 203.79.82.27... Connected to cvsup.example.org. Escape character is '^]'.
If that's what you see, then you've succeeded in setting up the cvs server. Congratulations. Now let's add a bit of security.
Adding passwords to the server
When adding passwords to the server, make sure you don't use the same passwords people use to login into the system. Keep them different. If the cvs passwords are ever compromised, they can't be used to get into the rest of the system. I put my cvs repository files under the control of a dedicated user. I created the user especially for this task. Just use adduser. Read The Password-Authenticating Server for more detail here.
Here's what I added to /usr/local/cvs/CVSROOT/passwd:
dan:tGX1fS8sun6rY:pubcvs
Entries in this file are of the format:
<USERNAME>:<ENCRYPTED_PASSWORD>:<OPTIONAL_SYSTEM_USERNAME>
There's a script at the above URL for generating such passwords. I suggest you use it. Note that the output from the password script is time sensitive. That's OK. It's supposed to be that way. It's not a problem. It's also not a bug. That's by design. And it does work.
Accessing the server using the password
Let's go back to where I started. This was the command I used to access the cvs server:
$ cvs -d :pserver:dan@cvs.example.org:/usr/local/cvs login (Logging in to dan@cvs.example.org) CVS password: $
And that's it. You're logged into the cvs server. You can issue all the normal commands. Such as a checkout:
$ cvs co scripts cvs server: Updating scripts U scripts/.procmailrc U scripts/archive-logs.sh U scripts/crontab U scripts/fp-updates.dtd U scripts/load_xml_into_db.pl U scripts/log-catcher.awk U scripts/log-munger.awk U scripts/openbsd-cvs-parse.pl U scripts/process_cvs_mail.pl
On the cvs server, the repository resides at /usr/local/cvs. We are obtaining the contents of /usr/local/cvs/scripts. The above checkout obtains a working copy of that repository. You can treat those files exactly as you would any other files.
And when you're finished, don't forget to log out.
$ cvs logout (Logging out of dan@cvs.example.org)
using ssh for added secrecy
So far I have been using the pserver method for connecting to the cvs server. This method works fine and is acceptable over trusted networks (e.g. over your own LAN). But if the Internet or other shared network lies between you and the cvs server, you might want to consider using a more secure method. Luckily, cvs is designed to use other external programs for client-server communication.
In this example, I'm going to use ssh. In my previous examples, cvs has been told that the repository exists on another box (e.g. pserver:dan@cvs.example.org). That works well. But for this example, I'm going to make cvs think the repository is local, but it will actually reside remotely. I will use an SSH tunnel for this. This method requires that you have a shell account on the cvs server and that you an access that account from your workstation.
If you use this method, you'll also need to use two terminal session on the workstation. One will be used for your cvs operations. The second will be used for an ssh tunnel.
My reference for this configuration is http://jakarta.apache.org/site/cvsonunix.html.
ssh -L 2401:localhost:2401 cvsup.example.org dan@cvsup.example.org's password: Last login: Fri Feb 16 09:05:30 2001 from box.example Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD 4.2-STABLE (XEON) #0: Sun Feb 11 14:45:37 NZDT 2001 Welcome to the dual XEON.You will remember port 2401 from above. That's the port on which cvs connects to the cvs server. The above command redirects local port 2401 (-L 2401) to port 2401 on cvsup.example.org.
$ cvs -d :pserver:dan@localhost:/usr/local/cvs login (Logging in to dan@localhost) CVS password:Note that I am using localhost here. Not cvsup.example.org as I have in previous examples. I can use localhost because of the ssh tunnel set up in step 1. This tunnel redirects port 2401 on localhost (which the login will use) to port 2401 on the cvs.example.org.
$ cvs checkout www cvs server: Updating www cvs server: Updating www/imagesThat's it.
I use screen to keep that second connection in the background:
screen -S tunnel ssh -p 2222 -L 2401:localhost:2401 cvsup.example.org
Then I detach from the screen session, leaving the ssh tunnel in the background.
Keep it short and sweet
You don't have to specify the -d option with the cvs command. You can set an environment variable:
export CVSROOT=:pserver:dan@cvs.example.org:/usr/local/cvs
Then you can just issue this command:
$ cvs login (Logging in to dan@cvs.example.org) CVS password:
But if you are using an ssh tunnel, you should specify local host. If you don't, cvs will ignore the ssh tunnel and connect directly to the remote host and transmissions will be in clear text.
export CVSROOT=:pserver:dan@localhost:/usr/local/cvs