Come posso calcolare il numero di righe modificate tra due commit in git?


748

Esiste un modo semplice per calcolare il numero di righe modificate tra due commit in git?

So che posso fare un git diff, e contare le linee, ma questo sembra noioso. Vorrei anche sapere come posso farlo, compresi solo i miei commit nei conteggi.


3
Dai un'occhiata a BitBucket.
Alex78191,

Risposte:


1114

Vuoi l' --statopzione di git diff, o se stai cercando di analizzarla in uno script, l' --numstatopzione.

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

--statproduce l'output leggibile dall'uomo che sei abituato a vedere dopo le fusioni; --numstatproduce un bel layout di tabella che gli script possono interpretare facilmente.

In qualche modo mi mancava che stavi cercando di farlo su più commit contemporaneamente - questo è un compito per git log. Ron DeVera ci tocca, ma in realtà puoi fare molto di più di quello che menziona. Dato che git logchiama internamente il macchinario diff per stampare le informazioni richieste, puoi fornirle una qualsiasi delle opzioni stat stat - non solo --shortstat. Quello che probabilmente vuoi usare è:

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

ma puoi usare --numstato --shortstatpure. git logpuò anche selezionare commit in vari altri modi - dai un'occhiata alla documentazione . Potresti essere interessato a cose come --since(piuttosto che specificare intervalli di commit, seleziona i commit solo dalla scorsa settimana) e --no-merges(i commit di unione non introducono effettivamente modifiche), così come le graziose opzioni di output ( --pretty=oneline, short, medium, full...).

Ecco un one-liner per ottenere le modifiche totali invece delle modifiche per commit dal registro git (cambia le opzioni di selezione del commit come desiderato - questo è il tuo commit, da commit1 a 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)}'

(devi lasciare che git log stampi alcune informazioni identificative sul commit; ho scelto arbitrariamente l'hash, quindi ho usato awk per selezionare solo le linee con tre campi, che sono quelli con le informazioni stat)


2
Questo non risponde alla domanda originale su "linee modificate". Una modifica di riga viene calcolata sia come riga inserita che come eliminata. Il calcolo del numero di righe modificate richiede più lavoro di quanto descritto qui.
Ville Laitila,

12
@VilleLaitila: questo è il più vicino possibile senza un assurdo sforzo, ed è stato abbastanza buono per l'OP e altri 15. (Come si definisce quando una linea modificata diventa una linea aggiunta e una linea eliminata? Mediante la distanza di modifica tra la linea - e +, come una frazione della lunghezza della linea?) Sappiamo tutti che le modifiche vengono raddoppiate; possiamo semplicemente chiamarla utile metrica della quantità di cambiamento e andare avanti con le nostre vite.
Cascabel,

188
git diff --shortstat <commit1> <commit2>era quello che volevo.
Kim,

9
Per riferimento, il formato della data per --sincee --untilè qualcosa di simile: yesterday, 1 month 2 weeks 3 days 1 hour 1 second ago, o1979-02-26 18:30:00
juanmirocks

4
@Bryson Sì, ecco perché dice quella riga: <commit-ish>funziona con tutto ciò che rappresenta un commit, inclusi commit letterali, branch, tag e ref in generale. Vedi anche stackoverflow.com/questions/23303549/…
Cascabel

193

Per i più pigri, usa git log --stat.


14
L'ho trovato utile, ho aggiunto a -10per mostrare i dieci commit precedenti.
Choylton B. Higginbottom,

2
Al termine della visualizzazione della cronologia di commit, digitare Qper tornare al terminale.
Stevoisiak,

180
git diff --shortstat

ti dà solo il numero di righe modificate e aggiunte. Funziona solo con modifiche non messe in scena. Per confrontare un ramo:

git diff --shortstat some-branch

3
Freddo! ma ...
tieni

3
Se hai messo in scena modifiche con git add, assicurati di farlogit diff --shortstat --cached
TomNash

2463 file modificati, 39745 inserzioni (+), 21383 eliminazioni (-) In realtà ho eliminato tra 5k e 10k nell'ultimo mese. È quasi tutto ciò che ho fatto a parte spostare le cose. Qualcosa è sbagliato. Non include i file rimossi o qualcosa del genere?
jgmjgm,

46
git diff --stat commit1 commit2

EDIT: devi specificare anche i commit (senza parametri confronta la directory di lavoro con l'indice). Per esempio

git diff --stat HEAD^ HEAD

per confrontare il genitore di HEADcon HEAD.


1
Non c'è mai davvero bisogno di usare diff-index- il difffrontend può gestire tutto; il caso di diff-indexè coperto dal --cached/--staged, credo. (E non c'è modo di usare diff-indexper confrontare due commit arbitrari come richiesto dal PO.)
Cascabel

L'output di questo non è niente per me.
Mike

@ Mike: hai lasciato un carato? Il tuo ultimo commit è stato un commit di tipo merge? Se git dice che non c'è differenza, è perché non c'è differenza.
Cascabel,

6
o se non impegnatigit diff --stat HEAD
wieczorek1990

1
Inoltre, puoi confrontare più indietro rispetto al solo genitore usando HEAD~n, dove nè quanto vuoi tornare indietro. git diff --stat HEAD~5 HEADmostrerà le statistiche combinate per gli ultimi 5 commit relativi a HEAD.
Nathan Beck,

18

Supponendo che si desideri confrontare tutti i commit tra abcd123 (il primo commit) e wxyz789 (l'ultimo commit), inclusi:

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

Questo dà un output succinto come:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)

L'output di questo non è per me (ho fatto commit e verificato - autore è corretto usandolo con git log e nessun altro argomento).
Mike,

Questo è successo anche a me. I due commit erano nell'ordine sbagliato, scambiandoli attorno risolti.
bob esponja,

1
Aggiornato l'ordine di commit e chiarito cosa rappresentano i due SHA. Grazie per averlo catturato :)
Ron DeVera il

3
La --shortstatbandiera è fantastica, funziona git diffanche se (non git log).
lucke84,

Come sintetizzarli?
XP

13

Un altro modo per ottenere tutto il registro delle modifiche in un periodo di tempo specificato

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

Produzione:

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

Con un contenuto di output lungo, è possibile esportare in file per una maggiore leggibilità

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

2

Sebbene tutte le risposte di cui sopra siano corrette, di seguito una è utile da usare se è necessario contare gli ultimi molti commit

sotto uno c'è il conteggio degli ultimi 5 commit

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

per contare gli ultimi 10 commit

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

generico: cambia N con il conteggio degli ultimi numerosi commit necessari

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

per contare tutti i commit dall'inizio

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


Questo dà "'tail' non è riconosciuto come comando interno o esterno, programma eseguibile o file batch."
Charles Roddie,


1

Ho appena risolto questo problema da solo, quindi condividerò quello che mi è venuto in mente. Ecco il risultato finale:

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

Il comando sottostante è simile al seguente:

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

Nota il $@comando nel registro per passare argomenti come --author="Brian"o --since=yesterday.

Fuggire dal awk per inserirlo in un alias git era disordinato, quindi invece l'ho inserito in uno script eseguibile sul mio percorso ( ~/bin/git-stat-sum), quindi ho usato lo script nell'alias nel mio .gitconfig:

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

E funziona davvero bene. Un'ultima cosa da notare è che file changesè il numero di modifiche ai file, non il numero di file univoci modificati. Questo è quello che stavo cercando, ma potrebbe non essere quello che ti aspetti.

Ecco un altro esempio o due

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

Davvero, dovresti essere in grado di sostituire qualsiasi git logcomando con git summary.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.