Приведенный ниже код анализирует выходные данные git diff-tree
для коммитов без слияния, чтобы показать хэш, статус (изменен, добавлен, удален и т. Д.) Для каждого файла, измененного в коммите.
Например, в истории Git show-hashes 08da6496b6134
выводит
Documentation/RelNotes/2.24.0.txt M bda29d224a4f75b7497be901bd269f69d99de508
Направления для его расширения включают поддержку фиксации слияния и обнаружение перемещения или переименования.
#! /usr/bin/env perl
use strict;
use warnings;
no warnings 'exec';
my $treeish = @ARGV ? shift : "HEAD";
my $sha1 = qr/[0-9a-f]{40}/;
my $mode = qr/[0-9]{6}/;
my $file_change = qr/
^ :
$mode # mode for src; 000000 if creation or unmerged
[ ]
$mode # mode for dst; 000000 if deletion or unmerged
[ ]
($sha1) # sha1 for src; 0{40} if creation or unmerged
[ ]
($sha1) # sha1 for dst; 0{40} if creation, unmerged, or "look at work tree"
[ ]
([ACDMRTUX])([0-9]*)
$
/x;
my @cmd = (qw/ git diff-tree --raw -r -z /, $treeish);
open my $fh, "-|", @cmd
or die "$0: failed to start @cmd";
$/ = "\0";
my $commit = <$fh>;
die "$0: merge commits not supported" unless defined $commit;
chomp $commit;
die "$0: expected commit SHA1" unless $commit =~ /^$sha1$/;
while (<$fh>) {
chomp;
die "$0: unexpected [$_]"
unless my($src,$dst,$status,$score) = /$file_change/;
chomp(my $srcpath = <$fh> || "");
die "$0: commit=$commit, dst=$dst: missing path" if $srcpath eq "";
print "$srcpath $status $dst\n";
}
close $fh or die "$0: @cmd failed";