我想列出存储库中每个文件的每个贡献者。每个文件的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 ./
你可以得到get shortlog
文件的编辑列表(git blame
是矫枉过正):
git shortlog -s -- $file
因此,对于ls-tree
响应中的每个文件,应该调用shortlog
和mod ify它的输出,但你想要的。
+ 1,这是正确的方法,但它不遵循文件重命名,并且如果文件名包含空格,它将失败。查看我的答案以解决此问题 – CharlesB 2012-07-31 13:33:48
以ДМИТРИЙ的回答为基础,我会说以下内容:
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 2012-08-02 10:01:03
这很快,但它不报告完整的文件路径。 – log0 2012-08-02 09:56:04
如果您的目录结构很深以便文件名被切断,只需为'--stat'选项指定一个任意的高输出宽度参数,例如'--stat = 1000' – igor 2012-08-02 10:00:47
'--stat = 1000,1000'做过这个工作 – log0 2012-08-02 11:51:13