Чтобы вычислить размер каждого коммита в репо, проверять каждый коммит будет довольно медленно. Во-первых, вы дублируете лот работы, так как вы будете пересчитывать размеры файлов, которые не меняются. Кроме того, вы будете постоянно проверять свою файловую систему.
Вот скрипт, который запрашивает git-репо, чтобы получить необходимую информацию. Основное преимущество заключается в том, что вы никогда не смотрите на двоичные объекты, чтобы вычислить их размер, а просто попросите git сообщить вам. Кроме того, вы запрашиваете git для каждого блоба только один раз (через магию Memoize).
Нет сомнений в том, что этот скрипт нуждается в работе (было бы неплохо использовать autodie для обнаружения ошибок git), но он должен дать вам место для начала. (Я изменил это из оригинальной публикации, чтобы включить аргумент, который можно использовать в качестве refspec. Если вызывается без аргумента, это печатает информацию для каждой фиксации в истории. ограничить работу. Например, если у вас есть теги v0 и v1, вы можете передать «v0..v1» в качестве первого аргумента.)
#!/usr/bin/env perl
use warnings;
use strict;
use Memoize;
my $rev_list = $ARGV[ 0 ] || "--all";
# Query git for the size of a blob. This is memoized, so we only
# ask for any blob once.
sub get_blob_size($) {
my $hash = shift;
my $size = qx( git cat-file -s $hash );
return int( $size );
}
memoize( 'get_blob_size' );
# Recursively compute the size of a tree. Note that git cat-file -s
# does not give the cumulative size of all the blobs in a tree.
sub compute_tree_size($);
sub compute_tree_size($) {
my $sha = shift;
my $size;
open my $objects, '-|', "git cat-file -p $sha";
while( <$objects> ) {
my ( $mode, $type, $hash, $name ) = split;
if( $type eq 'blob' ) {
$size += get_blob_size( $hash );
} elsif( $type eq 'tree' ) {
$size += compute_tree_size( $hash );
}
}
return $size;
}
memoize( 'compute_tree_size' );
# Generate a list of all commits
open my $objects, '-|', "git rev-list $rev_list |
git cat-file --batch-check";
# Traverse the commit list and report on the size of each.
while( <$objects> ) {
my( $commit, $type, $size ) = split;
my( $tree, $date ) = split( '@',
qx( git show --format="%T@%ci" $commit | sed 1q ));
chop $date;
printf "$date: %d\n", compute_tree_size $tree;
}