我如何“滥用”责备(或一些更合适的函数,和/或与shell命令结合)来给我一个关于当前存储库中有多少行(代码)来自每个提交者的统计数据?
示例输出:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
我如何“滥用”责备(或一些更合适的函数,和/或与shell命令结合)来给我一个关于当前存储库中有多少行(代码)来自每个提交者的统计数据?
示例输出:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
当前回答
请从http://gitstats.sourceforge.net/查看gitstats命令
其他回答
下面是来自@Alex的回答的主要片段,它实际上做了聚集指责行的操作。我已经将其缩减为对单个文件而不是一组文件进行操作。
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nr
我在这里发表这篇文章是因为我经常回到这个答案,重新阅读这篇文章,重新消化例子,以提取我重视的部分,这是很费力的。对于我的用例来说,它也不够通用;它的范围是整个C项目。
我喜欢列出每个文件的统计数据,通过使用bash for迭代器而不是xargs来实现,因为我发现xargs可读性较差,很难使用/记忆,xargs vs for的优点/缺点应该在其他地方讨论。
下面是一个实用的代码片段,它将单独显示每个文件的结果:
for file in $(git ls-files); do \
echo $file; \
git blame --line-porcelain $file \
| grep "^author " | sort | uniq -c | sort -nr; \
echo; \
done
我测试过,在bash shell中直接运行它是ctrl+c安全的,如果你需要把它放在bash脚本中,如果你想让用户能够打破你的for循环,你可能需要在SIGINT和SIGTERM上捕获。
更新
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#],它也会排除第一个非空白字符不是#的行(许多脚本语言中的注释)。
我采用了Powershell最上面的答案:
(git ls-tree -rz --name-only HEAD).Split(0x00) | where {$_ -Match '.*\.py'} |%{git blame -w --line-porcelain HEAD $_} | Select-String -Pattern '^author ' | Group-Object | Select-Object -Property Count, Name | Sort-Object -Property Count -Descending
是否使用-w开关运行git blame是可选的,我添加它是因为它会忽略空白的更改。
虽然Bash解决方案在WSL2下运行,但我的机器上的性能对Powershell有利(在相同的repo下~50秒vs ~65秒)
我自己的脚本是@nilbus和@Alex的组合
#!/bin/sh
for f in $(git ls-tree -r --name-only HEAD --);
do
j=$(file "$f" | grep -E ': .*text'| sed -r -e 's/: .*//');
if [ "$f" != "$j" ]; then
continue;
fi
git blame -w --line-porcelain HEAD "$f" | grep "^author " | sed 's/author //'`enter code here`
done | sort | uniq -c | sort -nr
git shortlog -sec
这将显示每个作者的提交列表。