#!/usr/bin/perl use strict; my $ret; my $i; my @wanted = (); 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); } sub print_commit($) { my ($c) = @_; print "git-cat-file commit $c\n"; open(COMMIT, "git-cat-file commit $c|") || die "git-cat-file $c failed"; while() { print " $_"; } close(COMMIT); if ($? && ($ret = $? >> 8)) { die "git-cat-file failed with $ret"; } print "\n"; } sub test_diff($$) { my ($a, $b) = @_; my $matched = 0; open(DT, "git-diff-tree -r $a $b $file_list|") || die "git-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 "git-diff-tree -r $a $b\n"; } print "$words[2] $file\n"; $matched = 1; } } } close(DT); if ($? && ($ret = $? >> 8)) { die "git-diff-tree failed with $ret"; } return $matched; } 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; } open(RL, "git-rev-list $commit|") || die "git-rev-list failed"; while() { chomp; my $cur = $_; my $matched = 0; open(PARENT, "git-cat-file commit $cur|") || die "git-cat-file failed"; while() { chomp; my @words = split; if ($words[0] eq "tree") { next; } elsif ($words[0] ne "parent") { last; } $matched += test_diff($words[1], $cur); } close(PARENT); if ($? && ($ret = $? >> 8)) { die "cat-file failed with $ret"; } if ($matched) { print_commit($cur); } if ($cur eq $stop) { last; } } close(RL); if ($? && ($ret = $? >> 8)) { die "git-rev-list failed with $ret"; }