在 git 中显示每个作者的更改行数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2787253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Show number of changed lines per author in git
提问by knittl
i want to see the number of removed/added line, grouped by author for a given branch in git history. there is git shortlog -s
which shows me the number of commits per author. is there anything similar to get an overall diffstat?
我想查看删除/添加的行数,按作者为 git 历史记录中的给定分支分组。有git shortlog -s
一个显示每个作者的提交次数。有没有类似的东西可以得到一个整体的diffstat?
回答by Sebastien Horin
It's an old post but if someone is still looking for it:
这是一个旧帖子,但如果有人仍在寻找它:
install git extras
安装 git 附加功能
brew install git-extras
then
然后
git summary --line
回答by VonC
Since the SO question "How to count total lines changed by a specific author in a Git repository?"is not completely satisfactory, commandlinefuhas alternatives (albeit not per branch):
由于SO 问题“如何计算 Git 存储库中特定作者更改的总行数?” 并不完全令人满意,commandlinefu有替代方案(尽管不是每个分支):
git ls-files | while read i; do git blame $i | sed -e 's/^[^(]*(//' -e 's/^\([^[:digit:]]*\)[[:space:]]\+[[:digit:]].*//'; done | sort | uniq -ic | sort -nr
It includes binary files, which is not good, so you could (to remove really random binary files):
它包含二进制文件,这不好,所以你可以(删除真正随机的二进制文件):
git ls-files | grep -v "\.\(pdf\|psd\|tif\)$"
(Note: as commentedby trcarden, a -x
or --exclude
option wouldn't work.
From git ls-files
man page, git ls-files -x "*pdf" ...
would only excluded untrackedcontent, if --others
or --ignored
were added to the git ls-files
command.)
(注意:正如trcarden所评论的, a or选项不起作用。
从手册页,如果 或被添加到命令中,只会排除未跟踪的内容。)-x
--exclude
git ls-files
git ls-files -x "*pdf" ...
--others
--ignored
git ls-files
Or:
或者:
git ls-files "*.py" "*.html" "*.css"
to only include specific file types.
只包含特定的文件类型。
Still, a "git log
"-based solutionshould be better, like:
不过,基于" git log
" 的解决方案应该更好,例如:
git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=; minus+=} END {printf("+%d, -%d\n", plus, minus)}'
but again, this is for one path (here 2 commits), not for all branches per branches.
但同样,这是针对一条路径(这里是 2 次提交),而不是针对每个分支的所有分支。
回答by alswl
one line code(support time range selection):
一行代码(支持时间范围选择):
git log --since=4.weeks --numstat --pretty="%ae %H" | sed 's/@.*//g' | awk '{ if (NF == 1){ name = }; if(NF == 3) {plus[name] += ; minus[name] += }} END { for (name in plus) {print name": +"plus[name]" -"minus[name]}}' | sort -k2 -gr
explain:
解释:
git log --since=4.weeks --numstat --pretty="%ae %H" \
| sed 's/@.*//g' \
| awk '{ if (NF == 1){ name = }; if(NF == 3) {plus[name] += ; minus[name] += }} END { for (name in plus) {print name": +"plus[name]" -"minus[name]}}' \
| sort -k2 -gr
# query log by time range
# get author email prefix
# count plus / minus lines
# sort result
output:
输出:
user-a: +5455 -3471
user-b: +5118 -1934
回答by alswl
This script here will do it. Put it into authorship.sh, chmod +x it, and you're all set.
这里的脚本会做到这一点。把它放到 authorship.sh 中,chmod +x 它,你就大功告成了。
#!/bin/sh
declare -A map
while read line; do
if grep "^[a-zA-Z]" <<< "$line" > /dev/null; then
current="$line"
if [ -z "${map[$current]}" ]; then
map[$current]=0
fi
elif grep "^[0-9]" <<<"$line" >/dev/null; then
for i in $(cut -f 1,2 <<< "$line"); do
map[$current]=$((map[$current] + $i))
done
fi
done <<< "$(git log --numstat --pretty="%aN")"
for i in "${!map[@]}"; do
echo -e "$i:${map[$i]}"
done | sort -nr -t ":" -k 2 | column -t -s ":"
回答by Nicolas
From How to count total lines changed by a specific author in a Git repository?
The output of the following command should be reasonably easy to send to script to add up the totals:
以下命令的输出应该很容易发送到脚本以将总数相加:
git log --author="<authorname>" --oneline --shortstat
This gives stats for all commits on the current HEAD. If you want to add up stats in other branches you will have to supply them as arguments to git log.
这提供了当前 HEAD 上所有提交的统计信息。如果要在其他分支中添加统计信息,则必须将它们作为参数提供给 git log。
回答by pydsigner
On my repos I've gotten a lot of trash output from the one-liners floating around, so here is a Python script to do it right:
在我的存储库中,我从漂浮的单线中获得了大量垃圾输出,因此这里有一个 Python 脚本可以正确执行此操作:
import subprocess
import collections
import sys
def get_lines_from_call(command):
return subprocess.check_output(command).splitlines()
def get_files(paths=()):
command = ['git', 'ls-files']
command.extend(paths)
return get_lines_from_call(command)
def get_blame(path):
return get_lines_from_call(['git', 'blame', path])
def extract_name(line):
"""
Extract the author from a line of a standard git blame
"""
return line.split('(', 1)[1].split(')', 1)[0].rsplit(None, 4)[0]
def get_file_authors(path):
return [extract_name(line) for line in get_blame(path)]
def blame_stats(paths=()):
counter = collections.Counter()
for filename in get_files(paths):
counter.update(get_file_authors(filename))
return counter
def main():
counter = blame_stats(sys.argv[1:])
max_width = len(str(counter.most_common(1)[0][1]))
for name, count in reversed(counter.most_common()):
print('%s %s' % (str(count).rjust(max_width), name))
if __name__ == '__main__':
main()
Note that the arguments to the script will be passed to git ls-files
, so if you only want to show Python files:
blame_stats.py '**/*.py'
请注意,脚本的参数将传递给git ls-files
,因此如果您只想显示 Python 文件:
blame_stats.py '**/*.py'
If you only want to show files in one subdirectory:blame_stats.py some_dir
如果您只想显示一个子目录中的文件:blame_stats.py some_dir
And so on.
等等。