Subversion repository mirror

Creating a mirror of your Subversion repository means you have an up to date copy of your repository in a safe place. ThisĀ guide shows how to set up a mirror and configure it for synchronisation. The instructions are for Windows.

Setting up the mirror uses svnsync which can be very slow over the network. It’s better to take a dump of the repository and load that into the mirror before starting the sync.

Take a backup

On the central repository:
$ cd c:\temp
$ svnadmin dump c:\subversion\my_repository --incremental -q > my-repository.dump
Create a 7zip archive of the dump file and delete the dump.
Copy the archived dump file to the repository mirror machine.

Create the mirror

On the mirror’s machine:
$ mkdir c:\repos && cd c:\repos
$ svnadmin create my-mirror

Load the dump file.
$ svnadmin load my-mirror -q < c:\temp\my-repository.dump

Serve up.
$ svnserve -d -r c:\repos\my-mirror
$ svn info svn://localhost/

Allow write access

anon-access = none
auth-access = write
password-db = passwd.txt
authz-db = authz.txt

repobot = Robot1

repobot = rw

Note: It can be easier to set up with anon-access = write and once it’s all working then upgrade the security.

Set up a pre-revision hook

[ > Step 3.]
$ cp C:\repos\my-mirror\hooks\pre-revprop-change.tmpl pre-revprop-change.bat
set repository=%1
set revision=%2
set userName=%3
set propertyName=%4
set action=%5

:: Allow editing of revision properties for user.
if "%userName%" == "repobot" goto :eof else goto :ERROR_USER

echo Only admin user may change revision properties. >&2

exit 1

Set up properties to allow svnsync with the pre-populated mirror

$ svn info https://repo-box:8443/svn/my_repository

Use the UUID of the remote:
$ svn propset --revprop -r0 svn:sync-from-uuid 5aab9995-1597-de4e-ac02-ede68baf940a svn://localhost/

Use the last merged revision number:
$ svn propset --revprop -r0 svn:sync-last-merged-rev 14175 svn://localhost/

Set to sync from url:
$ svn propset --revprop -r0 svn:sync-from-url https://repo-box:8443/svn/my_repository svn://localhost/

Initial Sync

$ svnsync synchronize svn://localhost/


svnsync --non-interactive --steal-lock --sync-username repobot --sync-password Robot1 --source-username repobot --source-password Robot1 sync svn://mirror-box/ svn://repo-box/

$ sc create SvnServe binpath= "\"%programfiles%\CollabNet\Subversion Client\svnserve.exe\" --service -r c:\subversion\my_repository" depend= Tcpip start= auto
$ net start svnserve

Create Windows Service for svnserve

sc delete SvnServe
sc create SvnServe binPath= "%programfiles%\TortoiseSVN\bin\svnserve.exe --service -r c:\repos\my-mirror" depend= Tcpip start= auto
net start SvnServe

Mercurial with a Subversion central repository

This How-To is for developers wishing to use Mercurial (Hg) on their Windows development boxes when the source code is in a central Subversion (SVN) repository.

Install TortoiseHg.

In a Windows development environment the easiest way to get started with Hg is to install TortoiseHg. The Windows Explorer extension not only makes it easy to work with files by using icon overlays and context menus but also packages up Python, the SVN bindings and a large number of Hg extensions that will prove very useful.

If you are behind a proxy you must first configure Hg with the proxy settings. Use the TortoiseHg context menu and Global Settings > Proxy.

Working with SVN.

Given that you are working against a central SVN repository then Hg has a number of extensions that can talk to the SVN repo. I use HgSubversion. To install this extension you need to clone the hgsubversion repo:

hg clone c:\hgsvn

Use the TortoiseHg context menu and Global Settings > Edit File.

hgsubversion = c:\hgsvn

Start with a single project. It’s better to clone the whole repo, the trunk, branches and tags, rather than just a branch. This way you only need to do the clone once – clones can take a while. Create a project folder, i.e. c:\development\local\myproject, change to it and then clone the SVN repo:

hg clone sv://subversion/myproject/


It’s best to set up the ignore list for Hg now. Save this as .hgignore and copy it to the root of your local Hg clone (next to .hg).

# Mercurial .hgignore file template by
# For syntax see:
# Source:

# Visual Studio

# Subversion

# Build structure

# Misc

Local Development.

If you use local branches and merge them in your local Hg repo you won’t be able to push changes to SVN.

If you commit often then you will end up with lots of changesets to push to SVN that will make it harder to see what the intention of your update was.

A good way to solve both problems is to submit patches to the central repo. Hg has an extension for patch management called Mercurial Queues (MQ).

Mercurial Queues.

Mercurial Queues (MQ) provides patch management integrated with Hg. This is incredibly useful for packaging up a lot of small changes that you record as you work locally into a single submission to the central repo. You can also work on a number of patches concurrently.

Enable the MQ extension in Hg, TortoiseHg > Global Settings > Extensions and check ‘mq’. In the mercurial.ini set diffs to use the git format.

git = True

In the Hg Repository Explorer you can create a new patch from the latest revision. This means you will need to commit something you want to go into a patch before you can create the patch. The other way is to use the command line.

hg qnew mylatestpatch

qnew will include the latest changes found in the working directory.


One way to work with plenty of local commits but to have a single, tidy submission to the central repo is to use MQ’s qfold to create a patch.

Once you have some changesets you wish to publish you convert them into patches. In Hg Repository Explorer use the context menu on the latest changeset first: Mercurial Queues > Import Revision to MQ. Repeat for each of the changesets. Next, unapply the latest patches until just the earliest is still applied. Now at the command line use qfold. When you refresh Hg Repository Explorer you will see a single patch. Use the patch context menu’s ‘Finish Applied’ to change the patch into a single changeset you can push to the central repo.

For example, you have three changesets: 16; 17 and 18. You then create three patches: 16.diff; 17.diff and 18.diff. You unapply 17.diff and 18.diff then go to the command line:

hg qfold 17
hg qfold 18

Now you have a single patch, 16.diff, that contains all the work commited in the original three changesets.