Gentoo - Subversion

By: John McFarlane <john.mcfarlane@rockfloat.com>
Last updated: 09/20/2008 @ 01:35

Abstract:
This document outlines how to install and user the excellent Subversion along with a few other tools like Apache, ViewCVS, and Subclipse. This howto assumes you want to use FSFS, and intend to have more than one repository with WEBDAV as the primary means of access.



1. Install Subversion and Apache

A bit of background...
Subversion is able to store it's repositories in two different formats:
  1. FSFS (Filesystem implementation that uses the OS filesystem to store data)
  2. BDB (Berkeley DB)
The former is the new and better format while the latter was the original default format and is now depricated. Because FSFS is now the default version, there's no need to mess around with the berkdb USE flag. We do however want to add support for Apache, so add the apache2 USE flag to /etc/make.conf Mine looks like this:

USE="apache2 postgres gd xml -X -gtk -gnome -qt -kde -alsa"
    
That being said, it's time to do the install of Subversion and Apache. If you already have Apache installed, you can skip over that one.
root# emerge -a subversion apache
I'm finished with this step

2. Setup directories, users and permissions


# Create a group for ssh access to the repositories
root# groupadd svnusers

# Create the directory where all repositories are kept
root# mkdir -p /var/svn/repos
root# chmod -R 775 /var/svn/repos
root# mkdir /var/svn/conf

# Give Apache access to the repositories
root# gpasswd -a apache svnusers

# Give access to yourself and whoever else you want
root# gpasswd -a your-username svnusers
root# gpasswd -a your-friend svnusers
    
I'm finished with this step

3. Create a test repository

A test repository is a good way to test and learn how things work. For this step we're not going to use webdav to communicate with Subversion as we haven't fully set that part up yet. Instead we will communicate using file://. Later we'll enable http:// style access.

# Create the test repository
root# svnadmin create /var/svn/repos/test

# Set permissions!
root# chown -R apache:svnusers /var/svn/repos/
root# chmod -R g-w /var/svn/repos/test
root# chmod -R g+rw /var/svn/repos/test/db
root# chmod -R g+rw /var/svn/repos/test/locks

# Add a test directory, and validate that it's there
root# svn mkdir file:///var/svn/repos/test/foo -m "Creat test directory"
root# svn ls file:///var/svn/repos/test
foo/
I recommend checking this repository out and playing around with it a little. You can cleanly delete it later.

user# svn co file:///var/svn/repos/test ~/Desktop/test
user# cd ~/Desktop/test
user# echo "hello world" > some-file
user# svn add some-file
user# svn commit
user# svn log
    
I'm finished with this step

4. Create a real repository

Here we will use the svnadmin tool to create an empty repository:

root# svnadmin create /var/svn/repos/your-project

# Set permissions!
root# chown -R apache:svnusers /var/svn/repos/your-project
root# chmod -R g-w /var/svn/repos/your-project
root# chmod -R g+rw /var/svn/repos/your-project/db
root# chmod -R g+rw /var/svn/repos/your-project/locks        
    
I'm finished with this step

5. Typical repository structure

The typical repository structure looks kinda like this:

project
|--branches
|--tags
|--trunk
    
  1. branches hold copies of the source that are being actively worked on or maintained but require separation. For example the code for v4 might be inside a branch to allow people to work on future changes that won't be implemented for a while. This allows them to do their work without prematurely placing code in the trunk. These branches are often called "project branches".
  2. tags hold copies of the software at various milestones, like v1, v2, v3.
  3. trunk is used to hold the most up to date stable version of your software.

REFERENCE: http://svnbook.red-bean.com/en/1.0/ch05s04.html
I'm finished with this step

6. Place your project under version control

