ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Accessing Secure Subversion Servers

by Dru Lavigne
08/11/2005

In the previous article, I demonstrated how to install Subversion and set up a shared data repository. This article shows how to access and use the repository using both the command line and a GUI.

Starting the Server

Because I use SSH for authentication, I first needed to start the svn server in tunnel (-t) mode on the system hosting the repository. I could simply type this as the user svn:

% svnserve -t

However, that user would lose his prompt. You might be thinking, do this instead:

% svnserve -t &

to start the service in the background. That is better; however, the service is still attached to svn's shell, so the service will stop abruptly if that shell ever closes. In this case, it is better to write a small shell script owned by the user svn. I saved mine as /usr/local/home/svn/repository/conf/svnserve.sh:

#!/bin/sh
#script to start svn server in tunnel mode
#first, set correct umask
umask 007
#then, use nohup to prevent program from closing if starting shell closes,
#send standard output and error to the bit bucket,
#and start in the background (to get prompt back)
nohup /usr/local/sbin/svnserve -t 2>&1 > /dev/null&

Don't forget to make the script executable and to double-check the permissions and ownership:

% chmod u+x ~svn/repository/conf/svnserve.sh
% ls -l ~svn/repository/conf/svnserve.sh
-rwxr--r-- 1 svn svn 112 Apr 29 09:36 /usr/home/svn/repository/conf/svnserve.sh

Then, as the user svn, run the script to start the service:

% ~svn/repository/conf/svnserve.sh

Simplifying User Authentication

Unless you configure a mechanism to cache your users' credentials, they will receive authentication prompts every time they view or make a change to the repository. Constant reauthentication can become very irritating very quickly.

Because I'm using the svn+ssh access method, I chose to implement public key authentication and use keychain to prevent the user from having to constantly retype in their passphrase. (Read more about this process at the IBM Developerworks article OpenSSH Key Management, part 2, which introduced this utility.)

