3

For a particular file, it is possible to see which author last modified each line in a file (git blame etc). I want to do this at a project level, either by specifying author name or the total for all authors that contributed to the repo.

I understand that git blame only shows who last edited a line, so if someone add a line and someone else edits it, it will show only the second person. That's fine.

Note that this is different from (Git: How to estimate a contribution of a person to my project in terms of added/changed lines of code?) this question, because it covers the entire history of the project, I'm only interested in the current state.

hoodakaushal
  • 1,253
  • 2
  • 16
  • 31

2 Answers2

10

List all the files of a revision:

git ls-tree -r $revision

Run git blame against the files one by one:

git blame --line-porcelain $file

Print only the authors:

grep '^author '

Count the occurrence number of each author, and print the name and the number:

awk '{a[$0]+=1} END{for(i in a){print i,a[i]}}'

Combine them, taking the revision HEAD for example:

git ls-tree -r HEAD | while read a b c d
do
    git blame --line-porcelain $d
done | grep '^author ' | sed -e 's/author //' | awk '{a[$0]+=1} END{for(i in a){print i,a[i]}}'

It takes some time to run. I tried with my repository which has 2800+ files and it took 43 seconds.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53
2

You can do git blame on every file on the repo, and then sum up each author's contribution. Here's an example on how to get number of lines per author at the current state:

for file in $(git ls-files); do git blame -c $file; done | tr '(' ' ' | awk '{print $2, $3}' | sort | uniq -c | sort -k1 -r;
alamoot
  • 1,966
  • 7
  • 30
  • 50
  • For my repo this reported multiple entries per author by date. – hoodakaushal Dec 14 '19 at 13:56
  • 1
    You might have to tweak the `awk` portion a bit. For me this works as authors have their first name and last name defined. If in your case they only have one of them, or an email set (ie, there is no space for author name) you might have to do `awk '{print $2}' instead – alamoot Dec 14 '19 at 14:36