如何计算Git存储库中特定作者更改的总行数?

时间:2009-08-12 08:59:45

标签: git command-line statistics repository

我是否可以调用一个命令来计算Git存储库中特定作者更改的行?我知道必须有方法来计算提交次数,因为Github会为其影响图执行此操作。

24 个答案:

答案 0 :(得分:540)

这提供了一些关于作者的统计数据,根据需要进行修改。

使用Gawk:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat \
| gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }' -

在Mac OSX上使用Awk:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

编辑(2017)

github上有一个新的包看起来很光滑,并使用bash作为依赖项(在linux上测试)。它更适合直接使用而不是脚本。

这是git-quick-stats (github link)

git-quick-stats复制到文件夹,然后将该文件夹添加到路径。

mkdir ~/source
cd ~/source
git clone git@github.com:arzzen/git-quick-stats.git
mkdir ~/bin
ln -s ~/source/git-quick-stats/git-quick-stats ~/bin/git-quick-stats
chmod +x ~/bin/git-quick-stats
export PATH=${PATH}:~/bin

用法:

git-quick-stats

enter image description here

答案 1 :(得分:277)

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

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

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

对于传递给脚本,甚至可以使用空日志格式删除“oneline”格式,并且如JakubNarębski所评论,--numstat是另一种选择。它生成每个文件而不是每行统计信息,但更容易解析。

git log --author="<authorname>" --pretty=tformat: --numstat

答案 2 :(得分:178)

如果有人想在他们的代码库中看到每个用户的统计数据,我的几个同事最近想出了这个可怕的单行代码:

git log --shortstat --pretty="%cE" | sed 's/\(.*\)@.*/\1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/\1 0 insertions\(+\), \2/;s/\(\+\)$/\(\+\), 0 deletions\(-\)/;s/insertions?\(\+\), //;s/ deletions?\(-\)//' | awk 'BEGIN {name=""; files=0; insertions=0; deletions=0;} {if ($1 != name && name != "") { print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net"; files=0; insertions=0; deletions=0; name=$1; } name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net";}'

(花几分钟时间来处理我们的回购,其中有大约10-15k的提交。)

答案 3 :(得分:134)

Git成名 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数据。

答案 4 :(得分:102)

我发现以下内容对于查看当前代码库中包含最多行的人员非常有用:

git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n

其他答案主要集中在提交中更改的行,但如果提交无法生存并被覆盖,则可能只是流失。上面的咒语也会让你所有提交者按行排序,而不是一次只有一个。您可以为git blame(-C -M)添加一些选项,以获得一些更好的数字,以便将文件移动和文件之间的行移动考虑在内,但是如果你这样做,命令可能运行的时间会更长。

此外,如果您正在寻找所有提交者的所有提交中更改的行,则以下小脚本很有帮助:

http://git-wt-commit.rubyforge.org/#git-rank-contributors

答案 5 :(得分:86)

要计算给定分支上给定作者(或所有作者)的提交数,您可以使用git-shortlog;请特别注意其--numbered--summary选项,例如在git repository上运行时:

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

答案 6 :(得分:68)

在查看 Alex Gerty3000 的答案后,我试图缩短单行:

基本上,使用git log numstat和跟踪文件的数量已更改。

Mac OSX上的Git 2.1.0版:

git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

示例:

Jared Burrows   added lines: 6826, removed lines: 2825, total lines: 4001

答案 7 :(得分:25)

来自AnswerAaronM使用shell one-liner是好的,但实际上,还有另一个错误,如果空格之间存在不同数量的空格,则会破坏用户名。用户名和日期。损坏的用户名将为用户计数提供多行,您必须自己总结它们。

这个小改动为我解决了这个问题:

git ls-files -z | xargs -0n1 git blame -w --show-email | perl -n -e '/^.*?\((.*?)\s+[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

注意\ after后面的+会消耗从名称到日期的所有空格。

实际上,为了我自己的记忆而添加这个答案,就像帮助其他人一样,因为这至少是我第二次谷歌主题:)

  • 修改2019-01-23 已将--show-email添加到git blame -w以汇总电子邮件,因为有些人在不同的计算机上使用不同的Name格式,并且有时两个同名的人在同一个git中工作。

答案 8 :(得分:22)

这是一个简短的单行程序,为所有作者生成统计数据。它比上面https://stackoverflow.com/a/20414465/1102119的Dan解决方案要快得多(我的时间复杂度为O(N)而不是O(NM),其中N是提交数,M是作者数。)

