Risposte:
L'output del comando seguente dovrebbe essere ragionevolmente facile da inviare allo script per sommare i totali:
git log --author="<authorname>" --oneline --shortstat
Ciò fornisce statistiche per tutti gli commit sull'attuale HEAD. Se vuoi sommare le statistiche in altri settori dovrai fornirle come argomenti git log
.
Per passare a uno script, rimuovere anche il formato "online" può essere fatto con un formato di registro vuoto e, come commentato da Jakub Narębski, --numstat
è un'altra alternativa. Genera statistiche per file anziché per riga ma è ancora più facile da analizzare.
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
invece di --shortstat
aggiungere statistiche un po 'più semplici.
git help log
mi dice che le prime sono le righe aggiunte, le seconde cancellate.
Questo fornisce alcune statistiche sull'autore, modificarle come richiesto.
Utilizzando 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 }' -
Utilizzando Awk su 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 }' -
Esiste un nuovo pacchetto su github che sembra elegante e usa bash come dipendenze (testato su Linux). È più adatto per l'uso diretto piuttosto che per gli script.
È git-quick-stats (link github) .
Copia git-quick-stats
in una cartella e aggiungi la cartella al percorso.
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
Uso:
git-quick-stats
gawk
per awk
farlo funzionare nel terminale OSX
git clone https://github.com/arzzen/git-quick-stats.git
Nel caso in cui qualcuno volesse vedere le statistiche per ogni utente nella propria base di codice, un paio dei miei colleghi hanno recentemente inventato questo orribile one-liner:
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";}'
(Ci vogliono alcuni minuti per eseguire il repository sul nostro repository, che ha circa 10-15k di commit.)
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Git fame https://github.com/oleander/git-fame-rb
è uno strumento utile per ottenere il conteggio di tutti gli autori contemporaneamente, inclusi il conteggio dei file di commit e modificati:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
Esiste anche la versione di Python su https://github.com/casperdcl/git-fame (menzionata da @fracz):
sudo apt-get install python-pip python-dev build-essential
pip install --user git-fame
cd /path/to/gitdir && git fame
Uscita campione:
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 |
+------------------------+--------+---------+-------+--------------------+
Ma attenzione: come menzionato da Jared nel commento, per farlo su un archivio molto grande ci vorranno ore. Non sono sicuro se ciò potrebbe essere migliorato, considerando che deve elaborare così tanti dati Git.
git fame --branch=dev --timeout=-1 --exclude=Pods/*
Ho trovato quanto segue utile per vedere chi aveva più righe che erano attualmente nella base di codice:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
Le altre risposte si sono concentrate principalmente sulle linee modificate nei commit, ma se i commit non sopravvivono e vengono sovrascritti, potrebbero semplicemente essere sfocati. L'incantesimo di cui sopra ti fa anche ordinare tutti i committer ordinati per linee anziché solo uno alla volta. Puoi aggiungere alcune opzioni a git blame (-C -M) per ottenere numeri migliori che tengano conto dello spostamento dei file e dello spostamento della linea tra i file, ma il comando potrebbe essere eseguito molto più a lungo se lo fai.
Inoltre, se stai cercando le righe modificate in tutti i commit per tutti i commit, il seguente piccolo script è utile:
/^.*\((.*?)\s[\d]{4}/
dovrebbe essere /^.*?\((.*?)\s[\d]{4}/
per impedire l'abbinamento delle parentesi nella fonte come autore.
Per contare il numero di commit di un determinato autore (o di tutti gli autori) su un determinato ramo puoi usare git-shortlog ; vedere soprattutto le sue --numbered
e le --summary
opzioni, ad es. quando eseguito sul repository 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
è qui in questo esempio per rendere deterministico l'output: sarà lo stesso indipendentemente da quando hai clonato e / o recuperato dal repository git.
v1.6.4
mi dà:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
oppure, se preferisci non includere le fusionigit shortlog -sne --no-merges
-s
è --summary
, -n
è --numbered
e [nuovo] -e
deve --email
mostrare le e-mail degli autori (e contare separatamente lo stesso autore con un indirizzo e-mail diverso, tenendo conto delle .mailmap
correzioni). Buona telefonata --no-merges
.
Dopo aver esaminato la risposta di Alex e Gerty3000 , ho cercato di abbreviare il one-liner:
Fondamentalmente, usando git log numstat e non tenere traccia del numero di file modificati.
Git versione 2.1.0 su 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
Esempio:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
La risposta di AaronM che utilizza la shell one-liner è buona, ma in realtà c'è ancora un altro bug, in cui gli spazi danneggeranno i nomi degli utenti se ci sono diverse quantità di spazi bianchi tra il nome dell'utente e la data. I nomi utente danneggiati forniranno più righe per il conteggio degli utenti e dovrai sommarli da soli.
Questa piccola modifica ha risolto il problema per me:
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
Notare il segno + dopo che consumerà tutti gli spazi bianchi dal nome alla data.
In realtà aggiungendo questa risposta tanto per il mio ricordo quanto per aiutare chiunque altro, poiché questa è almeno la seconda volta che google l'argomento :)
--show-email
a git blame -w
per aggregare via e-mail, poiché alcune persone usano Name
formati diversi su computer diversi, e talvolta due persone con lo stesso nome lavorano nello stesso git.unsupported file type
ma per il resto sembra funzionare anche con loro (li salta).
Ecco un breve one-liner che produce statistiche per tutti gli autori. È molto più veloce della soluzione di Dan sopra su https://stackoverflow.com/a/20414465/1102119 (la mia ha una complessità temporale O (N) invece di O (NM) dove N è il numero di commit e M il numero di autori ).
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
, altrimenti le persone che firmano pgp i loro commit non verranno conteggiate.
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"
. (Nota che sono su Windows; potrebbe essere necessario utilizzare diversi tipi di virgolette)
@mmrobins @AaronM @ErikZ @JamesMishra ha fornito varianti che hanno tutti un problema in comune: chiedono a git di produrre una miscela di informazioni non destinate al consumo di script, inclusi i contenuti di linea dal repository sulla stessa linea, quindi abbinano il pasticcio con un regexp .
Questo è un problema quando alcune righe non sono valide per il testo UTF-8 e anche quando alcune righe corrispondono al regexp (questo è successo qui).
Ecco una riga modificata che non presenta questi problemi. Richiede a git di inviare i dati in modo pulito su linee separate, il che semplifica il filtraggio di ciò che vogliamo in modo affidabile:
git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n
È possibile eseguire il grep per altre stringhe, come la posta autore, il committer, ecc.
Forse prima fai export LC_ALL=C
(supponendo bash
) per forzare l'elaborazione a livello di byte (questo succede anche per accelerare enormemente grep dalle localizzazioni basate su UTF-8).
Una soluzione è stata data con ruby nel mezzo, perl essendo un po 'più disponibile di default qui è un'alternativa che utilizza perl per le righe correnti dell'autore.
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
Oltre alla risposta di Charles Bailey , potresti voler aggiungere il -C
parametro ai comandi. In caso contrario, i nomi dei file vengono conteggiati come molte aggiunte e rimozioni (quante sono le righe del file), anche se il contenuto del file non è stato modificato.
Per illustrare, ecco un commit con molti file che vengono spostati da uno dei miei progetti, quando si utilizza il git log --oneline --shortstat
comando:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
E qui lo stesso commit utilizzando il git log --oneline --shortstat -C
comando che rileva le copie e le ridenominazioni dei file:
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
A mio avviso, quest'ultimo offre una visione più realistica dell'impatto che una persona ha avuto sul progetto, perché rinominare un file è un'operazione molto più piccola rispetto alla scrittura del file da zero.
puoi usare whodid ( https://www.npmjs.com/package/whodid )
$ npm install whodid -g
$ cd your-project-dir
e
$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week
o semplicemente digitare
$ whodid
allora puoi vedere il risultato in questo modo
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
doveva venire prima del nome del pacchetto, su macOS
. Sto semplicemente cercando di aiutare.
Ecco uno script ruby rapido che corregge l'impatto per utente rispetto a una determinata query di registro.
Ad esempio, per rubinius :
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
il copione:
#!/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
Ho fornito una modifica di una breve risposta sopra, ma non era sufficiente per le mie esigenze. Avevo bisogno di essere in grado di classificare sia le righe impegnate sia le righe nel codice finale. Volevo anche una suddivisione per file. Questo codice non viene utilizzato, restituirà solo i risultati per una singola directory, ma è un buon inizio se qualcuno volesse andare oltre. Copia e incolla in un file e rendilo eseguibile o eseguilo con 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};
}
Per gli utenti di Windows è possibile utilizzare il seguente script batch che conta le righe aggiunte / rimosse per l'autore specificato
@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
Basta scegliere quale opzione si desidera da questo elenco digitando il numero elencato e premendo invio.
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)
Questo script qui lo farà. Inseriscilo in authorship.sh, chmod + x it e sei pronto.
#!/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 ":"
Salva i tuoi log in file usando:
git log --author="<authorname>" --oneline --shortstat > logs.txt
Per gli amanti di 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')
Le tue uscite sarebbero come:
225 files changed
6751 insertions
1379 deletions
Vuoi colpa di Git .
C'è un'opzione --show-stats per stampare alcune, beh, statistiche.
blame
, ma in realtà non ha dato le statistiche che pensavo fossero necessarie all'OP?
La domanda richiedeva informazioni su un autore specifico , ma molte delle risposte erano soluzioni che restituivano elenchi classificati di autori in base alle loro linee di codice modificate.
Era quello che cercavo, ma le soluzioni esistenti non erano del tutto perfette. Nell'interesse delle persone che potrebbero trovare questa domanda tramite Google, ho apportato alcuni miglioramenti e li ho trasformati in uno script di shell, che visualizzo di seguito. Una annotata (che continuerò a mantenere) può essere trovata sul mio Github .
Non ci sono alcun dipendenze su entrambi Perl o Ruby. Inoltre, nel conteggio dei cambi di linea vengono presi in considerazione spazi bianchi, rinominazioni e movimenti di linea. Basta inserirlo in un file e passare il repository Git come primo parametro.
#!/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
Lo strumento migliore che ho identificato finora è gitinspector. Fornisce il rapporto impostato per utente, per settimana ecc. È possibile installare come di seguito con npm
npm install -g gitinspector
I collegamenti per ottenere maggiori dettagli
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Documentation
https://github.com/ejwa/gitinspector
comandi di esempio sono
gitinspector -lmrTw
gitinspector --since=1-1-2017 etc
Ho scritto questo script Perl per compiere quel compito.
#!/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;
}
L'ho chiamato git-line-changes-by-author
e inserito /usr/local/bin
. Poiché è stato salvato nel mio percorso, posso inviare il comando git line-changes-by-author --before 2018-12-31 --after 2020-01-01
per ottenere il rapporto per l'anno 2019. Come esempio. E se dovessi sbagliare, il nome git suggerirà l'ortografia corretta.
Potresti voler regolare il _get_repo_slug
sottotitolo per includere solo l'ultima porzione di remote.origin.url
come i miei repository vengono salvati come project/repo
e il tuo potrebbe non esserlo.
git://git.lwn.net/gitdm.git
.