fcopy and ignoring .svn directories when copying recursively

Henning Glawe glaweh at physik.fu-berlin.de
Wed Nov 10 18:41:19 CET 2004


On Fri, Nov 05, 2004 at 11:12:31AM +0100, Steffen Grunewald wrote:
> If (as I suppose) subversion internal information is stored in a .svn/
> directory in every subdir of the tree, then the fifth line should be
> replaced by
> 
> -d && ! ($_ =~ /^.*CVS$/) && ! ($_ =~ /^.*\.svn/) && ($nlink=(lstat($_))[3]) &&
> 
> (question to Thomas: shouldn't there be a \/ prepended to CVS - and .svn ?)

To answer the question (this messy bit of code was one of my first
contributions to FAI...):
when using File::Find, $_ only contains the basename, not the complete path,
so matching on '/' would break the code.

the attached patch (already submitted to thomas) contains a clean solution:
it cleans up the code, making it actually readable and makes the list of
ignored directories configurable.

-- 
c u
henning
-------------- next part --------------
--- orig/man/fcopy.8
+++ mod/man/fcopy.8
@@ -65,6 +65,11 @@
 .B \-i
 Ignore warnings about no matching class and always exit with 0.
 .TP
+.BI "\-I " dir[,dir]
+Override list of ignored directories when recursing. If not given, it is 
+taken from $FCOPY_IGNOREDIRS and as a last chance an internal list of known
+revision control system's metadata is used (CVS, .cvs, {arch}, .arch\-ids).
+.TP
 .B \-l
 Do not copy if destination is a symbolic link
 .TP
@@ -101,7 +106,7 @@
 .B \-r
 Copy recursively (traverse down the tree).  Copy all files below
 SOURCE.  These are all subdirectory leaves in the SOURCE tree.  Ignore
-CVS directories.
+"ignored" directories (see "\-I" for details).
 .TP
 .BI "\-s " source_dir
 Look for SOURCE files relative to \fIsource_dir\fR.  Use $FAI/files if


--- orig/scripts/fcopy
+++ mod/scripts/fcopy
@@ -57,10 +57,12 @@
 my $nobackup;
 my $opt_update;
 my $backupdir;
+my @ignoredirs = qw'CVS .svn .arch-ids {arch}';
 
 # getopts:
 our ($opt_s, $opt_t, $opt_r, $opt_m, $opt_M, $opt_v, $opt_d, $opt_D, $opt_i);
 our ($opt_B, $opt_c, $opt_C, $opt_h, $opt_F, $opt_l, $opt_L, $opt_P, $opt_b);
+our $opt_I;
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 sub copy_one {
@@ -322,13 +324,14 @@
    -F file              Read list of sources from file.
    -h                   Show summary of options.
    -i                   Exit with 0 when no class applies.
+   -I dir[,dir]         Override default list of ignored subdirectories
    -l                   Do not copy if destination is a symbolic link.
    -L file              Log destination and used class to file
    -m user,group,mode   Set user, group and mode for copied files.
    -M                   Same as -m root,root,0644
    -P log,changes       Copy if class or source for class has changed since
                         previous run
-   -r                   Copy recursivly but skip CVS directories.
+   -r                   Copy recursivly but skip ignored directories.
    -s source_dir        Look for source files relative to source_dir.
    -t target_dir        Copy files relativ to target_dir.
    -b backup_dir        Where to save backups of overwritten files
@@ -342,16 +345,21 @@
 sub rfilter {
 
   # Filter for recursive copying
-  my $nlink;
-  -d && ! ($_ =~ /^CVS$/) && ($nlink=(lstat($_))[3]) && 
-    ( (-d 'CVS') && ($nlink==3) || ($nlink==2) ) && 
-      push @rlist,$File::Find::name;
+  
+  # are we in a directory ? should we ignore it ?
+  my $location=$_;
+  (-d and (! grep $location eq $_, at 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, at ignoredirs);
+  # push leaf
+  push @rlist,$File::Find::name unless $subdirs;
 }
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # main program
 
 $|=1;
-getopts('Ms:t:rm:vidDc:C:hF:lL:P:Bb:');
+getopts('Ms:t:rm:vidDc:C:hF:lL:P:Bb:I:');
 $opt_h && usage;
 $opt_M and $opt_m="root,root,0644";  # set default modes
 $opt_m && check_mopt();
@@ -380,6 +388,9 @@
 $opt_C and @classes = read_classes($opt_C);
 warn join ' ','Classes:', at classes,"\n" if $debug;
 $opt_F and @ARGV = read_files($opt_F);
+$ENV{'FCOPY_IGNOREDIRS'} and @ignoredirs = split /\s+/,$ENV{'FCOPY_IGNOREDIRS'};
+$opt_I and @ignoredirs = split /,/,$opt_I;
+
 die "fcopy: source undefined\n" unless $source;
 die "fcopy: target undefined\n" unless $target;
 



-------------- next part --------------
Summary: provide a more intelligent mechanism to ignore dirs in fcopy
Keywords: fcopy feature

- rewrite rfilter to check against a list @ignoredirs
- initialize @ignoredirs for config managed in CVS, subversion and GNU arch
- include command line option "-I blah[,blubb]" and environment variable 
  $FCOPY_IGNOREDIRS to override @ignoredirs
- comment the code and make it understandable (YEAH!)

-------------- next part --------------
provide a more intelligent mechanism to ignore dirs in fcopy


More information about the linux-fai mailing list