git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = ""; next } END { for (a in ins) { printf "%10d %10d %10d %s\n", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn

答案 9 :(得分:21)

@mrobins @AaronM @ErikZ @JamesMishra提供的变体都有一个共同的问题:他们要求git生成一个不用于脚本消费的信息混合,包括来自同一行上的存储库的行内容,然后匹配混乱正则表达式。

当某些行不是有效的UTF-8文本时,以及当某些行恰好与正则表达式匹配时(这发生在这里),这是一个问题。

这是一条没有这些问题的修改过的行。它要求git在不同的行上干净地输出数据,这样可以很容易地过滤我们想要的内容:

git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n

你可以grep其他字符串,比如author-mail,committer等。

也许首先做export LC_ALL=C(假设bash)来强制执行字节级处理(这也恰好可以从基于UTF-8的语言环境中大大加快grep)。

答案 10 :(得分:16)

在中间给出了一个ruby的解决方案,perl在默认情况下更加可用,这是作者对当前行使用perl的替代方案。

git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

答案 11 :(得分:13)

除了Charles Bailey's answer之外,您可能还想在命令中添加-C参数。否则文件重命名计为大量添加和删除(尽管文件有行数),即使文件内容未被修改。

为了说明,使用git log --oneline --shortstat命令时,a commit有很多文件在我的一个项目中移动:

9052459 Reorganized project structure
 43 files changed, 1049 insertions(+), 1000 deletions(-)

这里使用git log --oneline --shortstat -C命令检测文件副本并重命名:

9052459 Reorganized project structure
 27 files changed, 134 insertions(+), 85 deletions(-)

在我看来,后者提供了一个更真实的视图,了解一个人对项目的影响,因为重命名文件比从头编写文件要小得多。

答案 12 :(得分:11)

这是一个快速的ruby脚本,可以根据给定的日志查询来确定每个用户的影响。

例如,对于rubinius

Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...

脚本:

#!/usr/bin/env ruby

impact = Hash.new(0)

IO.popen("git log --pretty=format:\"%an\" --shortstat #{ARGV.join(' ')}") do |f|
  prev_line = ''
  while line = f.gets
    changes = /(\d+) insertions.*(\d+) deletions/.match(line)

    if changes
      impact[prev_line] += changes[1].to_i + changes[2].to_i
    end

    prev_line = line # Names are on a line of their own, just before the stats
  end
end

impact.sort_by { |a,i| -i }.each do |author, impact|
  puts "#{author.strip}: #{impact}"
end

答案 13 :(得分:9)

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

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

$ 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>
=====================================================

答案 14 :(得分:8)

这是最好的方式,它还可以让您清楚地了解所有用户提交的总数

git shortlog -s -n

答案 15 :(得分:6)

这是一个很棒的仓库,可以让您的生活更轻松

git-quick-stats

在安装了brew的Mac上

brew install git-quick-stats

运行

git-quick-stats

只需通过键入列出的数字并按Enter键,从此列表中选择所需的选项即可。

 Generate:
    1) Contribution stats (by author)
    2) Contribution stats (by author) on a specific branch
    3) Git changelogs (last 10 days)
    4) Git changelogs by author
    5) My daily status
    6) Save git log output in JSON format

 List:
    7) Branch tree view (last 10)
    8) All branches (sorted by most recent commit)
    9) All contributors (sorted by name)
   10) Git commits per author
   11) Git commits per date
   12) Git commits per month
   13) Git commits per weekday
   14) Git commits per hour
   15) Git commits by author per hour

 Suggest:
   16) Code reviewers (based on git history)

答案 16 :(得分:5)

我在上面提供了一个简短答案的修改,但它不足以满足我的需要。我需要能够在最终代码中对提交的行和行进行分类。我也希望按文件分解。此代码不会递归,它只会返回单个目录的结果,但如果有人想要更进一步,这是一个良好的开端。复制并粘贴到文件中并生成可执行文件或使用Perl运行它。

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $dir = shift;

die "Please provide a directory name to check\n"
    unless $dir;

chdir $dir
    or die "Failed to enter the specified directory '$dir': $!\n";

