diff options
Diffstat (limited to 'git-cvsimport.perl')
-rwxr-xr-x | git-cvsimport.perl | 118 |
1 files changed, 90 insertions, 28 deletions
diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 4853bf7a0d..8d41610bcf 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This tool is copyright (c) 2005, Matthias Urlichs. # It is released under the Gnu Public License, version 2. @@ -13,6 +13,7 @@ # The head revision is on branch "origin" by default. # You can change that with the '-o' option. +use 5.008; use strict; use warnings; use Getopt::Long; @@ -29,7 +30,7 @@ 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_P, $opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r); +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,$opt_L, $opt_a, $opt_r, $opt_R); my (%conv_author_name, %conv_author_email); sub usage(;$) { @@ -40,7 +41,7 @@ Usage: git cvsimport # fetch/update GIT from CVS [-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file] [-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k] [-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit] - [-r remote] [CVS_module] + [-r remote] [-R] [CVS_module] END exit(1); } @@ -89,28 +90,45 @@ sub write_author_info($) { } # convert getopts specs for use by git config +my %longmap = ( + 'A:' => 'authors-file', + 'M:' => 'merge-regex', + 'P:' => undef, + 'R' => 'track-revisions', + 'S:' => 'ignore-paths', +); + sub read_repo_config { - # Split the string between characters, unless there is a ':' - # So "abc:de" becomes ["a", "b", "c:", "d", "e"] + # Split the string between characters, unless there is a ':' + # So "abc:de" becomes ["a", "b", "c:", "d", "e"] my @opts = split(/ *(?!:)/, shift); foreach my $o (@opts) { my $key = $o; $key =~ s/://g; my $arg = 'git config'; $arg .= ' --bool' if ($o !~ /:$/); - - chomp(my $tmp = `$arg --get cvsimport.$key`); + my $ckey = $key; + + if (exists $longmap{$o}) { + # An uppercase option like -R cannot be + # expressed in the configuration, as the + # variable names are downcased. + $ckey = $longmap{$o}; + next if (! defined $ckey); + $ckey =~ s/-//g; + } + chomp(my $tmp = `$arg --get cvsimport.$ckey`); if ($tmp && !($arg =~ /--bool/ && $tmp eq 'false')) { - no strict 'refs'; - my $opt_name = "opt_" . $key; - if (!$$opt_name) { - $$opt_name = $tmp; - } + no strict 'refs'; + my $opt_name = "opt_" . $key; + if (!$$opt_name) { + $$opt_name = $tmp; + } } } } -my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:"; +my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:R"; read_repo_config($opts); Getopt::Long::Configure( 'no_ignore_case', 'bundling' ); @@ -209,6 +227,31 @@ sub new { return $self; } +sub find_password_entry { + my ($cvspass, @cvsroot) = @_; + my ($file, $delim) = @$cvspass; + my $pass; + local ($_); + + if (open(my $fh, $file)) { + # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z + CVSPASSFILE: + while (<$fh>) { + chomp; + s/^\/\d+\s+//; + my ($w, $p) = split($delim,$_,2); + for my $cvsroot (@cvsroot) { + if ($w eq $cvsroot) { + $pass = $p; + last CVSPASSFILE; + } + } + } + close($fh); + } + return $pass; +} + sub conn { my $self = shift; my $repo = $self->{'fullrep'}; @@ -241,19 +284,23 @@ sub conn { if ($pass) { $pass = $self->_scramble($pass); } else { - open(H,$ENV{'HOME'}."/.cvspass") and do { - # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z - while (<H>) { - chomp; - s/^\/\d+\s+//; - my ($w,$p) = split(/\s/,$_,2); - if ($w eq $rr or $w eq $rr2) { - $pass = $p; - last; - } + my @cvspass = ([$ENV{'HOME'}."/.cvspass", qr/\s/], + [$ENV{'HOME'}."/.cvs/cvspass", qr/=/]); + my @loc = (); + foreach my $cvspass (@cvspass) { + my $p = find_password_entry($cvspass, $rr, $rr2); + if ($p) { + push @loc, $cvspass->[0]; + $pass = $p; } - }; - $pass = "A" unless $pass; + } + + if (1 < @loc) { + die("Multiple cvs password files have ". + "entries for CVSROOT $opt_d: @loc"); + } elsif (!$pass) { + $pass = "A"; + } } my ($s, $rep); @@ -348,7 +395,9 @@ sub conn { $self->{'socketo'}->write("valid-requests\n"); $self->{'socketo'}->flush(); - chomp(my $rep=$self->readline()); + my $rep=$self->readline(); + die "Failed to read from server" unless defined $rep; + chomp($rep); if ($rep !~ s/^Valid-requests\s*//) { $rep="<unknown>" unless $rep; die "Expected Valid-requests from server, but got: $rep\n"; @@ -611,7 +660,7 @@ my %index; # holds filenames of one index per branch unless (-d $git_dir) { system(qw(git init)); die "Cannot init the GIT db at $git_tree: $?\n" if $?; - system(qw(git read-tree)); + system(qw(git read-tree --empty)); die "Cannot init an empty tree: $?\n" if $?; $last_branch = $opt_o; @@ -659,6 +708,11 @@ if ($opt_A) { write_author_info("$git_dir/cvs-authors"); } +# open .git/cvs-revisions, if requested +open my $revision_map, '>>', "$git_dir/cvs-revisions" + or die "Can't open $git_dir/cvs-revisions for appending: $!\n" + if defined $opt_R; + # # run cvsps into a file unless we are getting @@ -742,7 +796,7 @@ sub write_tree () { } my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); -my (@old,@new,@skipped,%ignorebranch); +my (@old,@new,@skipped,%ignorebranch,@commit_revisions); # commits that cvsps cannot place anywhere... $ignorebranch{'#CVSPS_NO_BRANCH'} = 1; @@ -825,6 +879,11 @@ sub commit { system('git' , 'update-ref', "$remote/$branch", $cid) == 0 or die "Cannot write branch $branch for update: $!\n"; + if ($revision_map) { + print $revision_map "@$_ $cid\n" for @commit_revisions; + } + @commit_revisions = (); + if ($tag) { my ($xtag) = $tag; $xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY ** @@ -959,6 +1018,7 @@ while (<CVS>) { push(@skipped, $fn); next; } + push @commit_revisions, [$fn, $rev]; print "Fetching $fn v $rev\n" if $opt_v; my ($tmpname, $size) = $cvs->file($fn,$rev); if ($size == -1) { @@ -981,7 +1041,9 @@ while (<CVS>) { unlink($tmpname); } elsif ($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) { my $fn = $1; + my $rev = $2; $fn =~ s#^/+##; + push @commit_revisions, [$fn, $rev]; push(@old,$fn); print "Delete $fn\n" if $opt_v; } elsif ($state == 9 and /^\s*$/) { |