aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJosef Karthauser <joe@FreeBSD.org>2002-02-28 20:12:52 +0000
committerJosef Karthauser <joe@FreeBSD.org>2002-02-28 20:12:52 +0000
commit49ae32af4f3d4f0919e5b3f8ceec731b03463c44 (patch)
tree40ba4f51196d3b6146003ed65508b59855a59bb5 /tools
parent2e6f61b9bc4b79676aea878a65084b3ff6d0b744 (diff)
downloadsrc-49ae32af4f3d4f0919e5b3f8ceec731b03463c44.tar.gz
src-49ae32af4f3d4f0919e5b3f8ceec731b03463c44.zip
Add a tool that I've written to help with finding what other
files/revisions were changed with a particular commit.
Notes
Notes: svn path=/head/; revision=91501
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/README2
-rw-r--r--tools/tools/commitsdb/make_commit_db102
-rw-r--r--tools/tools/commitsdb/query_commit_db61
3 files changed, 165 insertions, 0 deletions
diff --git a/tools/tools/README b/tools/tools/README
index 0d47beb92cf0..6bdc8c4f0897 100644
--- a/tools/tools/README
+++ b/tools/tools/README
@@ -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.
diff --git a/tools/tools/commitsdb/make_commit_db b/tools/tools/commitsdb/make_commit_db
new file mode 100644
index 000000000000..7b0fee780c78
--- /dev/null
+++ b/tools/tools/commitsdb/make_commit_db
@@ -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
diff --git a/tools/tools/commitsdb/query_commit_db b/tools/tools/commitsdb/query_commit_db
new file mode 100644
index 000000000000..f753f327b898
--- /dev/null
+++ b/tools/tools/commitsdb/query_commit_db
@@ -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