1#!/usr/bin/perl -w 2 3# This script walks the tree from the current directory 4# and spits out a database generated by md5'ing the cvs log 5# messages of each revision of every file in the tree. 6 7use strict; 8use Digest::MD5 qw(md5_hex); 9 10my $dbname = "commitsdb"; 11open DB, "> $dbname" or die "$!\n"; 12 13# Extract all the logs for the current directory. 14my @dirs = "."; 15while (@dirs) { 16 my $dir = shift @dirs; 17 my %logs; 18 19 opendir DIR, $dir or die $!; 20 foreach my $f (grep { /[^\.]/ } readdir DIR) { 21 my $filename = "$dir/$f"; 22 if (-f $filename) { 23 my %loghash = parse_log_message($filename); 24 next unless %loghash; 25 26 $logs{$filename} = {%loghash}; 27 } elsif (-d $filename) { 28 next if $filename =~ /\/CVS$/; 29 push @dirs, $filename; 30 } 31 } 32 close DIR; 33 34 # Produce a database of the commits 35 foreach my $f (keys %logs) { 36 my $file = $logs{$f}; 37 foreach my $rev (keys %$file) { 38 my $hash = $$file{$rev}; 39 40 print DB "$f $rev $hash\n"; 41 } 42 } 43 44 print "\r" . " " x 30 . "\r$dir"; 45} 46print "\n"; 47 48close DB; 49 50 51 52################################################## 53# Run a cvs log on a file and return a parse entry. 54################################################## 55sub parse_log_message { 56 my $file = shift; 57 58 # Get a log of the file. 59 open LOG, "cvs -R log $file 2>/dev/null |" or die $!; 60 my @log = <LOG>; 61 my $log = join "", @log; 62 close LOG; 63 64 # Split the log into revisions. 65 my @entries = split /----------------------------\n/, $log; 66 67 # Throw away the first entry. 68 shift @entries; 69 70 # Record the hash of the message against the revision. 71 my %loghash = (); 72 foreach my $e (@entries) { 73 # Get the revision number 74 $e =~ s/^revision\s*(\S*)\n//s; 75 my $rev = $1; 76 77 # Strip off any other headers. 78 my $user; 79 while ($e =~ s/^(date|branches):([^\n]*)\n//sg) { 80 my $sub = $2; 81 $user = $1 if $sub =~ /author: (.*?);/; 82 }; 83 84 my $hash = string_to_hash($e); 85 $loghash{$rev} = "$user:$hash"; 86 } 87 88 return %loghash; 89} 90 91 92################################################## 93# Convert a log message into an md5 checksum. 94################################################## 95sub string_to_hash { 96 my $logmsg = shift; 97 98 return md5_hex($logmsg); 99} 100 101 102 103#end 104