我是否可以调用一个命令来计算Git存储库中特定作者更改的行数?我知道一定有方法来计算提交的数量,因为Github为他们的影响图这样做。


当前回答

你可以使用whodid (https://www.npmjs.com/package/whodid)

$ npm install whodid -g
$ cd your-project-dir

and

$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week

或者直接输入

$ whodid

然后你可以看到这样的结果

Contribution state
=====================================================
 score  | author
-----------------------------------------------------
 3059   | someguy <someguy@tensorflow.org>
 585    | somelady <somelady@tensorflow.org>
 212    | niceguy <nice@google.com>
 173    | coolguy <coolgay@google.com>
=====================================================

其他回答

我发现下面的方法对于查看当前代码库中谁拥有最多的行很有用:

git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n

其他答案主要集中在提交中更改的行,但如果提交无法存活并被覆盖,则它们可能只是被更改了。上面的咒语还可以让您按行对所有提交者进行排序,而不是一次只排序一个。您可以向git blame (-C -M)添加一些选项,以获得一些更好的数字,将文件移动和文件之间的行移动考虑在内,但如果这样做,该命令可能会运行更长时间。

同样,如果你正在为所有提交者寻找在所有提交中更改的行,下面的小脚本很有帮助:

http://git-wt-commit.rubyforge.org/#git-rank-contributors

对于windows用户,可以使用以下批处理脚本计算指定作者添加/删除的行数

@echo off

set added=0
set removed=0

for /f "tokens=1-3 delims= " %%A in ('git log --pretty^=tformat: --numstat --author^=%1') do call :Count %%A %%B %%C

@echo added=%added%
@echo removed=%removed%
goto :eof

:Count
  if NOT "%1" == "-" set /a added=%added% + %1
  if NOT "%2" == "-" set /a removed=%removed% + %2
goto :eof

https://gist.github.com/zVolodymyr/62e78a744d99d414d56646a5e8a1ff4f

除了Charles Bailey的回答之外,您可能还想在命令中添加-C参数。否则,即使文件内容没有被修改,文件重命名也会被视为大量的添加和删除(与文件的行数一样多)。

为了说明,当使用git log——oneline——shortstat命令时,这里有一个从我的一个项目中移动的大量文件的提交:

9052459 Reorganized project structure
 43 files changed, 1049 insertions(+), 1000 deletions(-)

这里使用git log——oneline——shortstat -C命令来检测文件的复制和重命名:

9052459 Reorganized project structure
 27 files changed, 134 insertions(+), 85 deletions(-)

在我看来,后者给出了一个人对项目有多大影响的更现实的观点,因为重命名一个文件比从头开始写文件要小得多。

AaronM使用shell一行程序得到的答案很好,但实际上,还有另一个错误,如果用户名和日期之间有不同数量的空格,空格会破坏用户名。损坏的用户名将给出多行用户计数,您必须自己将它们相加。

这个小小的改变解决了我的问题:

git ls-files -z | xargs -0n1 git blame -w --show-email | perl -n -e '/^.*?\((.*?)\s+[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

注意\s后面的+,它将占用从名称到日期的所有空白。

实际上,添加这个答案既是为了帮助别人,也是为了我自己的记忆,因为这至少是我第二次谷歌这个主题:)

增加了——show-email to git blame -w来聚合email,因为有些人在不同的计算机上使用不同的Name格式,有时两个同名的人在同一个git中工作。

@mmrobins @AaronM @ErikZ @JamesMishra提供的变体都有一个共同的问题:他们要求git生成不用于脚本使用的信息的混合物,包括来自存储库的行内容在同一行,然后用regexp匹配混乱。

当某些行不是有效的UTF-8文本时,以及当某些行恰好与regexp匹配时(这里发生了这种情况),就会出现问题。

这是一条修改过的线,没有这些问题。它要求git在单独的行上干净地输出数据,这使得它很容易过滤我们想要的内容:

git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n

您可以grep其他字符串,如author-mail, committer等。

也许首先要导出LC_ALL=C(假设是bash)以强制进行字节级处理(这碰巧也大大加快了来自基于utf -8的区域设置的grep的速度)。