Splitting rev-list into revisions lib, end of beginning.
[gitweb.git] / git-svnimport.perl
index 45d77c5bae9c055641c416676c1d783c73fc28bb..ee2940f4803955f2746baf3c78f64a67b4790cab 100755 (executable)
@@ -10,7 +10,6 @@
 # The head revision is on branch "origin" by default.
 # You can change that with the '-o' option.
 
-require 5.008; # for shell-safe open("-|",LIST)
 use strict;
 use warnings;
 use Getopt::Std;
 $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_s,$opt_l,$opt_d,$opt_D);
+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_s,$opt_l,$opt_d,$opt_D);
 
 sub usage() {
        print STDERR <<END;
 Usage: ${\basename $0}     # fetch/update GIT from SVN
-       [-o branch-for-HEAD] [-h] [-v] [-l max_num_changes]
+       [-o branch-for-HEAD] [-h] [-v] [-l max_rev]
        [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
-       [-d|-D] [-i] [-u] [-s start_chg] [-m] [-M regex] [SVN_URL]
+       [-d|-D] [-i] [-u] [-r] [-s start_chg] [-m] [-M regex] [SVN_URL]
 END
        exit(1);
 }
 
-getopts("b:C:dDhil:mM:o:s:t:T:uv") or usage();
+getopts("b:C:dDhil:mM:o:rs:t:T:uv") or usage();
 usage if $opt_h;
 
 my $tag_name = $opt_t || "tags";
@@ -96,8 +95,10 @@ sub new {
 sub conn {
        my $self = shift;
        my $repo = $self->{'fullrep'};
-       my $s = SVN::Ra->new($repo);
-
+       my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
+                         SVN::Client::get_ssl_server_trust_file_provider,
+                         SVN::Client::get_username_provider]);
+       my $s = SVN::Ra->new(url => $repo, auth => $auth);
        die "SVN connection to $repo: $!\n" unless defined $s;
        $self->{'svn'} = $s;
        $self->{'repo'} = $repo;
@@ -126,8 +127,9 @@ sub file {
 package main;
 use URI;
 
-my $svn = $svn_url;
+our $svn = $svn_url;
 $svn .= "/$svn_dir" if defined $svn_dir;
+my $svn2 = SVNconn->new($svn);
 $svn = SVNconn->new($svn);
 
 my $lwp_ua;
@@ -198,7 +200,7 @@ ($$)
 my $maxnum = 0;
 my $last_rev = "";
 my $last_branch;
-my $current_rev = $opt_s-1;
+my $current_rev = $opt_s || 1;
 unless(-d $git_dir) {
        system("git-init-db");
        die "Cannot init the GIT db at $git_tree: $?\n" if $?;
@@ -254,7 +256,7 @@ ($$)
                my($num,$branch,$ref) = split;
                $branches{$branch}{$num} = $ref;
                $branches{$branch}{"LAST"} = $ref;
-               $current_rev = $num if $current_rev < $num;
+               $current_rev = $num+1 if $current_rev <= $num;
        }
        close($B);
 }
@@ -315,12 +317,16 @@ ($$$)
                        die $res->status_line." at $url\n";
                }
        } else {
-               $name = $svn->file("/$svnpath",$rev);
+               $name = $svn->file("$svnpath",$rev);
                return undef unless defined $name;
        }
 
-       open my $F, '-|', "git-hash-object", "-w", $name
+       my $pid = open(my $F, '-|');
+       die $! unless defined $pid;
+       if (!$pid) {
+           exec("git-hash-object", "-w", $name)
                or die "Cannot create object: $!\n";
+       }
        my $sha = <$F>;
        chomp $sha;
        close $F;
@@ -395,7 +401,12 @@ ($$$$$$$$)
                        $srcpath =~ s#/*$#/#;
        }
        
