Como posso calcular o número de linhas alteradas entre dois commit no git?

748

Existe alguma maneira fácil de calcular o número de linhas alteradas entre dois commits no git?

Eu sei que posso fazer um git diffe contar as linhas, mas isso parece entediante. Eu também gostaria de saber como fazer isso, incluindo apenas meus próprios commits nas contas de linha.

Mike
fonte
3
Você olha para o BitBucket.
Alex78191

Respostas:

1114

Você deseja a --statopção git diffou, se estiver procurando analisar isso em um script, a --numstatopção.

git diff --stat <commit-ish> <commit-ish>

--statproduz a saída legível por humanos que você está acostumado a ver após mesclagens; --numstatproduz um bom layout de tabela que os scripts podem interpretar facilmente.

De alguma forma, senti falta de que você estava procurando fazer isso em vários commits ao mesmo tempo - essa é uma tarefa git log. Ron DeVera aborda isso, mas você pode realmente fazer muito mais do que o que ele menciona. Como git logchama internamente o equipamento diff para imprimir as informações solicitadas, você pode fornecer qualquer uma das opções de stat diff - não apenas --shortstat. O que você provavelmente deseja usar é:

git log --author="Your name" --stat <commit1>..<commit2>

mas você pode usar --numstatou --shortstattambém. git logtambém é possível selecionar confirmações de várias outras maneiras - consulte a documentação . Você pode estar interessado em coisas como --since(em vez de especificar intervalos de confirmação, basta selecionar confirmações desde a semana passada) e --no-merges(confirmações de mesclagem não introduzem alterações), bem como as opções de saída bastante interessantes ( --pretty=oneline, short, medium, full...).

Aqui está uma lista para obter o total de alterações em vez das alterações por confirmação do git log (altere as opções de seleção de confirmação conforme desejado - isso é confirmado por você, de commit1 para commit2):

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

(você precisa deixar o git log imprimir algumas informações de identificação sobre o commit; eu escolhi arbitrariamente o hash e depois usei o awk para escolher apenas as linhas com três campos, que são os que contêm as informações estatísticas)

Cascabel
fonte
2
Isso não responde à pergunta original sobre "linhas alteradas". Uma alteração de linha é calculada como linha inserida e excluída. O cálculo do número de linhas alteradas precisa de mais trabalho do que o descrito aqui.
Ville Laitila
12
@VilleLaitila: É o mais próximo possível sem esforço absurdo e foi bom o suficiente para o OP e outros 15. (Como você define quando uma linha alterada se torna uma linha adicionada e uma excluída? Ao editar a distância entre a linha - e +, como uma fração do comprimento da linha?) Todos nós sabemos que as alterações são duplicadas; podemos simplesmente chamar isso de uma métrica útil de quantidade de mudança e seguir em frente com nossas vidas.
Cascabel
188
git diff --shortstat <commit1> <commit2>era o que eu queria.
24712 Kim
9
Para referência, o formato de data para --sincee --untilé algo como: yesterday, 1 month 2 weeks 3 days 1 hour 1 second agoou1979-02-26 18:30:00
juanmirocks
4
@Ryson Sim, é por isso que essa linha diz <commit-ish>- ela funciona com qualquer coisa que represente uma confirmação, incluindo confirmações literais, ramificações, tags e refs em geral. Veja também stackoverflow.com/questions/23303549/…
Cascabel
193

Para os preguiçosos, use git log --stat.

Thomas
fonte
14
Achei isso útil, adicionei um -10para mostrar os dez commits anteriores.
30616 Choelton B. Higginbottom
2
Quando terminar de visualizar o histórico de confirmação, digite Qpara retornar ao terminal.
Stevoisiak 18/05/19
180
git diff --shortstat

fornece apenas o número de linhas alteradas e adicionadas. Isso funciona apenas com alterações não faseadas. Para comparar com uma ramificação:

git diff --shortstat some-branch
orkoden
fonte
3
Legal! mas .. estar ciente de que isso só funciona com mudanças unstaged
TomCobo
3
Se você já encenado alterações com git add, certifique-se de fazergit diff --shortstat --cached
TomNash
2463 arquivos alterados, 39745 inserções (+), 21383 exclusões (-) Na verdade, eu apaguei de 5 a 10k no último mês. É quase tudo o que tenho feito além de mudar as coisas. Algo está errado. Não inclui arquivos removidos ou algo assim?
jgmjgm 8/08/19
46
git diff --stat commit1 commit2

