1#!/usr/bin/perl -w
2
3# $FreeBSD$
4
5# This script takes a filename and revision number as arguments
6# and spits out a list of other files and their revisions that share
7# the same log message.  This is done by referring to the database
8# previously written by running make_commit_db.
9
10use strict;
11use Digest::MD5 qw(md5_hex);
12
13my $dbname = "commitsdb";
14
15# Take the filename and revision number from the command line.
16# Also take a flag to say whether to generate a patch or not.
17my ($file, $revision, $genpatch) = (shift, shift, shift);
18
19# Find the checksum of the named revision.
20my %possible_files;
21open DB, "< $dbname" or die "$!\n";
22my $cksum;
23while (<DB>) {
24	chomp;
25	my ($name, $rev, $hash) = split;
26	$name =~ s/^\.\///g;
27
28	$possible_files{$name} = 1 if $file !~ /\// && $name =~ /^.*\/$file/;
29
30	next unless $name eq $file and $rev eq $revision;
31	$cksum = $hash;
32}
33close DB;
34
35# Handle the fall-out if the file/revision wasn't matched.
36unless ($cksum) {
37	if (%possible_files) {
38		print "Couldn't find the file. Maybe you meant:\n";
39		foreach (sort keys %possible_files) {
40			print "\t$_\n";
41		}
42	}
43	die "Can't find $file rev $revision in database\n";
44}
45
46
47# Look for similar revisions.
48my @results;
49open DB, "< $dbname" or die "$!\n";
50while (<DB>) {
51	chomp;
52	my ($name, $rev, $hash) = split;
53
54	next unless $hash eq $cksum;
55
56	push @results, "$name $rev";
57}
58close DB;
59
60# May as well show the log message if we're producing a patch
61print `cvs log -r$revision $file` if $genpatch;
62
63# Show the commits that match, and their patches if required.
64foreach my $r (sort @results) {
65	print "$r\n";
66	next unless $genpatch;
67
68	my ($name, $rev) = split /\s/, $r, 2;
69	my $prevrev = previous_revision($rev);
70	print `cvs diff -u -r$prevrev -r$rev $name`;
71	print "\n\n";
72}
73
74#
75# Return the previous revision number.
76#
77sub previous_revision {
78	my $rev = shift;
79
80	$rev =~ /(?:(.*)\.)?([^\.]+)\.([^\.]+)$/;
81	my ($base, $r1, $r2) = ($1, $2, $3);
82
83	my $prevrev = "";
84	if ($r2 == 1) {
85		$prevrev = $base;
86	} else {
87		$prevrev = "$base." if $base;
88		$prevrev .= "$r1." . ($r2 - 1);
89	}
90	return $prevrev;
91}
92
93#end
94