-       open my $f,"-|","git-ls-tree","-r","-z",$gitrev,$srcpath;
+       my $pid = open my $f,'-|';
+       die $! unless defined $pid;
+       if (!$pid) {
+               exec("git-ls-tree","-r","-z",$gitrev,$srcpath)
+                       or die $!;
+       }
        local $/ = "\0";
        while(<$f>) {
                chomp;
@@ -543,23 +554,34 @@ sub commit {
                        }
                }
 
-               if(@old) {
-                       open my $F, "-|", "git-ls-files", "-z", @old or die $!;
-                       @old = ();
+               while(@old) {
+                       my @o1;
+                       if(@old > 55) {
+                               @o1 = splice(@old,0,50);
+                       } else {
+                               @o1 = @old;
+                               @old = ();
+                       }
+                       my $pid = open my $F, "-|";
+                       die "$!" unless defined $pid;
+                       if (!$pid) {
+                               exec("git-ls-files", "-z", @o1) or die $!;
+                       }
+                       @o1 = ();
                        local $/ = "\0";
                        while(<$F>) {
                                chomp;
-                               push(@old,$_);
+                               push(@o1,$_);
                        }
                        close($F);
 
-                       while(@old) {
+                       while(@o1) {
                                my @o2;
-                               if(@old > 55) {
-                                       @o2 = splice(@old,0,50);
+                               if(@o1 > 55) {
+                                       @o2 = splice(@o1,0,50);
                                } else {
-                                       @o2 = @old;
-                                       @old = ();
+                                       @o2 = @o1;
+                                       @o1 = ();
                                }
                                system("git-update-index","--force-remove","--",@o2);
                                die "Cannot remove files: $?\n" if $?;
@@ -640,6 +662,7 @@ sub commit {
                $pr->reader();
 
                $message =~ s/[\s\n]+\z//;
+               $message = "r$revision: $message" if $opt_r;
 
                print $pw "$message\n"
                        or die "Error writing to git-commit-tree: $!\n";
@@ -708,17 +731,17 @@ sub commit {
        print "DONE: $revision $dest $cid\n" if $opt_v;
 }
 
-my ($changed_paths, $revision, $author, $date, $message, $pool) = @_;
-sub _commit_all {
-       ($changed_paths, $revision, $author, $date, $message, $pool) = @_;
+sub commit_all {
+       # Recursive use of the SVN connection does not work
+       local $svn = $svn2;
+
+       my ($changed_paths, $revision, $author, $date, $message, $pool) = @_;
        my %p;
        while(my($path,$action) = each %$changed_paths) {
                $p{$path} = [ $action->action,$action->copyfrom_path, $action->copyfrom_rev, $path ];
        }
        $changed_paths = \%p;
-}
 
-sub commit_all {
        my %done;
        my @col;
        my $pref;
@@ -734,19 +757,20 @@ sub commit_all {
        }
 }
 
-while(++$current_rev <= $svn->{'maxrev'}) {
-       if (defined $opt_l) {
-               $opt_l--;
-               if ($opt_l < 0) {
-                       last;
-               }
-       }
-       my $pool=SVN::Pool->new;
-       $svn->{'svn'}->get_log("/",$current_rev,$current_rev,1,1,1,\&_commit_all,$pool);
-       $pool->clear;
-       commit_all();
+$opt_l = $svn->{'maxrev'} if not defined $opt_l or $opt_l > $svn->{'maxrev'};
+
+if ($svn->{'maxrev'} < $current_rev) {
+    print "Up to date: no new revisions to fetch!\n" if $opt_v;
+    unlink("$git_dir/SVN2GIT_HEAD");
+    exit;
 }
 
+print "Fetching from $current_rev to $opt_l ...\n" if $opt_v;
+
+my $pool=SVN::Pool->new;
+$svn->{'svn'}->get_log("/",$current_rev,$opt_l,0,1,1,\&commit_all,$pool);
+$pool->clear;
+
 
 unlink($git_index);