在git中显示每位作者更改的行数

时间:2010-05-07 08:41:23

标签: git diff history logging

我想查看删除/添加的行数,按作者分组,在git历史记录中给定分支。有git shortlog -s显示每位作者的提交数量。是否有类似的东西得到整体diffstat?

6 个答案:

答案 0 :(得分:38)

这是一个老帖子,但如果有人还在寻找它:

安装git extras

brew install git-extras

然后

git summary --line

https://github.com/tj/git-extras

答案 1 :(得分:18)

由于the SO question "How to count total lines changed by a specific author in a Git repository?"并不完全令人满意,commandlinefu有替代方案(尽管不是每个分支):

git ls-files | while read i; do git blame $i | sed -e 's/^[^(]*(//' -e 's/^\([^[:digit:]]*\)[[:space:]]\+[[:digit:]].*/\1/'; done | sort | uniq -ic | sort -nr

它包含二进制文件,这是不好的,所以你可以(删除真正随机的二进制文件):

git ls-files | grep -v "\.\(pdf\|psd\|tif\)$"

(注意:commentedtrcarden-x--exclude选项不起作用。
如果git ls-files -x "*pdf" ...--others添加到--ignored命令,git ls-files man page git ls-files只会排除未跟踪的内容。< / p>

或者:

git ls-files "*.py" "*.html" "*.css" 

仅包含特定文件类型。


仍然,"git log"-based solution应该更好,例如:

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

但同样,这是针对一条路径(此处为2次提交),而不是针对每个分支的所有分支。

答案 2 :(得分:6)

一行代码(支持时间范围选择):

protected

解释:

git log --since=4.weeks --numstat --pretty="%ae %H" | sed 's/@.*//g' | awk '{ if (NF == 1){ name = $1}; if(NF == 3) {plus[name] += $1; minus[name] += $2}} END { for (name in plus) {print name": +"plus[name]" -"minus[name]}}' | sort -k2 -gr

输出:

git log --since=4.weeks --numstat --pretty="%ae %H" \
    | sed 's/@.*//g'  \
    | awk '{ if (NF == 1){ name = $1}; if(NF == 3) {plus[name] += $1; minus[name] += $2}} 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

答案 3 :(得分:2)

这个脚本会在这里完成。把它放入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 ":"

答案 4 :(得分:2)

来自How to count total lines changed by a specific author in a Git repository?

以下命令的输出应该相当容易发送到脚本以添加总计:

git log --author="<authorname>" --oneline --shortstat

这为当前HEAD上的所有提交提供了统计信息。如果你想在其他分支中添加统计数据,你必须将它们作为参数提供给git log。

答案 5 :(得分:1)

在我的回购中,我从周围的单行中获得了大量的垃圾输出,所以这是一个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()

请注意,脚本的参数将传递给git ls-files,因此如果您只想显示Python文件: blame_stats.py '**/*.py'

如果您只想在一个子目录中显示文件:blame_stats.py some_dir

等等。