Gav*_*Gav 420 git statistics command-line repository
是否有一个我可以调用的命令,它将计算Git存储库中特定作者更改的行?我知道必须有方法来计算提交次数,因为Github会为其影响图执行此操作.
Ale*_*lex 569
这提供了有关作者的一些统计信息,根据需要进行修改
使用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 }' -
Run Code Online (Sandbox Code Playgroud)
在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 }' -
Run Code Online (Sandbox Code Playgroud)
在github上有一个新的包看起来很光滑,并使用bash作为依赖(在linux上测试).它更适合直接使用而不是脚本.
复制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
Run Code Online (Sandbox Code Playgroud)
用法:
git-quick-stats
Run Code Online (Sandbox Code Playgroud)
CB *_*ley 292
以下命令的输出应该相当容易发送到脚本以添加总计:
git log --author="<authorname>" --oneline --shortstat
Run Code Online (Sandbox Code Playgroud)
这为当前HEAD上的所有提交提供了统计信息.如果你想在其他分支中添加统计数据,你必须提供它们作为参数git log
.
对于传递给脚本,甚至可以使用空日志格式删除"oneline"格式,并且由JakubNarębski评论,--numstat
是另一种选择.它生成每个文件而不是每行统计信息,但更容易解析.
git log --author="<authorname>" --pretty=tformat: --numstat
Run Code Online (Sandbox Code Playgroud)
Dan*_*Dan 199
如果有人想看到他们的代码库中每个用户的统计数据,我的几个同事最近提出了这个可怕的单行:
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";}'
Run Code Online (Sandbox Code Playgroud)
(花几分钟时间来处理我们的仓库,它有大约10-15k的提交.)
Cir*_*四事件 139
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
Run Code Online (Sandbox Code Playgroud)
还有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
Run Code Online (Sandbox Code Playgroud)
样本输出:
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 |
+------------------------+--------+---------+-------+--------------------+
Run Code Online (Sandbox Code Playgroud)
但要注意:正如Jared在评论中所提到的那样,在一个非常大的存储库上进行它需要几个小时.不确定是否可以改进,考虑到它必须处理如此多的Git数据.
mmr*_*ins 103
我发现以下内容对于查看当前代码库中包含最多行的人员非常有用:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)
其他答案主要集中在提交中更改的行,但如果提交无法生存并被覆盖,则可能只是流失.上面的咒语也会让你所有提交者按行排序,而不是一次只有一个.您可以为git blame(-C -M)添加一些选项,以获得一些更好的数字,以便将文件移动和文件之间的行移动考虑在内,但是如果这样做,命令可能会运行更长时间.
此外,如果您要查找所有提交的所有提交中更改的行,则以下小脚本很有用:
http://git-wt-commit.rubyforge.org/#git-rank-contributors
Jak*_*ski 88
要计算给定分支上给定作者(或所有作者)的提交次数,您可以使用git-shortlog ; 特别参见它--numbered
和--summary
选项,例如在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
Run Code Online (Sandbox Code Playgroud)
Jar*_*ows 71
在看了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
Run Code Online (Sandbox Code Playgroud)
例:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
Run Code Online (Sandbox Code Playgroud)
Eri*_*vic 29
来自AaronM的使用shell 单行的答案是好的,但实际上,还有另一个错误,如果用户名和日期之间有不同数量的空格,空格将破坏用户名.损坏的用户名将为用户计数提供多行,您必须自己总结它们.
这个小改动为我解决了这个问题:
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
Run Code Online (Sandbox Code Playgroud)
注意+ after后面会消耗从名称到日期的所有空格.
实际上添加这个答案对我自己的记忆和帮助其他人一样多,因为这至少是我第二次谷歌主题:)
--show-email
到git blame -w
电子邮件聚合,因为有些人Name
在不同的计算机上使用不同的格式,有时两个同名的人在同一个git中工作.kcc*_*qzy 23
这是一个简短的单行程序,为所有作者生成统计数据.它比上面的Dan解决方案快得多,速度为/sf/answers/1429012581/(我的时间复杂度为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
Run Code Online (Sandbox Code Playgroud)
Sté*_*hon 21
@mmrobins @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
Run Code Online (Sandbox Code Playgroud)
你可以grep其他字符串,如author-mail,committer等.
也许首先export LC_ALL=C
(假设bash
)强制执行字节级处理(这也恰好可以从基于UTF-8的语言环境中大大加快grep).
Aar*_*onM 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
Run Code Online (Sandbox Code Playgroud)
Esk*_*ola 13
除了Charles Bailey的回答,您可能还想将-C
参数添加到命令中.否则,文件重命名计为大量添加和删除(尽管文件有行数),即使文件内容未被修改也是如此.
为了说明,这里是一个提交,在使用git log --oneline --shortstat
命令时,我的一个项目会移动大量文件:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
Run Code Online (Sandbox Code Playgroud)
这里使用git log --oneline --shortstat -C
检测文件副本和重命名的命令进行相同的提交:
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
Run Code Online (Sandbox Code Playgroud)
在我看来,后者提供了一个更真实的视图,了解一个人对项目的影响,因为重命名文件比从头开始编写文件要小得多.
Nev*_*vir 11
这是一个快速的ruby脚本,可以根据给定的日志查询来确定每个用户的影响.
例如,对于rubinius:
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
Run Code Online (Sandbox Code Playgroud)
剧本:
#!/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
Run Code Online (Sandbox Code Playgroud)
小智 11
你可以使用whodid(https://www.npmjs.com/package/whodid)
$ npm install whodid -g
$ cd your-project-dir
Run Code Online (Sandbox Code Playgroud)
和
$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week
Run Code Online (Sandbox Code Playgroud)
或者只是输入
$ whodid
Run Code Online (Sandbox Code Playgroud)
然后你可以看到这样的结果
Contribution state
=====================================================
score | author
-----------------------------------------------------
3059 | someguy <someguy@tensorflow.org>
585 | somelady <somelady@tensorflow.org>
212 | niceguy <nice@google.com>
173 | coolguy <coolgay@google.com>
=====================================================
Run Code Online (Sandbox Code Playgroud)
小智 8
这是最好的方法,它还可以让您清楚地了解所有用户提交的总数
git shortlog -s -n
Run Code Online (Sandbox Code Playgroud)
git-quick-stats
brew install git-quick-stats
git-quick-stats
只需输入列出的数字并按回车键,即可从此列表中选择您想要的选项。
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)
Run Code Online (Sandbox Code Playgroud)
我在上面提供了一个简短答案的修改,但它不足以满足我的需求.我需要能够在最终代码中对提交的行和行进行分类.我也希望按文件分解.此代码不会递归,它只会返回单个目录的结果,但如果有人想要更进一步,这是一个良好的开端.复制并粘贴到文件中并生成可执行文件或使用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};
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
239604 次 |
最近记录: |