How did I split my monolithic SVN repository

First time I used Subversion it seemed to be a good idea to create a single repository under /var/lib/svn and to open a subdirectory for each separated project I work on.

A few years later I don't think it so good. :-)

So I started to search the web for ideas how to "export" individual projects (i.e subdirs) from the monolithic repository and create new small ones keeping revision history. I found that basic SVN commands do not support this operation.

Finally I decided to write a script that selects certain parts of output of "svnadmin dump" command. Fortunately I found the SVN::Dump package from Philippe "BooK" Bruhat. This module does the dirty work of parsing dump output so I've just select the records to keep.

Internal structure of my original repository in /var/lib/svn/looked like this:

	+---+---project1/---+---tags/
	    |               |
	    |               +---trunks/
	    |
	    +---project2/---+---branches/
	    |               |
	    |               +---tags/
	    |               |
	    |               +---trunk/
	    |               |
	    |               +---vendor/
	    |
	    +--project1b/-------trunk/
Projects are totally separated, they have no common files and I've never executed "svn commit" that would affect more than one project.

Therefore I could write a small script called svngrep that looks for each revisions in dump and select those where Node-path matches a given PERL compatible regular expression.

Let's see an example:
$ ssh remotehost mkdir /var/lib/svn/new
$ ssh remotehost svnadmin create /var/lib/svn/new
$ svnadmin dump /var/lib/svn | svngrep '^project1\b' | ssh remotehost svnadmin load /var/lib/svn/new
The \b (word boundary) metacharacter prevents svngrep to select revisions affecting project project1b. (You have to choose a proper regular expression that fits your requirements.)

Now this the layout of the new repository under remotehost:/var/lib/svn/new

	+-------project1/---+---tags/
	                    |
	                    +---trunks/
Intermediate directory project1 is not necessary any more therefore you can move all subdirs one level up. Issue these commands:
locahost$ ssh remotehost
remotehost$ svn move -m normalize file:///var/lib/svn/new/project1/trunks file:///var/lib/svn/new
remotehost$ svn move -m normalize file:///var/lib/svn/new/project1/tags file:///var/lib/svn/new
remotehost$ svn delete -m normalize file:///var/lib/svn/new/project1
or equivalent ones:
$ svn move -m normalize svn+ssh://remotehost/var/lib/svn/new/project1/trunks \
	svn+ssh://remotehost/var/lib/svn/new
...

Download svngrep and enjoy. (Eeeerr... never delete original repository until you have checked the new small repos.)

Gábor