2012-07-31 15 views
8

リポジトリ内の各ファイルのすべての投稿者をリストしたいと思います。ここで各ファイルのGit投稿者

は、私が何をすべきか、現在ある:

find . | xargs -L 1 git blame -f | cut -d' ' -f 2-4 | sort | uniq 

これは非常に遅いです。より良い解決策はありますか?

答えて

4

git log --stat --pretty=format:'%cN'の出力を解析する小さなスクリプトを作成します。線に沿って何か:

#!/usr/bin/env perl 

my %file; 
my $contributor = q(); 

while (<>) { 
    chomp; 
    if (/^\S/) { 
     $contributor = $_; 
    } 
    elsif (/^\s*(.*?)\s*\|\s*\d+\s*[+-]+/) { 
     $file{$1}{$contributor} = 1; 
    } 
} 

for my $filename (sort keys %file) { 
    print "$filename:\n"; 
    for my $contributor (sort keys %{$file{$filename}}) { 
     print " * $contributor\n"; 
    } 
} 

(。ちょうどすぐに書かれた、バイナリファイルのようなケースをカバーしていない)

このスクリプトを保存した場合、例えば、~/git-contrib.plとして、あなたがそれを呼び出すことができます。

git log --stat=1000,1000 --pretty=format:'%cN' | perl ~/git-contrib.pl 

利点:gitを一度だけ呼び出すと、それは合理的に速いことを意味します。欠点:別のスクリプトです。ベースとしてДМИТРИЙの答えを撮影

+0

これは高速ですが、完全なファイルパスを報告しません。 – log0

+0

ディレクトリ構造が深く、ファイル名が切れるようにするには、 '--stat'オプションに任意の高出力幅パラメータを指定するだけです。 '--stat = 1000' – igor

+0

' --stat = 1000,1000'は仕事をしました – log0

2

tldr

for file in `git ls-tree -r --name-only master ./`; do 
    echo $file 
    git shortlog -s -- $file | sed -e 's/^\s*[0-9]*\s*//' 
done 
  1. あなたが得ることができますが、すべてのgit ls-treeと、リポジトリ内のファイルを追跡しました。 Findは本当に悪い選択です。

    たとえば、現在のディレクトリ(./)に支店masterで追跡ファイルのリストを取得:

    git ls-tree -r --name-only master ./ 
    
  2. あなたは(git blameが過剰です)get shortlogでファイルの編集者のリストを取得することができますが:

    git shortlog -s -- $file 
    

したがって、ls-treeの各ファイルについて、shortlogとmodもしあなたが望むなら、その出力をifyします。

+0

+ 1、これは正しいアプローチですが、ファイルの名前変更には追従しません。ファイル名にスペースが含まれていれば失敗します。これを修正するための私の答えを参照してください – CharlesB

5

、私は次のことを言うと思います:

git ls-tree -r --name-only master ./ | while read file ; do 
    echo "=== $file" 
    git log --follow --pretty=format:%an -- $file | sort | uniq 
done 

強化は、その歴史の中で、ファイルの名前の変更に従うことで、ファイルはスペース(| while read file)が含まれている場合は正しく動作

+0

これはigorの回答に比べてかなり遅いです。我々は巨大なリポジトリを持っている。これはファイルごとに数秒かかる。 – log0

関連する問題