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

示例输出:

Committer 1: 8046 Lines
Committer 2: 4378 Lines

当前回答

下面是来自@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上捕获。

其他回答

这适用于repo源结构的任何目录,以防您想检查某个源模块。

find . -name '*.c' | xargs -n1 git blame --line-porcelain | grep "^author "|sort|uniq -c|sort -nr

git shortlog -sec

这将显示每个作者的提交列表。

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

Git -extras包提供的Git摘要正是您所需要的。在git-extras - git-summary处签出文档:

git summary --line

给出如下输出:

project  : TestProject
lines    : 13397
authors  :
8927 John Doe            66.6%
4447 Jane Smith          33.2%
  23 Not Committed Yet   0.2%

下面是来自@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上捕获。