我如何“滥用”责备(或一些更合适的函数,和/或与shell命令结合)来给我一个关于当前存储库中有多少行(代码)来自每个提交者的统计数据?

示例输出:

Committer 1: 8046 Lines
Committer 2: 4378 Lines

当前回答

更新

git ls-tree -r -z --name-only HEAD -- */*.c  | sed 's/^/.\//' | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

我在路上更新了一些东西。

为了方便,你也可以把它放到它自己的命令中:

#!/bin/bash

# save as i.e.: git-authors and set the executable flag
git ls-tree -r -z --name-only HEAD -- $1 | sed 's/^/.\//' | xargs -0 -n1 git blame \
 --line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

将它存储在路径中的某个地方或修改路径并像这样使用它

Git作者的*/*.c' #查找所有以.c结尾的递归文件 Git作者的*/*。查找所有递归以.c或.h结尾的文件 git authors 'Makefile' #只计算Makefile中作者的行数

原来的答案

虽然公认的答案起作用了,但它是非常缓慢的。

$ git ls-tree --name-only -z -r HEAD|egrep -z -Z -E '\.(cc|h|cpp|hpp|c|txt)$' \
  |xargs -0 -n1 git blame --line-porcelain|grep "^author "|sort|uniq -c|sort -nr

几乎是瞬间的。

要获得当前跟踪的文件列表,您可以使用

git ls-tree --name-only -r HEAD

该解决方案避免调用file来确定文件类型,并出于性能考虑使用grep来匹配所需的扩展名。如果应该包括所有文件,只需将其从该行中删除。

grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$'               # for Python files

如果文件可以包含空格,这对shell不好,你可以使用:

git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'

给出一个文件列表(通过管道),可以使用xargs调用命令并分发参数。允许处理多个文件的命令省略-n1。在这种情况下,我们调用git blame -line-porcelain,并且每次调用都使用一个参数。

xargs -n1 git blame --line-porcelain

然后,我们过滤输出中出现“author”的情况,对列表进行排序,并通过以下方法计算重复的行数:

grep "^author "|sort|uniq -c|sort -nr

Note

其他答案实际上过滤掉了只包含空格的行。

grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "

上面的命令将打印包含至少一个非空格字符的行的作者。您也可以使用match \w*[^\w#],它也会排除第一个非空白字符不是#的行(许多脚本语言中的注释)。

其他回答

Erik的解决方案非常棒,但我在变音符上遇到了一些问题(尽管我的LC_*环境变量表面上设置正确),并且在实际上包含日期的代码行中泄漏了噪音。我的sed-fu很差,所以我最终得到了这个带有红宝石的弗兰肯斯坦代码片段,但它在20万+ LOC上完美无缺地为我工作,并对结果进行了分类:

git ls-tree -r HEAD | gsed -re 's/^.{53}//' | \
while read filename; do file "$filename"; done | \
grep -E ': .*text' | gsed -r -e 's/: .*//' | \
while read filename; do git blame "$filename"; done | \
ruby -ne 'puts $1.strip if $_ =~ /^\w{8} \((.*?)\s*\d{4}-\d{2}-\d{2}/' | \
sort | uniq -c | sort -rg

还要注意gsed而不是sed,因为这是二进制的自制程序安装,使系统sed完好无损。

Bash函数,目标是在MacOS上运行的单个源文件。

function glac {
    # git_line_author_counts
    git blame -w "$1" |  sed -E "s/.*\((.*) +[0-9]{4}-[0-9]{2}.*/\1/g" | sort | uniq -c | sort -nr
}
git ls-tree -r HEAD|sed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c

逐级讲解:

列出版本控制下的所有文件

git ls-tree -r HEAD|sed -re 's/^.{53}//'

将列表修剪为仅文本文件

|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'

Git责备所有的文本文件,忽略空白的变化

|while read filename; do git blame -w "$filename"; done

找出作者的名字

|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'

排序作者列表,并让uniq计算连续重复的行数

|sort|uniq -c

示例输出:

   1334 Maneater
   1924 Another guy
  37195 Brian Ruby
   1482 Anna Lambda

请从http://gitstats.sourceforge.net/查看gitstats命令

我写了一个叫git-fame的gem,可能有用。

安装使用:

$ gem安装git_fame $ CD /path/to/gitdir $ git名声

输出:

Statistics based on master
Active files: 21
Active lines: 967
Total commits: 109

Note: Files matching MIME type image, binary has been ignored

+----------------+-----+---------+-------+---------------------+
| name           | loc | commits | files | distribution (%)    |
+----------------+-----+---------+-------+---------------------+
| Linus Oleander | 914 | 106     | 21    | 94.5 / 97.2 / 100.0 |
| f1yegor        | 47  | 2       | 7     |  4.9 /  1.8 / 33.3  |
| David Selassie | 6   | 1       | 2     |  0.6 /  0.9 /  9.5  |
+----------------+-----+---------+-------+---------------------+