Here are the steps I used for the user devel1 who uses FreeBSD as his desktop. First, I had him generate a public/private key pair using RSA as the type (-t) of algorithm. (If you're rusty on encryption algorithms, you may wish to read through Cryptographic Terminology 101 first.)

% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key 
   (/home/devel1/.ssh/id_rsa): /usr/home/devel1/.ssh/id_rsa
Enter passphrase (empty for no passphrase): type something long but memorable 
Enter same passphrase again:
Your identification has been saved in /usr/home/devel1/.ssh/id_rsa.
Your public key has been saved in /usr/home/devel1/.ssh/id_rsa.pub.
The key fingerprint is:
f6:c2:51:ae:5c:17:91:57:53:c4:58:86:3f:5f:9a devel1@hostname.com

I then had devel1 copy over his new public key to his home directory on the system hosting the repository; in this case, 10.1.1.1:

% scp ~/.ssh/id_rsa.pub 10.1.1.1:/usr/home/devel1/.ssh

Note: When you do this, make sure you copy over the key with the .pub extension!

Before you can use that key, you have to append it to a file called authorized_keys. This will require one last ssh into the repository system using devel1's username and password:

% ssh 10.1.1.1
(login using password as usual)

% cd ~/.ssh
% cat id_rsa.pub >> authorized_keys
% exit

Finally, I had devel1 verify that SSH was using his public key for authentication:

% ssh 10.1.1.1

This time, instead prompting him for his password, it prompted for his passphrase:

Enter passphrase for key '/home/devel1/.ssh/id_rsa':
% exit

Now that the public key works on the repository system, it's time to deal with the private key. On devel1's PC:

% ssh-add ~/.ssh/id_rsa
Enter passphrase for .ssh/id_rsa:
Identity added: .ssh/id_rsa (.ssh/id_rsa)

Finally, I set up keychain to cache the credentials. As superuser on devel1's system:

# pkg_add -r keychain

Then, I had devel1 add these lines to his ~/.cshrc file:

`eval ssh-agent`
/usr/local/bin/keychain /usr/home/devel1/.ssh/id_rsa
source /usr/home/devel1/.ssh-agent > /dev/null

and inform csh about the change:

% source ~/.cshrc
KeyChain 2.5.3.1; http://www.gentoo.org/proj/en/keychain/
Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL

 * Initializing /home/devel1/.keychain/hostname.org-csh file...
 * Adding 1 ssh key(s)...
Enter passphrase for /usr/home/devel1/.ssh/id_rsa:
 * Identity added: /usr/home/devel1/.ssh/id_rsa (/usr/home/devel1/.ssh/id_rsa)

devel1 entered his passphrase. Now, he will see no prompts for any credentials for the entirety of his session as "keychain" will inform the SSH server that the identity has not changed.

Note: If your users instead use the bash shell, the DeveloperWorks article has the lines required for .bash_profile.

Version Control with Subversion

Related Reading

Version Control with Subversion
By Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato

Checking Out the Repository

Now that the server is running and authentication works, it's time to access the repository. Because devel1 prefers to work at the command line, I'll demonstrate the svn commands he'll use most often. I'll then install a GUI for devel2 and demonstrate that it is merely a front end for the same commands.

Before you can make any changes to the repository, you must download a working copy to your system. In Subversion terms, this is a checkout. If you always work from the same PC, you need to run this command only once. The syntax is:

% svn checkout svn+ssh://10.1.1.1/usr/home/svn/repository/www
A www/apache
A www/apache/index.html
<snip long output>
Checked out revision 1.

The above command copied the entire repository to a directory called www in devel1's home directory. This is his working copy. If you wish to specify an alternate location for your working copy, place it at the end of the command. For example, this will create a working copy called mycopy:

% svn checkout svn+ssh://10.1.1.1/usr/home/svn/repository/www mycopy

Using your working copy

Once you've checked out your working copy, you can modify its files, add files, and remove files. In order to use any svn commands, your present working directory will have to be somewhere within your working copy. For example, if I try to view the log from devel1's home directory, I'll receive this error:

% pwd
/usr/home/devel1
% svn log
svn: '.' is not a working copy

However, if I cd to the working copy, in this case www:

% cd www
% svn log

the svn command will work. If you get a "working copy" error, cd to your working copy and try again.

It is very important that you always run this command before making any changes to your working copy:

% svn update
At revision 1.

The update command checks your working copy against the repository to ensure that they are the same. Because I just checked out my working copy, there aren't any differences. However, if someone else had made any changes to the repository, that command would download those changes and merge them into my working copy.

Suppose that you want to add a file to a repository. After you have created the file somewhere in your working copy, use svn add to add it. Here, I wish to add a test file called ~devel1/www/test:

% pwd
/usr/home/devel1/www
% svn add test
A	test

This has added the file, but it didn't upload it to the main repository yet. That won't happen until I commit the change:

% svn commit -m "test file added by devel1"
Adding	test
Transmitting file data .
Committed revision 2.

Note that I used the -m switch to add a message to the log and that the revision number has incremented.

You don't have to commit after every change, as svn will queue up your changes and commit everything when you issue svn commit. However, if you're the forgetful sort or if many people work on the repository simultaneously, it doesn't do any harm to commit often. If you do queue up a lot of changes, don't forget to mention them all when you add your message to the log.

Note that the main repository is now at revision 2, but my working copy is still at revision 1. For example, if I type svn log, I won't see my comment. However, if I update, I will:

% svn update
At revision 2.

% svn log
------------------------------------------------------------------
r2 | devel1 | 2005-05-02 11:37:02 -0400 (Mon, 02 May 2005) | 1 line
test file added by devel1
------------------------------------------------------------------
r1 | svn | 2005-04-29 08:31:47 -0400 (Fri, 29 Apr 2005) | 1 line
initial import
------------------------------------------------------------------

More svn commands

You can also delete files. However, don't use rm to do so. The proper method is svn delete:

% ls
apache	default.php	en	test

% svn delete test
D	test

% ls
apache	default.php	en

See how svn removed that file from my working copy? The D also indicates that issuing a commit will delete the file from the repository:

% svn commit -m "removed test file"
Deleting	test
Committed revision 4.

Why is it showing revision 4 when I'm at revision 2? Because someone else has committed a change since the last time I ran svn update. Let's see what it is:

% svn update
U frameset.html
Updated to revision 4.

Note that a new (added) file starts with A, a deleted file starts with D, and a modified (updated) file starts with U. Someone else modified the file frameset.html before I committed my change. svn log would tell me who, and I would see that my change was revision 4 and the other person's change was revision 3.

I could get exact details on the file's modifications by issuing a diff on revision 3:

% svn diff -r 3
Index: en/frameset.html
=================================================================
--- en/frameset.html (revision 3)
+++ en/frameset.html (working copy)
@@ -2,10 +2,10 @@
<snip>
-<frameset rows="21%, 79%" border="0">
+<frameset rows=27%,73%" border="0">
<snip other changes>

You'll see that this is like any diff output. In this snippet, a single line has changed from its original values of 21 percent and 79 percent to new values of 27 percent and 73 percent.

If you wish to modify an existing file, simply make your edits. You don't have to svn add, as the file already exists. When you issue your next svn commit, your modifications will upload to the repository. Do remember to add a useful message to remind yourself and others of the edits you made.

Summary of svn commands

Here are the commands you'll use most often:

Chapter 9 of the SVN book gives details and examples for all of the svn commands.

Installing and Using a GUI

I originally planned to use esvn as the GUI, but found that the current version truncated the name of the repository, which made it impossible to use any svn commands. However, I had good luck with rapidsvn.

Installing on FreeBSD was a simple matter of:

# pkg_add -r rapidsvn

There are also binaries available as a Debian .deb, a Red Hat RPM, and a Windows installer.

Once devel2 had keychain set up and working, I had him open up rapidsvn and choose Checkout from the Repository menu. (Figure 1). He typed the same URL that devel1 had used at the command line, and chose to save his working copy as www. Selecting Add to Bookmarks ensures that the copy will show up as a tree in the left pane.

Thumbnail, click for full-size image.
Figure 1. Checking out with rapidsvn--click for full-size image

Once he had a working copy, devel2 went into the View menu and chose Preferences, then Programs. Here he defined his favorite editor and file explorer. That made it very easy for him to navigate between existing files on his system and his working copy.

The Modify menu contains the most often used svn commands. Each has either a Ctrl-letter or a function key shortcut for quick access. Once devel1 learned how to use the various svn commands, he quickly became comfortable with the interface and was able to return to his real work of web development.

Summary

svn provides a feature-rich yet easy-to-learn method for sharing a project's files between users. Edits are simple to track, and if need be, users can revert any file to an earlier revision. While I've covered the most used commands in this article, refer to the Subversion web site for more information on how to get the most out of your repository.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter

Return to O'Reilly SysAdmin

Copyright © 2009 O'Reilly Media, Inc.