Respostas:
A saída do comando a seguir deve ser razoavelmente fácil de enviar ao script para adicionar os totais:
git log --author="<authorname>" --oneline --shortstat
Isso fornece estatísticas para todos os commits no HEAD atual. Se você quiser adicionar estatísticas em outras ramificações, precisará fornecê-las como argumentos git log
.
Para passar para um script, remover até o formato "on-line" pode ser feito com um formato de log vazio e, como comentado por Jakub Narębski, --numstat
é outra alternativa. Ele gera estatísticas por arquivo em vez de estatísticas por linha, mas é ainda mais fácil de analisar.
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
vez de, --shortstat
se quiser adicionar estatísticas um pouco mais fácil.
git help log
diz que as primeiras são linhas adicionadas e as segundas excluídas.
Isso fornece algumas estatísticas sobre o autor, modifique conforme necessário.
Usando o 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 }' -
Usando o Awk no 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 }' -
Existe um novo pacote no github que parece liso e usa o bash como dependências (testado no linux). É mais adequado para uso direto, em vez de scripts.
É git-quick-stats (link do github) .
cópia de git-quick-stats
para uma pasta e adicione a pasta ao caminho.
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
para awk
fazê-lo funcionar no terminal OSX
git clone https://github.com/arzzen/git-quick-stats.git
Caso alguém queira ver as estatísticas de todos os usuários em sua base de código, alguns de meus colegas de trabalho recentemente criaram essa horrível frase:
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";}'
(Demora alguns minutos para analisar nosso repo, que tem cerca de 10 a 15 mil confirmações.)
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Git fame https://github.com/oleander/git-fame-rb
é uma boa ferramenta para obter a contagem de todos os autores de uma só vez, incluindo a contagem de arquivos modificados e confirmados:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
Também há a versão do Python em https://github.com/casperdcl/git-fame (mencionada por @fracz):
sudo apt-get install python-pip python-dev build-essential
pip install --user git-fame
cd /path/to/gitdir && git fame
Saída de amostra:
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 |
+------------------------+--------+---------+-------+--------------------+
Mas esteja avisado: como mencionado por Jared no comentário, fazê-lo em um repositório muito grande levará horas. Não tenho certeza se isso pode ser melhorado, considerando que ele deve processar tantos dados do Git.
git fame --branch=dev --timeout=-1 --exclude=Pods/*
Eu achei o seguinte útil para ver quem tinha mais linhas que estavam atualmente na base de código:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
As outras respostas se concentraram principalmente nas linhas alteradas nos commits, mas se os commits não sobreviverem e forem sobrescritos, eles podem ter sido apenas rotativos. O encantamento acima também fornece a todos os committers classificados por linhas, em vez de apenas um de cada vez. Você pode adicionar algumas opções para culpar git (-C -M) para obter números melhores que consideram a movimentação de arquivos e a linha entre arquivos, mas o comando pode demorar muito mais se você o fizer.
Além disso, se você estiver procurando linhas alteradas em todas as confirmações para todos os confirmadores, o pequeno script a seguir é útil:
/^.*\((.*?)\s[\d]{4}/
deve ser /^.*?\((.*?)\s[\d]{4}/
para evitar parênteses correspondentes na fonte como autor.
Para contar o número de confirmações de um determinado autor (ou todos os autores) em um determinado ramo, você pode usar o git-shortlog ; veja especialmente its --numbered
e --summary
options, por exemplo, quando executado no repositório 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
está aqui neste exemplo para tornar a saída determinística: será o mesmo, não importa quando você clonou e / ou buscou no repositório git.
v1.6.4
me dá:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
ou, se você preferir não incluir mesclagensgit shortlog -sne --no-merges
-s
é --summary
, -n
é --numbered
e [novo] -e
é --email
para mostrar emails de autores (e contar separadamente o mesmo autor com endereço de email diferente, levando em consideração as .mailmap
correções). Boa ligação --no-merges
.
Depois de olhar para a resposta de Alex e Gerty3000 , tentei encurtar a frase :
Basicamente, usando o git log numstat e não mantendo o controle do número de arquivos alterados.
Git versão 2.1.0 no 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
Exemplo:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
A resposta do AaronM usando o one-liner do shell é boa, mas, na verdade, existe outro bug, em que os espaços corrompem os nomes de usuário se houver quantidades diferentes de espaços em branco entre o nome do usuário e a data. Os nomes de usuário corrompidos fornecerão várias linhas para a contagem de usuários e você deverá resumir você mesmo.
Essa pequena alteração corrigiu o problema para mim:
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
Observe os + após \ s que consumirão todos os espaços em branco do nome até a data.
Na verdade, adicionar esta resposta tanto para minha lembrança quanto para ajudar outras pessoas, já que esta é pelo menos a segunda vez que pesquiso no assunto :)
--show-email
para git blame -w
agregar no email, pois algumas pessoas usam Name
formatos diferentes em computadores diferentes e, às vezes, duas pessoas com o mesmo nome estão trabalhando no mesmo git.unsupported file type
mas, caso contrário, parece funcionar bem mesmo com eles (os ignora).
Aqui está uma pequena lista que produz estatísticas para todos os autores. É muito mais rápido que a solução de Dan acima em https://stackoverflow.com/a/20414465/1102119 (a mina possui complexidade de tempo O (N) em vez de O (NM) onde N é o número de confirmações e M o número de autores )
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
, caso contrário, as pessoas que assinam pgp seus commits não serão contadas.
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"
. (Note que eu estou no Windows, você pode precisar usar diferentes tipos de citações)
O @mmrobins @AaronM @ErikZ O @JamesMishra forneceu variantes que todos têm um problema em comum: pedem ao git que produza uma mistura de informações não destinadas ao consumo de scripts, incluindo conteúdo de linha do repositório na mesma linha e, em seguida, combine a bagunça com um regexp .
Esse é um problema quando algumas linhas não são válidas para texto UTF-8 e também quando algumas linhas coincidem com o regexp (isso aconteceu aqui).
Aqui está uma linha modificada que não apresenta esses problemas. Ele solicita ao git que produza dados de maneira limpa em linhas separadas, o que facilita a filtragem do que queremos de maneira robusta:
git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n
Você pode grep para outras strings, como autor-mail, committer, etc.
Talvez o primeiro faça export LC_ALL=C
(supondo bash
) forçar o processamento no nível de bytes (isso também acelera tremendamente o grep a partir das localidades baseadas em UTF-8).
Uma solução foi fornecida com o ruby no meio, sendo o perl um pouco mais disponível por padrão aqui é uma alternativa usando o perl para linhas atuais por autor.
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
Além da resposta de Charles Bailey , você pode adicionar o -C
parâmetro aos comandos. Caso contrário, as renomeações de arquivos contam como muitas adições e remoções (tantas quanto o arquivo tiver linhas), mesmo que o conteúdo do arquivo não tenha sido modificado.
Para ilustrar, aqui está um commit com muitos arquivos sendo movidos de um dos meus projetos, ao usar o git log --oneline --shortstat
comando:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
E aqui o mesmo commit usando o git log --oneline --shortstat -C
comando que detecta cópias de arquivos e renomeia:
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
Na minha opinião, o último fornece uma visão mais realista do impacto que uma pessoa teve no projeto, porque renomear um arquivo é uma operação muito menor do que gravá-lo do zero.
você pode usar o 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
ou apenas digite
$ whodid
então você pode ver resultados como este
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
tive que vir antes do nome do pacote macOS
. Simplesmente tentando ajudar.
Aqui está um script ruby rápido que aumenta o impacto por usuário em relação a uma determinada consulta de log.
Por exemplo, para rubinius :
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
o script:
#!/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
Forneci uma modificação de uma resposta curta acima, mas ela não foi suficiente para minhas necessidades. Eu precisava ser capaz de categorizar linhas confirmadas e linhas no código final. Eu também queria uma divisão por arquivo. Esse código não é recorrente, retornará apenas os resultados para um único diretório, mas é um bom começo se alguém quiser ir além. Copie e cole em um arquivo e torne o executável ou execute-o com 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};
}
Para usuários do Windows, você pode usar o seguinte script em lote que conta linhas adicionadas / removidas para o autor especificado
@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 escolher a opção desejada nesta lista, digitando o número listado e pressionando 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)
Este script aqui fará isso. Coloque-o em authorship.sh, chmod + x it, e está tudo 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 ":"
Salve seus logs no arquivo usando:
git log --author="<authorname>" --oneline --shortstat > logs.txt
Para os amantes de 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')
Suas saídas seriam como:
225 files changed
6751 insertions
1379 deletions
Você quer culpa do Git .
Existe uma opção --show-stats para imprimir algumas estatísticas.
blame
, mas realmente não deu as estatísticas que eu pensei que o OP precisaria?
A pergunta pedia informações sobre um autor específico , mas muitas das respostas eram soluções que retornavam listas classificadas de autores com base em suas linhas de código alteradas.
Era isso que eu estava procurando, mas as soluções existentes não eram perfeitas. No interesse das pessoas que podem encontrar essa pergunta pelo Google, eu fiz algumas melhorias e as transformei em um shell script, que mostro abaixo. Uma anotada (que continuarei mantendo) pode ser encontrada no meu Github .
Não há dependências no Perl ou no Ruby. Além disso, espaços em branco, renomeações e movimentos de linha são levados em consideração na contagem de alterações de linha. Basta colocar isso em um arquivo e passar seu repositório Git como o primeiro parâmetro.
#!/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
A melhor ferramenta até agora identificada é o gitinspector. Ele fornece o relatório definido por usuário, por semana, etc. Você pode instalar como abaixo com o npm
npm install -g gitinspector
Os links para obter mais detalhes
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Documentation
https://github.com/ejwa/gitinspector
comandos de exemplo são
gitinspector -lmrTw
gitinspector --since=1-1-2017 etc
Eu escrevi esse script Perl para realizar essa tarefa.
#!/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;
}
Eu o nomeei git-line-changes-by-author
e coloquei /usr/local/bin
. Como ele está salvo no meu caminho, posso emitir o comando git line-changes-by-author --before 2018-12-31 --after 2020-01-01
para obter o relatório para o ano de 2019. Como um exemplo. E se eu escrever incorretamente, o nome git sugerirá a grafia correta.
Convém ajustar o _get_repo_slug
sub para incluir apenas a última parte do remote.origin.url
arquivo, pois meus repositórios são salvos project/repo
e o seu pode não ser.
git://git.lwn.net/gitdm.git
.