#!/usr/bin/perl use strict; my $last; my $ret; my $i; my @wanted = (); my $matched; my $argc = scalar(@ARGV); my $commit; my $stop; my $file_list = ""; sub print_usage() { print STDERR "usage: file-changes [-c commit] [-s stop commit] file_list\n"; exit(1); } if ($argc < 1) { print_usage(); } for ($i = 0 ; $i < $argc ; $i++) { if ($ARGV[$i] eq "-c") { if ($i == $argc - 1) { print_usage(); } $commit = $ARGV[++$i]; } elsif ($ARGV[$i] eq "-s") { if ($i == $argc - 1) { print_usage(); } $stop = $ARGV[++$i]; } else { push @wanted, $ARGV[$i]; $file_list .= "$ARGV[$i] "; } } if (!defined($commit)) { $commit = `commit-id`; if ($?) { print STDERR "commit-id failed, try using -c to specify a commit\n"; exit(1); } chomp $commit; } $last = $commit; open(RL, "rev-list $commit|") || die "rev-list failed"; while() { chomp; my $cur = $_; $matched = 0; if ($cur eq $last) { next; } # rev-list gives us the commits from newest to oldest open(DT, "diff-tree -r $cur $last $file_list|") || die "diff-tree failed"; while(
) { chomp; my @words = split; my $file = $words[3]; # if the filename has whitespace, suck it in if (scalar(@words) > 4) { if (m/$file(.*)/) { $file .= $1; } } foreach my $m (@wanted) { if ($file =~ m/^$m/) { if (!$matched) { print "diff-tree -r $cur $last\n"; } print "$words[2] $file\n"; $matched = 1; } } } close(DT); if ($?) { $ret = $? >> 8; die "diff-tree failed with $ret"; } if ($matched) { print "cat-file commit $last\n"; open(COMMIT, "cat-file commit $last|") || die "cat-file $last failed"; while() { print " $_"; } close(COMMIT); if ($?) { $ret = $? >> 8; die "cat-file failed with $ret"; } print "\n"; } if ($cur eq $stop) { last; } $last = $cur; } close(RL); if ($? && ($ret = $? >> 8)) { die "rev-list failed with $ret"; }