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