We need to import your files into the your-project respository. I'll use a fake project named Bella as an example:
  1. Look at the project you want to place under version control:
    
    user # cd ~/projects/Bella
    user # tree    # I recommend emerging tree if you don't have it
    .
    |-- Changelog
    |-- LICENSE
    |-- README
    `-- bella
        |-- __init__.py
        |-- lib
        `-- server.py
    
    2 directories, 5 files
            
  2. Since I want the contents of Bella to be in trunk of the /var/svn/repos/bella repository, I want to import my project like this:
    
    user# cd ~/projects
    user# svn import Bella file:///var/svn/repos/bella/trunk -m 'Initial import'
    
    Adding...
    Adding...
    
    Committed revision 1.
  3. Validate that the files were added to the repository:
    
    root# svn ls file:///var/svn/repos/bella/trunk
    
    Changelog
    LICENSE
    README
    bella/
I'm finished with this step

7. Checkout your newly versioned project

Currently your files are safe inside the repository, but you need a working copy to work against:
  1. First you need to move your existing project out of the way:
    mv ~/projects/Bella ~/projects/Bella-B4-SVN
  2. Now you can checkout your project from the repository exactly where it was before:
    svn co file:///var/svn/repos/bella/trunk ~/Projects/Bella
I'm finished with this step

8. Explanation of Subversion communication protocols

Before we move on it's important to understand that technically you don't need to do anything else in order to properly version your project with Subversion. The following steps of this howto explain how to enable webdav access to your repositories. Before we do that let's spend a little time understanding what this means. Currently Subversion allows a few different types of access to your repositories:
Protocol Description
file:// This is the most basic protocol and though it works great, it means you can only work on the actual box that hosts the repositores. If this works for you, there's nothing else you need to do besides setup backups :)
svn:// This protocol uses a lightweight server that communicates with Subversion (in this howto we use Apache for this role). To use this protocol you would need to have /etc/init.d/svnserve running.
svn+ssh:// This protocol uses SSH to communicate with the server. This is actually now my preferred way to communicate with Subverison, especially when you have keychain properly configured.
http:// This protocol uses WEBDAV to allow communication over HTTP to the Subversion repositories. This protocol has several advantages, including a more friendly setup for clients like TortoiseSVN.
https:// Same as above only with SSL encryption

REFERENCE: http://svnbook.red-bean.com/en/1.0/ch06.html

TODO: Write down the permission tweaks...
I'm finished with this step

9. Configure Apache to support subversion at startup

Update /etc/conf.d/apache2 by adding the following to the APACHE2_OPTS parameter:

-D SVN -D SVN_AUTHZ -D DAV -D DAV_FS -D SSL -D SSL_DEFAULT_VHOST
    
Mine looks like this for example:

APACHE2_OPTS="-D PYTHON -D SSL -D SVN -D SVN_AUTHZ -D DAV -D DAV_FS"
    
I'm finished with this step

10. Create an Apache password file

When users access Subversion using WEBDAV, authentication is actually handled by Apache. For this to work Apache needs a file to check passwords against. It's obviously important that this file only be writable by root..

# Use -c to create the file while adding the first user
root# htpasswd2 -c /var/svn/conf/svnusers foouser

# Add another user, rinse and repeat
root# htpasswd2 /var/svn/conf/svnusers baruser
    
I'm finished with this step

11. Create an SVN policy file

The support for policies is awesome. It allows you to say that foo user has read/write on this and that, while bar only has write on this.

root# nano -w /var/svn/conf/svnpolicy

[your-project:/]
* = r

[another-project:/]
foouser = rw
baruser = r

[yet-another:/trunk/protected]
foouser = rw
    
Tip Subversion support for slick policies like this is only available when using the http:// (or https) protocol.
I'm finished with this step

12. Configure Apache to support serving up svn

First make a backup, and then make /etc/apache2/modules.d/47_mod_dav_svn.conf look like this:

