Table of Contents

Subversion Setup and Configuration (SVN)

This article explains how to perform version control using Subversion (Linux or Windows server) and SVN (Linux client) or TortoiseSVN (Windows client).

Subversion under Linux

Installation

Install package while installing Linux, or from the menu Start > System > Add/Remove Software.

Configuration

Setup Server Permissions

Create a directory where future repositories will be stored. Note: this is not the repository, but a container to the repositories.

$ mkdir /data/repos

Create a specific user to run Subversion. Create system account for svnuser (use repository directory as home directory):

$ /usr/sbin/groupadd -r svnuser
$ /usr/sbin/useradd -g svnuser -c "Subversion User" -d /data/repos -s /bin/bash -r -l -n svnuser

Run Subversion server (svnserve). Restrict Subversion to allow exporting trees only under a specific directory (-d for daemon, -T for threaded, -r for root directory). Execute one of these commands (assuming the repository is in /data/repos):

$ svnserve -d -T -r /data/repos
$ sudo -u svnuser svnserve -d -T -r /data/repos
$ su -l svnuser -c "svnserve -d -T -r /data/repos"

Add exception rule to firewall to allow traffice through port 3690 on the subversion server. In Ubuntu:

$ ufw status
$ # Only to 192.168.0.31: ufw allow from 192.168.0.0/24 to 192.168.0.31 port 3690
$ ufw allow from 192.168.0.0/24 to any port 3690
Note for SELinux / Fedora Core 3+ / Red Hat Enterprise users 1) :


In addition to regular Unix permissions, under SELinux every file, directory, process, etc. has a 'security context'. When a process attempts to access a file, besides checking the Unix permissions the system also checks to see if the security context of the process is compatible with the security context of the file.


Fedora Core 3, among other systems, comes with SELinux installed by default, configured so that Apache runs in a fairly restricted security context. To run Subversion under Apache, you have to set the security context of the repository to allow Apache access (or turn off the restrictions on Apache, if you think all this is overkill). The chcon command is used to set the security context of files (similarly to how the chmod sets the traditional Unix permissions). For example, one user had to issue this command


$ chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY


to set the security context to be able to successfully access the repository.

Script for Start/Stop Subversion Service

Create a script to launch svnserve at server boot time. The file should be called /etc/init.d/svnserve:

#!/bin/bash
#
# Startup script for the Subversion's SVNSERVE
#
# chkconfig: - 85 15
# description: Subversion is an excellent VCS.
# processname: svnserve
# pidfile: /var/run/subversion.pid
# config:  /etc/subversion.conf or /etc/subversion/config ?
#
# Author: Dejan Lekic, dejan@nu6.org, http://dejan.lekic.org
# Version: 1.0
# Modification:
#   2005.01.11 by Wan-rong Jih
#   2006.08.17 by Siegwart Mayr
#

# Source function library.
. /etc/rc.d/init.d/functions

# This will prevent initlog from swallowing up a pass-phrase prompt.
INITLOG_ARGS=""

# Path to the svnserve binary.
svnserve_prog=/usr/bin/svnserve
svnserve_exec=svnserve
svnserve_pidf=/var/run/subversion.pid
svnserve_user=svnuser
svnserve_repo=/data/repos

RETVAL=0

start() {
        echo -n $"Starting $svnserve_exec: "
        #echo -n $"Executing $svnserve_prog -d -T -r $svnserve_repo"
        echo -n $"Repository => $svnserve_repo"
        su -l $svnserve_user -c $"$svnserve_prog -d -T -r $svnserve_repo"
        RETVAL=$?
        #echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/subversion
        [ $RETVAL -eq 0 ] && echo_success
        [ $RETVAL -ne 0 ] && echo_failure
        echo `/sbin/pidof svnserve` > $svnserve_pidf
        echo
        return $RETVAL
}
stop() {
	echo -n $"Stopping $prog: "
	killproc $svnserve_exec
	RETVAL=$?
	echo
	[ $RETVAL = 0 ] && rm -f /var/lock/subsys/subversion $svnserve_pidf
}

# See how we were called.
case "$1" in
start)
	start
	;;
stop)
	stop
	;;
status)
	status $svnserve_exec
	;;
restart)
	stop
	start
	;;
reload)
	echo -n $"Reloading $svnserve_exec: "
	killproc $svnserve_exec -HUP
	RETVAL=$?
	echo
	;;
condrestart)
	if [ -f $svnserve_pidf ] ; then
		stop
		start
	fi
	;;
*)
	echo $"Usage: $prog {start|stop|restart|reload|condrestart|status}"
	exit 1
esac

exit $RETVAL

Creating a Project Repository

Create a project repository (proj1) in directory /data/repos:

$ svnadmin create /data/repos/proj1

Add a repository user to have access to the project. Edit file proj1/conf/passwd to include:

