6 # alias cvsfiles='cvsutil --files --print'
7 # alias cvsignores='cvsutil --ignores --print'
8 # alias cvsignoresall='cvsutil --ignores --workings --print'
9 # alias cvsignoresrm='cvsutil --ignores --rm'
10 # alias cvsignoresrmall='cvsutil --ignores --workings --rm'
11 # alias cvsignoresallrm='cvsutil --ignores --workings --rm'
17 use Cwd qw(chdir fastgetcwd);
19 use File::Remove qw(remove);
20 use Carp qw(confess cluck croak carp);
22 use constant ENTRIES =>"CVS/Entries";
23 use constant CVSIGNORE=>".cvsignore";
24 use constant ROOT =>"CVS/Root";
26 my($opt_files,$opt_ignores,$opt_workings,$opt_dirs);
27 my($opt_rm,$opt_print);
28 our($opt_root); # undefined=>no rooting, ""=>print roots or first phase for root checking, ne ""=>set roots
29 my($opt_verbose,$opt_fatal);
30 my($opt_force); # set roots without their checking
33 $Getopt::Long::ignorecase=0;
34 $Getopt::Long::bundling=1;
35 die if !GetOptions_shortfilter(
36 "f|files!" ,\$opt_files,
37 "i|ignores!" ,\$opt_ignores,
38 "w|workings!",\$opt_workings,
39 "d|dirs!" ,\$opt_dirs,
41 "p|print!" ,\$opt_print,
43 "v|verbose!" ,\$opt_verbose,
44 "fatal!" ,\$opt_fatal,
45 "force!" ,\$opt_force,
46 "I|ignore=s" ,\@opt_ignore,
49 die "--root possible only with (optional and ignored) -d|--dirs"
50 if defined $opt_root && ($opt_files || $opt_ignores || $opt_workings || $opt_dirs || $opt_rm || $opt_print);
51 die "-d|--dirs forbidden with -r|--rm"
52 if $opt_dirs && $opt_rm;
53 die "Nothing to do (no -r|--rm, no -p|--print)"
54 if !$opt_rm && !$opt_print && !defined $opt_root;
55 die "Nothing to process (no -f|--files, no -i|--ignores, no -w|--workings, no -d|--dirs)"
56 if !defined $opt_root && (!$opt_files && !$opt_ignores && !$opt_workings && !$opt_dirs);
58 my @all_ignore=("CVS");
61 @all_ignore=() if $_ eq "!";
64 my($root_contents,@root_dirs);
66 @ARGV=(".") if !@ARGV;
68 our(@dir_files,@dir_ignores,@dir_workings,@dir_victims);
70 unless ((defined $opt_root && $opt_root ne "") && $opt_force) {
71 local($opt_root)=$opt_root;
72 $opt_root="" if defined $opt_root && $opt_root ne "";
76 actionrootfinal() if defined $opt_root && $opt_root eq "";
77 if (defined $opt_root && $opt_root ne "") {
78 die "Non-matching \"".ROOT."\" contents, use --force for override" if !@root_dirs && !$opt_force;
89 $msg.=" in \"".fastgetcwd."\" (CVS \"$dir_dirname\")".($opts{"noerrno"} ? "" : ": $errstr");
90 croak $msg if $opt_fatal;
98 my $origdir=fastgetcwd;
101 mayfatal "Unable to process directory \"$_\"";
111 my($localdirname)=@_;
113 verbose("localdir(\"$localdirname\") entry");
115 local(@dir_dirs,@dir_files,@dir_ignores,@dir_workings,@dir_victims);
116 local($dir_dirname)=$dir_dirname.$localdirname."/";
118 localreaddir() or return;
122 verbose("localdir(\"$localdirname\") exit");
127 localvictims() if !defined $opt_root;
130 fordirs \&localdir,@dir_dirs;
137 my %hash=map { $_=>1; } @$from;
147 if (!open E,ENTRIES) {
148 mayfatal "File \"".ENTRIES."\" cannot be opened";
154 do { push @dir_dirs ,$1; next; } if m#^D/([^/]*)/#;
155 next if m#^/[^/]*/-#; # deleted file: /filename/-1.1/dummy timestamp//
156 next if m#^/[^/]*/0/#; # new file: /filename/0/dummy timestamp//
157 do { push @dir_files,$1; next; } if m#^/([^/]*)/# ;
158 mayfatal "File ".ENTRIES." contains invalid line \"$_\"",("noerrno"=>1);
162 return 1 if defined $opt_root;
165 if (open I,CVSIGNORE) {
169 push @dir_ignores,$_ if -e $_;
174 @dir_ignores=filterout \@dir_ignores,@dir_dirs,@dir_files;
177 mayfatal "File \"".CVSIGNORE."\" cannot be opened" if !$!{ENOENT};
181 if (!opendir D,".") {
182 mayfatal "Cannot read directory \".\"";
185 @dir_workings=filterout [readdir D],@dir_dirs,@dir_files,@dir_ignores,@all_ignore,".","..";
192 push @dir_victims,@dir_files if $opt_files;
193 push @dir_victims,@dir_ignores if $opt_ignores;
194 push @dir_victims,@dir_workings if $opt_workings;
195 push @dir_victims,@dir_dirs if $opt_dirs;
202 mayfatal "File \"$filename\" does not exist",("noerrno"=>1) if !-e $filename;
203 print "${dir_dirname}$filename\n";
211 if (!remove \1,$filename) {
212 mayfatal "File \"$_\" cannot be removed" if !$!{ENOENT};
216 sub localactionrootset
219 if (!open R,'+<',ROOT) {
220 mayfatal "File \"".ROOT."\" cannot be written";
223 print R "$opt_root\n";
228 sub localactionrootprint
232 mayfatal "File \"".ROOT."\" cannot be opened";
236 localactionrootprintcheck(<R>);
240 sub localactionrootprintcheck
244 if (!defined $root_contents) {
245 push @root_dirs,$dir_dirname;
246 $root_contents=$contents;
249 if (@root_dirs && $root_contents eq $contents) {
250 push @root_dirs,$dir_dirname;
254 print map "$_: $root_contents",@root_dirs;
257 print "$dir_dirname: $contents";
262 return if !@root_dirs;
263 print $root_contents;
268 if ("" ne $dir_dirname && defined $opt_root) {
269 localactionrootset() if defined $opt_root && "" ne $opt_root;
270 localactionrootprint() if defined $opt_root && "" eq $opt_root;
274 localactionprint $_ if $opt_print;
275 localactionrm $_ if $opt_rm;
283 return if !$opt_verbose;
284 print fastgetcwd.": $msg\n";
287 sub GetOptions_shortfilter
293 push @r,$1,$ref,$',$ref;
298 return GetOptions @r;