¿Cómo diferenciar un commit con su padre?

460

Además de escribir un alias o script, ¿hay un comando más corto para obtener la diferencia para un commit en particular?

git diff 15dc8^..15dc8

Si solo le da la identificación de confirmación única git diff 15dc8, difiere esa confirmación contra HEAD.

Brian L
fuente
Lo mejor de esto sería que funcionaría con "git difftool", usando las herramientas para mostrar el diff.
orip
Como referencia, la respuesta a esta otra pregunta ilustra cómo se puede configurar un alias basado en bash para simplificar lo anterior: stackoverflow.com/questions/3321492/…
Nick

Respuestas:

641

Uso git show $COMMIT. Le mostrará el mensaje de registro para la confirmación y la diferencia de esa confirmación en particular.

mipadi
fuente
45
Lástima que no pueda usar difftool :(
orip
1
@orip siempre puede establecer GIT_EXTERNAL_DIFF en un script que haga lo mismo que su difftool.
Slacy
77
Prefiero la respuesta de JakubNarebski, ya que la expresión de compromiso dada allí funcionará en muchos contextos: stackoverflow.com/a/449128/992887
RichVel
1
Si no se muestra la diferencia, probablemente no hay cambios reales, como para una confirmación de fusión
Devin G Rhode
66
@PTWithy: La pregunta era: "¿Hay un comando más corto para obtener la diferencia para una confirmación en particular?", Que responde esta pregunta.
mipadi
439

Utilizar:

git diff 15dc8^!

como se describe en el siguiente fragmento de la página de manual de git-rev-parse (1) (o en la página de manual moderna de git gitrevisions (7) ):

Existen otros dos shorthands para nombrar un conjunto formado por un commit y sus commits primarios. La notación r1 ^ @ significa todos los padres de r1. r1 ^! incluye commit r1 pero excluye a todos sus padres.

Esto significa que puede usarlo 15dc8^!como abreviatura para 15dc8^..15dc8cualquier lugar en git donde se necesiten revisiones. Para el comando diffgit diff 15dc8^..15dc8 se entiende como git diff 15dc8^ 15dc8, lo que significa la diferencia entre padre de commit ( 15dc8^) y commit ( 15dc8).

Nota : la descripción en la página de git-rev-parse(1)manual habla sobre los rangos de revisión , donde debe funcionar también para los commits de fusión, con más de un padre. Entonces r1^!es " r1 --not r1^@" es decir " r1 ^r1^1 ^r1^2 ..."


Además, puede usar git show COMMITpara obtener una descripción de compromiso y diff para un compromiso. Si solo quieres diff, puedes usargit diff-tree -p COMMIT

Jakub Narębski
fuente
77
Esta debería ser la respuesta aceptada, es mucho más ordenada. Sin embargo, la última oración del extracto de git-rev-parse es bastante confusa, parece que significa 'rango desde el padre de este commit a este commit'.
RichVel
1
@RichVel: es un poco confuso porque intenta describir también la situación en la que commit tiene más de un padre (es un commit de fusión). r1 ^! funciona como se esperaba también entonces.
Jakub Narębski
@ JakubNarębski: buen punto, tal vez podría editar su respuesta para resumir su comprensión de los casos monoparentales y multiparentales; las declaraciones separadas sobre cada una podrían ser más fáciles de entender.
RichVel
1
@ JakubNarębski: sí, ¡mucho mejor! Ahora uso este acceso directo todo el tiempo, gracias.
RichVel
1
La ^!notación abreviada principal funciona correctamente con difftool para los commits normales, pero el diff se invierte para los commits de fusión. ¿Porque?
FELIZ
56

Si sabe cuánto tiempo atrás, puede intentar algo como:

# Current branch vs. parent
git diff HEAD^ HEAD

# Current branch, diff between commits 2 and 3 times back
git diff HEAD~3 HEAD~2

Los compromisos previos funcionan más o menos así:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

Hay muchas formas de especificar confirmaciones:

# Great grandparent
git show HEAD~3

Vea esta página para más detalles .

Paul Vincent Craven
fuente
2
HEAD ^ 2 no es el abuelo, si HEAD ^ 1 es papá, entonces HEAD ^ 2 es mamá. Use HEAD ~ 2 para el papá de papá.
Binario
11

Como señala @mipadi, puede usar git show $COMMIT, pero esto también muestra algunos encabezados y el mensaje de confirmación. Si quieres una diferencia directa, usagit show --pretty=format:%b $COMMIT .

Obviamente, esta no es una mano muy corta, así que mantengo este alias en mi .gitconfig

    [alias]
      sd = show --pretty=format:%b

Esto me permite usar git sd $COMMITpara mostrar diff .

Øystein Steimler
fuente
1
Este alias puede incluir --color que hace que sea más fácil de leer: sd = show --color --pretty = format:% b
RichVel
@RichVel De hecho! Muy buen punto. Sin embargo, si tiene los colores habilitados de forma predeterminada en git, no necesitará este interruptor. Eso es lo que normalmente hago.
Øystein Steimler
5

Muchos de los ejemplos mencionados (p git diff 15dc8^!. Ej. , O git diff 15dc8^..15dc8) no funcionan si está usando zsh y tiene una extendedglobopción establecida. Puede solucionarlo de una de las siguientes tres maneras:

  1. unsetopt extendedglob (y / o eliminarlo de .zshrc)

  2. setopt NO_NOMATCH (y / o configurarlo en .zshrc)

  3. escapar del caos y golpear cada vez con una barra diagonal inversa, por ejemplo git diff 15dc8\^\!

Ville
fuente
3
git diff 15dc8 15dce~1

~ 1 significa 'padre', ~ 2 'abuelo, etc.

John Lawrence Aspden
fuente
2

La solución anterior de Paul hizo lo que esperaba.

$ git diff HEAD^1

Además, es útil agregar alias como las placas mencionadas, si coloca lo siguiente en la sección [alias] de su archivo ~ / .gitconfig, puede usar la mano corta para ver la diferencia entre head y anterior.

[alias]
    diff-last = diff HEAD^1

Luego, ejecutando $ git diff-last obtendrás tu resultado. Tenga en cuenta que esto también incluirá cualquier cambio que aún no haya confirmado, así como la diferencia entre confirmaciones. Si desea ignorar los cambios que aún no ha confirmado, puede usar diff para comparar el HEAD con su padre directamente:

$ git diff HEAD^1 HEAD
Graham R. Armstrong
fuente
0

Utiliza alias, por lo que no responde su pregunta exactamente, pero me parece útil para hacer lo que pretende ...

alias gitdiff-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"

alias gitlog-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
placas
fuente