W3docs

git diff

Aprende a usar el comando git diff, entiende su salida y compara archivos y ramas con ejemplos prácticos.

Qué hace git diff

El comando git diff muestra exactamente qué ha cambiado, línea por línea, entre dos fuentes de tu proyecto. Toma dos conjuntos de datos e imprime las diferencias entre ellos como un parche.

Esas dos fuentes pueden ser cualquier par de: tu árbol de trabajo (los archivos que estás editando ahora mismo), el área de preparación (el índice, lo que git add ha capturado) y cualquier instantánea confirmada. Como todos los demás comandos de Git solo te dicen que algo cambió, git diff es la herramienta que te dice qué cambió antes de prepararlo o confirmarlo.

Se usa habitualmente junto con git status y git log para inspeccionar el estado de un repositorio git: git status lista qué archivos cambiaron y git diff muestra el contenido de esos cambios.

gitdiff

Qué dos fuentes se comparan

La forma del comando determina qué se compara:

ComandoCompara
git diffÁrbol de trabajo vs. área de preparación (cambios sin preparar)
git diff --stagedÁrea de preparación vs. último commit (lo que git commit registraría)
git diff HEADÁrbol de trabajo vs. último commit (todos los cambios sin confirmar)
git diff <commit> <commit>Un commit frente a otro
git diff <branch> <branch>Los extremos de dos ramas

Un git diff sin argumentos solo muestra lo que aún no has preparado con git add. Este es el error más común: si ya has ejecutado git add, git diff parece vacío aunque tengas ediciones — usa git diff --staged para verlas.

Leer la salida de diff

Un diff tiene varias partes diferenciadas. Las secciones a continuación las van construyendo y explican cada línea.

Formato de salida sin procesar

Observa los comandos a continuación para crear un repositorio sencillo:

mkdir test_repo
cd test_repo
touch test.txt
echo "this is a git diff test example" > test.txt
git init .
#Initialized empty Git repository in /Users/kev/code/test/.git/
git add test.txt
git commit -am "add diff test file"
#[master (root-commit) 9e2dcac] add diff test file
#1 file changed, 1 insertion(+)
#create mode 100644 test.txt

Si quieres que git diff produzca salida, debes modificar el contenido de test.txt después de confirmarlo. Ejecuta el siguiente comando:

echo "this is a diff example" > test.txt

Solo ahora podemos ver un diff y analizar la salida. Al ejecutar git diff se producirá lo siguiente:

diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Fuentes de entrada del diff

La primera línea nombra las dos fuentes que se comparan. Aquí a/test.txt (la versión "antes") y b/test.txt (la versión "después") se pasan al diff. Los prefijos a/ y b/ siempre marcan los dos lados, incluso cuando se trata del mismo archivo.

diff --git a/test.txt b/test.txt

Metadatos

Esta línea muestra los metadatos internos de Git. Los dos números son los hashes abreviados de los objetos (blob) del archivo antes y después del cambio, y 100644 es el modo del archivo (un archivo normal, no ejecutable).

index 6b0c6cf..b37e70a 100644

Símbolos para los cambios

Estas líneas asignan un símbolo a cada fuente de entrada del diff. Las líneas de a/test.txt (el original) se marcan con ---, y las líneas de b/test.txt (la nueva versión) se marcan con +++.

--- a/test.txt
+++ b/test.txt

Fragmentos del diff

Un diff no muestra el archivo completo — solo las regiones modificadas. Cada una de estas regiones se denomina fragmento (o hunk). Los fragmentos incluyen algunas líneas sin cambios del contexto circundante para que puedas ver dónde se encuentra el cambio.

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

La primera línea es la cabecera del fragmento, delimitada por símbolos @@. Resume los rangos de líneas afectados: -1 significa "a partir de la línea 1 del archivo antiguo" y +1 significa "a partir de la línea 1 del archivo nuevo". Debajo de la cabecera, un - al inicio marca una línea eliminada y un + al inicio marca una línea añadida. Una línea modificada aparece como una eliminación seguida de una adición.

Opciones frecuentes

Git ofrece varias opciones útiles para distintos flujos de trabajo:

  • --staged (o --cached): Compara los cambios preparados en el índice con el commit HEAD — lo que un git commit registraría.
  • --stat: Muestra un resumen condensado de los archivos modificados (inserciones/eliminaciones por archivo) en lugar del diff completo.
  • --name-only: Muestra solo los nombres de los archivos modificados.
  • --name-status: Como --name-only, pero añade delante de cada archivo su letra de estado (M modificado, A añadido, D eliminado).
  • -w (o --ignore-all-space): Ignora los cambios que solo afectan a los espacios en blanco, lo cual es útil cuando la reindentación oculta las ediciones reales.

Por ejemplo, para obtener una visión rápida de cuánto cambió cada archivo:

git diff --stat
# test.txt | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)

Resaltar cambios

Para ediciones a nivel de línea, la salida predeterminada puede resultar ruidosa, porque Git muestra una línea eliminada completa y una línea añadida completa aunque solo difiera una palabra. Las dos herramientas a continuación resaltan las partes exactas que cambiaron.

