191501Sjoe#!/usr/bin/perl -w 291501Sjoe 391501Sjoe# $FreeBSD$ 491501Sjoe 591501Sjoe# This script takes a filename and revision number as arguments 691501Sjoe# and spits out a list of other files and their revisions that share 791501Sjoe# the same log message. This is done by referring to the database 891501Sjoe# previously written by running make_commit_db. 991501Sjoe 1091501Sjoeuse strict; 1191501Sjoeuse Digest::MD5 qw(md5_hex); 1291501Sjoe 1391501Sjoemy $dbname = "commitsdb"; 1491501Sjoe 1591501Sjoe# Take the filename and revision number from the command line. 1693545Sjoe# Also take a flag to say whether to generate a patch or not. 1793545Sjoemy ($file, $revision, $genpatch) = (shift, shift, shift); 1891501Sjoe 1991501Sjoe# Find the checksum of the named revision. 2091501Sjoemy %possible_files; 2191501Sjoeopen DB, "< $dbname" or die "$!\n"; 2291501Sjoemy $cksum; 2391501Sjoewhile (<DB>) { 2491501Sjoe chomp; 2591501Sjoe my ($name, $rev, $hash) = split; 2691501Sjoe $name =~ s/^\.\///g; 2791501Sjoe 2891501Sjoe $possible_files{$name} = 1 if $file !~ /\// && $name =~ /^.*\/$file/; 2991501Sjoe 3091501Sjoe next unless $name eq $file and $rev eq $revision; 3191501Sjoe $cksum = $hash; 3291501Sjoe} 3391501Sjoeclose DB; 3491501Sjoe 3591501Sjoe# Handle the fall-out if the file/revision wasn't matched. 3691501Sjoeunless ($cksum) { 3791501Sjoe if (%possible_files) { 3891501Sjoe print "Couldn't find the file. Maybe you meant:\n"; 3991501Sjoe foreach (sort keys %possible_files) { 4091501Sjoe print "\t$_\n"; 4191501Sjoe } 4291501Sjoe } 4391501Sjoe die "Can't find $file rev $revision in database\n"; 4491501Sjoe} 4591501Sjoe 4691501Sjoe 4791501Sjoe# Look for similar revisions. 4891501Sjoemy @results; 4991501Sjoeopen DB, "< $dbname" or die "$!\n"; 5091501Sjoewhile (<DB>) { 5191501Sjoe chomp; 5291501Sjoe my ($name, $rev, $hash) = split; 5391501Sjoe 5491501Sjoe next unless $hash eq $cksum; 5591501Sjoe 5691501Sjoe push @results, "$name $rev"; 5791501Sjoe} 5891501Sjoeclose DB; 5991501Sjoe 6093556Sjoe# May as well show the log message if we're producing a patch 6193556Sjoeprint `cvs log -r$revision $file` if $genpatch; 6293556Sjoe 6393556Sjoe# Show the commits that match, and their patches if required. 6493545Sjoeforeach my $r (sort @results) { 6593545Sjoe print "$r\n"; 6693545Sjoe next unless $genpatch; 6791501Sjoe 6893545Sjoe my ($name, $rev) = split /\s/, $r, 2; 6993545Sjoe my $prevrev = previous_revision($rev); 7093545Sjoe print `cvs diff -u -r$prevrev -r$rev $name`; 7193545Sjoe print "\n\n"; 7293545Sjoe} 7393545Sjoe 7493545Sjoe# 7593545Sjoe# Return the previous revision number. 7693545Sjoe# 7793545Sjoesub previous_revision { 7893545Sjoe my $rev = shift; 7993545Sjoe 8093545Sjoe $rev =~ /(?:(.*)\.)?([^\.]+)\.([^\.]+)$/; 8193545Sjoe my ($base, $r1, $r2) = ($1, $2, $3); 8293545Sjoe 8393545Sjoe my $prevrev = ""; 8493545Sjoe if ($r2 == 1) { 8593545Sjoe $prevrev = $base; 8693545Sjoe } else { 8793545Sjoe $prevrev = "$base." if $base; 8893545Sjoe $prevrev .= "$r1." . ($r2 - 1); 8993545Sjoe } 9093545Sjoe return $prevrev; 9193545Sjoe} 9293545Sjoe 9391501Sjoe#end 94