Setting up a Subversion server using Apache2

From openSUSE

Contents

Introduction

This howto is based on the Readme at/usr/share/doc/packages/subversion/README.SuSE, but extends it. The steps have been tested on Subversion 1.4.0, running on openSUSE 10.2.

Subversion is a versioning system, which allows you to store a development filetree in a "repository", keeps track of edits made to the files, and allows those edits to be rolled back if necessary.

The "SVN book" (Version Control with Subversion, Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato) is essential reading. The copy in /usr/share/doc/packages/subversion/html/book/svn-book.html is for Subversion 1.2. For 1.4 it is better to download the book from the website - substantial changes have been made, with a lot more information added. The book is rebuilt nightly.

Subversion flavours

The simplest way to run Subversion on an individual PC is by using the file:// protocol to access the PC's filesystem. In most cases, however, you will want to allow access to the repository over the network. There are two options here - the svnserve protocol, or http://, using a webserver like Apache and the web-dav module.

svnserve should not run as root user. On openSUSE, the startup script rcsvnserve expects a user/group named svn, configureable via /etc/sysconfig/svnserve. But this user/group must be created first:

 (su) groupadd -r svn; useradd -r -g svn -d /srv/svn -s /bin/false svn

However, since Apache is more flexible, the rest of this howto deals with that.

Software installation

Ensure these packages are installed: apache2, apache2-doc, apache2-prefork, libapr1, libapr-util1, neon, subversion, subversion-server.

Update /etc/sysconfig/apache2 by adding dav and dav_svn to $APACHE_MODULES:

 (su) a2enmod dav
 (su) a2enmod dav_svn

Configuration

The configuration suggested in /usr/share/doc/packages/subversion/README.SuSE sets up individual repositories for each filetree. But since each one requires its own section in the Apache configuration file (/etc/apache2/conf.d/subversion.conf), the edits can be tiresome if you have a significant number of repositories, or are adding or deleting them regularly. Instead, the approach here sets up one parent repository which will hold all the project repositories. (Note that this may raise security issues if you don't want people to know what project repositories you are hosting, so consider that.)

Configure the parent repository

Using a text editor (nano in this case), run:

 (su) nano /etc/apache2/conf.d/subversion.conf

and edit it to read as follows:

 # Example configuration for a subversion repository
 # see /usr/share/doc/packages/subversion for the full documentation
 <IfModule mod_dav_svn.c>
 # Set up single repository directory 'kdrepos'
 # This has open read access, but limited write (commit) access
 <Location /kdrepos>
   DAV svn
   SVNParentPath /srv/svn/kdrepos
   # Allow the 'kdrepos' index page to list all the repositories it contains
   SVNListParentPath On
   # Limit write permission to list of valid users.
   <LimitExcept GET PROPFIND OPTIONS REPORT>
     # Require SSL connection for password protection.
     # SSLRequireSSL
     AuthType Basic
     # Message to give to the committer
     AuthName "Write access requires a password"
     # File listing users with write (commit) access
     AuthUserFile /srv/svn/user_access/svn_passwdfile
     Require valid-user
   </LimitExcept>
 </Location>
 # Set up stricter conditions for one directory within the 'kdrepos' dir:
 # 'secret_repo' has limited write access, and also limited read access.
 <Location /kdrepos/secret_repo>
   Require valid-user
 </Location>
 </IfModule>

Without the SVNListParentPath directive, you cannot go to the repositories' index page - you will get the response:

 Access forbidden!
 You don't have permission to access the requested directory. There is either no index document or the directory is read-protected. 
 If you think this is a server error, please contact the webmaster. 
 Error 403

Thanks to this page for the secret_repo tip - this subdir will inherit the properties from the kderepos <Location> block, so we just need to tell Apache to require a valid user for anything, rather than for write access only.

Create the repository directory:

 (su) mkdir -p /srv/svn/kdrepos

Configure user access to the parent repository

Note that only one user password file is being used here. However, this could be adjusted by writing clauses on a per-directory basis, as with secret_repo above.

Set up the password file:

 (su) mkdir /srv/svn/user_access
 (su) touch /srv/svn/user_access/svn_passwdfile

Change the group so that Apache can access it:

 (su) chown root:www /srv/svn/user_access/svn_passwdfile

Tighten the permissions:

 (su) chmod 640 /srv/svn/user_access/svn_passwdfile

Add the users:

 (su) htpasswd2 /srv/svn/user_access/svn_passwdfile your_user

and enter the password twice.

Restart Apache2:

 (su) rcapache2 restart

You should now be able to access the parent repository by opening a browser and going to http://localhost/kdrepos, but of course nothing will be listed there.

Set up a project repository

Create an svn dir for each project you want to import, and change its permissions:

 (su) svnadmin create /srv/svn/kdrepos/meddaliadur
 (su) chown -R wwwrun:www /srv/svn/kdrepos/meddaliadur/{dav,db,locks}

Here we are setting up a repository for a project called Meddaliadur

Import the new project:

 svn import /path/to/meddaliadur/files http://localhost/kdrepos/meddaliadur -m "initial import"

and give your password when prompted.

Note that if you try to import before you have created the project repository directory, you will get the following error message:

 svn: PROPFIND request failed on '/kdrepos/meddaliadur'
 svn: Could not open the requested SVN filesystem

If you browse back to your parent repository, http://localhost/kdrepos, you should now see a link to the meddaliadur project repository, and clicking on it will give a new page with the files in the project.

Check out a working copy

Move into the directory where you will be keeping a local working copy (maybe /public_html if you are doing web development), and checkout the versioned filetree:

 cd ~/public_html
 svn checkout http://localhost/kdrepos/meddaliadur

This will create the directory /public_html/meddaliadur, with a fresh version of the files from the Subversion repository.

Move into the new working copy, and run a few commands:

 cd /meddaliadur
 svn list --verbose  # Review what files were checked out
 svn info  # Get summary information on this working copy
 cat > info.txt  # Try adding a new file to the working copy
 This is a new file  # Press Return, and then Ctrl-D to write this text to info.txt
 cat info.txt  # Review the new file
 svn add info.txt  # Let Subversion know that a new file has been created

You should get a response like:

 A         info.txt
 svn commit info.txt  # Commit the new file to the project repository

You should be asked for a commit message (see below), and then your password, and you should get a response like:

 Adding         info.txt
 Transmitting file data .
 Committed revision 2.
 

The above svn commit command does not include a commit message, which will inform other developers (and remind yourself) of what this new file or edit was intended to do. By default, Subversion opens an editor so that you can add a message. The default editor is the rather forbidding vi - if this opens and you don't have a clue how to use it, just type in:

 :wq!

This will close the editor. You may find it easier to change the default editor for one you are more familiar with. To do this, open /home/your_user/.subversion/config and adjust the editor-cmd line. For instance, to use nano, the line should read:

 editor-cmd = nano

To commit and add a message in one go, use:

 svn commit info.txt -m "My first commit"

If other developers have added or edited files (or if you have done this on another PC on the LAN and want to update your working copy on this PC), run:

 svn update