Note: if you haven't already, you may want to read part 1 of this article first.

Phew, and that was all the work you needed to do to migrate your Subversion repository to another server. We've barely touched that other server that we wanted to use for mirroring the repository!

"Bootstrapping" your mirror SVN server for svnsync

This mirror SVN server also needs Subversion 1.4.x installed, so go ahead and do the (almost) same things we've done in part 1 to get Subversion installed. You should be able to use the .deb package generated by checkinstall on your main Subversion server to install Subversion 1.4.x on the mirror SVN server. Just scp it to the mirror SVN server and install it (dpkg -i subversion-1.4.3.deb).

With Subversion installed, create a new Subversion repository (using svnadmin create, remember?), but don't load the repository dump like we did on the main SVN server in part 1 (of course, since we are going to be mirroring the repository!).

Setting up svnsync to mirror your repository

First, create a SVN user for svnsync to use - let's call this the 'svnsync user'. The easiest (and best) way to do this is edit the svnserve.conf and passwd files:


# Uncomment this line.
password-db = passwd


svnsync = secret

This gives read and write access to the 'svnsync user'. The svnsync program will authenticate with our repositories as this user via the svn:// protocol (i.e. via svnserve).

Next, we need to create a pre-revprop-change hook for the destination repository. The svnsync documentation has a detailed explanation. Create a hooks/pre-revprop-change file under your destination repository's directory.


if [ "$USER" = "svnsync" ]; then exit 0; fi

echo "Only the svnsync user can change revprops" >&2
exit 1

Make it executable, and then initialize the sync:

chmod +x hooks/pre-revprop-change
svnsync init file:///var/svn/repositories/destination_repos svn://

Don't worry, this only sets up the sync - there's no actual data copying yet. Syncing your repository data may take a long time if you have a big source repository, so I suggest using nohup to run the code overnight (or something), or at least saving the output in a log. Either way, the command to start the sync is:

svnsync sync --username svnsync file:///var/svn/repositories/testsync/

You should start seeing svnsync committing in changes from your source repository. Instant gratification (well, almost)! Should your svnsync process get aborted or killed, you can remove the hanging lock by running:

svn propdel svn:sync-lock --revprop -r 0

Setting up 'on-the-fly' syncing

So now you have your source and destination repositories synced, but what happens when you start committing changes to your source repository? Nothing! That's because svnsync is merely a passive syncing tool (meaning you have to run it to sync, instead of it knowing when to sync automatically).

There are two ways you can setup 'real-time' syncing:

  1. Use cron (or a similar scheduler) on the destination repository server. Add something like this to your crontab:

    * * * * * /usr/local/bin/svnsync --non-interactive sync svn://

    This basically runs svnsync on your destination repository server every minute to pull down any changes to your source repository.

  2. Add a post-commit hook to the source repository. I found this svnsync entry by Paul Querna that has a sample post-commit hook. If I recall correctly I tried it but it didn't work for me, so I settled on using cron to sync up my repositories.

Things that I skipped

There're some things that I skipped over while writing this, mainly to do with SVN authentication.

  • If you're accessing your repository via the svn+ssh:// protocol, you've to manage the (group) permissions of the repository files in the filesystem appropriately (basically the repository should be group writable by your users). chmod and chown are your friends, as is NIS (or something similar) to manage your users. I use these steps to create a new SVN repository that gets access via the svn+ssh:// protocol:

    sudo mkdir /var/svn/repositories/funky_project
    mkdir /tmp/funky_project
    mkdir /tmp/funky_project/trunk
    mkdir /tmp/funky_project/branches
    mkdir /tmp/funky_project/tags
    sudo svnadmin create /var/svn/repositories/funky_project
    sudo svn import /tmp/YourProjectNameHere file:////var/svn/repositories/funky_project -m "Initial import."
    rm -rf /tmp/funky_project
    sudo chown -R www-data:www-data /var/svn/repositories/funky_project
    sudo chmod -R g+w /var/svn/repositories/funky_project

    As you can see, my SVN users are part of the www-data group, and the repository directory is made group-writable.

  • The svn:// protocol has authentication configuration files in the conf/ directory of your repository. The SVN book has a section explaining how to configure authentication for svnserve.
  • Apache httpd can be used to expose your SVN repositories via the WebDAV protocol. This allows for the very commonly seen http:// repository URLs (especially for Open Source projects). Configuration is a little more involved and you would probably have to install Apache from source as well. The SVN book has the details.

Wrapping up

I hope someone found this entry useful - I know I could have used one when I was setting up Subversion and svnsync.