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

Reply via email to