Skip to content
This page has been auto-translated and may contain errors.View in English

Ver el historial de Git con log, show y diff ​

docs.scrimba.com

Imagina que abres weather-app un lunes por la mañana y no recuerdas exactamente qué subiste el viernes. O un compañero te pregunta por qué cambió la conversión de temperatura la semana pasada, y quieres darle la respuesta real en lugar de una suposición. El ciclo del commit explica cómo se guarda un commit. Este capítulo trata sobre cómo leer ese historial: qué pasó, quién lo hizo y cuándo. El comando para eso es git log, y esto es todo lo que imprime para un proyecto pequeño:

bash
$ git log
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: Priya Nair <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    Fix temperature conversion in Celsius-to-Fahrenheit formula

commit 5f3d8b21a90e7c6d5b4a3f2e1d0c9b8a7f6e5d4c
Author: Kwame Boateng <[email protected]m>
Date:   Mon Jul 13 16:45:22 2026 +0100

    Add five-day forecast to the dashboard

commit 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
Author: Kwame Boateng <[email protected]m>
Date:   Mon Jul 13 11:03:47 2026 +0100

    Set up project structure

Con un solo comando, tienes toda la historia del proyecto ahí mismo: tres commits, del más reciente al más antiguo, cada uno con quién lo escribió, cuándo y por qué.

Leer el historial con git log ​

git log recorre hacia atrás cada commit alcanzable desde donde estás, empezando por el más reciente. Cada entrada muestra cuatro cosas: un hash (la cadena larga de letras y números que identifica ese commit exacto), el autor, la fecha y el mensaje que su autor escribió.

Un commit es la combinación de esas cuatro cosas: una foto de todos los archivos rastreados en ese momento, el mensaje que describe el cambio, quién lo hizo y un enlace al commit inmediatamente anterior, su commit padre. Ese enlace al padre es lo que convierte un montón de fotos sueltas en una línea de tiempo real. Si lees git log de arriba hacia abajo, estás recorriendo esa línea de tiempo al revés, desde el presente hasta el inicio.

El hash se ve intimidante al principio, pero casi nunca necesitas la cadena completa. 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c y 4f2a1c9 apuntan al mismo commit. Git solo necesita la cantidad de caracteres del hash que baste para distinguirlo de cualquier otro commit del repositorio, y los primeros siete caracteres casi siempre son suficientes. Vas a ver la forma corta en todos lados, incluidos los comandos del resto de este capítulo.

La salida por defecto de git log es completa pero ocupa mucho espacio: tres commits ya llenaron toda tu terminal. Hay algunas variantes que la hacen más útil en el día a día.

bash
$ git log --oneline
4f2a1c9 Fix temperature conversion in Celsius-to-Fahrenheit formula
5f3d8b2 Add five-day forecast to the dashboard
1a2b3c4 Set up project structure

--oneline reduce cada commit a su hash corto y su mensaje, una línea por commit, que es la forma que más vas a usar. --graph dibuja la forma del historial junto al log, como un conjunto de líneas y puntos. En un proyecto sin ramas todavía, dibuja simplemente una línea recta, pero conviene que te acostumbres a usarla desde ya: en el momento en que aparecen las ramas (el próximo capítulo) es cuando esa imagen realmente empieza a valer la pena.

También puedes filtrar el log en lugar de desplazarte por él. git log --author="Kwame" muestra solo los commits escritos por Kwame, útil cuando quieres ver el trabajo de una persona en un proyecto compartido. git log -- src/index.js muestra solo los commits que tocaron ese archivo específico, ignorando todo lo que nunca se acercó a él:

bash
$ git log --oneline -- src/index.js
4f2a1c9 Fix temperature conversion in Celsius-to-Fahrenheit formula
1a2b3c4 Set up project structure

Ese segundo commit, el del pronóstico, nunca tocó src/index.js, así que no aparece. Ambos filtros se combinan bien con --oneline.

Los filtros anteriores responden "qué commits tocaron este archivo". La pregunta que en realidad te manda a revisar el historial en un mal día es más precisa: ¿cuándo apareció o desapareció exactamente esta línea de código? Para eso está git log -S, conocido como el pickaxe. Le das una cadena de texto, y solo conserva los commits donde cambió la cantidad de veces que aparece esa cadena, es decir, los commits que la agregaron o la eliminaron:

bash
$ git log --oneline -S "showLoadingSpinner"
7d1e8c3 Add loading spinner while forecast data loads

Un solo commit, de todo el historial: el momento en que esa llamada entró al código. Esta es la forma más rápida de responder "cuándo se introdujo esta línea con el bug" sin tener que revisar nada manualmente. La regla de conteo tiene una consecuencia que vale la pena conocer: un commit que solo mueve la línea dentro de un archivo no cambia el número de apariciones, así que -S lo omite. Cuando quieras encontrar cada commit cuyo diff toque ese texto de alguna forma, incluyendo movimientos, usa git log -G con una expresión regular en su lugar. Recurre primero a -S; es la herramienta más precisa para la pregunta que normalmente tienes.

JunoLeer el historialgit log lista cada commit, del más reciente al más antiguo, con su hash, autor, fecha y mensaje. Un commit es esa foto del proyecto más su mensaje más un enlace al commit anterior. Casi nunca necesitas el hash completo: los primeros caracteres bastan para que Git sepa exactamente a qué commit te refieres.
JunoLeer el historialgit log --oneline es la forma que vas a usar todos los días, una línea por commit. Agrega --author o una ruta al final con -- ruta para filtrar por el trabajo de una persona o el historial de un archivo, y recurre a --graph en cuanto entren las ramas en escena.
JunoLeer el historial El hash de cada commit es una huella digital de su propio contenido más el hash de su padre, así que dos commits nunca coinciden por accidente y es seguro escribir un prefijo corto. Y cuando la pregunta es "cuándo apareció o desapareció esta línea", git log -S "texto" recorre todo el historial por ti y solo conserva los commits que la agregaron o la eliminaron. Entre eso y el enlace al padre, este capítulo es la mayor parte de mis herramientas para depurar.

Inspeccionar un commit con git show ​

git log te dice que ocurrió un commit. git show <hash> te dice exactamente qué hizo:

bash
$ git show 4f2a1c9
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: Priya Nair <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    Fix temperature conversion in Celsius-to-Fahrenheit formula

diff --git a/src/index.js b/src/index.js
index 3f2c1a9..7b8e2d4 100644
--- a/src/index.js
+++ b/src/index.js
@@ -12,7 +12,7 @@ function celsiusToFahrenheit(celsius) {
-  return celsius * (9 / 5 + 32)
+  return (celsius * 9) / 5 + 32

La mitad superior es la misma información que muestra git log. Debajo está el cambio real: una línea que empieza con - es una línea que el commit eliminó, una línea que empieza con + es una línea que agregó, y las líneas sin marca son contexto que se mantuvo igual. Aquí se lee con claridad: la línea antigua agrupaba el 32 dentro del paréntesis, así que se sumaba antes de que ocurriera la multiplicación. La corrección reagrupa los paréntesis alrededor de celsius * 9 para que el 32 se sume al final, el error de precedencia de operadores que describe el mensaje de Priya.

Agrega una ruta para ver solo una parte de un commit más grande: git show 4f2a1c9 -- src/index.js muestra solo la porción del cambio correspondiente a ese archivo, algo que importa cuando un solo commit toca varios archivos y solo te interesa uno de ellos.

JunoInspeccionar un commitgit show <hash> muestra un commit completo: quién lo hizo, cuándo y las líneas exactas que cambió. Las líneas eliminadas empiezan con un signo menos, las líneas agregadas empiezan con un signo más. Es la forma más rápida de responder "qué hizo realmente este commit".
JunoInspeccionar un commitgit show <hash> te da la información general y el diff completo de un commit. También puedes indicarle una ruta específica, git show <hash> -- ruta/al/archivo, cuando un commit tocó varios archivos y solo necesitas la parte de uno en particular.
JunoInspeccionar un commitgit show está comparando la foto guardada de un commit contra la de su padre, e imprimiendo solo las líneas que difieren. Una vez que empiezas a leer los diffs de esta forma, un commit deja de ser una caja misteriosa y se convierte en dos fotos con una diferencia entre ellas.

Qué muestra git diff, y la confusión en la que casi todos caen ​

git log y git show leen el historial ya confirmado. git diff lee lo que todavía no se ha confirmado: los cambios que están en tu directorio de trabajo en este momento, comparados con tu último commit.

bash
$ git diff
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+A five-day weather dashboard built with vanilla JavaScript.

Ese es el cambio que hiciste en README.md, mostrado antes de que hicieras stage o commit de nada. Aquí viene la parte que atrapa a casi todos en su primera semana: ejecuta git add . para hacer stage de ese mismo cambio, luego ejecuta git diff otra vez, y no muestra absolutamente nada.

bash
$ git add .
$ git diff

No se imprime nada. El cambio no desapareció, y no pasó nada malo. git diff en su forma simple compara tu directorio de trabajo contra el área de staging, y una vez que hiciste stage de todo, esas dos cosas ahora coinciden, así que no queda ninguna diferencia que mostrar ahí. Para ver los cambios que están esperando en el área de staging, usa git diff --staged.

bash
$ git diff --staged
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+A five-day weather dashboard built with vanilla JavaScript.

El mismo cambio, ahora visible, porque --staged compara el área de staging contra tu último commit en lugar del directorio de trabajo.

git diff en su forma simple y git diff --staged responden dos preguntas distintas, y ayuda nombrarlas con precisión. git diff en su forma simple compara tu directorio de trabajo con el área de staging: muestra los cambios que hiciste pero que todavía no pusiste en stage. git diff --staged compara el área de staging con tu último commit: muestra exactamente lo que entraría en tu próximo commit si ejecutaras git commit ahora mismo. Ninguno de los dos muestra ambas cosas a la vez, y por eso justamente un cambio completamente en stage hace que git diff en su forma simple no muestre nada. A veces vas a ver --cached en tutoriales y documentación más antiguos; significa lo mismo que --staged.

Ejecutar ambos antes de confirmar un commit es un buen hábito: git diff en su forma simple confirma que no quedó nada importante sin stage, y git diff --staged confirma exactamente lo que está a punto de guardarse.

JunoVer qué cambiógit diff muestra los cambios en tu directorio de trabajo que todavía no están en stage. Una vez que haces stage de todo con git add, git diff en su forma simple no muestra nada. Eso es lo esperado, tus cambios siguen ahí. Usa git diff --staged para ver lo que está esperando para confirmarse.
JunoVer qué cambiógit diff en su forma simple compara el directorio de trabajo contra el área de staging, git diff --staged compara el área de staging contra tu último commit, son dos comparaciones distintas. Ejecutar ambas antes de confirmar un commit te dice qué está sin stage y qué está a punto de guardarse. En material más antiguo a veces se usa --cached, es la misma opción con otro nombre.
JunoVer qué cambió Ambos diffs son la misma operación aplicada a pares distintos de fotos: el árbol de trabajo contra el área de staging, o el área de staging contra el último commit. Identificar cuáles dos cosas estás comparando es todo el truco para no volver a confundirte con un git diff vacío.

Por qué el historial de Git forma un grafo ​

Cada commit que has visto hasta ahora apunta exactamente a un padre, y leer git log de arriba hacia abajo se ha sentido como leer una línea recta. Eso se cumple en un proyecto individual que trabaja en una sola línea de desarrollo. Deja de cumplirse en el momento en que entran en juego las ramas y las fusiones, que se cubren a continuación en Ramas, porque el historial real de un proyecto puede dividirse en líneas separadas y luego volver a unirse.

Para esto sirve en realidad la opción --graph que vimos antes. En weather-app, por ahora dibuja una sola columna, porque solo hay una línea de commits que dibujar. En cuanto una rama se separa y más adelante se fusiona de nuevo, --graph empieza a dibujar la separación y la reunión como columnas distintas que se encuentran, algo mucho más fácil de leer que tratar de imaginarlo a partir de una lista plana de hashes.

Ejecuta git show sobre un commit de fusión y, por defecto, solo imprime la información general: ningún diff. Agrega -m y va a imprimir un diff separado para cada padre, uno por uno. Ambos comportamientos se explican por la misma estructura: el historial de Git es un DAG, un grafo acíclico dirigido. "Dirigido" significa que cada enlace apunta en un solo sentido, de un commit hacia su padre, nunca hacia adelante. "Acíclico" significa que esos enlaces nunca forman ciclos, así que al recorrerlos siempre te mueves hacia el inicio del proyecto, nunca de vuelta a un commit que ya pasaste. Un commit normal tiene exactamente un padre, por eso el historial de un proyecto individual se lee como una línea recta. Un commit de fusión es la excepción: carga dos hashes de padre en lugar de uno, y con dos padres, git show en su forma simple no tiene "el diff" único para imprimir hasta que -m le indica que compare contra cada padre por separado. Ramas y Fusiones, los próximos dos capítulos, se construyen directamente sobre este mismo grafo.

JunoEl historial como grafo Por ahora, cada commit que has visto apunta a un solo padre, así que el historial se lee como una línea recta. Eso cambia en cuanto las ramas se separan y luego se vuelven a unir, algo que verás a continuación. La estructura de fondo, commits enlazados al commit anterior, es lo que hace posible todo esto.
JunoEl historial como grafo Una línea individual de commits se ve recta porque cada uno tiene un solo padre. La opción --graph es lo que hace visible esa estructura en cuanto empiezan las ramas, dibujando bifurcaciones y fusiones en lugar de una lista plana. Consérvala en tu caja de herramientas incluso antes de necesitarla.
JunoEl historial como grafo El historial de Git es un grafo acíclico dirigido: los punteros a los padres siempre apuntan hacia atrás, y nunca forman ciclos. Un commit de fusión es el único caso donde un commit tiene dos padres en lugar de uno, y por eso git show en su forma simple no imprime ningún diff ahí hasta que agregas -m para elegir un padre. Ramas y Fusiones te enseñan el resto de este mismo grafo, desde ángulos distintos.