$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);
+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() {
Usage: ${\basename $0} # fetch/update GIT from CVS
[-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
[-p opts-for-cvsps] [-C GIT_repository] [-z fuzz] [-i] [-k] [-u]
- [-s subst] [-m] [-M regex] [CVS_module]
+ [-s subst] [-m] [-M regex] [-S regex] [CVS_module]
END
exit(1);
}
open my $f, '<', "$file" or die("Failed to open $file: $!\n");
while (<$f>) {
- chomp;
- # Expected format is this;
+ # Expected format is this:
# exon=Andreas Ericsson <ae@op5.se>
- if (m/^([^ \t=]*)[ \t=]*([^<]*)(<.*$)\s*/) {
+ if (m/^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/) {
$user = $1;
- $conv_author_name{$1} = $2;
- $conv_author_email{$1} = $3;
- # strip trailing whitespace from author name
- $conv_author_name{$1} =~ s/\s*$//;
+ $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);
}
die("Failed to open $file for writing: $!");
foreach (keys %conv_author_name) {
- print $f "$_=" . $conv_author_name{$_} .
- " " . $conv_author_email{$_} . "\n";
+ print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>\n";
}
close ($f);
}
-getopts("hivmkuo:d:p:C:z:s:M:P:A:") or usage();
+getopts("hivmkuo:d:p:C:z:s:M:P:A:S:") or usage();
usage if $opt_h;
@ARGV <= 1 or usage();
}
}
}
+ return undef;
}
sub file {
my($self,$fn,$rev) = @_;
$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);
- if ($res eq '') {
- die "Looks like the server has gone away while fetching $fn $rev -- exiting!";
- }
-
return ($name, $res);
}
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) {
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();
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);
print "Drop $fn\n" if $opt_v;
} else {
print "".($init ? "New" : "Update")." $fn: $size bytes\n" if $opt_v;
- open my $F, '-|', "git-hash-object -w $tmpname"
+ my $pid = open(my $F, '-|');
+ die $! unless defined $pid;
+ if (!$pid) {
+ exec("git-hash-object", "-w", $tmpname)
or die "Cannot create object: $!\n";
+ }
my $sha = <$F>;
chomp $sha;
close $F;