X-Git-Url: https://git.jankratochvil.net/?p=nethome.git;a=blobdiff_plain;f=bin%2Fcvsutil;h=72c19d5624a4b358ed523bcd99e5124757c60d92;hp=27a4ab5f54ec79540625fe9018c283fb17971273;hb=8104eca7d9cf4376bfa2eddc3c2a71b84b9d9d02;hpb=9d45569122b4c86a98c42fee954885f33af27e8d diff --git a/bin/cvsutil b/bin/cvsutil index 27a4ab5..72c19d5 100755 --- a/bin/cvsutil +++ b/bin/cvsutil @@ -1,4 +1,14 @@ #! /usr/bin/perl +# +# $Id$ +# +# Recommended aliases: +# alias cvsfiles='cvsutil --files --print' +# alias cvsignores='cvsutil --ignores --print' +# alias cvsignoresall='cvsutil --ignores --workings --print' +# alias cvsignoresrm='cvsutil --ignores --rm' +# alias cvsignoresrmall='cvsutil --ignores --workings --rm' +# alias cvsignoresallrm='cvsutil --ignores --workings --rm' use strict; use warnings; @@ -6,6 +16,22 @@ use warnings; use Getopt::Long; use Cwd qw(chdir fastgetcwd); use Errno qw(ENOENT); +use Carp qw(confess cluck croak carp); +BEGIN { + if (!eval q{ use File::Remove qw(remove); 1; }) {{ + sub main::remove(@) + { + my $r=""; + if ("SCALAR" eq ref $_[0]) { + $r="-r" if ${$_[0]}; + shift; + } + my $cmd="rm -f $r ".join(" ",map({s/'/'\\''/g;"'$_'";} @_)); + my $err=system($cmd) and confess("$cmd: $cmd"); + return @_; + } + }} +} use constant ENTRIES =>"CVS/Entries"; use constant CVSIGNORE=>".cvsignore"; @@ -75,8 +101,8 @@ my($msg,%opts)=@_; my $errstr=$!; $msg.=" in \"".fastgetcwd."\" (CVS \"$dir_dirname\")".($opts{"noerrno"} ? "" : ": $errstr"); - die $msg if $opt_fatal; - warn $msg; + croak $msg if $opt_fatal; + carp $msg; } sub fordirs @@ -118,6 +144,17 @@ sub localdircore fordirs \&localdir,@dir_dirs; } +sub filterout +{ +my($from,@what)=@_; + + my %hash=map { $_=>1; } @$from; + for (@what) { + delete $hash{$_}; + } + return keys %hash; +} + sub localreaddir { local *E; @@ -127,9 +164,12 @@ sub localreaddir } while () { chomp; + next if /^D$/; do { push @dir_dirs ,$1; next; } if m#^D/([^/]*)/#; + next if m#^/[^/]*/-#; # deleted file: /filename/-1.1/dummy timestamp// + # New file is a valid entry! + # next if m#^/[^/]*/0/#; # new file: /filename/0/dummy timestamp// do { push @dir_files,$1; next; } if m#^/([^/]*)/# ; - next if /^D$/; mayfatal "File ".ENTRIES." contains invalid line \"$_\"",("noerrno"=>1); } close E; @@ -146,6 +186,7 @@ sub localreaddir } } close I; + @dir_ignores=filterout \@dir_ignores,@dir_dirs,@dir_files; } else { mayfatal "File \"".CVSIGNORE."\" cannot be opened" if !$!{ENOENT}; @@ -156,13 +197,8 @@ sub localreaddir mayfatal "Cannot read directory \".\""; return 0; } - @dir_workings=readdir D; + @dir_workings=filterout [readdir D],@dir_dirs,@dir_files,@dir_ignores,@all_ignore,".",".."; closedir D; - my %delworkings=map { $_=>1; } @dir_workings; - for (@dir_dirs,@dir_files,@dir_ignores,@all_ignore,".","..") { - delete $delworkings{$_}; - } - @dir_workings=keys %delworkings; return 1; } @@ -186,19 +222,25 @@ sub localactionrm { my($filename)=@_; - if (!unlink $filename) { + # &chmod follows the symlinks. + -l $filename or chmod 0700,$filename or do { + mayfatal "File \"$_\" cannot be chmod(2)ed" if !$!{ENOENT}; + }; + # '\1' for '-r': + remove \1,$filename or do { mayfatal "File \"$_\" cannot be removed" if !$!{ENOENT}; - } + }; } sub localactionrootset { local *R; - if (!open R,'>',ROOT) { + if (!open R,'+<',ROOT) { mayfatal "File \"".ROOT."\" cannot be written"; return; } print R "$opt_root\n"; + truncate R,tell R; close R; }