At work we have a single Subversion repository with loads of projects and one single Trac instance. We are now in the process of splitting this up into several smaller repositories that will have a matching Trac instance. Yesterday I moved a project called “Dine Penger” and here is how I did it.
To move a project out of a repository and into another one we have to do some stuff locally on the machines that hold these repositories. I could of course just do an
svn export of the project from the old repository and then
import the code into the new, but then all history would get lost.
svnadmin to the rescue!
svnadmin has a subcommand called
dump that dumps a complete repository to a file so you can load it somewhere else. Since we only want to move the dinepenger directory at this time we can filter the output of
svnadmin through the
svndumpfilter command. This command has two interesting subcommands:
exclude. These two subcommands lets you decide on what to let through the filter. Since we only wanted stuff inside the dinepenger path I did the following:
svnadmin dump /path/to/repos | svndumpfilter include dinepenger > dinepenger.dump
This will only include stuff that has dinepenger in the path. Now we need to move this dump file over to the new machine and use the
load subcommand of
svnadmin to load the dump file into the new repository:
svnadmin create dinepenger; svnadmin load dinepenger < dinepenger.dump
And that’s that! I did some restructuring of the new repository after I loaded the old one since I did not want dinepenger on root, but the regular branches, tags, trunk directories instead.
If some developers have the old version of dinepenger as a working copy checked out (the one in the old repository) they can “easily” switch to the new one using
svn switch with the
--relocate option. I tried this myself by doing a fresh checkout of dinepenger after I had moved it and then doing:
Everything worked fine until I tried to do a command that actually talks to the new repository. The
switch command used together with the
--relocate option only does some local changes and does not contact any of the repositories. When I tried an
svn up, it complained that the revision did not exist. This was because someone on our dev team had commited something to the old repository so that the global revision counter had increased. The change was not inside the dinepenger directory but something else. When I did the fresh checkout I got a different global revision number than the one in the new repository. I therefore had to do a checkout of the same revision as the one I moved from the old repository:
svn co --revision <num> http://<oldurl>
<num> is the global revision number found in the new dinepenger repository. Because the changed made to the old repository did not involve anything inside the dinepenger directory I did not have to do a new
After I figured this out everything worked like a charm!