Add a tool that I've written to help with finding what other

files/revisions were changed with a particular commit.
This commit is contained in:
joe 2002-02-28 20:12:52 +00:00
parent 88a86c89ad
commit 9013c37b04
3 changed files with 165 additions and 0 deletions

View File

@ -7,6 +7,8 @@ other categories.
Please make a subdir per program, and add a brief description to this file.
commitsdb A tool for reconstructing commit history using md5
checksums of the commit logs.
editing Editor modes and the like to help editing FreeBSD code.
epfe Extract printing filter examples from printing.sgml.
html-mv Rename HTML generated filenames to human readable filenames.

View File

@ -0,0 +1,102 @@
#!/usr/bin/perl -w
# $FreeBSD$
# This script walks the tree from the current directory
# and spits out a database generated by md5'ing the cvs log
# messages of each revision of every file in the tree.
use strict;
use Digest::MD5 qw(md5_hex);
my $dbname = "commitsdb";
open DB, "> $dbname" or die "$!\n";
# Extract all the logs for the current directory.
my @dirs = ".";
while (@dirs) {
my $dir = shift @dirs;
my %logs;
opendir DIR, $dir or die $!;
foreach (grep { /[^\.]/ } readdir DIR) {
my $filename = "$dir/$_";
if (-f $filename) {
my %loghash = parse_log_message($filename);
next unless %loghash;
$logs{$filename} = {%loghash};
} elsif (-d $_) {
next if /^CVS$/;
push @dirs, $_;
}
}
close DIR;
# Product a database of the commits
foreach my $f (keys %logs) {
my $file = $logs{$f};
foreach my $rev (keys %$file) {
my $hash = $$file{$rev};
print DB "$f $rev $hash\n";
}
}
print "\r" . " " x 30 . "\r$dir";
}
print "\n";
close DB;
##################################################
# Run a cvs log on a file and return a parse entry.
##################################################
sub parse_log_message {
my $file = shift;
# Get a log of the file.
open LOG, "cvs -R log $file |" or die $!;
my @log = <LOG>;
my $log = join "", @log;
close LOG;
# Split the log into revisions.
my @entries = split /----------------------------\n/, $log;
# Throw away the first entry.
shift @entries;
# Record the hash of the message against the revision.
my %loghash = ();
foreach my $e (@entries) {
# Get the revision number
$e =~ s/^revision\s*(\S*)\n//s;
my $rev = $1;
# Strip off any other headers.
while ($e =~ s/^(date|branches):[^\n]*\n//sg) {
};
my $hash = string_to_hash($e);
$loghash{$rev} = $hash;
}
return %loghash;
}
##################################################
# Convert a log message into an md5 checksum.
##################################################
sub string_to_hash {
my $logmsg = shift;
return md5_hex($logmsg);
}
#end

View File

@ -0,0 +1,61 @@
#!/usr/bin/perl -w
# $FreeBSD$
# This script takes a filename and revision number as arguments
# and spits out a list of other files and their revisions that share
# the same log message. This is done by referring to the database
# previously written by running make_commit_db.
use strict;
use Digest::MD5 qw(md5_hex);
my $dbname = "commitsdb";
# Take the filename and revision number from the command line.
my ($file, $revision) = (shift, shift);
# Find the checksum of the named revision.
my %possible_files;
open DB, "< $dbname" or die "$!\n";
my $cksum;
while (<DB>) {
chomp;
my ($name, $rev, $hash) = split;
$name =~ s/^\.\///g;
$possible_files{$name} = 1 if $file !~ /\// && $name =~ /^.*\/$file/;
next unless $name eq $file and $rev eq $revision;
$cksum = $hash;
}
close DB;
# Handle the fall-out if the file/revision wasn't matched.
unless ($cksum) {
if (%possible_files) {
print "Couldn't find the file. Maybe you meant:\n";
foreach (sort keys %possible_files) {
print "\t$_\n";
}
}
die "Can't find $file rev $revision in database\n";
}
# Look for similar revisions.
my @results;
open DB, "< $dbname" or die "$!\n";
while (<DB>) {
chomp;
my ($name, $rev, $hash) = split;
next unless $hash eq $cksum;
push @results, "$name $rev";
}
close DB;
print map { "$_\n" } sort @results;
#end