post thumbnail

Git desde Cero: Blame y Bisect

Publicado Por: Alberto Grespan, El 05/09/2013


Detalles del Curso:

Dificultad: Aprendiz

Duración: 15 min


Hemos habilitado un repo en GitHub para que puedas descargar el código de esta entrada:

Échale un vistazo aquí.

Bienvenidos a un nuevo capítulo de Git desde cero en este curso hablaremos sobre como realizar "debugging" utilizando Git, con las herramientas git bisect y git blame. Los comandos a utilizar esta semana serán los siguientes:

  • git blame * (varios comandos)
  • git bisect * (varios comandos)

¿Realizar "debugging" en git?

Muchas veces en nuestros proyectos y de manera involuntaria, introducimos errores en el código fuente. Existen herramientas que nos ayudan a resolver, a cubrir y darnos cuenta de los defectos que hemos introducido de forma "inmediata" sobre todo cuando se programa de manera orientada a pruebas, mayormente conocida como TDD (Test Driven Development). Con todo y estas "ayudas" para asegurarnos de que nuestras funciones realizan lo que queremos; muchas veces entre una versión y otra el comportamiento de una función cambia ligeramente y nuestra unidad de pruebas no lo detecta. Cómo confiamos plenamente en ella realizamos un "commit" de nuestro código y lo subimos al repositorio remoto. Seguimos programando y subimos otros más. De repente nuestros usuarios comienzan a levantar "tickets" a cerca de un error recurrente; cuando revisamos el código fuente para detectar porqué se produce este error, no detectamos a simple vista que es lo que sucede. En este punto recurrimos a el control de versiones para ir a versiones anteriores y ver que hemos cambiado en estos últimos "commits". Canalizamos la falla a un archivo, y utilizamos nuestras herramientas git blame y git bisect las cuales nos ayudarán a detectar, cuando se introdujo el error y que lo motiva.


¿Qué realiza el git blame?

El comando git blame nos permite observar toda la información de manera detallada a cerca de un "commit". Entre la información que nos brinda el comando está: Quién escribió cada linea en el archivo, cuando lo hizo y a que "commit" pertenece. La palabra "blame" en idioma Inglés es referente a "quien echarle la culpa" o "quien es el culpable" según sea su contexto. Por este motivo llaman a este comando de esta forma.

Vamos a verlo en acción.

$ git blame app.js
c4c4f2a2 (Jonathan Wiesel              2013-09-02 22:38:34 -0430  6) var dotenv = require('dotenv')();
c4c4f2a2 (Jonathan Wiesel              2013-09-02 22:38:34 -0430  7) dotenv.load();
c4c4f2a2 (Jonathan Wiesel              2013-09-02 22:38:34 -0430  8)
ae36bb76 (Oscar Vicente González Greco 2013-08-25 14:05:52 -0430  9) var express = require('express')
ae36bb76 (Oscar Vicente González Greco 2013-08-25 14:05:52 -0430 10) ,   http    = require('http')
ae36bb76 (Oscar Vicente González Greco 2013-08-25 14:05:52 -0430 11) ,   path    = require('path')
c4c4f2a2 (Jonathan Wiesel              2013-09-02 22:38:34 -0430 12) ,  db  = require('./dbConfig')
98b032f9 (Oscar Vicente González Greco 2013-08-29 18:14:19 -0430 13) ,  auth = require('./passportConfig')
98b032f9 (Oscar Vicente González Greco 2013-08-29 18:14:19 -0430 14) ,  flash = require("connect-flash");
ae36bb76 (Oscar Vicente González Greco 2013-08-25 14:05:52 -0430 15)

Podemos apreciar que lo primero que nos muestra es el "hash" corto, único del "commit", luego encontramos el nombre de usuario que realizó, la fecha, y la respectiva línea de código.

También podemos filtra el número de "commits" que queremos observar. Por ejemplo: si sabemos que nuestro problema comenzó a ocurrir a partir de un "commit" específico y se refleja hasta "X" "commit" más adelante filtramos estos resultados para encontrar que se modificó en estos "commit".

$ git blame ae36..c4c4 -- app.js

Si queremos cambiar el nombre de la persona por su email, realizamos lo siguiente.

$ git blame -e app.js

En general y con la ayuda este comando podemos encontrar quién fue el culpable de introducir un error particular en uno de nuestros proyectos.


¿Qué realiza el git bisect?