[users]
jdoe = mypassword123

Edit file proj1/conf/svnserve.conf to include:

[general]
password-db = passwd
realm = My Realm

Set correct file permissions for project repository:

$ chmod -R 750 proj1
$ chown -R svnuser:svnuser proj1

Create layout of project:

$ mkdir tmpdir
$ cd tmpdir
$ mkdir proj1
$ mkdir proj1/trunk
$ mkdir proj1/branches
$ mkdir proj1/tags

Import a project (/tmpdir/proj1) into the empty repository (proj1):

$ svn import /tmpdir/proj1 svn://server1.example.com/proj1 --message "Initial import"

Checkout a Project (get a Working Copy)

Checkout a copy of the project /data/repos/proj1 to create a working copy:

$ mkdir /projects/proj1
$ cd /projects/proj1
$ svn checkout svn://server1.example.com/proj1

Submitting Changes to Repository

Update your current copy with the latest repository changes:

$ svn update

Commit your changes to the repository (and log changes):

$ svn commit --message "Added a few more things"

Configure Server for Log Editing

Create or edit the file proj1/hooks/pre-revprop-change to have the following:

# The hook program typically does not inherit the environment of
# its parent process.  For example, a common problem is for the
# PATH environment variable to not be set to its usual value, so
# that subprograms fail to launch unless invoked via absolute path.
# If you're having unexpected problems with a hook program, the
# culprit may be unusual (or missing) environment variables.
#
# Here is an example hook script, for a Unix /bin/sh interpreter.# For more examples and pre-written hooks, see those in
# the Subversion repository at
# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/


REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"

if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi

echo "Changing revision properties other than svn:log is prohibited" >&2
exit 1

Make sure the file is owned by svnuser:svnuser and permissions are set to user read-execute (-r-x——).

Subversion under Windows

Installation

Configuration

Repository Setup (directory under Version Control)

Server Setup

Run Service

Create a Windows service to run server (svnserve.exe). This allows the system to run the server without needing a user to be logged in.

Repository Authentication (Quickstart)

Under repository, create/edit a file conf/svnserve.conf with the following (For example: D:\repos\ezfit4\conf\svnserve.conf):

[general]
anon-access = none
auth-access = write
password-db = passwd
realm = MyProject

Under repository, create/edit a file conf/passwd with the following (For example: D:\repos\ezfit4\conf\passwd):

[users]
smayr = mypasswordhere
joel = anotherpasswordhere

Repository Authentication (Detailed)

The default svnserve setup provides anonymous read-only access, so whilst you can use the repo-browser in TortoiseSVN to view a repository using an svn://URL, you won't be able to perform any normal Subversion operations such as checkout, update or commit.

To enable write access to a repository, you need to edit the conf/svnserve.conf file in your repository directory. This file controls the configuration of the svnserve daemon, and also contains useful documentation.

You can enable anonymous write access by simply setting:

  [general]
  anon-access = write

However, you will not know who has made changes to a repository, as the svn:author property will be empty. You will also be unable to control who makes changes to a repository. This is a somewhat risky setup!

One way to overcome this is to create a password database:

  [general]
  anon-access = none
  auth-access = write
  password-db = password.conf

Where password.conf is a file which exists in the same location as svnserve.conf, it can also exist on a path relative to the conf directory and has a structure of:

  [users]
  username = password
  ...

This example would deny all access for unauthenticated (anonymous) users, and give read-write access to all users in the password.conf file.

If you have multiple repositories, then setting up an authentication realm should make administration easier. For example, if you have two repositories, creatively named TestRepo and TestRepo2, and they both live as sub-directories under c:\repos, to setup an authentication realm between them:

c:\repos\TestRepo\conf\svnserve.conf

  [general]
  anon-access = read
  auth-access = write
  password-db = password.conf

c:\repos\TestRepo2\conf\svnserve.conf

  [general]
  realm = /TestRepo

TestRepo2 now shares the same password database as TestRepo, which gives read-only unauthenticated (anonymous) access and read-write access for authenticated users.

Test Server

Point browser or SVN client (TortoiseSVN or RapidSVN) to repository. For example: svn://localhost/ezfit4

Checkout a Project (get a Working Copy)

Submitting Changes to Repository

Configure Server for Log Editing

Open hooks directory in repository: D:\repos\ezfit4\hooks Create file pre-revprop-change.bat file in that folder with these contents (For example: D:\repos\ezfit4\hooks\pre-revprop-change.bat):

rem # PRE-REVPROP-CHANGE HOOK
rem # Only allow log messages to be changed.

if "%4" == "svn:log" exit 0
echo Property '%4' cannot be changed >&2
exit 1

Perform previous steps for each repository that needs log editing.

Setup Branches and Tags

Create a Branch/Tag

To create a branch (or tag), simply use one of the following:

Synchronizing Branch To Trunk