为了收集一些关于Git存储库的统计信息,我正在寻找一种方法来执行以下操作:
du -h
)。以准Bash表示的一个应用程序将运行
echo $HASH $TIME `du -hs --exclude=".git" . | awk '{ print $1; }'` >> ../sizeovertime
在所有提交中了解存储库的增长。
(不知何故,感觉应该可以使用git filter-branch --tree-filter
,但这对我来说看起来很可怕。)
答案 0 :(得分:7)
要计算repo中每个提交的大小,检查每个提交都会很慢。首先,您正在复制批次的工作,因为您将重新计算不变的文件大小。此外,您将不断检查文件系统。 这是一个查询git repo以获取所需信息的脚本。主要的好处是你从来没有真正查看任何blob来计算它们的大小,但只是请git告诉你。此外,您只需查询每个blob一次的git(通过Memoize的魔力) 毫无疑问,这个脚本需要工作(一个autodie来捕获任何git失败将是一个好主意),但它应该给你一个开始的地方。 (我从原始发布中修改了这个,以包含一个可以用作refspec的参数。如果没有参数调用,则会打印历史记录中每个提交的信息。您可以将ref-spec作为rev-list传递给限制工作。例如,如果你有标签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;
}
答案 1 :(得分:2)
我没有看到如何在不检查每个提交的情况下执行此操作,因此在大型存储库中需要一段时间。
以下是你如何用bash来解决这个问题:
#! /bin/bash
while read co dt ; do
git checkout $co > /dev/null 2>&1
size=$(du -hs --exclude=.git|cut -f1)
echo $co $size $dt
done < <(git rev-list --pretty=format:"%H %ci" --all --date-order |grep -v "^commit")
警告:这将使您处于最早的提交状态,这是一个不太好的地方。