¿Cómo puedo calcular el número de líneas cambiadas entre dos confirmaciones en git?

748

¿Hay alguna manera fácil de calcular el número de líneas cambiadas entre dos confirmaciones en git?

Sé que puedo hacer un git diff, y contar las líneas, pero esto parece tedioso. También me gustaría saber cómo puedo hacer esto, incluyendo solo mis propios commits en los conteos.

Miguel
fuente
3
Miras a BitBucket.
Alex78191

Respuestas:

1114

Desea la --statopción de git diff, o si está buscando analizar esto en un script, la --numstatopción.

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

--statproduce la salida legible para humanos que estás acostumbrado a ver después de las fusiones; --numstatproduce un buen diseño de tabla que los scripts pueden interpretar fácilmente.

De alguna manera extrañé que estuvieras buscando hacer esto en múltiples confirmaciones al mismo tiempo, esa es una tarea para git log. Ron DeVera toca esto, pero en realidad puedes hacer mucho más de lo que menciona. Dado que git logllama internamente a la maquinaria diff para imprimir la información solicitada, puede darle cualquiera de las opciones de estadísticas diff, no solo --shortstat. Lo que probablemente quiera usar es:

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

pero puedes usar --numstato --shortstattambién. git logTambién puede seleccionar confirmaciones de otras maneras: eche un vistazo a la documentación . Es posible que le interesen cosas como --since(en lugar de especificar rangos de compromiso, solo seleccione los compromisos desde la semana pasada) y --no-merges(los compromisos de combinación en realidad no introducen cambios), así como las opciones de salida bonitas ( --pretty=oneline, short, medium, full...).

Aquí hay una línea para obtener los cambios totales en lugar de los cambios por confirmación del registro de git (cambie las opciones de selección de confirmación según lo desee; esto es confirmaciones de usted, de 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)}'

(debe dejar que git log imprima cierta información de identificación sobre el compromiso; Elegí arbitrariamente el hash, luego usé awk para seleccionar solo las líneas con tres campos, que son los que tienen la información estadística)

Cascabel
fuente
2
Esto no responde a la pregunta original sobre "líneas cambiadas". El cambio de una línea se calcula como línea insertada y eliminada. Calcular el número de líneas cambiadas necesita más trabajo del que se describe aquí.
Ville Laitila
12
@VilleLaitila: Esto es lo más cercano posible sin una cantidad absurda de esfuerzo, y fue lo suficientemente bueno para el OP y otros 15. (¿Cómo define cuándo una línea cambiada se convierte en una línea agregada y una línea eliminada? ¿Al editar la distancia entre la línea - y +, como una fracción de la longitud de la línea?) Todos sabemos que los cambios se duplican; podemos llamar a eso una medida útil de la cantidad de cambio y seguir adelante con nuestras vidas.
Cascabel
188
git diff --shortstat <commit1> <commit2>Era el que yo quería.
Kim
99
Como referencia, el formato de fecha para --sincey --untiles algo así como: yesterday, 1 month 2 weeks 3 days 1 hour 1 second agoo1979-02-26 18:30:00
juanmirocks
44
@Bryson Sí, es por eso que esa línea dice <commit-ish>: funciona con cualquier cosa que represente una confirmación, incluidas las confirmaciones literales, ramas, etiquetas y referencias en general. Ver también stackoverflow.com/questions/23303549/…
Cascabel
193

Para los perezosos, use git log --stat.

Thomas
fuente
14
Encontré esto útil, agregué una -10para mostrar las diez confirmaciones anteriores.
Choylton B. Higginbottom
2
Cuando termine de ver el historial de confirmación, escriba Qpara volver al terminal.
Stevoisiak
180
git diff --shortstat

le da solo el número de líneas cambiadas y agregadas. Esto solo funciona con cambios no organizados. Para comparar contra una rama:

