リポジトリ内の各ファイルのすべての投稿者をリストしたいと思います。ここで各ファイルのGit投稿者
は、私が何をすべきか、現在ある:
find . | xargs -L 1 git blame -f | cut -d' ' -f 2-4 | sort | uniq
これは非常に遅いです。より良い解決策はありますか?
リポジトリ内の各ファイルのすべての投稿者をリストしたいと思います。ここで各ファイルのGit投稿者
は、私が何をすべきか、現在ある:
find . | xargs -L 1 git blame -f | cut -d' ' -f 2-4 | sort | uniq
これは非常に遅いです。より良い解決策はありますか?
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
を一度だけ呼び出すと、それは合理的に速いことを意味します。欠点:別のスクリプトです。ベースとしてДМИТРИЙの答えを撮影
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
あなたが得ることができますが、すべてのgit ls-tree
と、リポジトリ内のファイルを追跡しました。 Find
は本当に悪い選択です。
たとえば、現在のディレクトリ(./
)に支店master
で追跡ファイルのリストを取得:
git ls-tree -r --name-only master ./
あなたは(git blame
が過剰です)get shortlog
でファイルの編集者のリストを取得することができますが:
git shortlog -s -- $file
したがって、ls-tree
の各ファイルについて、shortlog
とmodもしあなたが望むなら、その出力をifyします。
+ 1、これは正しいアプローチですが、ファイルの名前変更には追従しません。ファイル名にスペースが含まれていれば失敗します。これを修正するための私の答えを参照してください – CharlesB
、私は次のことを言うと思います:
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
)が含まれている場合は正しく動作
これはigorの回答に比べてかなり遅いです。我々は巨大なリポジトリを持っている。これはファイルごとに数秒かかる。 – log0
これは高速ですが、完全なファイルパスを報告しません。 – log0
ディレクトリ構造が深く、ファイル名が切れるようにするには、 '--stat'オプションに任意の高出力幅パラメータを指定するだけです。 '--stat = 1000' – igor
' --stat = 1000,1000'は仕事をしました – log0