git diff --color-words

La primera forma es un modo especial integrado en git diff: --color-words. Tokeniza las líneas añadidas y eliminadas por espacios en blanco y luego compara esos tokens, de modo que solo las palabras modificadas reciben color en lugar de líneas enteras.

git diff --color-words
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

(Nota: --color-words resalta los cambios en línea usando colores de terminal. En texto plano, el formato de salida coincide con el diff estándar.)

git diff-highlight

Cuando clonas el código fuente de Git, se incluye un subdirectorio llamado contrib. Contiene herramientas relacionadas con Git, una de las cuales es diff-highlight. Resalta las partes modificadas a nivel de subpalabra, con mayor granularidad que --color-words. Ten en cuenta que esta herramienta filtra la entrada estándar (le canalizas un diff) y requiere coloreado de terminal para ser visible.

git diff | git diff-highlight
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Comparar archivos binarios

git diff puede ejecutarse no solo sobre archivos de texto, sino también sobre archivos binarios. Por defecto, el resultado no es muy útil — Git solo indica que el archivo cambió, no cómo:

git diff
# Binary files a/script.pdf and b/script.pdf differ

Git tiene una funcionalidad que te permite especificar un comando de shell para convertir el contenido del archivo binario a texto antes de realizar el diff. Se requiere algo de configuración. Primero, define un filtro textconv que describa cómo convertir un determinado tipo binario a texto. Por ejemplo, la utilidad pdftohtml (disponible en Homebrew) puede convertir un PDF en HTML. Hay dos lugares donde configurarlo: por repositorio en .git/config, o globalmente en ~/.gitconfig.

[diff "pdfconv"]
textconv=pdftohtml -stdout

Luego conecta uno o más patrones de archivo al filtro pdfconv creando un archivo .gitattributes en la raíz del repositorio:

*.pdf diff=pdfconv

Tras esta configuración, git diff ejecuta primero cada archivo binario coincidente a través del convertidor y compara la salida de texto del convertidor. Usando la misma técnica puedes obtener diffs legibles de muchos formatos binarios (zips, jars y otros archivos comprimidos).

Comparar un único archivo

git diff también acepta una ruta de archivo explícita. Cuando se pasa una ruta, la operación se limita a ese archivo. En el ejemplo siguiente, el argumento ./path/to/file compara las modificaciones en el directorio de trabajo con el commit HEAD:

git diff HEAD ./path/to/file

Comparar todos los cambios

Para comparar los cambios en todo el repositorio, ejecuta git diff sin una ruta de archivo. Cualquiera de las formas anteriores puede invocarse sin el argumento ./path/to/file para aplicar la misma comparación a todos los archivos del repositorio local.

Cambios desde el commit más reciente

Un git diff sin argumentos compara el directorio de trabajo con el área de preparación (índice), por lo que solo muestra las ediciones sin preparar. Para ver todos los cambios sin confirmar desde el commit más reciente — tanto preparados como sin preparar — compara con HEAD:

git diff HEAD

Comparar dos commits

git diff acepta referencias de Git, como nombres de ramas, etiquetas e identificadores de commit. Cada commit tiene un ID único que puedes encontrar con git log. Pasa dos IDs de commit para compararlos directamente:

git diff <commit-hash-1> <commit-hash-2>

La salida muestra qué cambió al ir del primer commit al segundo.

Comparar ramas

Comparar ramas funciona como cualquier otra entrada de referencia en git diff. Hay dos operadores que debes conocer.

El operador de dos puntos compara los extremos de ambas ramas:

git diff branch1..branch2

Obtienes el mismo resultado si se omiten los puntos y se usa un espacio entre los nombres de las ramas. También existe un operador de tres puntos:

git diff branch1...branch2

El operador de tres puntos rebasa la comparación sobre el historial compartido: sustituye branch1 por el ancestro común (base de fusión) de las dos ramas, mientras que la segunda entrada sigue siendo el extremo de branch2. En otras palabras, branch1...branch2 responde a "qué ha ocurrido en branch2 desde que divergió de branch1", que es habitualmente lo que quieres al revisar una rama de funcionalidad antes de un git merge.

Comparar un archivo entre dos ramas

Para comparar un archivo específico entre ramas, pasa la ruta del archivo como tercer argumento:

git diff master new_branch ./test.txt

Comandos relacionados

  • git status — muestra qué archivos cambiaron antes de usar git diff para ver qué cambió en ellos.
  • git add — una vez que un diff parece correcto, prepáralo; luego usa git diff --staged para revisar lo que está preparado.
  • git commit — registra los cambios preparados.
  • git log — encuentra los hashes de commit que pasas a git diff <commit> <commit>.
  • git show — muestra el diff introducido por un único commit.

Práctica

Práctica
¿Cuáles son las funcionalidades y opciones del comando 'git diff'?
¿Cuáles son las funcionalidades y opciones del comando 'git diff'?
Was this page helpful?