if ( ! open(GIT_LS,'-|','git ls-files') ) {
    die "Failed to process 'git ls-files': $!\n";
}
my %stats;
while (my $file = <GIT_LS>) {
    chomp $file;
    if ( ! open(GIT_LOG,'-|',"git log --numstat $file") ) {
        die "Failed to process 'git log --numstat $file': $!\n";
    }
    my $author;
    while (my $log_line = <GIT_LOG>) {
        if ( $log_line =~ m{^Author:\s*([^<]*?)\s*<([^>]*)>} ) {
            $author = lc($1);
        }
        elsif ( $log_line =~ m{^(\d+)\s+(\d+)\s+(.*)} ) {
            my $added = $1;
            my $removed = $2;
            my $file = $3;
            $stats{total}{by_author}{$author}{added}        += $added;
            $stats{total}{by_author}{$author}{removed}      += $removed;
            $stats{total}{by_author}{total}{added}          += $added;
            $stats{total}{by_author}{total}{removed}        += $removed;

            $stats{total}{by_file}{$file}{$author}{added}   += $added;
            $stats{total}{by_file}{$file}{$author}{removed} += $removed;
            $stats{total}{by_file}{$file}{total}{added}     += $added;
            $stats{total}{by_file}{$file}{total}{removed}   += $removed;
        }
    }
    close GIT_LOG;

    if ( ! open(GIT_BLAME,'-|',"git blame -w $file") ) {
        die "Failed to process 'git blame -w $file': $!\n";
    }
    while (my $log_line = <GIT_BLAME>) {
        if ( $log_line =~ m{\((.*?)\s+\d{4}} ) {
            my $author = $1;
            $stats{final}{by_author}{$author}     ++;
            $stats{final}{by_file}{$file}{$author}++;

            $stats{final}{by_author}{total}       ++;
            $stats{final}{by_file}{$file}{total}  ++;
            $stats{final}{by_file}{$file}{total}  ++;
        }
    }
    close GIT_BLAME;
}
close GIT_LS;

print "Total lines committed by author by file\n";
printf "%25s %25s %8s %8s %9s\n",'file','author','added','removed','pct add';
foreach my $file (sort keys %{$stats{total}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{total}{by_file}{$file}{total}{added}/$stats{total}{by_author}{total}{added};
    foreach my $author (sort keys %{$stats{total}{by_file}{$file}}) {
        next if $author eq 'total';
        if ( $stats{total}{by_file}{$file}{total}{added} ) {
            printf "%25s %25s %8d %8d %8.0f%%\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}}
            ,100*$stats{total}{by_file}{$file}{$author}{added}/$stats{total}{by_file}{$file}{total}{added};
        } else {
            printf "%25s %25s %8d %8d\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}} ;
        }
    }
}
print "\n";

print "Total lines in the final project by author by file\n";
printf "%25s %25s %8s %9s %9s\n",'file','author','final','percent', '% of all';
foreach my $file (sort keys %{$stats{final}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{final}{by_file}{$file}{total}/$stats{final}{by_author}{total};
    foreach my $author (sort keys %{$stats{final}{by_file}{$file}}) {
        next if $author eq 'total';
        printf "%25s %25s %8d %8.0f%% %8.0f%%\n",'', $author,$stats{final}{by_file}{$file}{$author}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_file}{$file}{total}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_author}{total}
        ;
    }
}
print "\n";


print "Total lines committed by author\n";
printf "%25s %8s %8s %9s\n",'author','added','removed','pct add';
foreach my $author (sort keys %{$stats{total}{by_author}}) {
    next if $author eq 'total';
    printf "%25s %8d %8d %8.0f%%\n",$author,@{$stats{total}{by_author}{$author}}{qw{added removed}}
        ,100*$stats{total}{by_author}{$author}{added}/$stats{total}{by_author}{total}{added};
};
print "\n";


print "Total lines in the final project by author\n";
printf "%25s %8s %9s\n",'author','final','percent';
foreach my $author (sort keys %{$stats{final}{by_author}}) {
    printf "%25s %8d %8.0f%%\n",$author,$stats{final}{by_author}{$author}
        ,100*$stats{final}{by_author}{$author}/$stats{final}{by_author}{total};
}

答案 17 :(得分:2)

对于Windows用户,您可以使用以下批处理脚本来计算指定作者的添加/删除行数

@echo off

set added=0
set removed=0

for /f "tokens=1-3 delims= " %%A in ('git log --pretty^=tformat: --numstat --author^=%1') do call :Count %%A %%B %%C

@echo added=%added%
@echo removed=%removed%
goto :eof

:Count
  if NOT "%1" == "-" set /a added=%added% + %1
  if NOT "%2" == "-" set /a removed=%removed% + %2
goto :eof

https://gist.github.com/zVolodymyr/62e78a744d99d414d56646a5e8a1ff4f

答案 18 :(得分:1)

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

答案 19 :(得分:1)

使用以下方法将日志保存到文件中:

git log --author="<authorname>" --oneline --shortstat > logs.txt

对于Python爱好者:

with open(r".\logs.txt", "r", encoding="utf8") as f:
    files = insertions = deletions = 0
    for line in f:
        if ' changed' in line:
            line = line.strip()
            spl = line.split(', ')
            if len(spl) > 0:
                files += int(spl[0].split(' ')[0])
            if len(spl) > 1:
                insertions += int(spl[1].split(' ')[0])
            if len(spl) > 2:
                deletions += int(spl[2].split(' ')[0])

    print(str(files).ljust(10) + ' files changed')
    print(str(insertions).ljust(10) + ' insertions')
    print(str(deletions).ljust(10) + ' deletions')

您的输出将如下:

225        files changed
6751       insertions
1379       deletions

答案 20 :(得分:1)

我编写了这个Perl脚本来完成该任务。

#!/usr/bin/env perl

use strict;
use warnings;

# save the args to pass to the git log command
my $ARGS = join(' ', @ARGV);

#get the repo slug
my $NAME = _get_repo_slug();

#get list of authors
my @authors = _get_authors();
my ($projectFiles, $projectInsertions, $projectDeletions) = (0,0,0);
#for each author
foreach my $author (@authors) {
  my $command = qq{git log $ARGS --author="$author" --oneline --shortstat --no-merges};
  my ($files, $insertions, $deletions) = (0,0,0);
  my @lines = `$command`;
  foreach my $line (@lines) {
    if ($line =~ m/^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\([\+|\-]\),\s(\d+)\s\w+\([\+|\-]\)$|^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\(([\+|\-])\)$/) {
      my $lineFiles = $1 ? $1 : $4;
      my $lineInsertions = (defined $6 && $6 eq '+') ? $5 : (defined $2) ? $2 : 0;
      my $lineDeletions = (defined $6 && $6 eq '-') ? $5 : (defined $3) ? $3 : 0;
      $files += $lineFiles;
      $insertions += $lineInsertions;
      $deletions += $lineDeletions;
      $projectFiles += $lineFiles;
      $projectInsertions += $lineInsertions;
      $projectDeletions += $lineDeletions;
    }
  }
  if ($files || $insertions || $deletions) {
    printf(
      "%s,%s,%s,+%s,-%s,%s\n",
      $NAME,
      $author,
      $files,
      $insertions,
      $deletions,
      $insertions - $deletions
    );
  }
}

printf(
  "%s,%s,%s,+%s,-%s,%s\n",
  $NAME,
  'PROJECT_TOTAL',
  $projectFiles,
  $projectInsertions,
  $projectDeletions,
  $projectInsertions - $projectDeletions
);

exit 0;

#get the remote.origin.url joins that last two pieces (project and repo folder)
#and removes any .git from the results. 
sub _get_repo_slug {
  my $get_remote_url = "git config --get remote.origin.url";
  my $remote_url = `$get_remote_url`;
  chomp $remote_url;

  my @parts = split('/', $remote_url);

  my $slug = join('-', @parts[-2..-1]);
  $slug =~ s/\.git//;

  return $slug;
}

sub _get_authors {
  my $git_authors = 'git shortlog -s | cut -c8-';
  my @authors = `$git_authors`;
  chomp @authors;

  return @authors;
}

我将其命名为git-line-changes-by-author,然后放入/usr/local/bin。因为它已保存在我的路径中,所以我可以发出命令git line-changes-by-author --before 2018-12-31 --after 2020-01-01来获取2019年的报告。举个例子。如果我拼错了名字,git会建议正确的拼写。

您可能需要调整_get_repo_slug子项,使其仅包含remote.origin.url的最后一部分,因为我的存储库另存为project/repo,而您可能没有。

答案 21 :(得分:0)

你想要Git blame

有一个--show-stats选项可以打印一些好的统计数据。

答案 22 :(得分:0)

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

这就是我所寻求的,但现有的解决方案并不完美。为了可能通过Google找到这个问题的人的利益,我已经对它们做了一些改进,并将它们变成了一个shell脚本,我将在下面显示。带注释的(我将继续维护)可以是found on my Github

Perl或Ruby上都有 no 依赖项。此外,行更改计数中会考虑空格,重命名和行移动。只需将其放入文件并将您的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

答案 23 :(得分:0)

到目前为止我认识的最好的工具是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