EDIT: Você também deve especificar os commit (sem parâmetros, ele compara o diretório de trabalho com o índice). Por exemplo

git diff --stat HEAD^ HEAD

comparar o pai de HEADcom HEAD.

Matthew Flaschen
fonte
1
Nunca é realmente necessário usar diff-index- o difffrontend pode lidar com tudo; o caso de diff-indexé coberto pelo --cached/--staged, eu acredito. (E não há nenhuma maneira de usar diff-indexpara comparar dois commits arbitrárias como o OP perguntou.)
Cascabel
A saída disso não é nada para mim.
27510 Mike
@ Mike: Você deixou um quilate? O seu commit mais recente foi um commit de mesclagem? Se o git diz que não há diferenças, é porque não há diferenças.
Cascabel 27/03
6
ou se uncommitedgit diff --stat HEAD
wieczorek1990
1
Além disso, você pode comparar mais longe do que apenas o pai usando HEAD~n, onde né o quão longe você deseja voltar. git diff --stat HEAD~5 HEADmostrará estatísticas combinadas dos últimos 5 commits em relação ao HEAD.
Nathan Beck
18

Supondo que você queira comparar todas as suas confirmações entre abcd123 (a primeira confirmação) e wxyz789 (a última confirmação), inclusive:

git log wxyz789^..abcd123 --oneline --shortstat --author="Mike Surname"

Isso fornece resultados sucintos como:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)
Ron DeVera
fonte
A saída disso não é nada para mim (eu fiz confirmações e verifiquei - o autor está correto usando-o com o git log e sem outros argumentos).
Mike
Isso aconteceu comigo também. Os dois commits estavam na ordem errada, trocando-os por aí.
Bob Esponja
1
Atualizada a ordem de confirmação e esclareceu o que os dois SHAs representam. Obrigado por captura-lo :)
Ron DeVera
3
A --shortstatbandeira é incrível, mas funciona com git diff(não git log).
lucke84
Como resumi-los?
Xpto
13

Outra maneira de obter todo o log de alterações em um período especificado

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10"

Resultado:

2637cc736 Revert changed code
 1 file changed, 5 insertions(+), 5 deletions(-)
ba8d29402 Fix review
 2 files changed, 4 insertions(+), 11 deletions(-)

Com um conteúdo de saída longo, você pode exportar para um arquivo para facilitar a leitura

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10" > /mnt/MyChangeLog.txt
nmtri
fonte
2

Embora todas as respostas acima estejam corretas, abaixo de uma é útil se você precisar contar os últimos muitos commits

abaixo de um é obter a contagem dos últimos 5 commits

git diff $(git log -5 --pretty=format:"%h" | tail -1) --shortstat

para contar os últimos 10 commits

git diff $(git log -10 --pretty=format:"%h" | tail -1) --shortstat

genérico - altere N com a contagem dos últimos commits necessários

git diff $(git log -N --pretty=format:"%h" | tail -1) --shortstat

para contar todos os commits desde o início

git diff $(git log --pretty=format:"%h" | tail -1) --shortstat


fonte
Isso indica que "'cauda' não é reconhecida como um comando interno ou externo, programa operável ou arquivo em lote".
Charles Roddie
2

git log --numstat fornece apenas os números

nibinbhaskar
fonte
1

Acabei de resolver esse problema por conta própria, então vou compartilhar o que descobri. Aqui está o resultado final:

> git summary --since=yesterday
total: 114 file changes, 13800 insertions(+) 638 deletions(-)

O comando subjacente é assim:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'

Observe o $@comando no log para transmitir seus argumentos como --author="Brian"ou --since=yesterday.

Escapar do awk para colocá-lo em um alias do git era confuso; portanto, coloquei-o em um script executável no meu caminho ( ~/bin/git-stat-sum), depois usei o script no alias do meu .gitconfig:

[alias]
    summary = !git-stat-sum \"$@\"

E funciona muito bem. Uma última coisa a observar é que file changesé o número de alterações nos arquivos, não o número de arquivos exclusivos alterados. Era isso que eu estava procurando, mas pode não ser o que você espera.

Aqui está outro exemplo ou dois

git summary --author=brian
git summary master..dev
# combine them as you like
git summary --author=brian master..dev
git summary --all

Realmente, você poderá substituir qualquer git logcomando por git summary.

Indefinido
fonte