archivo git diff contra su último cambio

236

¿Es posible obtener git para producir una diferencia entre un archivo específico como existe ahora y como existía antes de la última confirmación que lo cambió?

Es decir, si sabemos:

$ git log --oneline myfile
123abc Fix some stuff
456def Frobble the foos
789dba Initial commit

Luego git diff 456def myfilemuestra el último cambio en myfile. Es posible hacer lo mismo sin el conocimiento producido por el git log; ¿Qué cambió en 123abc?

Chowlett
fuente
8
Prefiero usargit diff HEAD^ <file_path>
asgs
44
@asgs - No hace lo que estaba pidiendo (por dos razones - HEAD^es 123abc, HEAD^^es 456def; y si hubo otras confirmaciones que no afectaron este archivo, se HEAD^refiere a ellas)
Chowlett
Tienes razón, te perdiste la parte de "la última confirmación que lo cambió"
pide el

Respuestas:

215

Esto existe, pero en realidad es una característica de git log:

git log -p [--follow] [-1] <path>

Tenga en cuenta que -ptambién se puede usar para mostrar la diferencia en línea de una sola confirmación:

git log -p -1 <commit>

Opciones utilizadas:

  • -p(también -uo --patch) está oculto deeeeeeeep en la git-logpágina de manual, y en realidad es una opción de visualización para git-diff. Cuando se usa con log, muestra el parche que se generaría para cada confirmación , junto con la información de confirmación, y oculta las confirmaciones que no tocan la especificada <path>. (Este comportamiento se describe en el párrafo siguiente --full-diff, lo que hace que se muestre la diferencia completa de cada confirmación).
  • -1muestra solo el cambio más reciente al archivo especificado ( -n 1se puede usar en lugar de -1); de lo contrario, se muestran todas las diferencias distintas de cero de ese archivo.
  • --follow es necesario para ver los cambios que ocurrieron antes de un cambio de nombre.

Por lo que puedo decir, esta es la única forma de ver de inmediato el último conjunto de cambios realizados en un archivo sin usar git log(o similar) para contar el número de revisiones intermedias o determinar el hash de la confirmación.

Para ver los cambios de revisiones anteriores, simplemente desplácese por el registro o especifique una confirmación o etiqueta desde la cual iniciar el registro. (Por supuesto, especificar una confirmación o etiqueta lo devuelve al problema original de descubrir cuál es la confirmación o etiqueta correcta).

Crédito a quien crédito merece:

  • Descubrí log -pgracias a esta respuesta .
  • Gracias a Francisco Puga y esta respuesta por mostrarme la --followopción.
  • Gracias a ChrisBetti por mencionar la -n 1opción y atatko por mencionar la -1variante.
  • Gracias a sweaver2112 por haberme hecho leer la documentación y descubrir qué -psignifica "semánticamente".
Kyle Strand
fuente
66
Esta fue una gran solución para mí. Mostré cada confirmación y sus diferencias con el archivo actual cuando ejecutégit log -p filename
Ian Jamieson
44
Perfecto. Para ver solo el último cambio, es tan simple como agregar el -n 1parámetro. git log -p -n 1 filename
Chris Betti
@ChrisBetti Gracias; ¡Lo he incorporado a mi respuesta!
Kyle Strand
1
-n 1también se puede reemplazar por -1, no cambia el resultado, solo prefiero la sintaxis:git log -p -1 filename
atatko
1
hay una opción útil "--skip = [n]". Puede escribir git log -p -1 --skip=1 <path>para mostrar la segunda confirmación.
Maciek Łoziński
220

Una de las formas de usar git diff es:

git diff <commit> <path>

Y una forma común de referir un commit del último commit es como una ruta relativa al HEAD real. Puede hacer referencia a confirmaciones anteriores como HEAD ^ (en su ejemplo, será 123abc) o HEAD ^^ (456def en su ejemplo), etc.

Entonces la respuesta a su pregunta es:

git diff HEAD^^ myfile
Francisco Puga
fuente
66
Oh por supuesto. Lo intenté HEAD^, pero por supuesto eso no produjo nada. No pensé en intentarlo HEAD^^.
Chowlett
17
Quizás una sintaxis más fácil para los commits de hace mucho tiempo:HEAD~2
ibizaman
19
No es cierto (al menos para Git 1.9.0) que en HEAD^^ myfilerealidad se referirá al penúltimo commit que cambió myfile; se referirá al penúltimo compromiso general. ¿Hay alguna forma de especificar "Quiero ver el último cambio realizado en este archivo" sin especificar (parte de) el hash de confirmación o sin contar el número de confirmaciones entre el último cambio realizado en ese archivo y la revisión actual?
Kyle Strand
3
Hm, parece que git log -pestá bastante cerca.
Kyle Strand
30
motivo de voto negativo: la pregunta se formula "entre un archivo específico tal como existe ahora y como existía antes de la última confirmación que lo modificó ", pero si el archivo no se modificó en la última confirmación general, esta respuesta no funciona.
Chris Betti
8

Si está bien usando una herramienta gráfica, esto funciona muy bien:

gitk <file>

gitk ahora muestra todas las confirmaciones donde se actualizó el archivo. Marcar una confirmación le mostrará la diferencia con la confirmación anterior en la lista. Esto también funciona para directorios, pero también puede seleccionar el archivo para diferir para la confirmación seleccionada. Super útil!

Martin G
fuente
1
También muy útil: git difftool HEAD^ fileogit difftool -d HEAD^ path
ForeverLearning