Câu trả lời:
Đầu ra của lệnh sau phải dễ dàng gửi đến tập lệnh để thêm tổng số:
git log --author="<authorname>" --oneline --shortstat
Điều này cung cấp số liệu thống kê cho tất cả các cam kết trên ĐẦU hiện tại. Nếu bạn muốn thêm số liệu thống kê trong các nhánh khác, bạn sẽ phải cung cấp chúng làm đối số git log
.
Để chuyển đến một tập lệnh, loại bỏ ngay cả định dạng "trực tuyến" có thể được thực hiện với định dạng nhật ký trống và như nhận xét của Jakub Narębski, --numstat
là một cách khác. Nó tạo ra mỗi tệp chứ không phải thống kê trên mỗi dòng nhưng thậm chí còn dễ phân tích hơn.
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
thay vì --shortstat
nếu bạn muốn thêm số liệu thống kê dễ dàng hơn một chút.
git help log
cho tôi biết rằng dòng đầu tiên được thêm vào, dòng thứ hai bị xóa.
Điều này cung cấp một số thống kê về tác giả, sửa đổi theo yêu cầu.
Sử dụng 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 }' -
Sử dụng Awk trên Mac OSX:
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 }' -
Có một gói mới trên github trông bóng bẩy và sử dụng bash làm phụ thuộc (được thử nghiệm trên linux). Nó phù hợp hơn cho việc sử dụng trực tiếp hơn là các tập lệnh.
Đó là git-quick-stats (liên kết github) .
Sao chép git-quick-stats
vào một thư mục và thêm thư mục vào đường dẫn.
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
Sử dụng:
git-quick-stats
gawk
để awk
làm cho nó hoạt động tại nhà ga OSX
git clone https://github.com/arzzen/git-quick-stats.git
Trong trường hợp bất cứ ai muốn xem số liệu thống kê cho mọi người dùng trong cơ sở mã của họ, một vài đồng nghiệp của tôi gần đây đã đưa ra một lớp lót khủng khiếp này:
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";}'
(Mất vài phút để truy cập vào repo của chúng tôi, có khoảng 10-15k cam kết.)
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Danh tiếng Git https://github.com/oleander/git-fame-rb
là một công cụ tuyệt vời để lấy số lượng cho tất cả các tác giả cùng một lúc, bao gồm số lượng tệp cam kết và sửa đổi:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
Ngoài ra còn có phiên bản Python tại https://github.com/casperdcl/git-fame (được đề cập bởi @fracz):
sudo apt-get install python-pip python-dev build-essential
pip install --user git-fame
cd /path/to/gitdir && git fame
Đầu ra mẫu:
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 |
+------------------------+--------+---------+-------+--------------------+
Nhưng hãy cảnh báo: như Jared đã đề cập trong bình luận, thực hiện nó trên một kho lưu trữ rất lớn sẽ mất nhiều giờ. Không chắc chắn nếu điều đó có thể được cải thiện, xem xét rằng nó phải xử lý rất nhiều dữ liệu Git.
git fame --branch=dev --timeout=-1 --exclude=Pods/*
Tôi thấy những điều sau đây là hữu ích để xem ai có nhiều dòng nhất trong cơ sở mã:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
Các câu trả lời khác chủ yếu tập trung vào các dòng thay đổi trong các cam kết, nhưng nếu các cam kết không tồn tại và bị ghi đè, chúng có thể đã bị đảo lộn. Câu thần chú trên cũng giúp bạn có tất cả các ủy viên được sắp xếp theo dòng thay vì chỉ một lần. Bạn có thể thêm một số tùy chọn để git đổ lỗi (-C -M) để có được một số số tốt hơn giúp di chuyển tệp và chuyển động dòng giữa các tệp vào tài khoản, nhưng lệnh có thể chạy lâu hơn nếu bạn làm như vậy.
Ngoài ra, nếu bạn đang tìm kiếm các dòng thay đổi trong tất cả các cam kết cho tất cả các ủy viên, tập lệnh nhỏ theo sau là hữu ích:
/^.*\((.*?)\s[\d]{4}/
nên /^.*?\((.*?)\s[\d]{4}/
để ngăn chặn dấu ngoặc đơn trong nguồn với tư cách là một tác giả.
Để đếm số lượng cam kết của một tác giả nhất định (hoặc tất cả các tác giả) trên một nhánh nhất định, bạn có thể sử dụng git-shortlog ; đặc biệt là xem các tùy chọn --numbered
và --summary
tùy chọn của nó , ví dụ như khi chạy trên kho 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
v1.6.4
ở đây trong ví dụ này để xác định đầu ra: nó sẽ giống nhau bất kể khi nào bạn sao chép và / hoặc tìm nạp từ kho git.
v1.6.4
cho tôi:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
hoặc, nếu bạn không bao gồm các sự hợp nhấtgit shortlog -sne --no-merges
-s
is --summary
, -n
is --numbered
và [new] -e
là --email
hiển thị email của các tác giả (và tính riêng biệt cùng một tác giả với địa chỉ email khác nhau, có tính đến .mailmap
chỉnh sửa tài khoản ). Gọi tốt về --no-merges
.
Sau khi nhìn vào Alex's và Gerty3000 câu trả lời , tôi đã cố gắng rút ngắn phần một:
Về cơ bản, sử dụng git log numstat và không theo dõi số lượng tệp đã thay đổi.
Phiên bản Git 2.1.0 trên Mac OSX:
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
Thí dụ:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
Câu trả lời từ AaronM sử dụng shell one-liner là tốt, nhưng thực tế, vẫn còn một lỗi khác, trong đó khoảng trắng sẽ làm hỏng tên người dùng nếu có số lượng khoảng trắng khác nhau giữa tên người dùng và ngày. Tên người dùng bị hỏng sẽ cung cấp nhiều hàng cho số lượng người dùng và bạn phải tự tổng hợp chúng.
Thay đổi nhỏ này đã khắc phục sự cố cho tôi:
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
Lưu ý + sau \ s sẽ tiêu thụ tất cả các khoảng trắng từ tên đến ngày.
Trên thực tế, việc thêm câu trả lời này cho sự ghi nhớ của riêng tôi cũng như giúp đỡ bất kỳ ai khác, vì đây ít nhất là lần thứ hai tôi google chủ đề :)
--show-email
để git blame -w
tổng hợp trên email, vì một số người sử dụng các Name
định dạng khác nhau trên các máy tính khác nhau và đôi khi hai người có cùng tên đang làm việc trong cùng một git.unsupported file type
nhưng nếu không thì nó có vẻ hoạt động tốt ngay cả với chúng (nó bỏ qua chúng).
Đây là một lớp lót ngắn tạo ra số liệu thống kê cho tất cả các tác giả. Nó nhanh hơn nhiều so với giải pháp của Dan ở trên tại https://stackoverflow.com/a/20414465/1102119 (của tôi có độ phức tạp thời gian O (N) thay vì O (NM) trong đó N là số lượng cam kết và M là số lượng tác giả ).
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
--no-show-signature
, nếu không, những người đăng ký cam kết của họ sẽ không được tính.
count-lines = "!f() { 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; }; f"
. (Lưu ý tôi đang dùng Windows; bạn có thể cần sử dụng các loại trích dẫn khác nhau)
@mmrobins @AaronM @ErikZ @JamesMishra cung cấp các biến thể mà tất cả đều có vấn đề chung: họ yêu cầu git tạo ra một hỗn hợp thông tin không dành cho tiêu thụ tập lệnh, bao gồm nội dung dòng từ kho lưu trữ trên cùng một dòng, sau đó khớp với mớ hỗn độn với regrec .
Đây là một vấn đề khi một số dòng không hợp lệ văn bản UTF-8 và cả khi một số dòng xảy ra khớp với biểu thức chính quy (điều này đã xảy ra ở đây).
Đây là một dòng sửa đổi không có những vấn đề này. Nó yêu cầu git xuất dữ liệu sạch trên các dòng riêng biệt, giúp dễ dàng lọc những gì chúng ta muốn một cách mạnh mẽ:
git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n
Bạn có thể grep cho các chuỗi khác, như tác giả-mail, committer, v.v.
Có lẽ trước tiên phải export LC_ALL=C
(giả sử bash
) để buộc xử lý mức byte (điều này cũng xảy ra để tăng tốc grep rất nhiều từ các địa phương dựa trên UTF-8).
Một giải pháp đã được đưa ra với ruby ở giữa, perl có sẵn hơn một chút theo mặc định ở đây là một thay thế sử dụng perl cho các dòng hiện tại của tác giả.
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
Ngoài câu trả lời của Charles Bailey , bạn có thể muốn thêm -C
tham số vào các lệnh. Mặt khác, đổi tên tệp được tính là rất nhiều bổ sung và loại bỏ (nhiều như tệp có dòng), ngay cả khi nội dung tệp không được sửa đổi.
Để minh họa, đây là một cam kết với rất nhiều tệp được di chuyển xung quanh từ một trong các dự án của tôi, khi sử dụng git log --oneline --shortstat
lệnh:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
Và ở đây, cùng một cam kết sử dụng git log --oneline --shortstat -C
lệnh phát hiện các bản sao và đổi tên tệp:
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
Theo ý kiến của tôi, cái sau đưa ra một cái nhìn thực tế hơn về mức độ ảnh hưởng của một người đối với dự án, bởi vì đổi tên một tệp là một hoạt động nhỏ hơn nhiều so với việc viết tệp từ đầu.
bạn có thể sử dụng whodid ( https://www.npmjs.com/package/whodid )
$ npm install whodid -g
$ cd your-project-dir
và
$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week
hoặc chỉ gõ
$ whodid
sau đó bạn có thể thấy kết quả như thế này
Contribution state
=====================================================
score | author
-----------------------------------------------------
3059 | someguy <someguy@tensorflow.org>
585 | somelady <somelady@tensorflow.org>
212 | niceguy <nice@google.com>
173 | coolguy <coolgay@google.com>
=====================================================
-g
đã phải đến trước tên gói, trên macOS
. Đơn giản chỉ cần cố gắng để giúp đỡ.
Đây là một tập lệnh ruby nhanh giúp điều chỉnh tác động của mỗi người dùng đối với một truy vấn nhật ký đã cho.
Ví dụ: đối với rubinius :
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
kịch bản:
#!/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
Tôi đã cung cấp một sửa đổi của một câu trả lời ngắn ở trên, nhưng nó không đủ cho nhu cầu của tôi. Tôi cần để có thể phân loại cả dòng và dòng cam kết trong mã cuối cùng. Tôi cũng muốn chia nhỏ theo tập tin. Mã này không lặp lại, nó sẽ chỉ trả về kết quả cho một thư mục duy nhất, nhưng đó là một khởi đầu tốt nếu ai đó muốn đi xa hơn. Sao chép và dán vào một tệp và thực hiện hoặc chạy nó với 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};
}
Đối với người dùng windows, bạn có thể sử dụng tập lệnh bó sau để đếm các dòng được thêm / xóa cho tác giả được chỉ định
@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
git-quick-stats
brew install git-quick-stats
git-quick-stats
Chỉ cần chọn tùy chọn bạn muốn từ danh sách này bằng cách nhập số được liệt kê và nhấn 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)
Kịch bản này ở đây sẽ làm điều đó. Đặt nó vào quyền tác giả.sh, chmod + x nó và bạn đã hoàn tất.
#!/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 ":"
Lưu nhật ký của bạn vào tệp bằng cách sử dụng:
git log --author="<authorname>" --oneline --shortstat > logs.txt
Dành cho những người yêu thích 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')
Kết quả đầu ra của bạn sẽ như sau:
225 files changed
6751 insertions
1379 deletions
Bạn muốn Git đổ lỗi .
Có một tùy chọn --show-stats để in một số, tốt, thống kê.
blame
, nhưng nó không thực sự đưa ra số liệu thống kê mà tôi nghĩ OP sẽ cần?
Câu hỏi yêu cầu thông tin về một cụ thể tác giả , nhưng nhiều câu trả lời là các giải pháp trả về danh sách xếp hạng của các tác giả dựa trên các dòng mã của họ đã thay đổi.
Đây là những gì tôi đang tìm kiếm, nhưng các giải pháp hiện tại không hoàn hảo. Vì lợi ích của những người có thể tìm thấy câu hỏi này thông qua Google, tôi đã thực hiện một số cải tiến về chúng và biến chúng thành tập lệnh shell, mà tôi hiển thị bên dưới. Một chú thích (mà tôi sẽ tiếp tục duy trì) có thể được tìm thấy trên Github của tôi .
Không có sự phụ thuộc vào Perl hoặc Ruby. Hơn nữa, khoảng trắng, đổi tên và chuyển động của dòng được tính đến trong số lượng thay đổi dòng. Chỉ cần đặt nó vào một tệp và vượt qua kho Git của bạn làm tham số đầu tiên.
#!/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
Công cụ tốt nhất cho đến nay tôi xác định là gitinspector. Nó cung cấp báo cáo được thiết lập cho mỗi người dùng, mỗi tuần, v.v. Bạn có thể cài đặt như bên dưới với npm
cài đặt npm -g gitinspector
Các liên kết để có thêm thông tin chi tiết
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Documentation
https://github.com/ejwa/gitinspector
các lệnh ví dụ là
gitinspector -lmrTw
gitinspector --since=1-1-2017 etc
Tôi đã viết kịch bản Perl này để hoàn thành nhiệm vụ đó.
#!/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;
}
Tôi đặt tên cho nó git-line-changes-by-author
và đưa vào /usr/local/bin
. Vì nó được lưu trong đường dẫn của tôi, tôi có thể ra lệnh git line-changes-by-author --before 2018-12-31 --after 2020-01-01
để nhận báo cáo cho năm 2019. Làm ví dụ Và nếu tôi viết sai chính tả, tên git sẽ gợi ý cách viết đúng.
Bạn có thể muốn điều chỉnh _get_repo_slug
phụ để chỉ bao gồm phần cuối cùng vì các remote.origin.url
repos của tôi được lưu dưới dạng project/repo
và có thể không.
git://git.lwn.net/gitdm.git
.