git bisect
Aprende el comando git bisect para buscar en binario tu historial y encontrar el commit exacto que introdujo un error. Incluye automatización con run.
El comando git bisect te ayuda a encontrar el commit exacto que introdujo un error realizando una búsqueda binaria a través de tu historial. Le indicas a Git un commit donde el código funcionaba ("good") y otro donde está roto ("bad"), y Git extrae el punto intermedio para que lo pruebes, reduciendo a la mitad el rango sospechoso cada vez, hasta que queda un único culpable.
Este capítulo cubre cómo ejecutar una sesión de bisect manualmente, cómo interpretar el progreso que Git imprime tras cada respuesta, cómo automatizar toda la búsqueda con un comando de prueba, cómo omitir commits que no se pueden probar, y cómo recuperarse si cometes un error.
Definición
Por qué búsqueda binaria
Si un error apareció en algún lugar de los últimos 1.000 commits, revisarlos uno por uno sería agotador. La búsqueda binaria necesita solo unas diez pruebas para identificar al culpable, porque cada respuesta reduce a la mitad los candidatos restantes — aproximadamente log2(N) pasos para N commits. git bisect automatiza el seguimiento para que solo tengas que responder "¿funciona aquí?"
Iniciar una sesión de bisect
Comienza la sesión, luego marca el estado roto actual y un commit pasado conocido como bueno:
git bisect start
git bisect bad # the current commit is broken
git bisect good v1.4.0 # this tag was known to workGit extrae un commit a mitad de camino entre ellos. Compilas y pruebas esa revisión, luego reportas el resultado:
git bisect good # this commit works — bug is newer
# or
git bisect bad # this commit is broken — bug is here or olderDespués de cada respuesta Git imprime cuánto del rango queda y extrae el siguiente punto intermedio:
Bisecting: 7 revisions left to test after this (roughly 3 steps)
[a1b2c3d4...] Refactor the parserRepite el ciclo de prueba y marcado hasta que Git anuncia el primer commit malo:
a1b2c3d4 is the first bad commit
commit a1b2c3d4...
Refactor the parserLeer el resultado con git bisect log
En cualquier momento puedes revisar las respuestas que has dado hasta ahora. Esto también es útil para mantener un registro de la sesión:
git bisect logSi sospechas que marcaste un commit incorrectamente, reinicia y repite un log corregido en lugar de empezar de nuevo:
git bisect log > bisect-run.txt # edit out the mistaken line
git bisect reset
git bisect replay bisect-run.txtTerminar la sesión
Cuando Git reporta al culpable, regresa al punto donde comenzaste:
git bisect resetEsto restaura HEAD a la rama en la que estabas antes del bisect.
Automatizar con git bisect run
Si puedes expresar la prueba como un script o comando que termina con 0 para bueno y distinto de cero para malo, Git ejecutará toda la búsqueda sin supervisión:
git bisect start HEAD v1.4.0
git bisect run npm testGit extrae cada punto intermedio, ejecuta el comando, interpreta el código de salida y se detiene en el primer commit fallido — no se requiere marcado manual.
El comando puede ser cualquier ejecutable: una línea de código, un script de shell o un binario. El código de salida 0 significa bueno, cualquier código entre 1 y 127 (excepto 125) significa malo. El código de salida especial 125 le indica a Git que el commit no se puede probar y equivale a ejecutar git bisect skip — úsalo cuando la propia compilación está rota en esa revisión:
#!/bin/sh
# test.sh — skip commits that don't even compile
make || exit 125
./run-the-failing-case # exits non-zero when the bug is presentgit bisect start HEAD v1.4.0
git bisect run ./test.shgit bisect run debe ser idempotente y autocontenido. Si tu prueba deja artefactos de compilación o archivos modificados, añade un paso de limpieza para que el siguiente checkout empiece limpio — de lo contrario, un binario obsoleto puede hacer que un commit bueno parezca malo.Omitir commits que no se pueden probar
A veces el commit extraído está roto por una razón no relacionada — no compila, o falta una dependencia — por lo que genuinamente no puedes decir "good" ni "bad". Dile a Git que lo descarte:
git bisect skipGit elige un commit cercano en su lugar y continúa reduciendo el rango. Si se omiten demasiados commits en una región, Git puede reportar un rango de candidatos en lugar de un único commit.
Opciones comunes
| Comando | Descripción |
|---|---|
git bisect start | Inicia una sesión de bisect. |
git bisect bad [<commit>] | Marca un commit como roto (por defecto el actual). |
git bisect good [<commit>] | Marca un commit como funcional. |
git bisect skip | Omite un commit que no se puede probar (por ejemplo, no compila). |
git bisect run <cmd> | Automatiza la búsqueda usando el código de salida de un comando de prueba. |
git bisect log | Imprime las respuestas good/bad dadas hasta ahora. |
git bisect replay <file> | Reproduce un log de bisect guardado. |
git bisect reset | Termina la sesión y restaura el HEAD original. |
Comandos relacionados
Una vez que bisect señala al culpable, estos comandos te ayudan a inspeccionarlo y actuar sobre él:
- git show — ver los cambios exactos que introdujo el commit malo.
- git blame — ver qué commit modificó por última vez una línea específica.
- git log — explorar el historial por el que bisect buscó.
- git revert — deshacer el commit malo sin reescribir el historial.
- git checkout — cómo Git mueve
HEAD, que bisect usa internamente.