每个文件的Git贡献者

时间:2012-07-31 10:05:01

标签: git sh

我想列出存储库中每个文件的每个贡献者。

目前我正在做的事情:

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

这很慢。有更好的解决方案吗?

5 个答案:

答案 0 :(得分:6)

以ДМИТРИЙ的答案为基础,我会说以下内容:

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

,则行为正确

答案 1 :(得分: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一次,这意味着速度相当快。缺点:它是一个单独的脚本。

答案 2 :(得分: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. 您可以使用get shortlog获取文件编辑器列表(git blame过度杀伤):

    git shortlog -s -- $file
    
  3. 因此,对于ls-tree响应中的每个文件,您应该调用shortlog并根据需要修改其输出。

答案 3 :(得分:0)

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

参考:https://www.atlassian.com/git/tutorials/git-log

答案 4 :(得分:0)

如果您不需要统计信息,请不要使用--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
                }
        }
'