为了收集有关 Git 存储库的一些统计信息,我正在寻找一种方法来执行以下操作:
- 对于每次提交,执行一条命令(例如;
du -h
)。 - 该命令应在提交后“看起来像”从存储库基目录运行。
- 理想情况下,该命令可以访问提交哈希和时间戳。
一个用类 Bash 表示的应用程序将运行
echo $HASH $TIME `du -hs --exclude=".git" . | awk '{ print $1; }'` >> ../sizeovertime
在所有提交上了解存储库的增长情况。
(不知何故,感觉应该可以为此使用 git filter-branch --tree-filter
但对我来说这看起来像是一个糟糕的 hack。)
最佳答案
要计算存储库中每个提交的大小,检查每个提交会非常慢。一方面,您正在重复很多 工作,因为您将重新计算未更改的文件的大小。此外,您将不断检查您的文件系统。
这是一个查询 git repo 以获取所需信息的脚本。主要的好处是你永远不会真正查看任何 blob 来计算它们的大小,而只是让 git 告诉你。此外,您只需为每个 blob 查询 git 一次(通过 Memoize 的魔力)。
毫无疑问,这个脚本需要工作(一个捕捉任何 git 故障的自动死机是个好主意),但它应该给你一个开始的地方。 (我已经从原始帖子中修改了这个,以包含一个可以用作 refspec 的参数。如果不带参数调用,这将打印历史中每个提交的信息。您可以将 ref-spec as to 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;
}
关于git - 将命令应用于所有提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9140008/