git - 将命令应用于所有提交

标签 git

为了收集有关 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/

相关文章:

git - 如何在 IIS 上设置 Git 裸 HTTP 可用存储库

git - 以下git配置有什么区别

git - Angular 2 和 .net core 2.0 - Azure 上自动部署的问题

git - 如何列出添加到 GIT 存储库第一次提交的所有文件?

git - "large file"必须有多大才能受益于 Git LFS?

svn - 如何使用 git-svn 跟踪仅限本地的更改/更改集?

Git SVN 重置 : Numeric SVN revision expected error

Git 如何在功能分支上保留最新的 N 次提交并删除所有内容

linux - 在 CentOS 5.6 上安装 Gitolite 时遇到问题

git - 如何git rm一个名称以 ':'开头的文件