2012-02-04 71 views
3

在試圖收集有關的Git庫的一些統計數據,我正在尋找一個辦法做到以下幾點:適用於所有命令提交

  • 對於每個提交,執行命令(例如,du -h )。
  • 該命令應該在提交之後從存儲庫基目錄「看起來像」運行。
  • 該命令理想情況下可以訪問提交散列和時間戳。

一個應用,在準巴什表示,將運行

echo $HASH $TIME `du -hs --exclude=".git" . | awk '{ print $1; }'` >> ../sizeovertime 
所有

承諾得到了倉庫的增長的想法。

(不知怎的,感覺它應該是可以使用git filter-branch --tree-filter這個,但看起來像一個可怕的黑客給我。)

回答

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") 

警告:這會讓你在分離的頭的狀態,在最古老的承諾,這是不是一個很好的地方。

+0

謝謝,我最終使用的東西非常接近這個。 – Philippe 2012-02-06 11:03:27

7

要計算回購中每個提交的大小,檢出每個提交的速度會很慢。一方面,您複製了很多工作,因爲您將重新計算未更改文件的大小。此外,你會錘擊你的文件系統不斷檢查出來的東西。 這是一個腳本,它查詢git repo以獲取所需的信息。主要好處是你從來沒有真正看過任何blob來計算它們的大小,而只是要求git告訴你。而且,你只需要查詢每個blob的git(通過Memoize的魔術)。
毫無疑問,這個腳本需要工作(一個自動抓取任何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="%[email protected]%ci" $commit | sed 1q)); 
    chop $date; 
    printf "$date: %d\n", compute_tree_size $tree; 
} 
+0

這似乎是計算大小的優雅和聰明的解決方案。儘管如此,我只是以此爲例。在我的情況下,任務更復雜(生成PDF並將其轉換爲圖像)。這就是爲什麼我接受另一個更一般的答案。 – Philippe 2012-02-06 11:02:16

+1

@philippe,你可以完全通用的方式使用這個解決方案。如果您需要訪問blob中的數據,可以使用git cat-file -p來獲取它。只需將get_blob_size替換爲get_blob並使用blob中的數據即可。沒有必要去檢查。 – 2012-02-06 11:06:43

相關問題