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:
parent
2e6f61b9bc
commit
49ae32af4f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=91501
@ -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.
|
||||
|
102
tools/tools/commitsdb/make_commit_db
Normal file
102
tools/tools/commitsdb/make_commit_db
Normal 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
|
61
tools/tools/commitsdb/query_commit_db
Normal file
61
tools/tools/commitsdb/query_commit_db
Normal 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
|
Loading…
Reference in New Issue
Block a user