<IfDefine SVN>
        <IfModule !mod_dav_svn.c>
                LoadModule dav_svn_module       modules/mod_dav_svn.so
        </IfModule>
        <Location /svn/repos>
                DAV svn
                SVNParentPath /var/svn/repos
                #SSLRequireSSL
                AuthType Basic
                AuthName "Super Duper SVN Repository"
                AuthUserFile /var/svn/conf/svnusers
                AuthzSVNAccessFile /var/svn/conf/svnpolicy
                <LimitExcept GET PROPFIND OPTIONS REPORT>
                        Require valid-user
                </LimitExcept>
                SVNIndexXSLT /svnindex.xsl
        </Location>
        <IfDefine SVN_AUTHZ>
                <IfModule !mod_authz_svn.c>
                        LoadModule authz_svn_module     modules/mod_authz_svn.so
                </IfModule>
        </IfDefine>
</IfDefine>
    
I'm finished with this step

13. Place the default Subversion xsl and css files

You do want to make Subversion look pretty... don't you?

root# cp /usr/share/doc/subversion-1.5.1/svnindex.* /var/www/localhost/htdocs/
root# cd /var/www/localhost/htdocs
root# gunzip svnindex.css.gz 
root# gunzip svnindex.xsl.gz
    
I'm finished with this step

14. Restart Apache

Let's give our initial setup a try:
root# /etc/init.d/apache2 restart
Now you should be able to browse to your project by hitting:
http://your-server/svn/repos/your-project/trunk/
I'm finished with this step

15. Gentoo ebuild notes


 * Subversion Server Notes
 * -----------------------
 * 
 * If you intend to run a server, a repository needs to be created using
 * svnadmin (see man svnadmin) or the following command to create it in
 * /var/svn:
 * 
 *     ebuild /path/to/ebuild/subversion-1.5.1.ebuild config
 * 
 * If you upgraded from an older version of berkely db and experience
 * problems with your repository then run the following commands as root:
 *     db4_recover -h /var/svn/repos
 *     chown -Rf apache:apache /var/svn/repos
 * 
 * Subversion has multiple server types, take your pick:
 * 
 *  - svnserve daemon: 
 *    1. edit /etc/conf.d/svnserve
 *    2. start daemon: /etc/init.d/svnserve start
 *    3. make persistent: rc-update add svnserve default
 * 
 *  - svnserve via xinetd:
 *    1. edit /etc/xinetd.d/svnserve (remove disable line)
 *    2. restart xinetd.d: /etc/init.d/xinetd restart
 * 
 *  - svn over ssh:
 *    1. Fix the repository permissions:
 *         groupadd svnusers
 *         chown -R root:svnusers /var/svn/repos/
 *         chmod -R g-w /var/svn/repos
 *         chmod -R g+rw /var/svn/repos/db
 *         chmod -R g+rw /var/svn/repos/locks
 *    2. create an svnserve wrapper in /usr/local/bin to set the umask you
 *       want, for example:
 *          #!/bin/bash
 *          umask 002
 *          exec /usr/bin/svnserve "$@"
 * 
    
I'm finished with this step

16. TIP: howto create a tag

If you don't have a tags directory inside of your repository you first need to make one:

user# svn mkdir http://your-server.com/svn/repos/your-project/tags -m "Initial creation"
    
Here's how you then populate the tag, or copy the data from the trunk into the tag directory (notice you create the specific tag 0.1.0 and populate it in the same step):

user# svn cp \
> http://your-server.com/svn/repos/your-project/trunk \
> http://your-server.com/svn/repos/your-project/tags/0.1.0 \
> -m "Initial release, doesn't do much of anything really"
      
I'm finished with this step

Changelog: Date Description
02/09/2006 @ 10:00 Initial creation
10/03/2006 @ 17:30 Switch to dav over ssh for real imports
10/14/2006 @ 17:00 Typo: when using dav, it's /svn not /var/svn
11/19/2006 @ 22:13 Replaced http:// call with file:// for initial import as Apache isn't yet configured (credit: Adam)
01/15/2008 @ 22:14 Fixed typo (credit: Naginata)
06/28/2008 @ 23:59 Remove link to my svn repo
09/20/2008 @ 01:35 Cleaned up a few things and added in an svn co step(s) (credit: Sting-Ray)

This document was originally created on 02/09/2006


Disclaimer:
This page is not endorsed by gentoo.org or any other cool cats. Any information provided in this document is to be used at your own risk.