From: Steffen Prohaska Date: Wed, 9 May 2007 23:06:36 +0000 (+0200) Subject: Optimized cvsexportcommit: calling 'cvs status' once instead of once per touched... X-Git-Tag: v1.5.2~6^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c56f0d9c661dc918a088e60d0ab69dd48019a9be;p=git.git Optimized cvsexportcommit: calling 'cvs status' once instead of once per touched file. Runtime is now independent of the number of modified files. The old implementation executed 'cvs status' for each file touched by the patch to be applied. The new code calls 'cvs status' only once with all touched files and parses cvs's output to collect all available status information. Signed-off-by: Steffen Prohaska Signed-off-by: Junio C Hamano --- diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 6ed471918..d6ae99b8c 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -160,36 +160,51 @@ foreach my $p (@afiles) { } } +# ... check dirs, foreach my $d (@dirs) { if (-e $d) { $dirty = 1; warn "$d exists and is not a directory!\n"; } } -foreach my $f (@afiles) { - # This should return only one value - if ($f =~ m,(.*)/[^/]*$,) { - my $p = $1; - next if (grep { $_ eq $p } @dirs); + +# ... query status of all files that we have a directory for and parse output of 'cvs status' to %cvsstat. +my @canstatusfiles; +foreach my $f (@files) { + my $path = dirname $f; + next if (grep { $_ eq $path } @dirs); + push @canstatusfiles, $f; +} + +my %cvsstat; +if (@canstatusfiles) { + my @cvsoutput; + @cvsoutput= safe_pipe_capture(@cvs, 'status', @canstatusfiles); + my $matchcount = 0; + foreach my $l (@cvsoutput) { + chomp $l; + if ( $l =~ /^File:/ and $l =~ /Status: (.*)$/ ) { + $cvsstat{$canstatusfiles[$matchcount]} = $1; + $matchcount++; + } } - my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f)); - if (@status > 1) { warn 'Strange! cvs status returned more than one line?'}; - if (-d dirname $f and $status[0] !~ m/Status: Unknown$/ - and $status[0] !~ m/^File: no file /) { +} + +# ... validate new files, +foreach my $f (@afiles) { + if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") { $dirty = 1; warn "File $f is already known in your CVS checkout -- perhaps it has been added by another user. Or this may indicate that it exists on a different branch. If this is the case, use -f to force the merge.\n"; - warn "Status was: $status[0]\n"; + warn "Status was: $cvsstat{$f}\n"; } } - +# ... validate known files. foreach my $f (@files) { next if grep { $_ eq $f } @afiles; # TODO:we need to handle removed in cvs - my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f)); - if (@status > 1) { warn 'Strange! cvs status returned more than one line?'}; - unless ($status[0] =~ m/Status: Up-to-date$/) { + unless (defined ($cvsstat{$f}) and $cvsstat{$f} eq "Up-to-date") { $dirty = 1; - warn "File $f not up to date in your CVS checkout!\n"; + warn "File $f not up to date but has status '$cvsstat{$f}' in your CVS checkout!\n"; } } if ($dirty) {