Mirror an svn repository with svnsync
If you like to keep all your work under svn source control, you're probably going to also want to keep a backup of your svn repositories in case of a hardware failure or some other catastrophic event. svn comes with a utility to help you do this - svnsync, which we can use to keep a real-time, read only backup of our svn repositories.
I'm going to assume that you already have your main svn repository set up, and are providing access to it through Apache, however, this will work just as well for repositories served with svnserve.
On the Slave
On your Slave machine, set up a new svn repository. It's very important that you don't make any commits in this repository - it needs to be a blank canvas for svnsync to work with.
svnadmin create /svr/svn/myrepo chown -R www-data:www-data /svr/svn/myrepo
Since this repository is going to be a read-ony mirror, the best thing is to create a dedicated svnsync user that has read/write access to the repository. This should be the only user that is allowed to write to the repository to avoid accidental repository writes.
Set up Apache to make the repository available over the net.
<Location>
DAV svn
SVNParentPath /srv/svn/repos/
AuthType Basic
AuthName "My Read-only SVN Mirror"
AuthUserFile /srv/svn/dav_svn.passwd
Require valid-user
</Location>
Then create the htpasswd file to allow the svnsync user access to the repository:
htpasswd -c /srv/svn/dav_svn.passwd svnsync
Now, for a little more added security we will limit the repository so that it will only allow our svnsync user to make commits. We do this by creating a start-commit hook (still on the slave machine). Create the file /srv/svn/repos/myproject/hooks/start-commit).
#!/bin/sh USER="$2" if [ "$USER" = "svnsync" ]; then exit 0; fi echo "Only the svnsync user may commit new revisions" >&2 exit 1
And by a similar token, we want to be sure that svnsync is the only user that is able to add, modify or delete revision properties. Create the file /srv/svn/repos/myproject/hooks/pre-revprop-change.
#!/bin/sh USER="$3" if [ "$USER" = "svnsync" ]; then exit 0; fi echo "Only the svnsync user may change revision properties" >&2 exit 1
Make sure both of these scripts are executable.
chmod 755 /srv/svn/repos/myproject/hooks/start-commit chmod 755 /srv/svn/repos/myproject/hooks/pre-revprop-change
On the Master
Our Slave machine is now ready, so jump over to the Master machine. First thing we need to do here is to initialise the svnsync target.
svnsync initialize https://target/myproject/ https://source/myproject/ \ --sync-username svnsync --sync-password syncpassword \ --source-username sourceusername --source-password sourcepassword
Next, we want to add a post-commit script to tell our master repository that it should run svnsync after every commit. Create the file /srv/svn/repos/myproject/hooks/post-commit.
#!/bin/sh SVNSYNC=/usr/bin/svnsync TO=http://my.slave.machine/myproject/ SYNC_USER=svnsync SYNC_PASS=syncpassword SOURCE_USER=me SOURCE_PASS=mypassword $SVNSYNC --non-interactive sync $TO \ --sync-username $SYNC_USER --sync-password $SYNC_PASS \ --source-username $SOURCE_USER --source-password $SOURCE_PASS & exit 0
One last thing, we also want to ensure that changes to revision properties are also synced. Create the file /srv/svn/repos/myproject/hooks/post-revprop-change.
#!/bin/sh SVNSYNC=/usr/bin/svnsync TO=http://my.slave.machine/myproject/ SYNC_USER=svnsync SYNC_PASS=syncpassword SOURCE_USER=me SOURCE_PASS=mypassword $SVNSYNC --non-interactive copy-revprops $TO \ --sync-username $SYNC_USER --sync-password $SYNC_PASS \ --source-username $SOURCE_USER --source-password $SOURCE_PASS $2 & exit 0
Make sure both of these scripts are executable.
chmod 755 /srv/svn/repos/myproject/hooks/post-commit chmod 755 /srv/svn/repos/myproject/hooks/post-revprop-change
And that should be it!
Summing up
Hopefully, you should now find that any commits you make on your main svn repository are automatically synced over to a read-only backup. I must say that I haven't tested this extensively - it took me several years to even getting round to setting it up, but I now feel a lot safer in the knowledge that I will always have an up-to-date backup of my work.
Gotchas
Well, this one got me stumped for a good while... On my Master machine, I am serving my repositories with Apache over ssl (https). Apache is running under the www-data user, and since svnsync is being run on a post-commit hook, it too will run as the www-data user. Now in a normal situation, attempting to run svnsync against a server which is using a self-signed certificate like mine, would result in a prompt asking me if I would like to accept the certificate. It is possible to tell svn to accept specific certificates by adding the following to www-data's ~/.subversion/servers file:
ssl-authority-files = /etc/ssl/certs/svn.myserver.mydomain.pem
Similar articles on this site
LATEST ARTICLES
TODAY'S MOST POPULAR
-
4th Sep 08
-
8th Aug 08
-
20th Sep 08
MOST POPULAR ARTICLES
RECENT COMMENTS
-
1 day 6 hours ago
-
3 days 19 hours ago
-
4 days 31 min ago
-
4 days 6 hours ago
-
4 days 23 hours ago

Comments
8th Dec 2008, 10:10am
SVN is so last year! Get with the times... :D
8th Dec 2008, 12:56pm
Thanks for the howto. I might give this a try in the future. Right now I am using a traditional backup scheme.
Thanks!
Shrop
30th Jan 2009, 1:09pm
Even better...mirror it with git-svn. Git > SVN in every way possible!
16th Jul 2009, 12:51pm
first, can I run this on my post commit file:
svnsync initialize https://target/myproject/ https://source/myproject/ \
--sync-username svnsync --sync-password syncpassword \
--source-username sourceusername --source-password sourcepassword
How does the system know what svnsync is?
then, when I run your code above where SVNSYNC is a variable, how do you know what path to use.../usr/bin/svnsync?
my svnsync.exe file is located in /program files/visualSVN server/bin/
can you help me figure out how to use this code? I have followed the above steps, except for the initialize (i added that into my post commit file since i had not idea how to run it), however, it seems like it all comes down to either the initialize, and then the path to the svnsync.
Can you give me some guidence????
thanks
Dan
8th Oct 2009, 8:00am
Hi,, Thanks for the information. i have tried with my mac and ubuntu machine. in my both the i have configured Subversion on http protocol . and then i have tried with main server .which is on debian. in that i have configure subversion server on svn+ssh protocol and my mirroring machine on http protocol.. all commands are working fine . but mirroring is not going on .. any idea ??
13th Oct 2009, 10:00am
hi While Running Post Commit Script on Master machine.. It is giving Following error "Permission denied (publickey,password). svnsync: Connection closed unexpectedly" My Destination Running on http Protocol and my sourcemachine is running on svn+ssh protocol
Please share your thoughts, comments and suggestions...