#!/usr/bin/perl -w # richHistory.pl # This script provides access to each changelist that user usually can see in Perforce GUI client as a 'Revision Graph' # for more information please use command `pod2text richHistory.pl` # Author: Dmytro Gorbunov use strict; use Getopt::Long; use Pod::Usage; my %brs; #key - branch, value - undef - not checket yet, 0 - access denied, otherwise ref to array of submits my $help; my $naDirsFileName = 'naDirs.cache'; my $noCache = 0; GetOptions('help|?' => \$help, 'nocache' => \$noCache) or pod2usage(2); my $useCache = not $noCache; pod2usage(1) if $help; my $init = $ARGV[0]; $brs{$init} = undef; sub observe { my ($path, $cl,$type,$date,$author,$comment) = @_; foreach (@_) { s/^\s+//; s/\t//g; s/\n//g; } print join "\t", @_; print "\n"; } #--------------------------------------------------------- # p4/na.cache my %prevDenied; if ($useCache){ if (open (my $ifh, '<', $naDirsFileName) ){ local $/; %prevDenied = map {$_ => 1 } split "\n", <$ifh>; close $ifh; } } #--------------------------------------------------------- my $needRedo = 1; while ($needRedo == 1) { $needRedo = 0; while (my ($b, $val) = each %brs) { next if defined $val; my $out = qx{p4 filelog -l $b}; if ($out =~ /^$/) { $brs{$b} = 0; next} # no permitions $needRedo = 1; # we've got real output! my @sbs; foreach ( $out =~ /^\.\.\. #(.*?)(?=^\.\.\. #|\Z)/msg) { my $submit = $_; my ($cl, $type, $date, $author) = $submit =~ /\A.*?change (\d+) (\w+) on (.*?) by (.*?) /; my ($comment) = (split "\n\n", $submit)[1]; push @sbs, [$cl,$type,$date,$author,$comment]; foreach ($submit =~ /^\.\.\. .*?(\/\/.*?)#\d/mg){ my $path = $_; # cut filename and check for folders that was denied if (%prevDenied) { s{/[^/]+$}||; next if defined $prevDenied{$_}; } $brs{$path} = undef unless defined $brs{$path} } } $brs{$b} = \@sbs; } } #--------------------------------------------------------- if ($useCache){ open (my $fh, '>>', $naDirsFileName) or die; while (my ($b, $val) = each %brs) { next unless $val eq '0'; # remove filename (TODO: remove as much as possible) and save for caching access denied responses $b =~ s{/[^/]+$}||; print $fh "$b\n"; } } #--------------------------------------------------------- while (my ($path, $data) = each %brs){ next if $data eq '0'; foreach (@$data){ observe($path, @$_); } } __END__ =head1 NAME richHistory.pl - This script extracts list of changelists (with some additional info) that user usually can see in P4V as a 'Revision Graph' =head1 SYNOPSIS richHistory.pl - This script extracts list of changelists (with some additional info) that user usually can see in P4V as a 'Revision Graph' This script returns flat content of "Revision Graph" for futher analysis and usage. Usage: ./richHistory.pl -help ./richHistory.pl //depot/branch/test.cpp ./richHistory.pl -nocache //depot/branch/test.cpp Options: -help help message -nocache don't use cache for non-available pathes =head1 OUTPUT Output is tab-separated. One line contains information about one submit. The format is the following: PATH CHANGELIST TYPE_OF_CHANGE DATE AUTHOR COMMENT All tabs and new lines in comment(description of the submit) changed to '' and '' TYPE_OF_CHANGE can be add, branch, delete or integrate, for more details please look at p4 help