summaryrefslogtreecommitdiff
path: root/git-svnimport.perl
diff options
context:
space:
mode:
Diffstat (limited to 'git-svnimport.perl')
-rwxr-xr-xgit-svnimport.perl122
1 files changed, 79 insertions, 43 deletions
diff --git a/git-svnimport.perl b/git-svnimport.perl
index aca0e4f64e..cbaa8ab37c 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -31,7 +31,7 @@ $SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
- $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F);
+ $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,$opt_P);
sub usage() {
print STDERR <<END;
@@ -39,17 +39,19 @@ Usage: ${\basename $0} # fetch/update GIT from SVN
[-o branch-for-HEAD] [-h] [-v] [-l max_rev]
[-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
[-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
- [-m] [-M regex] [-A author_file] [-S] [-F] [SVN_URL]
+ [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
END
exit(1);
}
-getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:Suv") or usage();
+getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:uv") or usage();
usage if $opt_h;
my $tag_name = $opt_t || "tags";
my $trunk_name = $opt_T || "trunk";
my $branch_name = $opt_b || "branches";
+my $project_name = $opt_P || "";
+$project_name = "/" . $project_name if ($project_name);
@ARGV == 1 or @ARGV == 2 or usage();
@@ -193,6 +195,13 @@ sub ignore {
}
}
+sub dir_list {
+ my($self,$path,$rev) = @_;
+ my ($dirents,undef,$properties)
+ = $self->{'svn'}->get_dir($path,$rev,undef);
+ return $dirents;
+}
+
package main;
use URI;
@@ -342,35 +351,16 @@ if ($opt_A) {
open BRANCHES,">>", "$git_dir/svn2git";
-sub node_kind($$$) {
- my ($branch, $path, $revision) = @_;
+sub node_kind($$) {
+ my ($svnpath, $revision) = @_;
my $pool=SVN::Pool->new;
- my $kind = $svn->{'svn'}->check_path(revert_split_path($branch,$path),$revision,$pool);
+ my $kind = $svn->{'svn'}->check_path($svnpath,$revision,$pool);
$pool->clear;
return $kind;
}
-sub revert_split_path($$) {
- my($branch,$path) = @_;
-
- my $svnpath;
- $path = "" if $path eq "/"; # this should not happen, but ...
- if($branch eq "/") {
- $svnpath = "$trunk_name/$path";
- } elsif($branch =~ m#^/#) {
- $svnpath = "$tag_name$branch/$path";
- } else {
- $svnpath = "$branch_name/$branch/$path";
- }
-
- $svnpath =~ s#/+$##;
- return $svnpath;
-}
-
sub get_file($$$) {
- my($rev,$branch,$path) = @_;
-
- my $svnpath = revert_split_path($branch,$path);
+ my($svnpath,$rev,$path) = @_;
# now get it
my ($name,$mode);
@@ -413,10 +403,9 @@ sub get_file($$$) {
}
sub get_ignore($$$$$) {
- my($new,$old,$rev,$branch,$path) = @_;
+ my($new,$old,$rev,$path,$svnpath) = @_;
return unless $opt_I;
- my $svnpath = revert_split_path($branch,$path);
my $name = $svn->ignore("$svnpath",$rev);
if ($path eq '/') {
$path = $opt_I;
@@ -435,11 +424,25 @@ sub get_ignore($$$$$) {
close $F;
unlink $name;
push(@$new,['0644',$sha,$path]);
- } else {
+ } elsif (defined $old) {
push(@$old,$path);
}
}
+sub project_path($$)
+{
+ my ($path, $project) = @_;
+
+ $path = "/".$path unless ($path =~ m#^\/#) ;
+ return $1 if ($path =~ m#^$project\/(.*)$#);
+
+ $path =~ s#\.#\\\.#g;
+ $path =~ s#\+#\\\+#g;
+ return "/" if ($project =~ m#^$path.*$#);
+
+ return undef;
+}
+
sub split_path($$) {
my($rev,$path) = @_;
my $branch;
@@ -459,7 +462,11 @@ sub split_path($$) {
print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path});
return ()
}
- $path = "/" if $path eq "";
+ if ($path eq "") {
+ $path = "/";
+ } elsif ($project_name) {
+ $path = project_path($path, $project_name);
+ }
return ($branch,$path);
}
@@ -480,6 +487,27 @@ sub branch_rev($$) {
return $therev;
}
+sub expand_svndir($$$);
+
+sub expand_svndir($$$)
+{
+ my ($svnpath, $rev, $path) = @_;
+ my @list;
+ get_ignore(\@list, undef, $rev, $path, $svnpath);
+ my $dirents = $svn->dir_list($svnpath, $rev);
+ foreach my $p(keys %$dirents) {
+ my $kind = node_kind($svnpath.'/'.$p, $rev);
+ if ($kind eq $SVN::Node::file) {
+ my $f = get_file($svnpath.'/'.$p, $rev, $path.'/'.$p);
+ push(@list, $f) if $f;
+ } elsif ($kind eq $SVN::Node::dir) {
+ push(@list,
+ expand_svndir($svnpath.'/'.$p, $rev, $path.'/'.$p));
+ }
+ }
+ return @list;
+}
+
sub copy_path($$$$$$$$) {
# Somebody copied a whole subdirectory.
# We need to find the index entries from the old version which the
@@ -488,8 +516,11 @@ sub copy_path($$$$$$$$) {
my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_;
my($srcbranch,$srcpath) = split_path($rev,$oldpath);
- unless(defined $srcbranch) {
- print "Path not found when copying from $oldpath @ $rev\n";
+ unless(defined $srcbranch && defined $srcpath) {
+ print "Path not found when copying from $oldpath @ $rev.\n".
+ "Will try to copy from original SVN location...\n"
+ if $opt_v;
+ push (@$new, expand_svndir($oldpath, $rev, $path));
return;
}
my $therev = branch_rev($srcbranch, $rev);
@@ -503,7 +534,7 @@ sub copy_path($$$$$$$$) {
}
print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
if ($node_kind eq $SVN::Node::dir) {
- $srcpath =~ s#/*$#/#;
+ $srcpath =~ s#/*$#/#;
}
my $pid = open my $f,'-|';
@@ -582,10 +613,12 @@ sub commit {
if(defined $oldpath) {
my $p;
($parent,$p) = split_path($revision,$oldpath);
- if($parent eq "/") {
- $parent = $opt_o;
- } else {
- $parent =~ s#^/##; # if it's a tag
+ if(defined $parent) {
+ if($parent eq "/") {
+ $parent = $opt_o;
+ } else {
+ $parent =~ s#^/##; # if it's a tag
+ }
}
} else {
$parent = undef;
@@ -651,9 +684,10 @@ sub commit {
push(@old,$path); # remove any old stuff
}
if(($action->[0] eq "A") || ($action->[0] eq "R")) {
- my $node_kind = node_kind($branch,$path,$revision);
+ my $node_kind = node_kind($action->[3], $revision);
if ($node_kind eq $SVN::Node::file) {
- my $f = get_file($revision,$branch,$path);
+ my $f = get_file($action->[3],
+ $revision, $path);
if ($f) {
push(@new,$f) if $f;
} else {
@@ -668,19 +702,20 @@ sub commit {
\@new, \@parents);
} else {
get_ignore(\@new, \@old, $revision,
- $branch, $path);
+ $path, $action->[3]);
}
}
} elsif ($action->[0] eq "D") {
push(@old,$path);
} elsif ($action->[0] eq "M") {
- my $node_kind = node_kind($branch,$path,$revision);
+ my $node_kind = node_kind($action->[3], $revision);
if ($node_kind eq $SVN::Node::file) {
- my $f = get_file($revision,$branch,$path);
+ my $f = get_file($action->[3],
+ $revision, $path);
push(@new,$f) if $f;
} elsif ($node_kind eq $SVN::Node::dir) {
get_ignore(\@new, \@old, $revision,
- $branch,$path);
+ $path, $action->[3]);
}
} else {
die "$revision: unknown action '".$action->[0]."' for $path\n";
@@ -883,6 +918,7 @@ sub commit_all {
while(my($path,$action) = each %$changed_paths) {
($branch,$path) = split_path($revision,$path);
next if not defined $branch;
+ next if not defined $path;
$done{$branch}{$path} = $action;
}
while(($branch,$changed_paths) = each %done) {