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