¿Cómo diferenciar un archivo a una versión arbitraria en Git?

324

¿Cómo puedo diferenciar un archivo, por ejemplo pom.xml, de la rama maestra a una versión anterior arbitraria en Git?

Chris K
fuente

Respuestas:

347

Tu puedes hacer:

git diff master~20:pom.xml pom.xml

... para comparar su actual pom.xmlcon la de hace master20 revisiones hasta el primer padre. Puede reemplazar master~20, por supuesto, con el nombre del objeto (SHA1sum) de una confirmación o cualquiera de las muchas otras formas de especificar una revisión .

Tenga en cuenta que esto realmente compara la pom.xmlversión anterior con la versión en su árbol de trabajo, no la versión confirmada master. Si lo desea, puede hacer lo siguiente en su lugar:

git diff master~20:pom.xml master:pom.xml
Mark Longair
fuente
12
Tenga en cuenta que esto no solo funciona para archivos, sino que también funciona para (sub) directorios, por ejemplo git diff <revision>:foo/ HEAD:foo/.
2
También tenga en cuenta que en Windows debe usar barras diagonales para directorios si está utilizando un especificador de revisión o git le dará un error sobre el archivo / directorio que no existe en esa revisión.
Dylan Nissley
1
@DylanNissley o no le dará ningún error ni diferencia. Eso es lo que veo. En cualquier caso, gracias por la sugerencia sobre el uso de barras diagonales en lugar de barras diagonales inversas.
Gary S.
Con los archivos de Windows he encontrado que es más fácil cambiar el directorio y luego llamar a git diff master ~ 20: ./ pom.xml ./pom.xml
lloyd
Algunas versiones de git requieren "-" entre <revision> y <path>
Josh
140
git diff <revision> <path>

Por ejemplo:

git diff b0d14a4 foobar.txt
Benjamin Pollack
fuente
no funciona para la versión 1.7.11 si el archivo no está en el directorio actual. Ejemplo: 'git diff f76d078 test / Config' produce "error: No se pudo acceder a 'test / f76d078'"
simpleuser
1
@ user1663987 sólo tiene que pasar una ruta completa relativa a la raíz del proyecto: git diff <revision> root/path/file.
1
test / Config es relativo a la raíz (como en test es un subdirectorio de la raíz). pero entonces su ejemplo raíz / ruta / archivo parecería INCLUIR la raíz?
simpleuser
41

Si desea ver la diferencia entre la última confirmación de un solo archivo, puede hacer lo siguiente:

git log -p -1 filename

Esto le dará la diferencia del archivo en git, no está comparando su archivo local.

Gerardo
fuente
2
esto no está devolviendo nada
Andrei Cristian Prodan
@AndreiCristianProdan Entonces no tienes cambios allí. Puede incrementar el -1paso a paso hasta que obtenga los cambios.
Kaiser
Esto esta muy bien. Creé una función bash que podría ser útil: se gitlog () { git log -${3:-p} -${2:-1} $1; } usa como: gitlog Rakefileo gitlog Rakefile 5y gitlog Rakefile 10 s. El primero muestra una diferencia; el segundo muestra cinco diferencias; el tercero muestra diez --no-patch.
auxbuss
18

Para ver qué se modificó en un archivo en la última confirmación:

git diff HEAD~1 path/to/file.

Puede cambiar el número (~ 1) a la enésima confirmación con la que desea diferir.

Juampy NR
fuente
Esta respuesta es realmente solo un caso específico de esta respuesta más general , donde HEAD~1se sustituye por <revision>, lo que hace que esta respuesta sea un duplicado.
1
esto no está funcionando! fatal: argumento ambiguo 'HEAD ~ 1': revisión desconocida o ruta que no está en el árbol de trabajo. Use '-' para separar las rutas de las revisiones
Andrei Cristian Prodan
Esta respuesta es simple y funcional para mí.
Douglas Frari
6

Sintaxis Genérica:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

para todos los archivos llamados "FileName.xml" en cualquier parte de su repositorio.

Observe el espacio entre "-" y "**"

Responda a su pregunta:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

como siempre con git, puede usar una etiqueta / sha1 / "HEAD ^" para identificar una confirmación.

Probado con git 1.9.1 en Ubuntu.

soundslikeodd
fuente
6

Si ninguno de los commit es su HEAD, entonces la expansión de llaves de bash resulta realmente útil, especialmente si sus nombres de archivo son largos, el ejemplo anterior:

git diff master~20:pom.xml master:pom.xml

Se convertiría

git diff {master~20,master}:pom.xml

Más sobre la expansión de Brace con bash.

robstarbuck
fuente
6

Para comparar a 5 commit con el actual, ambos en adelante master, simplemente haga:

git diff master~5:pom.xml master:pom.xml

También puede referirse al número hash de confirmación, por ejemplo, si el número hash es x110bd64, puede hacer algo como esto para ver la diferencia:

git diff x110bd64 pom.xml
Alireza
fuente
4

git diff -w HEAD origin / master path / to / file

CatalinBerta
fuente
2
git diff master~20 -- pom.xml

Funciona si no estás en la rama maestra también.

Gunar Gessner
fuente
2

Si está bien con una herramienta gráfica (o incluso la prefiere) puede:

gitk pom.xml

En gitk puede hacer clic en cualquier confirmación (para "seleccionarla") y hacer clic con el botón derecho en cualquier otra confirmación para seleccionar "Diferenciar esto -> seleccionado" o "Diferenciar seleccionado -> esto" en el menú emergente, según el orden que prefiera.

Martin G
fuente
0

Si necesita diferenciar en un solo archivo en un escondite, por ejemplo, puede hacer

git diff stash@{0} -- path/to/file
lacostenycoder
fuente
-1

Si está buscando el diff en un commit específico y desea usar la interfaz de usuario de github en lugar de la línea de comando (digamos que desea vincularlo con otras personas), puede hacer lo siguiente:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Por ejemplo:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Tenga en cuenta los enlaces Anterior y Siguiente en la parte superior derecha que le permiten navegar a través de todos los archivos en la confirmación.

Sin embargo, esto solo funciona para una confirmación específica, no para comparar entre dos versiones arbitrarias.

Schmick
fuente