Code

Merge branch 'js/maint-cvsexport' into maint
authorJunio C Hamano <gitster@pobox.com>
Sat, 8 Mar 2008 10:13:52 +0000 (02:13 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 8 Mar 2008 10:13:52 +0000 (02:13 -0800)
* js/maint-cvsexport:
  cvsexportcommit: be graceful when "cvs status" reorders the arguments

Conflicts:

t/t9200-git-cvsexportcommit.sh

1  2 
git-cvsexportcommit.perl
t/t9200-git-cvsexportcommit.sh

diff --combined git-cvsexportcommit.perl
index 2a8ad1e9f4cbc2c21b83fd72fae1e0d2e582fbdc,9d142d08a5f59f15857453596d43ab9d8f987a25..b6036bd4d305215b4a70b6fd0fe54d7607dbe068
@@@ -5,7 -5,6 +5,7 @@@ use Getopt::Std
  use File::Temp qw(tempdir);
  use Data::Dumper;
  use File::Basename qw(basename dirname);
 +use File::Spec;
  
  our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w);
  
@@@ -16,15 -15,17 +16,15 @@@ $opt_h && usage()
  die "Need at least one commit identifier!" unless @ARGV;
  
  if ($opt_w) {
 +      # Remember where GIT_DIR is before changing to CVS checkout
        unless ($ENV{GIT_DIR}) {
 -              # Remember where our GIT_DIR is before changing to CVS checkout
 +              # No GIT_DIR set. Figure it out for ourselves
                my $gd =`git-rev-parse --git-dir`;
                chomp($gd);
 -              if ($gd eq '.git') {
 -                      my $wd = `pwd`;
 -                      chomp($wd);
 -                      $gd = $wd."/.git"       ;
 -              }
                $ENV{GIT_DIR} = $gd;
        }
 +      # Make sure GIT_DIR is absolute
 +      $ENV{GIT_DIR} = File::Spec->rel2abs($ENV{GIT_DIR});
  
        if (! -d $opt_w."/CVS" ) {
                die "$opt_w is not a CVS checkout";
@@@ -197,15 -198,39 +197,39 @@@ if (@canstatusfiles) 
        my @updated = xargs_safe_pipe_capture([@cvs, 'update'], @canstatusfiles);
        print @updated;
      }
-     my @cvsoutput;
-     @cvsoutput = xargs_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++;
+     # "cvs status" reorders the parameters, notably when there are multiple
+     # arguments with the same basename.  So be precise here.
+     my %added = map { $_ => 1 } @afiles;
+     my %todo = map { $_ => 1 } @canstatusfiles;
+     while (%todo) {
+       my @canstatusfiles2 = ();
+       my %fullname = ();
+       foreach my $name (keys %todo) {
+       my $basename = basename($name);
+       $basename = "no file " . $basename if (exists($added{$basename}));
+       chomp($basename);
+       if (!exists($fullname{$basename})) {
+         $fullname{$basename} = $name;
+         push (@canstatusfiles2, $name);
+         delete($todo{$name});
          }
+       }
+       my @cvsoutput;
+       @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles2);
+       foreach my $l (@cvsoutput) {
+         chomp $l;
+         if ($l =~ /^File:\s+(.*\S)\s+Status: (.*)$/) {
+         if (!exists($fullname{$1})) {
+           print STDERR "Huh? Status reported for unexpected file '$1'\n";
+         } else {
+           $cvsstat{$fullname{$1}} = $2;
+         }
+       }
+       }
      }
  }
  
index 49d57a81ec1cc55f83fb63436631dfdc7d647e0b,5c2ee237397a07e5e478b0f715798fe87905e7c1..58c59ed5ae0159810b4c8258f9182991bad33636
@@@ -2,7 -2,7 +2,7 @@@
  #
  # Copyright (c) Robin Rosenberg
  #
 -test_description='CVS export comit. '
 +test_description='Test export of commits to CVS'
  
  . ./test-lib.sh
  
@@@ -246,20 -246,39 +246,55 @@@ test_expect_success 
        ;;
  esac
  
 +test_expect_success '-w option should work with relative GIT_DIR' '
 +      mkdir W &&
 +      echo foobar >W/file1.txt &&
 +      echo bazzle >W/file2.txt &&
 +      git add W/file1.txt &&
 +      git add W/file2.txt &&
 +      git commit -m "More updates" &&
 +      id=$(git rev-list --max-count=1 HEAD) &&
 +      (cd "$GIT_DIR" &&
 +      GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id &&
 +      check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" &&
 +      diff -u "$CVSWORK/W/file1.txt" ../W/file1.txt &&
 +      diff -u "$CVSWORK/W/file2.txt" ../W/file2.txt
 +      )
 +'
 +
+ test_expect_success 'check files before directories' '
+       echo Notes > release-notes &&
+       git add release-notes &&
+       git commit -m "Add release notes" release-notes &&
+       id=$(git rev-parse HEAD) &&
+       git cvsexportcommit -w "$CVSWORK" -c $id &&
+       echo new > DS &&
+       echo new > E/DS &&
+       echo modified > release-notes &&
+       git add DS E/DS release-notes &&
+       git commit -m "Add two files with the same basename" &&
+       id=$(git rev-parse HEAD) &&
+       git cvsexportcommit -w "$CVSWORK" -c $id &&
+       check_entries "$CVSWORK/E" "DS/1.1/|newfile5.txt/1.1/" &&
+       check_entries "$CVSWORK" "DS/1.1/|release-notes/1.2/" &&
+       diff -u "$CVSWORK/DS" DS &&
+       diff -u "$CVSWORK/E/DS" E/DS &&
+       diff -u "$CVSWORK/release-notes" release-notes
+ '
+ test_expect_success 'commit a file with leading spaces in the name' '
+       echo space > " space" &&
+       git add " space" &&
+       git commit -m "Add a file with a leading space" &&
+       id=$(git rev-parse HEAD) &&
+       git cvsexportcommit -w "$CVSWORK" -c $id &&
+       check_entries "$CVSWORK" " space/1.1/|DS/1.1/|release-notes/1.2/" &&
+       diff -u "$CVSWORK/ space" " space"
+ '
  test_done