mirror of
git://git.sv.gnu.org/coreutils
synced 2026-06-05 07:12:30 -04:00
.
This commit is contained in:
-249
@@ -1,249 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# An efficient substitute for `cvs -n update'.
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
# Do a quick check to see what files are out of date.
|
||||
# tromey Thu Mar 16 1995
|
||||
#
|
||||
# derived from http://www.cygnus.com/~tromey/ - jmm
|
||||
|
||||
# To Do:
|
||||
# Add option to include leading (non-`.') directory names of mentioned files
|
||||
|
||||
(my $VERSION = '$Revision: 1.1 $ ') =~ tr/[0-9].//cd;
|
||||
(my $program_name = $0) =~ s|.*/||;
|
||||
|
||||
my @months = qw (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
|
||||
my @days = qw (Sun Mon Tue Wed Thu Fri Sat);
|
||||
|
||||
my $debug = 0;
|
||||
|
||||
# If this is set, do only local files.
|
||||
my $local = 0;
|
||||
|
||||
# If this is set, show conflicts with C
|
||||
my $conflicts = 0;
|
||||
|
||||
# If this is set, then don't check any dates and just print the names
|
||||
# of all version-controlled files (but no directories).
|
||||
my $list_all_files = 0;
|
||||
|
||||
# Regex that matches file (as opposed to dir) entries in CVS/Entries.
|
||||
# Note that we allow an empty value ('*' vs '+') for timestamp, to
|
||||
# work around an odd bug in CVS.
|
||||
my $file_entry_re = qr{^/([^/]+)/([^/]+)/([^/]*)};
|
||||
|
||||
sub usage ($)
|
||||
{
|
||||
my ($exit_code) = @_;
|
||||
no strict 'refs';
|
||||
no strict 'subs';
|
||||
my $STREAM = ($exit_code == 0 ? STDOUT : STDERR);
|
||||
if ($exit_code != 0)
|
||||
{
|
||||
print $STREAM "Try `$program_name --help' for more information.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print $STREAM <<EOF;
|
||||
Usage: $program_name [OPTIONS] [DIRECTORY]...
|
||||
|
||||
An efficient substitute for `cvs -n update'.
|
||||
|
||||
In a cvs-checked-out working directory, list all cvs-controlled files
|
||||
that have been modified (or even touched but not changed), cvs added, or
|
||||
cvs removed. This script is a lot faster than `cvs -n update' because
|
||||
it doesn't use the repository. So for people at remote sites, it's MUCH
|
||||
faster. Also, when you have changes to files in subdirectories, the
|
||||
listing it produces is more useful since it includes the relative path
|
||||
name on each line indicating an Added, Removed, or Modified file.
|
||||
|
||||
NOTE: since $program_name works only on the local files it may indicate
|
||||
files are modified that cvs can determine where merely touched. Similarly
|
||||
files with a C may have had conflicts that have since been removed.
|
||||
|
||||
Here are the options:
|
||||
|
||||
--list-all-files don't check any dates; just print the names of all
|
||||
version-controlled files (but no directories)
|
||||
--local (-l) don't process subdirectories (like cvs' -l option)
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
--conflicts show conflicts with C instead of the default M
|
||||
|
||||
EOF
|
||||
}
|
||||
exit $exit_code;
|
||||
}
|
||||
|
||||
sub do_directory ($$);
|
||||
|
||||
{
|
||||
GetOptions
|
||||
(
|
||||
debug => \$debug,
|
||||
'list-all-files' => \$list_all_files,
|
||||
conflicts => \$conflicts,
|
||||
local => \$local,
|
||||
l => \$local,
|
||||
help => sub { usage 0 },
|
||||
version => sub { print "$program_name version $VERSION\n"; exit },
|
||||
) or usage 1;
|
||||
|
||||
unshift (@ARGV, ".") if !@ARGV;
|
||||
# print "$#ARGV ; $ARGV[0], $ARGV[1]\n";
|
||||
foreach (@ARGV)
|
||||
{
|
||||
do_directory ($_, 1);
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub do_directory ($$) {
|
||||
my ($thisdir, $is_command_line_arg) = @_;
|
||||
|
||||
$thisdir =~ s,^\./,,;
|
||||
my $prefix = ($thisdir eq '.' ? '' : "$thisdir/");
|
||||
|
||||
print "\tCALL; thisdir = $thisdir\n"
|
||||
if $debug;
|
||||
|
||||
# Scan CVS/Entries.
|
||||
my %version;
|
||||
my %entries;
|
||||
my %is_dir;
|
||||
|
||||
my $entries_file = "${prefix}CVS/Entries";
|
||||
if ( ! open (ENTRIES, '<', $entries_file))
|
||||
{
|
||||
my $warn = $is_command_line_arg ? '' : "Warning: ";
|
||||
warn "$program_name: ${warn}couldn't open $entries_file: $!\n";
|
||||
$is_command_line_arg
|
||||
and exit 1;
|
||||
return;
|
||||
}
|
||||
|
||||
while (<ENTRIES>) {
|
||||
# Ignore entries for directories.
|
||||
if (m,^D,)
|
||||
{
|
||||
next if /^D$/;
|
||||
if (m,^D/([^/]+)/,)
|
||||
{
|
||||
$is_dir{$1} = 1;
|
||||
next;
|
||||
}
|
||||
# else fall through so we get the `invalid line' error
|
||||
}
|
||||
|
||||
/$file_entry_re/
|
||||
|| die "$program_name: $entries_file: $.: invalid line\n";
|
||||
$entries{$1} = $3 || 'Empty-Timestamp';
|
||||
$version{$1} = $2;
|
||||
}
|
||||
close (ENTRIES);
|
||||
|
||||
# process Entries.Log file if it exists
|
||||
# lines are prefixed by A (add) or R (remove)
|
||||
# we add or delete accordingly.
|
||||
my $entries_log_file = "${prefix}CVS/Entries.Log";
|
||||
my $type;
|
||||
if (open (ENTRIES, "< $entries_log_file")) {
|
||||
while (<ENTRIES>) {
|
||||
if (!/^([AR]) (.*)$/) {
|
||||
warn "$program_name: $entries_log_file: $.: unrecognized line format\n";
|
||||
next;
|
||||
}
|
||||
($type, $_) = ($1,$2);
|
||||
# Ignore entries for directories.
|
||||
if (m,^D,)
|
||||
{
|
||||
next if /^D$/;
|
||||
if (m,^D/([^/]+)/,)
|
||||
{
|
||||
if ($type eq 'A') {
|
||||
$is_dir{$1} = 1;
|
||||
} else {
|
||||
delete $is_dir{$1};
|
||||
}
|
||||
next;
|
||||
}
|
||||
# else fall through so we get the `invalid line' error
|
||||
}
|
||||
|
||||
/$file_entry_re/
|
||||
|| die "$program_name: $entries_log_file: $.: invalid line\n";
|
||||
if ($type eq 'A') {
|
||||
$entries{$1} = $3;
|
||||
$version{$1} = $2;
|
||||
} else {
|
||||
delete $entries{$1};
|
||||
delete $version{$1};
|
||||
}
|
||||
}
|
||||
close (ENTRIES);
|
||||
}
|
||||
|
||||
foreach (sort keys %entries) {
|
||||
# Handle directories later.
|
||||
die "$program_name: bogus entry: $prefix$_\n"
|
||||
if ($_ eq 'CVS' || $_ eq '.' || $_ eq '..');
|
||||
(print "$prefix$_\n"), next if $list_all_files;
|
||||
next if -l "$prefix$_";
|
||||
next unless $entries{$_};
|
||||
if ($version{$_} =~ /^-/)
|
||||
{
|
||||
# A negative revision number (e.g., `-1.9') means the file is
|
||||
# slated for removal.
|
||||
print "R $prefix$_\n";
|
||||
next;
|
||||
}
|
||||
elsif ($version{$_} eq '0')
|
||||
{
|
||||
# A revision number of `0' means the file is slated for addition.
|
||||
print "A $prefix$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# These strings appear in the date field only for additions
|
||||
# and removals.
|
||||
die "$program_name: unexpected entry for $_: $entries{$_}\n"
|
||||
if $entries{$_} eq 'dummy timestamp'
|
||||
|| $entries{$_} =~ /^Initial /;
|
||||
|
||||
next unless -f _;
|
||||
|
||||
my $mtime = (stat _) [9];
|
||||
print "\t$mtime $_\n"
|
||||
if $debug;
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime ($mtime);
|
||||
my $s = ($days[$wday] . ' ' . $months[$mon] . ' '
|
||||
. sprintf ("%2d %02d:%02d:%02d %02d", $mday, $hour, $min,
|
||||
$sec, 1900 + $year));
|
||||
if ($entries{$_} ne $s) {
|
||||
my $t = 'M';
|
||||
$t = 'C'
|
||||
if ($conflicts && $entries{$_} =~ /^Result of merge\+/);
|
||||
print "$t $prefix$_\n";
|
||||
if ($debug) {
|
||||
print "\t$entries{$_}\n";
|
||||
print "\t$s\n";
|
||||
print "================\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now do directories.
|
||||
if (!$local)
|
||||
{
|
||||
foreach (sort keys %is_dir)
|
||||
{
|
||||
print "\tdir = $thisdir, _ = $_\n"
|
||||
if $debug;
|
||||
do_directory ("$prefix$_", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user