#! /usr/bin/perl use strict; use warnings; # ====================================================================== sub usage { die "usage: $0 [--fast] [--quiet] directory\n" . " This tool doesn't work well with complex client views,\n" . " --fast : don't compare the file contents\n" . " --quiet : only report discrepancies\n"; } # ---------------------------------------------------------------------- sub findFiles { local $_; my @paths = @_; my @localfiles; while (@paths) { my $path = shift(@paths); opendir(DIR, $path) || die "could not open dir $path"; while ($_ = readdir(DIR)) { next if ($_ eq "." || $_ eq ".."); my $new = $path . "/" . $_; $new =~ s%\\%/%g; $new =~ s%//%/%g; if (-d $new) { push(@paths, $new); } else { push (@localfiles, $new); } } closedir(DIR); } return @localfiles; } # ====================================================================== my %files; my $quiet = 0; my $fast = 0; # ====================================================================== # process command line while (@ARGV && $ARGV[0] =~ /^-/) { my $arg = shift; if ($arg eq "--quiet") { $quiet = 1; } elsif ($arg eq "--fast") { $fast = 1; } else { usage(); } } usage() if (@ARGV != 1); # get the perforce locations for what was specified open(P4, "p4 where $ARGV[0] |"); $_ = ; chomp; my ($depot, $client, $local) = split(/ /, $_, 3); close(P4); # find all the local files $local =~ s%\\%\/%g; $local =~ s%\/\.\.\.$%%; foreach (findFiles($local)) { $files{$_} = "extra"; } if ($fast) { # fast mode doesn't compare the contents open(P4, "p4 fstat $client#have |") || die "$0: Can't open p4: $!\n"; my $file; my $action; while () { chomp; if (/^\s*$/) { if (defined($file) && defined($action)) { if ($action ne "delete") { if (defined $files{$file}) { # if we already knew about the file, then mark it as being in both places $files{$file} = "both"; } else { # if we didn't know about the file, then it's missing $files{$file} = "missing"; } } undef $file; undef $action; } } else { if (s%^\.\.\. clientFile %%) { s%\\%\/%g; $file = $_; } elsif (s%^\.\.\. headAction %%) { $action = $_; } } } close(P4) } else { # diff is more authoritative than the file search, but we'll still keep the extra files open(P4, "p4 diff -sl $client |") || die "$0: Can't open p4: $!\n"; while () { chomp; my ($status, $file) = split(/ /, $_, 2); $file =~ s%\\%/%g; $files{$file} = $status; } close(P4); } foreach (sort keys %files) { my $status = $files{$_}; print "$status $_\n" if (!$quiet || ($status ne "same" && $status ne "both")); }