Yanıtlar:
Toplamları toplamak için aşağıdaki komutun çıktısının komut dosyasına gönderilmesi oldukça kolay olmalıdır:
git log --author="<authorname>" --oneline --shortstat
Bu, geçerli HEAD'deki tüm taahhütlerin istatistiklerini verir. Diğer branşlara istatistik eklemek istiyorsanız, bunları bağımsız değişken olarak sağlamanız gerekir git log
.
Bir betiğe geçmek için, "oneline" biçimini bile kaldırmak boş bir günlük biçimiyle yapılabilir ve Jakub Narębski tarafından yorumlandığı gibi --numstat
başka bir alternatiftir. Satır başına istatistiklerden ziyade dosya başına oluşturur, ancak ayrıştırılması daha da kolaydır.
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
yerine kullanabilirsiniz --shortstat
.
git help log
bana birincisinin satır eklendiğini, ikinci satırların silindiğini söyledi.
Bu, yazar hakkında bazı istatistikler verir, gerektiği gibi değiştirin.
Gawk kullanma:
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'te Awk kullanma:
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 }' -
Github'da kaygan görünen ve bağımlılık olarak bash kullanan yeni bir paket var (linux üzerinde test edildi). Komut dosyalarından ziyade doğrudan kullanım için daha uygundur.
It adlı git-hızlı-istatistik (github bağlantı) .
Kopya git-quick-stats
bir klasöre ve yoluna klasör eklemek.
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
Kullanımı:
git-quick-stats
gawk
için awk
o OSX terminalde çalışması için
git clone https://github.com/arzzen/git-quick-stats.git
Herkesin kod tabanındaki her kullanıcının istatistiklerini görmek istemesi durumunda, birkaç iş arkadaşım kısa bir süre önce bu korkunç tek astarla geldi:
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";}'
(Yaklaşık 10-15 bin komisyonu olan repolarımızla uğraşmak birkaç dakika sürüyor.)
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Git şöhret https://github.com/oleander/git-fame-rb
taahhüt ve değiştirilmiş dosya sayısı da dahil olmak üzere tüm yazarların sayısını bir kerede almak için güzel bir araçtır:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
Https://github.com/casperdcl/git-fame adresinde (@fracz tarafından belirtilen) Python sürümü de vardır :
sudo apt-get install python-pip python-dev build-essential
pip install --user git-fame
cd /path/to/gitdir && git fame
Örnek çıktı:
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 |
+------------------------+--------+---------+-------+--------------------+
Ancak uyarılmalıdır: yorumda Jared tarafından belirtildiği gibi, çok büyük bir depoda yapılması saatler alacaktır. Git verilerini çok fazla işlemesi gerektiğini düşünerek bunun geliştirilip geliştirilemeyeceğinden emin değilim.
git fame --branch=dev --timeout=-1 --exclude=Pods/*
Ben şu anda kod üssünde kim en çok satır görmek için yararlı buldum:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
Diğer cevaplar çoğunlukla taahhütlerde değişen satırlara odaklanmıştır, ancak taahhütler hayatta kalmaz ve üzerine yazılırsa, sadece çalkalanmış olabilir. Yukarıdaki büyütme ayrıca tüm komisyoncuları teker teker değil, satırlara göre sıralar. Dosyalar arasında dosya hareketini ve satır hareketini dikkate alan daha iyi sayılar elde etmek için git blame (-C -M) öğesine bazı seçenekler ekleyebilirsiniz, ancak bunu yaparsanız komut çok daha uzun sürebilir.
Ayrıca, tüm komisyoncular için tüm taahhütlerde değiştirilen satırlar arıyorsanız, aşağıdaki küçük komut dosyası yararlıdır:
/^.*\((.*?)\s[\d]{4}/
/^.*?\((.*?)\s[\d]{4}/
kaynak olarak parantezin yazar olarak eşleşmesini önlemek olmalıdır .
Belirli bir daldaki belirli bir yazarın (veya tüm yazarların) taahhüt sayısını saymak için git-shortlog'u kullanabilirsiniz ; özellikle onun --numbered
ve --summary
seçeneklerine bakın, örneğin git deposunda çalıştırıldığında:
$ 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
Bu örnekte çıktıyı deterministik yapmak için burada olduğuna dikkat edin: git deposundan ne zaman klonladıysanız ve / veya aldığınız önemli değil.
v1.6.4
bana verir:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
veya birleştirme eklemek istemiyorsanızgit shortlog -sne --no-merges
-s
ise --summary
, -n
olduğu --numbered
ve [yeni] -e
olduğu --email
(hesap içine alarak, ayrı ayrı farklı e-posta adresi ile aynı yazar saymak yazarların e-postaları göstermek için .mailmap
düzeltmeler). Hakkında iyi bir çağrı --no-merges
.
Alex ve Gerty3000'in cevabına baktıktan sonra , tek astarı kısaltmaya çalıştım:
Temelde, git günlüğü numstat kullanarak ve değil sayısının takip dosyaları değişti.
Mac OSX'te Git sürüm 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
Misal:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
Cevap den AaronM kabuk havasında kullanarak iyidir, ama aslında, bir başka hata olduğu yerde boşluk olacak bozuk kullanıcı adı ve tarihi arasındaki boşluklardan farklı miktarlarda varsa kullanıcı adları. Bozuk kullanıcı adları, kullanıcı sayıları için birden çok satır verir ve bunları kendiniz toplamanız gerekir.
Bu küçük değişiklik benim için sorunu düzeltti:
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
Addan tarihe kadar tüm boşlukları tüketecek + after \ s öğesine dikkat edin.
Aslında bu yanıtı başkalarına yardım etmem kadar kendi hatırlamam için ekliyorum, çünkü bu en azından konuyu Google'a ikinci kez taktığımda :)
--show-email
için git blame -w
bazı insanlar farklı kullandıkları için, bunun yerine e-postayı toplamak için Name
farklı bilgisayarlarda biçimleri ve aynı adla bazen iki kişi aynı GIT'de çalışıyoruz.unsupported file type
ancak aksi takdirde onlarla bile iyi çalışır gibi görünüyor (onları atlıyor).
İşte tüm yazarlar için istatistik üreten kısa bir satırlık. Dan'ın https://stackoverflow.com/a/20414465/1102119 adresindeki yukarıdaki çözümünden çok daha hızlı (benim N'nin taahhüt sayısı olduğu O (NM) yerine O (N) zaman karmaşıklığı ve M yazar sayısı ).
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
aksi takdirde kaydedilmesini pgp-imzalamak insanlar sayılır almak için gidiş değildir.
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"
. (Not Windows'dayım; farklı türde alıntılar kullanmanız gerekebilir)
@mmrobins @AaronM @ErikZ @JamesMishra, hepsinin ortak bir sorunu olan varyantlar sağladı: git'ten, aynı satırdaki depodan satır içeriği de dahil olmak üzere komut dosyası tüketimi için tasarlanmamış bir bilgi karışımı üretmesini ve ardından karışıklığı bir regexp ile eşleştirmelerini istiyorlar. .
Bu, bazı satırlar geçerli UTF-8 metni olmadığında ve bazı satırlar normal ifadeyle eşleştiğinde (bu burada oldu) bir sorundur.
İşte bu sorunları olmayan değiştirilmiş bir satır. Git'in ayrı satırlarda temiz bir şekilde çıktı vermesini ister, bu da istediğimizi sağlam bir şekilde filtrelemeyi kolaylaştırır:
git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n
Yazar-posta, iletici, vb. Diğer dizeler için grep yapabilirsiniz.
Belki de ilk olarak bayt seviyesi işlemeyi zorlamak export LC_ALL=C
(varsayalım bash
) (bu aynı zamanda UTF-8 tabanlı yerel ayarlardan büyük ölçüde grep'i hızlandırmak için de geçerlidir).
Ortada yakut ile bir çözüm verildi, burada perl varsayılan olarak biraz daha kullanılabilir, mevcut satırlar için yazar tarafından perl kullanan bir alternatif.
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
Charles Bailey'nin cevabına ek olarak , -C
parametreyi komutlara eklemek isteyebilirsiniz . Aksi takdirde, dosya içeriği değiştirilmemiş olsa bile, dosya adları çok fazla ekleme ve kaldırma (dosyada satır olduğu kadar) sayılır.
Örnek olarak, komutu kullanırken, projelerimden birinden çok sayıda dosyanın taşınmasıyla ilgili bir taahhütgit log --oneline --shortstat
:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
Ve burada aynı taahhüt, git log --oneline --shortstat -C
dosya kopyalarını ve yeniden adlarını tespit eden komutu kullanarak :
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
Kanımca ikincisi, bir kişinin proje üzerinde ne kadar etkisi olduğuna dair daha gerçekçi bir görünüm verir, çünkü bir dosyayı yeniden adlandırmak dosyayı sıfırdan yazmaktan çok daha küçük bir işlemdir.
whodid kullanabilirsiniz ( https://www.npmjs.com/package/whodid )
$ npm install whodid -g
$ cd your-project-dir
ve
$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week
veya sadece yazın
$ whodid
o zaman sonucu böyle görebilirsiniz
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
paket adından önce gelmek zorundaydım macOS
. Sadece yardım etmeye çalışıyorum.
Aşağıda, belirli bir günlük sorgusuna karşı kullanıcı başına etkiyi artıran hızlı bir yakut komut dosyası verilmiştir.
Örneğin, rubinius için :
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
senaryo:
#!/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
Yukarıda kısa bir cevapta bir değişiklik sağladım, ancak ihtiyaçlarım için yeterli değildi. Son koddaki hem taahhütlü satırları hem de satırları kategorize edebilmem gerekiyordu. Ayrıca dosyaya göre bir döküm istedim. Bu kod geri çekilmez, yalnızca tek bir dizin için sonuçları döndürür, ancak birileri daha ileri gitmek isterse iyi bir başlangıçtır. Bir dosyaya kopyalayıp yapıştırın ve yürütülebilir yapın veya Perl ile çalıştırın.
#!/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};
}
Windows kullanıcıları için, belirtilen yazar için eklenen / kaldırılan satırları sayan aşağıdaki toplu komut dosyasını kullanabilirsiniz
@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
Listelenen numarayı yazıp enter tuşuna basarak bu listeden istediğiniz seçeneği seçin.
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)
Buradaki komut dosyası bunu yapacak. Bunu authorship'e koyun. Sh, chmod + x ve hepsi hazır.
#!/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 ":"
Günlüklerinizi aşağıdakileri kullanarak dosyaya kaydedin:
git log --author="<authorname>" --oneline --shortstat > logs.txt
Python sevenler için:
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')
Çıktılarınız şöyle olacaktır:
225 files changed
6751 insertions
1379 deletions
Soru , belirli bir yazar hakkında bilgi istedi , ancak cevapların çoğu, kod satırlarına göre sıralanmış yazar listelerini döndüren çözümlerdi.
Aradığım şey buydu, ancak mevcut çözümler tam olarak mükemmel değildi. Bu soruyu Google aracılığıyla bulabilecek kişilerin yararına, bunlarda bazı iyileştirmeler yaptım ve aşağıda görüntülediğim bir kabuk komut dosyasına dönüştürdüm. Ek açıklamalı olanı (korumaya devam edeceğim) Github'ımda bulunabilir .
Orada hiçbir Perl veya Ruby ya bağımlılıklan. Ayrıca satır değiştirme sayısında boşluk, yeniden adlandırma ve satır hareketleri dikkate alınır. Bunu bir dosyaya koyun ve Git deponuzu ilk parametre olarak iletin.
#!/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
Tanımladığım en iyi araç gitinspector. Kullanıcı başına haftalık rapor vb. Verir. Npm ile aşağıdaki gibi kurabilirsiniz
npm install -g gitinspector
Daha ayrıntılı bilgi için bağlantılar
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Documentation
https://github.com/ejwa/gitinspector
örnek komutlar
gitinspector -lmrTw
gitinspector --since=1-1-2017 etc
Bu görevi yerine getirmek için bu Perl betiğini yazdım.
#!/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;
}
Adını verdim git-line-changes-by-author
ve içine koydum /usr/local/bin
. Yoluma kaydedildiği git line-changes-by-author --before 2018-12-31 --after 2020-01-01
için, 2019 yılı için raporu alma komutunu verebilirim. Örnek olarak. Ve ben yanlış yazacak olsaydı git adı doğru yazım önerecektir.
Depolarım olarak kaydedildiği ve olmayabileceği için _get_repo_slug
alt öğeyi yalnızca son bölümünü içerecek şekilde ayarlamak isteyebilirsiniz.remote.origin.url
project/repo
git://git.lwn.net/gitdm.git
.