git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cvsexportcommit: be graceful when "cvs status" reorders the arguments
@ 2008-02-18  1:31 Johannes Schindelin
  2008-02-18  3:03 ` Junio C Hamano
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Schindelin @ 2008-02-18  1:31 UTC (permalink / raw)
  To: git, gitster, Robin Rosenberg


In my use cases, "cvs status" sometimes reordered the passed filenames,
which often led to a misdetection of a dirty state (when it was in
reality a clean state).

I finally tracked it down to two filenames having the same basename.

So no longer trust the order of the results blindly, but actually check
the file name.

Since "cvs status" only returns the basename (and the complete path on the
server which is useless for our purposes), run "cvs status" several times
with lists consisting of files with unique (chomped) basenames.

This makes cvsexportcommit slightly slower, when the list of changed files
has non-unique basenames, but at least it is accurate now.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	So I finally broke down.  I really need a working cvsexportcommit, 
	everything else is just too painful.

	Feel free to criticise/educate me on my Perl style.

 git-cvsexportcommit.perl       |   33 +++++++++++++++++++++++++--------
 t/t9200-git-cvsexportcommit.sh |   23 +++++++++++++++++++++++
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index 2a8ad1e..7fd05c7 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -197,15 +197,32 @@ 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.
+    while (@canstatusfiles) {
+      my @canstatusfiles2 = ();
+      my %basenames = ();
+      for (my $i = 0; $i <= $#canstatusfiles; $i++) {
+        my $name = $canstatusfiles[$i];
+	my $basename = $name;
+	$basename =~ s/.*\///;
+	$basename = "no file " . $basename if (grep {$_ eq $basename} @afiles);
+	chomp($basename);
+	if (!defined($basenames{$basename})) {
+	  $basenames{$basename} = $name;
+	  push (@canstatusfiles2, $name);
+	  splice (@canstatusfiles, $i, 1);
+	  $i--;
         }
+      }
+      my @cvsoutput;
+      @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles2);
+      foreach my $l (@cvsoutput) {
+          chomp $l;
+          if ( $l =~ /^File:\s+(.*\S)\s+Status: (.*)$/ ) {
+            $cvsstat{$basenames{$1}} = $2 if defined($basenames{$1});
+          }
+      }
     }
 }
 
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 49d57a8..483d8fa 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -262,4 +262,27 @@ test_expect_success '-w option should work with relative GIT_DIR' '
       )
 '
 
+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_done
-- 
1.5.4.2.217.g468be

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2008-02-18 20:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-18  1:31 [PATCH] cvsexportcommit: be graceful when "cvs status" reorders the arguments Johannes Schindelin
2008-02-18  3:03 ` Junio C Hamano
2008-02-18  3:20   ` Junio C Hamano
2008-02-18 15:25     ` Martin Langhoff
2008-02-18 16:27       ` Johannes Schindelin
2008-02-18 16:33         ` Martin Langhoff
2008-02-18 17:43           ` Johannes Schindelin
2008-02-18 17:55           ` [PATCH v2] " Johannes Schindelin
2008-02-18 17:54   ` [PATCH] " Johannes Schindelin
2008-02-18 18:36     ` Junio C Hamano
2008-02-18 18:50       ` Johannes Schindelin
2008-02-18 18:55       ` Martin Langhoff
2008-02-18 19:42         ` Johannes Schindelin
2008-02-18 20:06           ` Martin Langhoff
2008-02-18 20:29             ` Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).