我如何"滥用"指责(或者一些更适合的函数,和/或与shell命令结合使用)来统计存在来自每个提交者的存储库中当前有多少行(代码)?
示例输出:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 162
git ls-tree -r -z --name-only HEAD -- */*.c | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep "^author "|sort|uniq -c|sort -nr
Run Code Online (Sandbox Code Playgroud)
我在途中更新了一些东西.
对于懒惰你也可以把它放入它自己的命令:
#!/bin/bash
# save as i.e.: git-authors and set the executable flag
git ls-tree -r -z --name-only HEAD -- $1 | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep "^author "|sort|uniq -c|sort -nr
Run Code Online (Sandbox Code Playgroud)
将它存储在路径中的某个位置或修改路径并使用它
git authors '*/*.c' # look for all files recursively ending in .cgit authors '*/*.[ch]' # look for all files recursively ending in .c or .hgit authors 'Makefile' # just count lines of authors in the 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
Run Code Online (Sandbox Code Playgroud)
几乎是瞬间的.
要获取当前跟踪的文件列表,您可以使用
git ls-tree --name-only -r HEAD
Run Code Online (Sandbox Code Playgroud)
此解决方案避免调用file确定文件类型,并出于性能原因使用grep匹配所需的扩展名.如果应包含所有文件,只需将其从行中删除即可.
grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$' # for Python files
Run Code Online (Sandbox Code Playgroud)
如果文件可以包含空格,这对于shell可能会使用:
git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'
Run Code Online (Sandbox Code Playgroud)
给出一个文件列表(通过管道),可以使用xargs来调用命令并分发参数.允许处理多个文件的命令会忽略-n1.在这种情况下,我们调用git blame --line-porcelain并且每次调用我们都使用1个参数.
xargs -n1 git blame --line-porcelain
Run Code Online (Sandbox Code Playgroud)
然后,我们过滤输出"作者"的出现,对列表进行排序,并通过以下方式计算重复行:
grep "^author "|sort|uniq -c|sort -nr
Run Code Online (Sandbox Code Playgroud)
其他答案实际上过滤掉仅包含空格的行.
grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "
Run Code Online (Sandbox Code Playgroud)
上面的命令将打印包含至少一个非空白字符的行的作者.您还可以使用匹配\w*[^\w#],这也将排除第一个非空白字符不是a的行#(在许多脚本语言中注释).
Lin*_*der 118
我写了一个名为git-fame的宝石,它可能很有用.
安装和使用:
$ gem install git_fame $ cd /path/to/gitdir$ git fame输出:
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 |
+----------------+-----+---------+-------+---------------------+
Run Code Online (Sandbox Code Playgroud)
Edw*_*son 48
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
Run Code Online (Sandbox Code Playgroud)
分步说明:
列出版本控制下的所有文件
git ls-tree -r HEAD|sed -re 's/^.{53}//'
Run Code Online (Sandbox Code Playgroud)
将列表仅剪切为文本文件
|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'
Run Code Online (Sandbox Code Playgroud)
Git责怪所有文本文件,忽略空格更改
|while read filename; do git blame -w "$filename"; done
Run Code Online (Sandbox Code Playgroud)
拉出作者姓名
|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'
Run Code Online (Sandbox Code Playgroud)
对作者列表进行排序,并使uniq计算连续重复行的数量
|sort|uniq -c
Run Code Online (Sandbox Code Playgroud)
示例输出:
1334 Maneater
1924 Another guy
37195 Brian Ruby
1482 Anna Lambda
Run Code Online (Sandbox Code Playgroud)
adi*_*ius 31
git summary由git-extras包提供的正是您所需要的.在git-extras上查看文档- git-summary:
git summary --line
Run Code Online (Sandbox Code Playgroud)
给出如下所示的输出:
project : TestProject
lines : 13397
authors :
8927 John Doe 66.6%
4447 Jane Smith 33.2%
23 Not Committed Yet 0.2%
Run Code Online (Sandbox Code Playgroud)
Erik的解决方案非常棒,但我在变音符号方面遇到了一些问题(尽管我的LC_*环境变量表面上设置正确),并且噪声通过实际上有日期的代码行泄漏.我的sed-fu很差,所以我最终得到了这个带有红宝石的frankenstein片段,但它在200,000+ 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
Run Code Online (Sandbox Code Playgroud)
另请注意,gsed而不是sed因为这是二进制自制软件安装,使系统保持原样.
这是@Alex 回答中的主要片段,它实际上执行了聚合责备线的操作。我已将其缩减为对单个文件而不是一组文件进行操作。
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nr
Run Code Online (Sandbox Code Playgroud)
我在这里发布这个是因为我经常回到这个答案并重新阅读帖子并重新消化示例以提取我认为它征税的部分。对于我的用例来说,它也不够通用;它的范围是整个 C 项目。
我喜欢列出每个文件的统计信息,通过使用 bashfor迭代器而不是xargs因为我发现 xargs 可读性较差且难以使用/记忆而实现,应该在别处讨论xargs 与 for的优点/缺点。
这是一个实用的片段,将分别显示每个文件的结果:
for file in $(git ls-files); do \
echo $file; \
git blame --line-porcelain $file \
| grep "^author " | sort | uniq -c | sort -nr; \
echo; \
done
Run Code Online (Sandbox Code Playgroud)
我测试过,在 bash shell 中直接运行是 ctrl+c 安全的,如果您需要将其放入 bash 脚本中,如果您希望用户能够中断您的 for 循环,您可能需要在 SIGINT 和 SIGTERM 上设置陷阱。
| 归档时间: |
|
| 查看次数: |
49436 次 |
| 最近记录: |