【发布时间】:2012-07-29 01:49:41
【问题描述】:
我想列出存储库中每个文件的每个贡献者。
这是我目前的工作:
find . | xargs -L 1 git blame -f | cut -d' ' -f 2-4 | sort | uniq
这很慢。有没有更好的解决方案?
【问题讨论】:
我想列出存储库中每个文件的每个贡献者。
这是我目前的工作:
find . | xargs -L 1 git blame -f | cut -d' ' -f 2-4 | sort | uniq
这很慢。有没有更好的解决方案?
【问题讨论】:
以ДМИТРИЙ的回答为基础,我想说的是:
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)则行为正确
【讨论】:
我会编写一个小脚本来分析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,这意味着它相当快。缺点:它是一个单独的脚本。
【讨论】:
--stat 选项指定任意高输出宽度参数,例如--stat=1000
--stat=1000,1000 完成了这项工作
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 并根据需要修改其输出。
【讨论】:
git log --pretty=format:"%cn" <filename> | sort | uniq -c
您还可以使用git log 做更多事情,例如:在特定日期之后提交每个文件(例如:2018-10-1 之后):
git log --after="2018-10-1" --pretty=format:"%cn" <filename> | sort | uniq -c
【讨论】:
如果您不需要统计信息,请不要使用--stat,为什么要求它重新运行所有差异,然后刮掉所有结果?只需使用--name-only。
git log --all --pretty=%x09%cN --name-only | awk -F$'\t' '
NF==2 { name=$2 }
NF==1 { contribs[ $0 ][ name ] = 1 }
END {
n = asorti(contribs,sorted)
for ( i=0 ; ++i < n ; ) {
file = sorted[i]
print file
for ( name in contribs[file] ) print "\t"name
}
}
'
【讨论】: