Saltar al contenido

git diff

Descripción

El comando git diff se usa para comparar cambios entre commits, el árbol de trabajo y el área de preparación. Toma dos conjuntos de datos de entrada y muestra las modificaciones entre ellos. Normalmente, se usa junto con los comandos git status y git log para analizar el estado de un repositorio git.

gitdiff

Salidas de diff

La comparación diff puede tener varias salidas que se analizarán a continuación.

Formato de salida en bruto

Echa un vistazo a los comandos siguientes para crear un repositorio simple:

git diff

bash
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 tenga una salida, tienes que cambiar el contenido del archivo test.txt después de añadirlo al repositorio creado. Puedes hacerlo ejecutando el siguiente comando:

git diff

bash
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:

git diff

bash
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 de diff

A continuación puedes encontrar la entrada de comparación de diff. Como resultado, a/test.txt y b/test.txt se pasarán a diff.

git diff

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

Metadatos

Esta línea muestra algunos metadatos internos de Git. Los números de esta salida coinciden con los identificadores hash de versión de objetos de Git.

git diff

bash
index 6b0c6cf..b37e70a 100644

Símbolos para los cambios

Estas líneas muestran los símbolos asignados a cada fuente de entrada de diff. Los cambios de a/test.txt se marcan con --- y los cambios de b/test.txt se marcan con el símbolo +++.

git diff

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

Fragmentos de diff

Un diff no muestra el archivo completo. Solo muestra las líneas modificadas. Esa parte modificada se llama "fragmento". La ventaja de los fragmentos es que muestran líneas antes y después de los cambios, para que puedas comprender mejor las modificaciones.

git diff

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

La primera línea es el encabezado del fragmento. Cada fragmento se coloca mediante un encabezado dentro de los símbolos @@. Los cambios realizados en el archivo se resumen en el encabezado.

Banderas comunes

Git proporciona varias banderas útiles para distintos flujos de trabajo:

  • --staged (o --cached): compara los cambios preparados en el índice con el commit HEAD.
  • --stat: muestra un resumen condensado de los archivos cambiados en lugar del diff completo.
  • --name-only: muestra solo los nombres de los archivos cambiados.

Resaltado de cambios

Puedes usar las siguientes 2 herramientas para resaltar los cambios y hacerlos más visibles.

git diff --color-words

La primera forma de resaltar cambios es el modo especial que propone git diff: --color-words. Tokeniza las líneas añadidas y eliminadas por espacios en blanco y luego las compara.

git diff

bash
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

En el caso de clonar el código fuente de git, se encontrará un subdirectorio llamado contrib. Este subdirectorio contiene herramientas relacionadas con Git. Una de estas herramientas se llama diff-highlight. Resalta las partes cambiadas de subpalabras. Ten en cuenta que esta herramienta filtra la entrada estándar y requiere color en la terminal para que sea visible.

git diff

bash
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

Comparación de archivos binarios

Git diff puede ejecutarse no solo en archivos de texto, sino también en binarios. La opción predeterminada a veces puede no ser muy útil.

git diff

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

Git tiene una función que te permite especificar un comando de shell para convertir el contenido de los archivos binarios a texto antes de realizar el diff. Sin embargo, puede requerirse una pequeña configuración. Antes que nada, debes definir un filtro textconv con la descripción de la forma de conversión de cierto tipo de binario a texto. Por ejemplo, puedes usar una utilidad sencilla llamada pdftohtml (disponible a través de homebrew) para convertir PDF a HTML. Hay dos formas de configurarlo: editando el archivo .git/config o, de forma global, editando .gitconfig.

git diff

bash
[diff "pdfconv"]
textconv=pdftohtml -stdout

Luego necesitas asociar uno o más patrones de archivo con el filtro pdfconv, lo cual se puede hacer creando un archivo .gitattributes en la raíz del repositorio.

git diff

bash
*.pdf diff=pdfconv

Después de la configuración, git diff primero ejecutará el archivo binario mediante el script convertidor configurado y comparará la salida del convertidor. Usando la misma técnica, también puedes obtener diffs útiles de todo tipo de archivo binario (zip, jar y otros archivos comprimidos).

Comparación de archivos: git diff file

El comando git diff también tiene una opción explícita de ruta de archivo. La operación git diff procesará el archivo específico una vez que se le pase la ruta del archivo. En el ejemplo siguiente, el argumento ./path/to/file comparará las modificaciones en el directorio de trabajo con el commit HEAD.

git diff

bash
git diff HEAD ./path/to/file

Comparación de todos los cambios

Para comparar los cambios en todo el repositorio, debes ejecutar git diff sin una ruta de archivo. Así, puedes invocar los ejemplos anteriores sin el argumento ./path/to/file y obtener los mismos resultados en todos los archivos del repositorio local.

Cambios desde el commit más reciente

De forma predeterminada, git diff compara el directorio de trabajo con el área de preparación (índice). Para ver todos los cambios sin confirmar desde el commit más reciente:

git diff

bash
git diff

Comparación de archivos entre dos commits

El comando git diff puede recibir refs de Git, como nombres de heads, tags y ramas. Cada commit en Git tiene un ID de commit único, que puedes encontrar ejecutando git log. También puedes pasar dos IDs de commit para compararlos directamente:

git diff

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

Comparación de ramas

La comparación de ramas se ejecuta de forma similar a otras entradas ref para git diff. Veamos ejemplos del operador de dos puntos:

git diff

bash
git diff branch1..branch2

Los dos puntos en el ejemplo anterior muestran que la entrada del diff son las puntas de ambas ramas. Obtendrás el mismo resultado si se omiten los puntos y se usa un espacio entre las ramas. Además, existe un operador de tres puntos:

git diff

bash
git diff branch1...branch2

El operador de tres puntos cambia el primer parámetro de entrada branch1 que inicia el diff. Transforma branch1 en una ref del commit ancestro común compartido entre las dos entradas del diff. El último parámetro de entrada permanece igual como la punta de branch2.

Comparación de archivos de dos ramas

Para comparar un archivo específico en ramas, debes pasar la ruta del archivo como tercer argumento a git diff:

git diff

bash
git diff master new_branch ./test.txt

Práctica

¿Cuáles son las funcionalidades y opciones del comando 'git diff'?

¿Te resulta útil?

Vista previa dual-run — compárala con las rutas Symfony en producción.