Git contributors of each file

Taking ДМИТРИЙ's answer as a base, I'd say the following :

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

Enhancement is that it follows file's rename in its history, and behaves correctly if files contain spaces (| while read file)


I would write a small script that analyzes the output of git log --stat --pretty=format:'%cN'; something along the lines of:

#!/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";
    }
}

(Written just quickly; does not cover cases like binary files.)

If you stored this script, e.g., as ~/git-contrib.pl, you could call it with:

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

Advantage: call git only once, which implies that it is reasonably fast. Disadvantage: it’s a separate script.


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. You can get all tracked files in repository with git ls-tree. Find is really bad choice.

    For example, get list of tracked file in branch master in current dir (./):

    git ls-tree -r --name-only master ./
    
  2. You can get list of file editors with get shortlog (git blame is overkill):

    git shortlog -s -- $file
    

So, for each file from ls-tree response you should call shortlog and modify its output however you want.

Tags:

Git

Sh