git diff file renombrado

Tengo un file a.txt .

 cat a.txt > hello 

El contenido de a.txt es "hola".

Me comprometo

 git add a.txt git commit -m "first commit" 

Luego muevo a.txt a un directory de test .

 mkdir test mv a.txt test 

Luego hago mi segundo commit.

 git add -A git commit -m "second commit" 

Finalmente, edito a.txt para decir "adiós" en su lugar.

 cat a.txt > goodbye 

Hago mi último compromiso.

 git add a.txt git commit -m "final commit" 

Ahora aquí está mi pregunta:

¿Cómo diferencio el contenido de a.txt entre mi último commit y mi primer commit?

Lo he intentado: git diff HEAD^^..HEAD -M a.txt , pero eso no funcionó. git log --follow a.txt detecta correctamente el cambio de nombre, pero no puedo encontrar un equivalente para git diff . ¿Hay alguno?

El problema con la diferencia entre HEAD^^ y HEAD es que tienes un a.txt en ambos commits, así que solo teniendo en count esos dos commits (que es lo que diff hace), no hay ningún cambio de nombre, hay una copy y un cambio.

Para detectar copys, puede usar -C :

 git diff -C HEAD^^ HEAD 

Resultado:

 index ce01362..dd7e1c6 100644 --- a/a.txt +++ b/a.txt @@ -1 +1 @@ -hello +goodbye diff --git a/a.txt b/test/a.txt similarity index 100% copy from a.txt copy to test/a.txt 

Por cierto, si restringes tu diff a una sola ruta (como lo haces en git diff HEAD^^ HEAD a.txt , nunca verás los git diff HEAD^^ HEAD a.txt nombre o las copys porque has excluido todo excepto una ruta única y renombra o copy, por definición, implica dos paths.

Para diferir en un cambio de nombre de un file específico, use -M -- <old-path> <new-path> ( -C también funciona).

Entonces, si ambos renombraron y cambiaron un file en la última confirmación, puede ver los cambios con:

 git diff HEAD^ HEAD -M -- a.txt test/a.txt 

Esto produce:

 diff --git a/a.txt b/test/a.txt similarity index 55% rename from a.txt rename to test/a.txt index 3f855b5..949dd15 100644 --- a/a.txt +++ b/test/a.txt @@ -1,3 +1,3 @@ // a.txt -hello +goodbye 

( // a.txt líneas // a.txt para ayudar a detectar el cambio de nombre de git)


Si git no detecta el cambio de nombre, puede especificar un umbral de similitud bajo con -M[=n] , por ejemplo, 1%:

 git diff HEAD^ HEAD -M01 -- a.txt test/a.txt 

De los documentos de git diff :

-M [<n>] –find-renames [= <n>]

Detectar cambia de nombre Si se especifica n , es un umbral en el índice de similitud (es decir, cantidad de adiciones / eliminaciones en comparación con el tamaño del file). Por ejemplo, -M90% significa que Git debería considerar un par de eliminar / agregar para cambiar el nombre si más del 90% del file no ha cambiado. Sin un signo % , el número debe leerse como una fracción, con un punto decimal antes. Es decir, -M5 convierte en 0.5, y por lo tanto es lo mismo que -M50% . Del mismo modo, -M05 es lo mismo que -M5% . Para limitar la detección a los -M100% nombre exactos, use -M100% . El índice de similitud pnetworkingeterminado es 50%.

También puedes hacer:

git diff rev1:file1 rev2:file2

que, para su ejemplo, sería

git diff HEAD^^:./a.txt HEAD:./test/a.txt

Tenga en count el explícito ./ – este formatting asume que las routes son relativas a la raíz del repository. (Si está en la raíz del repository, puede, por supuesto, omitirlo).

Esto no depende en absoluto de la detección de cambio de nombre, ya que el usuario declara explícitamente exactamente qué comparar. (Por lo tanto, también es útil en otras circunstancias, como la comparación de files entre diferentes twigs de svn en un entorno git-svn).