git diff --shortstat some-branch
orkoden
fuente
3
¡Frio! pero ... tenga en cuenta que esto solo funciona con cambios no organizados
TomCobo
3
Si ha realizado cambios con git add, asegúrese de hacerlogit diff --shortstat --cached
TomNash
2463 archivos cambiados, 39745 inserciones (+), 21383 eliminaciones (-) En realidad, he eliminado alrededor de 5k a 10k en el último mes. Es casi todo lo que he estado haciendo aparte de mover cosas. Algo está mal. ¿No incluye archivos eliminados o algo así?
jgmjgm
46
git diff --stat commit1 commit2

EDITAR: también debe especificar las confirmaciones (sin parámetros, compara el directorio de trabajo con el índice). P.ej

git diff --stat HEAD^ HEAD

para comparar el padre de HEADcon HEAD.

Matthew Flaschen
fuente
1
Realmente nunca hay necesidad de usarlo diff-index: la diffinterfaz puede manejar todo; El caso de diff-indexestá cubierto por el --cached/--staged, creo. (Y no hay forma de diff-indexcomparar dos confirmaciones arbitrarias como lo solicitó el OP.)
Cascabel
El resultado de esto no es nada para mí.
Mike
@ Mike: ¿Dejaste un quilate? ¿Fue su confirmación más reciente una confirmación de fusión? Si git dice que no hay diferencias, es porque no hay diferencias.
Cascabel
66
o si no está comprometidogit diff --stat HEAD
wieczorek1990
1
Además, puede comparar más atrás que solo el padre mediante el uso HEAD~n, donde nes qué tan lejos desea retroceder. git diff --stat HEAD~5 HEADmostrará estadísticas combinadas de los últimos 5 commits en relación con HEAD.
Nathan Beck
18

Suponiendo que desea comparar todas sus confirmaciones entre abcd123 (la primera confirmación) y wxyz789 (la última confirmación), inclusive:

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

Esto da una salida sucinta 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
fuente
El resultado de esto no es nada para mí (hice confirmaciones y verifiqué que el autor es correcto al usarlo con git log y sin otros argumentos).
Mike
Esto me pasó a mí también. Los dos commits estaban en el orden incorrecto, intercambiándolos alrededor lo arreglaron.
bob esponja
1
Se actualizó el orden de confirmación y se aclaró lo que representan los dos SHA. Gracias por atraparlo :)
Ron DeVera
3
La --shortstatbandera es increíble, git diffaunque funciona (no git log).
lucke84
¿Cómo resumirlos?
xpto
13

Otra forma de obtener todos los registros de cambios en un período de tiempo específico

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

Salida:

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

Con un contenido de salida largo, puede exportar a un archivo para leerlo más

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

Aunque todas las respuestas anteriores son correctas, la siguiente es útil para usar si necesita contar las últimas confirmaciones

a continuación uno es para contar las últimas 5 confirmaciones

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

para contar las últimas 10 confirmaciones

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

genérico: cambie N con el recuento de las últimas confirmaciones que necesita

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

para contar todas las confirmaciones desde el inicio

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


fuente
Esto da "'cola' no se reconoce como un comando interno o externo, programa operativo o archivo por lotes".
Charles Roddie
2

git log --numstat solo te da solo los números

nibinbhaskar
fuente
1

Acabo de resolver este problema por mí mismo, así que compartiré lo que se me ocurrió. Aquí está el resultado final:

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

El comando subyacente se ve así:

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

Tenga $@en cuenta el comando en el registro para transmitir sus argumentos como --author="Brian"o --since=yesterday.

Escapar del awk para ponerlo en un alias git fue desordenado, así que en su lugar, lo puse en un script ejecutable en mi ruta ( ~/bin/git-stat-sum), luego usé el script en el alias en mi .gitconfig:

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

Y funciona muy bien. Una última cosa a tener en cuenta es que file changeses la cantidad de cambios en los archivos, no la cantidad de archivos únicos modificados. Eso es lo que estaba buscando, pero puede que no sea lo que esperas.

Aquí hay otro ejemplo o dos

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

Realmente, deberías poder reemplazar cualquier git logcomando con git summary.

indefinido
fuente