Hi,
I'm off to the beach for the next two weeks, so if somebody wants to
munge cvs2git into svn2git, here's the basics on how to pull from a
remote SVN repo:
#!/usr/bin/perl
use strict;
use warnings;
use SVN::Core;
use SVN::Ra;
my(@new,@del,@mod);
sub show_log {
my ($changed_paths, $revision, $author, $date, $message, $pool) = @_;
$author = '<unknown>' unless defined $author;
@new = (); @del = (); @mod = ();
(my $pmessage = $message) =~ s/\n/\n /g;
print "*** $revision: $author \@ $date:\n<<< $pmessage>>>\n";
print "Files:\n";
while(my($path,$action) = each %$changed_paths) {
my $act = $action->action;
my $oldpath = $action->copyfrom_path;
my $oldrev = $action->copyfrom_rev;
$oldrev = undef if defined $oldrev and $oldrev <= 0;
$oldpath = undef if defined $oldpath and ($oldpath eq "" or
$oldpath eq $path);
print "$act $path";
print " <-" if $oldpath or $oldrev;
print " $oldpath" if defined $oldpath;
print " $oldrev" if defined $oldrev;
print "\n";
if($act eq "A") {
push(@new,$path);
} elsif($act eq "D") {
push(@del,$path);
} else {
push(@mod,$path);
}
}
}
my $ra = SVN::Ra->new("svn://cvs.gnupg.org/gnupg");
my $latest = $ra->get_latest_revnum();
my $n = 1;
while($n <= $latest) {
$ra->get_log("/",$n,$n,$n,1,1,\&show_log,"");
foreach my $path(@new,@mod) {
print "Reading $path, $n...\n";
open(F,">/tmp/foo"); # ( OK, so use tempfile() here ;-)
eval {
$ra->get_file($path,$n,\*F);
};
close(F);
if ($@) {
print "... not a file\n";
next;
}
my $sz = (stat("/tmp/foo"))[7];
print "... done, $sz bytes\n.";
}
} continue {
$n++;
}
Paths in SVN are usually prefixed "/trunk/" (main branch) or
"/branches/foo/" (branch foo); tagging is done by creating "/tags/bar",
with the trunk (or branch) revision it is pointing to as its parent.
So a branch point looks like this:
*** 350: <unknown> @ 1999-09-18T11:04:00.000000Z:
<<< This commit was manufactured by cvs2svn to create branch
'STABLE-BRANCH-1-0'.>>>
Files:
A /branches/STABLE-BRANCH-1-0/cipher/rndw32.c <- /trunk/cipher/rndw32.c 349
A /branches/STABLE-BRANCH-1-0 <- /trunk 348
(and of *course* it may have changes from other revisions in it,
anything else would simply be too easy I guess...). Tags look like they
do, see tag 1-0-0 in the above repo; that seems to happen because their
CVS importer couldn't find a sane branchpoint. cvsps reports the same thing.
I haven't yet examined what a SVN merge looks like.
Nothing stops a SVN check-in from touching multiple branches at the same
time, though in practice that doesn't happen.
The mapping of SVN revision numbers to git SHA1s could get a bit
annoying because incremental imports need to work. Personally I'd use a
.svnmap file which has "svnid sha1" lines inside. The last line
obviously would not have a sha1 because we can't know that before
checking in the file...
So, if I find a working SVN importer when I come back I'll be happy ;-)
(munging cvs2git shouldn't be particularly difficult), otherwise I'll do
it myself, in a month or so.
--
Matthias Urlichs | {M:U} IT Design @ m-u-it.de | [EMAIL PROTECTED]
Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de
- -
I had been driving my car for 40 years when I fell asleep at the wheel and
had an accident.
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html