remove - git tag title




Como contar o total de linhas alteradas por um autor específico em um repositório Git? (14)

@mmrobins @AaronM @ErikZ @JamesMishra forneceu variantes que têm todos um problema em comum: eles pedem ao git para produzir uma mistura de informação não destinada ao consumo de scripts, incluindo conteúdos de linha do repositório na mesma linha, e então combinar a bagunça com um regexp .

Este é um problema quando algumas linhas não são texto UTF-8 válido, e também quando algumas linhas coincidem com o regexp (isso aconteceu aqui).

Aqui está uma linha modificada que não tem esses problemas. Ele solicita o git para a saída de dados limpa em linhas separadas, o que facilita filtrar o que queremos de forma 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 author-mail, committer, etc.

Talvez primeiro export LC_ALL=C (assumindo bash ) para forçar o processamento em nível de byte (isto também acelera tremendamente o grep a partir dos locales baseados em UTF-8).

https://code.i-harness.com

Existe um comando que eu possa invocar que contará as linhas alteradas por um autor específico em um repositório Git? Eu sei que deve haver maneiras de contar o número de commits como o Github faz para o seu gráfico de impacto.


A Answer do AaronM usando o shell one-liner é boa, mas na verdade, há outro bug, onde espaços corromperão os nomes de usuário se houver diferentes quantidades de espaços em branco entre o nome do usuário e a data. Os nomes de usuários corrompidos fornecerão várias linhas para as contagens de usuários e você precisará resumi-las.

Essa pequena mudança resolveu 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 o + após \ s que consumirá todos os espaços em branco do nome até a data.

Na verdade, adicionando esta resposta tanto para a minha própria lembrança como para ajudar alguém, uma vez que esta é, pelo menos, a segunda vez que eu google o assunto :)

  • Editar 2019-01-23 Adicionado --show-email para git blame -w para agregar no e-mail, já que algumas pessoas usam diferentes formatos de Name em diferentes computadores, e às vezes duas pessoas com o mesmo nome estão trabalhando no mesmo git.

A questão pedia informações sobre um autor específico , mas muitas das respostas eram soluções que retornavam listas de autores baseadas em suas linhas de código alteradas.

Isso era o que eu procurava, mas as soluções existentes não eram perfeitas. No interesse das pessoas que podem encontrar essa questão através do Google, eu fiz algumas melhorias nelas e as transformei em um shell script, que apresento abaixo. Um anotado (que continuarei a manter) pode ser encontrado no meu Github .

Não dependências em Perl ou Ruby. Além disso, espaços em branco, renomeações e movimentos de linha são levados em consideração na contagem de mudança 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 saída do seguinte comando deve ser razoavelmente fácil de enviar ao script para somar os totais:

git log --author="<authorname>" --oneline --shortstat

Isso dá estatísticas para todos os commits no HEAD atual. Se você quiser adicionar estatísticas em outros ramos, você terá que fornecê-los como argumentos para o git log .

Para passar para um script, remover até o formato "oneline" pode ser feito com um formato de log vazio e, como comentou Jakub Narębski, o --numstat é outra alternativa. Ele gera estatísticas por arquivo, em vez de por linha, mas é ainda mais fácil de analisar.

git log --author="<authorname>" --pretty=tformat: --numstat

Aqui está um pequeno one-liner que produz estatísticas para todos os autores. É muito mais rápido que a solução de Dan acima em https://.com/a/20414465/1102119 (o meu tem complexidade de tempo O (N) em vez de O (NM) onde N é o número de commits 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

Aqui está um script rápido de ruby ​​que corrige 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

Este script aqui vai fazer isso. Coloque em authorship.sh, chmod + x, 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 ":"

Eu achei o seguinte para ser ú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 concentraram-se 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 deixa todos os committers classificados por linhas em vez de apenas um por vez. Você pode adicionar algumas opções para git blame (-C -M) para obter alguns números melhores que levam movimento de arquivos e movimento de linha entre arquivos em conta, mas o comando pode correr muito mais se você fizer isso.

Além disso, se você está procurando por linhas alteradas em todos os commits para todos os committers, o pequeno script a seguir é útil:

http://git-wt-commit.rubyforge.org/#git-rank-contributors


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 }' -

EDITAR (2017)

Existe um novo pacote no github que parece liso e usa o bash como dependências (testado no linux). É mais adequado para uso direto do que para scripts.

É git-quick-stats (link do github) .

Copie git-quick-stats para uma pasta e adicione a pasta ao caminho.

mkdir ~/source
cd ~/source
git clone [email protected]: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


No caso de alguém querer ver as estatísticas de cada usuário em sua base de código, alguns de meus colegas de trabalho recentemente criaram este horrível 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";}'

(Leva alguns minutos para processar nosso repo, que tem cerca de 10-15k commits.)


Salve seus logs no arquivo usando:

git log --author="<authorname>" --oneline --shortstat > logs.txt

Para os amantes do 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

Uma solução foi dada com ruby ​​no meio, sendo perl um pouco mais disponível por padrão aqui é uma alternativa usando 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

esta é a melhor maneira e também lhe dá uma imagem clara do número total de commits de todos os usuários

git shortlog -s -n

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 o resultado como este

Contribution state
=====================================================
 score  | author
-----------------------------------------------------
 3059   | someguy <[email protected]>
 585    | somelady <[email protected]>
 212    | niceguy <[email protected]>
 173    | coolguy <[email protected]>
=====================================================




repository