Moin,
sorry for the "big" diff, but the problem was sitting a lot deeper in the
recursion codel. The attached patch should both clean up the code to make it
actually understandable and fix the aforementioned bug.

-- 
c u
henning
Wed Apr 13 14:03:50 CEST 2005  [EMAIL PROTECTED]
  * BUGFIX:297550 clean up the fcopy recursion code
  the File::Find code used in recursive fcopy descended into the ignored 
  directories and their subdirectories. this failed when a revision control 
  system keeps subdirectories there (in this case: subversion).
  
  while fixing this bug, the whole File::Find code was brought to a more 
  readable/debuggable form.
  
  this version differs from the first version sent to [EMAIL PROTECTED] 
  because it moves the newly introduced %ingnoredirs out of global scope.
diff -rN -u old-pfai/scripts/fcopy new-pfai/scripts/fcopy
--- old-pfai/scripts/fcopy      2005-04-30 09:59:41.815144432 +0200
+++ new-pfai/scripts/fcopy      2005-04-30 09:59:43.104948352 +0200
@@ -342,20 +342,6 @@
   exit 0;
 }
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub rfilter {
-
-  # Filter for recursive copying
-  
-  # are we in a directory ? should we ignore it ?
-  my $location=$_;
-  (-d and (! grep $location eq $_,@ignoredirs )) or return 0;
-  # a directory without subdirs has two hard links
-  # don't count @ignoredirs as subdirs
-  my $subdirs=(lstat($_))[3] - 2 - grep(-d,@ignoredirs);
-  # push leaf
-  push @rlist,$File::Find::name unless $subdirs;
-}
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # main program
 
 $|=1;
@@ -396,8 +382,20 @@
 
 if ($opt_r) {
   foreach (@ARGV) { $_="$source/$_"; } # add prefix to list of directories
-  File::Find::find(\&rfilter,@ARGV);
-  foreach (@rlist) { $_=~ s#^$source/##; }   # remove prefix from all fines 
found
+  my %has_subdirs;
+  my %ignoredirs;
+  map $ignoredirs{$_}=1,@ignoredirs;
+  File::Find::find({
+    wanted=>sub{ $has_subdirs{$File::Find::dir} |= -d},
+    preprocess=>sub{grep ! (-d and exists($ignoredirs{$_})),@_}},
+    @ARGV);
+  foreach (keys %has_subdirs) {
+    unless ($has_subdirs{$_}) {
+      # remove prefix from all files found
+      s#^$source/##;
+      push @rlist,$_;
+    }
+  }
   warn "List of all files found by File::Find::find: @rlist" if $debug;
   @ARGV = @rlist;
 }

Reply via email to