David Landgren wrote:
Parallel to that, I look after the mongueurs.net svnweb repositories,
and I've been trying to track down a memory leak with Nik Clayton. Alas,
at some point I ran some tests of his against a couple of live repos,
which emptied them out and filled them with test info. This was about
the time that I starting pondering the fact that I should dump the repos
regularly and move the backups off-site.
So, I have a couple of trashed repos, but I do have mirrors of both in
SVK repositories on my laptop. Is there a recipe that will let me
restore the contents of the SVN repo from my mirror? I don't really care
if the log messages are recorded as coming from SVK merges rather than
SVN itself, I just want the revision history.
Ah. Oops. I was wondering why I hadn't heard from you :-)
OK. Suppose you have a remote repo. Normal SVK practice is to mirror it in
to a directory in an SVK depot, and then copy it to a local directory in the
same depot.
For example, my copy of the Subversion code repo is in (svk parlance)
/svn/mirror, any my local copy for modifications is in /svn/local.
You need to find whatever your equivalent of the /svn/mirror directory is in
your SVK installation.
Then find out where the underlying repo is on your disk. Use "svk depotmap
--list" for that. For example, if I run that:
% svk depotmap --list | grep svn
/svn/ /home/nik/.svk/svn
So the SVK mirror is in /home/nik/.svk/svn. That will be a normal
Subversion repo, but it contains both the remote changes, and any local ones
too.
So, to recover the repo, dump the copy that SVK has, but include just the
paths that came from the remote repo.
% cd /home/nik/.svk
% svnadmin dump svn | svndumpfilter include --drop-empty-revs
--renumber-revs /mirror > repo.dump
repo.dump should then contain just the revisions from the remote repo.
However, all the paths will be wrong (in my example they'll all start
'/mirror/'). Also, all the revision numbers will be off by 1, because rev 1
is the revision in which the mirror is initialised.
To fix the first problem, you can search/replace;
perl -pi -e 's/^Node-path: mirror(.*)$/Node-path: $1/' repo.dump
should do it. Adjust 'mirror' in that RE as necessary for your situation.
To fix the second problem you need to edit repo.dump, and delete everything
from:
Revision-number: 1
up to, but not including the line:
Revision-number: 2
That nukes r1. Then you need to adjust all the following revision numbers.
That's everything that matches /^Revision-number: \d+$/.
Finally, the repo dump will also contain some svm:* properties. These
should probably be removed too, for completeness sake. A property
definition in the dump file looks like:
K \d+
<propname>
V \d+
<propval>
E.g.,
K 10
svn:author
V 3
nik
Keyword/value pairs, with the trailing digits indicating the string length,
not including the terminating '\n'. Again, you'll need to write a filter
that can strip these out.
That done, you should be able to create a new repo, and 'svnadmin load'
repo.dump in to it to recover the contents of the repository.
When it comes to writing filters that do this you may find SVN::Dump
helpful. For example, the "remove the svm: properties" bit is probably
(warning, untested code ahead)
use strict;
use warnings;
use SVN::Dump;
my $dump = SVN::Dump->new(shift);
print $dump->as_string(); # only print the dump header
while( $rec = $dump->next_record() ) {
$rec->delete_property('svm:headrev', 'svm:mirror',
'svm:source', 'svm:uuid');
print $rec->as_string();
}
Hope that helps -- FWIW, if you develop a tool that can, given an SVK
mirrored repo, regenerate the original repo, that would be a valuable
addition to CPAN.
N