Este comando nos ayuda a verificar que fue lo que sucedió con nuestro código entre varios "commits", es decir. Le notificamos a Git que versión está buena o no produce el error y que versión da el error o se comporta de manera extraña. De aquí en adelante git busca un "commit" intermedio a estos dos que le dimos anteriormente y realiza una especie de "checkout" el cual nos permite estar en la versión de código del "commit" intermedio, es aquí cuando realizamos nuestras pruebas, si todo marcha acode a lo deseado, le notificamos a git que éste "commit" se encuentra bien y proseguimos, luego git vuelve a buscar otro "commit" intermedio a este nuevo que nosotros confirmamos como "correcto" y el "commit" final de nuestra búsqueda. Realizamos el mismo procedimiento hasta dar con el error. Vamos a demostrarlo.

$ git log
* c811a8b - Jonathan Wiesel, 3 days ago : cambiado tamaño de username en model user
* 489c942 - Jonathan Wiesel, 3 days ago : ignorado archivo de intelliJ
* 98b032f - Oscar Vicente González Greco, 5 days ago : se agrego soporte para sesiones con passport.js
* 288dce7 - Oscar Vicente González Greco, 9 days ago : se eliminaron los DS_store ;
* 2b0356f - Oscar Vicente González Greco, 9 days ago : re arregló gitignore
* ae36bb7 - Oscar Vicente González Greco, 9 days ago : Se eliminó intellij. se agregó orm. se reorganizó estructura del proyecto a una más mantenible.
* e2d314d - Oscar Vicente González Greco, 2 weeks ago : commit inicial / se hizo un CRUD de usurio

Vamos a elegir el "commit" e2d314d cómo bueno y c4c4f2a cómo el malo.

$ git bisect start
$ git bisect good e2d314d
$ git bisect bad c4c4f2a
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[98b032f929230bcda22367f90223b270a3199800] se agrego soporte para sesiones con passport.js

En este punto corremos nuestra suite de pruebas o las pruebas necesarias.

$ git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[c811a8b18de58a2aed18b70df6019b03672ef637] cambiado tamaño de username en model user

Corremos nuevamente la suite de pruebas o las pruebas necesarias.

$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[b53c0dd8432aa928cded2efe2f49f2a3a81adcff] agregado modelo vehicle y userVehicle, agregado listar todos los vehículos del sistema

Corremos nuevamente la suite de pruebas o las pruebas necesarias. Encontramos el error, marcamos como malo.

$ git bisect bad
b53c0dd8432aa928cded2efe2f49f2a3a81adcff is the first bad commit
commit b53c0dd8432aa928cded2efe2f49f2a3a81adcff
Author: Jonathan W
Date:   Sat Aug 31 17:38:23 2013 -0430

    agregado modelo vehicle y userVehicle,
    agregado listar todos los vehículos del sistema

:100644 100644 983255ad9dd82962c0e577a89ee9fdc2ae77060d 260904ad4a32820ce4103e57e4558d06b2111f40 M  app.js
:040000 040000 03f3fa7be92462c3c4cbc52d1e023516540fe62f 4bddcd8a960bc0f6944e2c078b9e11d2f58085fd M  controllers
:100644 100644 6d17e5f8f000caf50ae4e13d93f6c1b0317a6711 49278121379ba65eb8db4652625bd4be34c802ce M  dbConfig.js
:040000 040000 5b87e3f615ac423234361bb062eaa2afd0011c3a ebba61f808c3d7894bcf02faf31d85c49e227e3b M  models

Reseteamos el estado del bisect

$ git bisect reset
Previous HEAD position was b53c0dd... agregado modelo vehicle y userVehicle, agregado listar todos los vehiculos del sistema
Switched to branch 'master'

De Aquí en adelante nos toca realizar un "checkout" de la versión que queremos corregir, o parcharla directamente sobre lo que venimos trabajando.


Conclusión

En este último capítulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder debugear con ayuda de git, utilizando las herramientas que nos ofrece. Dichas herramientas ciertamente nos pueden salvar de graves problemas, de igual forma te invitamos a revisar la documentación de ambas herramientas. Si te surge algún tipo de duda no te detengas y déjanos un comentario, que gustosamente lo responderemos.

¡Hasta la semana entrante!


¿Te ha gustado esta publicación?

Compártela:

Por Alberto Grespan

Conoce más sobre este autor aquí


comments powered by Disqus