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