我是否可以调用一个命令来计算Git存储库中特定作者更改的行数?我知道一定有方法来计算提交的数量,因为Github为他们的影响图这样做。


当前回答

该问题要求提供关于特定作者的信息,但许多答案都是根据修改的代码行返回作者排名列表的解决方案。

这正是我想要的,但现有的解决方案并不完美。为了方便人们通过谷歌找到这个问题,我对它们进行了一些改进,并将其制成一个shell脚本,下面显示该脚本。

它不依赖于Perl或Ruby。此外,空格、重命名和行移动都在行更改计数中被考虑在内。只需将其放入一个文件中,并将Git存储库作为第一个参数传递。

#!/bin/bash
git --git-dir="$1/.git" log > /dev/null 2> /dev/null
if [ $? -eq 128 ]
then
    echo "Not a git repository!"
    exit 128
else
    echo -e "Lines  | Name\nChanged|"
    git --work-tree="$1" --git-dir="$1/.git" ls-files -z |\
    xargs -0n1 git --work-tree="$1" --git-dir="$1/.git" blame -C -M  -w |\
    cut -d'(' -f2 |\
    cut -d2 -f1 |\
    sed -e "s/ \{1,\}$//" |\
    sort |\
    uniq -c |\
    sort -nr
fi

其他回答

要统计给定作者(或所有作者)在给定分支上提交的数量,可以使用git-shortlog;特别是它的——编号和——摘要选项,例如在git存储库上运行时:

$ git shortlog v1.6.4 --numbered --summary
  6904  Junio C Hamano
  1320  Shawn O. Pearce
  1065  Linus Torvalds
    692  Johannes Schindelin
    443  Eric Wong

到目前为止,我确定的最好的工具是gitinspector。它给每个用户,每周等设置报告 你可以像下面这样用npm安装

NPM install -g gitinspector

这些链接可以获得更多详细信息

https://www.npmjs.com/package/gitinspector

https://github.com/ejwa/gitinspector/wiki/Documentation

https://github.com/ejwa/gitinspector

命令示例如下

gitinspector -lmrTw 
gitinspector --since=1-1-2017 etc

你可以使用whodid (https://www.npmjs.com/package/whodid)

$ npm install whodid -g
$ cd your-project-dir

and

$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week

或者直接输入

$ whodid

然后你可以看到这样的结果

Contribution state
=====================================================
 score  | author
-----------------------------------------------------
 3059   | someguy <someguy@tensorflow.org>
 585    | somelady <somelady@tensorflow.org>
 212    | niceguy <nice@google.com>
 173    | coolguy <coolgay@google.com>
=====================================================

吉特名声

https://github.com/oleander/git-fame-rb

这是一个很好的工具,可以一次性获得所有作者的计数,包括提交和修改文件的计数:

sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame

https://github.com/casperdcl/git-fame上也有Python版本(@fracz提到过):

sudo apt-get install python-pip python-dev build-essential 
pip install --user git-fame
cd /path/to/gitdir && git fame

样例输出:

Total number of files: 2,053
Total number of lines: 63,132
Total number of commits: 4,330

+------------------------+--------+---------+-------+--------------------+
| name                   | loc    | commits | files | percent            |
+------------------------+--------+---------+-------+--------------------+
| Johan Sørensen         | 22,272 | 1,814   | 414   | 35.3 / 41.9 / 20.2 |
| Marius Mathiesen       | 10,387 | 502     | 229   | 16.5 / 11.6 / 11.2 |
| Jesper Josefsson       | 9,689  | 519     | 191   | 15.3 / 12.0 / 9.3  |
| Ole Martin Kristiansen | 6,632  | 24      | 60    | 10.5 / 0.6 / 2.9   |
| Linus Oleander         | 5,769  | 705     | 277   | 9.1 / 16.3 / 13.5  |
| Fabio Akita            | 2,122  | 24      | 60    | 3.4 / 0.6 / 2.9    |
| August Lilleaas        | 1,572  | 123     | 63    | 2.5 / 2.8 / 3.1    |
| David A. Cuadrado      | 731    | 111     | 35    | 1.2 / 2.6 / 1.7    |
| Jonas Ängeslevä        | 705    | 148     | 51    | 1.1 / 3.4 / 2.5    |
| Diego Algorta          | 650    | 6       | 5     | 1.0 / 0.1 / 0.2    |
| Arash Rouhani          | 629    | 95      | 31    | 1.0 / 2.2 / 1.5    |
| Sofia Larsson          | 595    | 70      | 77    | 0.9 / 1.6 / 3.8    |
| Tor Arne Vestbø        | 527    | 51      | 97    | 0.8 / 1.2 / 4.7    |
| spontus                | 339    | 18      | 42    | 0.5 / 0.4 / 2.0    |
| Pontus                 | 225    | 49      | 34    | 0.4 / 1.1 / 1.7    |
+------------------------+--------+---------+-------+--------------------+

但是要注意的是:正如Jared在评论中提到的,在一个非常大的存储库上做这件事将花费数小时。但考虑到它必须处理如此多的Git数据,不确定是否可以改进。

这个脚本可以做到这一点。把它放入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 ":"