X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=git-cvsimport.perl;h=24f983434249e0c37b7f2229e73c70b374403dc4;hb=39ba7d54649b35c943b026b54bff40cfa0153f3e;hp=f35c0d045b3db937e8bf447063c81e869b800f7e;hpb=79a9d8ea0d88a3667ad19be8e705405ab5d896f1;p=git.git diff --git a/git-cvsimport.perl b/git-cvsimport.perl index f35c0d04..24f98343 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -29,19 +29,63 @@ use IPC::Open2; $SIG{'PIPE'}="IGNORE"; $ENV{'TZ'}="UTC"; -our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_s,$opt_m,$opt_M); +our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S); +my (%conv_author_name, %conv_author_email); sub usage() { print STDERR <) { + # Expected format is this: + # exon=Andreas Ericsson + if (m/^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/) { + $user = $1; + $conv_author_name{$user} = $2; + $conv_author_email{$user} = $3; + } + # However, we also read from CVSROOT/users format + # to ease migration. + elsif (/^(\w+):(['"]?)(.+?)\2\s*$/) { + my $mapped; + ($user, $mapped) = ($1, $3); + if ($mapped =~ /^\s*(.*?)\s*<(.*)>\s*$/) { + $conv_author_name{$user} = $1; + $conv_author_email{$user} = $2; + } + elsif ($mapped =~ /^?$/) { + $conv_author_name{$user} = $user; + $conv_author_email{$user} = $1; + } + } + # NEEDSWORK: Maybe warn on unrecognized lines? + } + close ($f); +} + +sub write_author_info($) { + my ($file) = @_; + open my $f, '>', $file or + die("Failed to open $file for writing: $!"); + + foreach (keys %conv_author_name) { + print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>\n"; + } + close ($f); +} + +getopts("hivmkuo:d:p:C:z:s:M:P:A:S:") or usage(); usage if $opt_h; @ARGV <= 1 or usage(); @@ -317,6 +361,7 @@ sub _line { } } } + return undef; } sub file { my($self,$fn,$rev) = @_; @@ -328,12 +373,12 @@ sub file { $self->_file($fn,$rev) and $res = $self->_line($fh); if (!defined $res) { - # retry + print STDERR "Server has gone away while fetching $fn $rev, retrying...\n"; + truncate $fh, 0; $self->conn(); - $self->_file($fn,$rev) - or die "No file command send\n"; + $self->_file($fn,$rev) or die "No file command send"; $res = $self->_line($fh); - die "No input: $fn $rev\n" unless defined $res; + die "Retry failed" unless defined $res; } close ($fh); @@ -433,7 +478,11 @@ unless(-d $git_dir) { "Either use the correct '-o branch' option,\n". "or import to a new repository.\n"; - $last_branch = basename(readlink("$git_dir/HEAD")); + open(F, "git-symbolic-ref HEAD |") or + die "Cannot run git-symbolic-ref: $!\n"; + chomp ($last_branch = ); + $last_branch = basename($last_branch); + close(F); unless($last_branch) { warn "Cannot read the last branch name: $! -- assuming 'master'\n"; $last_branch = "master"; @@ -445,7 +494,7 @@ CVS2GIT_HEAD exists. Make sure your working directory corresponds to HEAD and remove CVS2GIT_HEAD. You may need to run - git-read-tree -m -u CVS2GIT_HEAD HEAD + git read-tree -m -u CVS2GIT_HEAD HEAD EOM } system('cp', "$git_dir/HEAD", "$git_dir/CVS2GIT_HEAD"); @@ -481,14 +530,30 @@ EOM -d $git_dir or die "Could not create git subdir ($git_dir).\n"; +# now we read (and possibly save) author-info as well +-f "$git_dir/cvs-authors" and + read_author_info("$git_dir/cvs-authors"); +if ($opt_A) { + read_author_info($opt_A); + write_author_info("$git_dir/cvs-authors"); +} + my $pid = open(CVS,"-|"); die "Cannot fork: $!\n" unless defined $pid; unless($pid) { my @opt; @opt = split(/,/,$opt_p) if defined $opt_p; unshift @opt, '-z', $opt_z if defined $opt_z; - exec("cvsps",@opt,"-u","-A","--cvs-direct",'--root',$opt_d,$cvs_tree); - die "Could not start cvsps: $!\n"; + unshift @opt, '-q' unless defined $opt_v; + unless (defined($opt_p) && $opt_p =~ m/--no-cvs-direct/) { + push @opt, '--cvs-direct'; + } + if ($opt_P) { + exec("cat", $opt_P); + } else { + exec("cvsps","--norc",@opt,"-u","-A",'--root',$opt_d,$cvs_tree); + die "Could not start cvsps: $!\n"; + } } @@ -511,7 +576,7 @@ unless($pid) { my $state = 0; my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); -my(@old,@new); +my(@old,@new,@skipped); my $commit = sub { my $pid; while(@old) { @@ -567,6 +632,7 @@ my $commit = sub { unless($pid) { $pr->writer(); $pw->reader(); + open(OUT,">&STDOUT"); dup2($pw->fileno(),0); dup2($pr->fileno(),1); $pr->close(); @@ -584,10 +650,9 @@ my $commit = sub { if ( -e "$git_dir/refs/heads/$mparent") { $mparent = get_headref($mparent, $git_dir); push @par, '-p', $mparent; - # printing here breaks import # - # # print "Merge parent branch: $mparent\n" if $opt_v; + print OUT "Merge parent branch: $mparent\n" if $opt_v; } - } + } } exec("env", @@ -607,6 +672,11 @@ my $commit = sub { substr($logmsg,32767) = "" if length($logmsg) > 32767; $logmsg =~ s/[\s\n]+\z//; + if (@skipped) { + $logmsg .= "\n\n\nSKIPPED:\n\t"; + $logmsg .= join("\n\t", @skipped) . "\n"; + } + print $pw "$logmsg\n" or die "Error writing to git-commit-tree: $!\n"; $pw->close(); @@ -633,6 +703,7 @@ my $commit = sub { my($xtag) = $tag; $xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY ** $xtag =~ tr/_/\./ if ( $opt_u ); + $xtag =~ s/[\/]/$opt_s/g; my $pid = open2($in, $out, 'git-mktag'); print $out "object $cid\n". @@ -685,6 +756,9 @@ while() { s/\s+$//; if (/^(.*?)\s+<(.*)>/) { ($author_name, $author_email) = ($1, $2); + } elsif ($conv_author_name{$_}) { + $author_name = $conv_author_name{$_}; + $author_email = $conv_author_email{$_}; } else { $author_name = $author_email = $_; } @@ -760,6 +834,12 @@ while() { my $fn = $1; my $rev = $3; $fn =~ s#^/+##; + if ($opt_S && $fn =~ m/$opt_S/) { + print "SKIPPING $fn v $rev\n"; + push(@skipped, $fn); + next; + } + print "Fetching $fn v $rev\n" if $opt_v; my ($tmpname, $size) = $cvs->file($fn,$rev); if($size == -1) { push(@old,$fn); @@ -817,8 +897,7 @@ if($orig_branch) { print "DONE; creating $orig_branch branch\n" if $opt_v; system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") unless -f "$git_dir/refs/heads/master"; - unlink("$git_dir/HEAD"); - symlink("refs/heads/$orig_branch","$git_dir/HEAD"); + system('git-update-ref', 'HEAD', "$orig_branch"); unless ($opt_i) { system('git checkout'); die "checkout failed: $?\n" if $?;