Git ofrece un amplio abanico de herramientas muy útiles para el desarrollo de software y que resulta muy interesante conocer y explorar. Hoy os hablaré sobre una de ellas: Git Bisect, ideal para cuando queremos buscar algo concreto en nuestro código.

¿Qué es Git Bisect y cómo funciona?

Bisect viene de binary search algorithm (algoritmo binario de búsqueda) y es una forma eficiente de buscar en grupos grandes de datos (ordenados). Dividiendo la pila por la mitad repetidamente y aplicando algún criterio de validación podremos escanear gran cantidad de información en un número limitado de iteraciones.

Podríamos realizar el bisect de forma manual simplemente haciendo checkout en un commit específico y revisar el código, pero la implementación que os proporcionamos nos protegerá de posibles errores y nos ahorrará mucho trabajo.

¿Cuándo es un buen momento para aplicar bisect? Cuando no estés seguro de cuándo ha tenido lugar un cambio específico en el código; puede ser un bug que no sepas en qué momento fue introducido, o sea difícil de trackear, o un cambio no deseado, por ejemplo un trozo de código que ha sido eliminado por accidente, etc. . . En todos estos casos, bisect te puede resultar muy útil.

GSAS

A modo de ejemplo vamos a imaginar que tenemos un bug. Es difícil saber qué cambio lo causó inicialmente, pero estamos seguros que hace una semana no existía. Perfecto, podemos empezar el bisect.

Antes de empezar con el bisect, ¡por favor guarda todo tu trabajo con un commit o stash!

En primer lugar, inicializamos la búsqueda con:

git bisect start

Luego necesitamos marcar dos commits como good (bueno) y bad (malo) para especificar los límites de la búsqueda. Marcaremos el HEAD actual como malo, ya que el bug se está reproduciendo en la actualidad:

git bisect bad

Acto seguido debemos marcar el punto temporal en el que estamos seguros que todo funcionaba correctamente. Mismo método, se puede especificar mediante el SHA, tag o branch del commit, o simplemente haciendo checkout a un commit en concreto y marcarlo como bueno:

git checkout 1234567

git bisect good

or

git bisect good 1234567

A partir de este momento Git empezará a mover el HEAD entre commits ofreciéndonos la posibilidad de verificar el estado del código en cada momento. Las instrucciones son bastante explícitas, y nos podemos encontrar algo como:

Bisecting: 191 revisions left to test after this (roughly 8 steps)

[commit_123] Add new transaction endpoint

Nuestra tarea es validar el código, bien compilando y ejecutando la aplicación o lanzando un caso de prueba para el problema en cuestión; todo dependerá de dicho problema. Git nos llevará a través del historial del código e irá optimizando paso a paso el número de validaciones que necesitemos hacer. Nuestro trabajo será simplemente decirle a Git en qué momento el código era bueno o ya se había vuelto malo – “git bisect good” o “git bisect bad”. Git automáticamente saltará al siguiente candidato al que se deberá juzgar:

git bisect good

Bisecting: 95 revisions left to test after this (roughly 7 steps)

[commit_321] Replace the User model with new implementation

Después del número especificado de pasos que hay que hacer, Git nos mostrará el commit sospechoso y toda su información.

Al final, no te olvides de hacer un reset. De hecho, que no te de miedo resetear en cualquier momento en caso de que algo haya ido mal y quieras empezar de nuevo, tal que así:

git bisect reset

Esto es todo lo que necesitas para parar el algoritmo de forma elegante.

En caso de que hayas olvidado resetearlo bien, Git guarda toda la información necesaria en el catálogo .git que encontrarás en la raíz de tu repositorio. Quitando todos los archivos `BISECT_` de allí seguramente solventarás buena parte de los posibles problemas relacionados con bisect que te puedas encontrar.

rm .git/BISECT_*

Hora de recapitular. Abre un terminal, si aún no lo has hecho, haz `cd` a un repositorio git que tengas por ahí y practica un poquito.

Primero, comprueba si hay cambios pendientes y hazles commit o stash. Acto seguido, haz lo siguiente:

git rev-list —max-parents=0 HEAD

Esto te dará el SHA del commit inicial de tu repositorio.

Puedes empezar con “git bisect start” o a pasar los puntos malos y buenos (en este orden). Prueba esto:

git bisect start first_commits_sha_number_here HEAD

Deberías ver un mensaje de error. Es normal: intentas buscar un cambio del punto malo al bueno, es decir, que ya todo está bien y el comando no tiene sentido.

El inicio del bisect puede aceptar uno o dos parámetros: solo el malo, o el malo y el bueno. Con esto en mente, vamos a arreglar el comando:

git bisect start HEAD first_commits_sha_number_here

El HEAD es malo. El primer commit es bueno.

Ahora:

`git bisect good/bad`

También puedes usar `git bisect next` o `git bisect skip`. Estas instrucciones te permiten saltar un commit en caso de que no se pueda validar.

Una vez hayas terminado, prueba:

git bisect log

para verlo todo de nuevo

git bisect run

para repetir la diversión. Aquí es interesante mencionar que “run” también puede aceptar un script para verificar el código de forma automática.

Prueba también:

git bisect visualise

Que abrirá tu herramienta visual por defecto. Prueba a experimentar con esto mientras haces un bisect.

Y el último truco de hoy (y por el que probablemente debería haber empezado, pero no habría sido ni la mitad de divertido para mi). Si aún no has abierto el terminal, esta es tu última oportunidad – tan solo haz:

git bisect

Aquí tenéis un recordatorio útil:

usage: git bisect [help|start|bad|good|skip|next|reset|visualize|replay|log|run]

Resumiendo:

Bisect es un algoritmo de búsqueda sencillo de utilizar que nos permite escanear historiales de código bastante largos en un tiempo razonablemente breve y además no es invasivo. Solo acuérdate a empezar con tu directorio de trabajo limpio y a resetear cuando hayas acabado. Utilízalo siempre que necesites buscar en tu historial.

El manual completo lo tienes a tu disposición si tecleas: `git help bisect`.

Referencias: