El increible Git III. ¿Qué hice el año pasado?


Luego de haber versionado tu proyecto n veces, es probable que desees navegar por el histórico de todas esas versiones, cambiar tu directorio de trabajo hacia alguna de ellas para comprobar el funcionamiento de la App en un estado anterior, analizar el comportamiento de los requisitos que han sido implementados en cada versión o reutilizar el primer commit que hiciste como plantilla para un nuevo proyecto.

¿Plantilla para un nuevo proyecto? Pregunta usted.

Sí, esta es una de las cosas que más me gustan de usar un VCS. Como desarrollador web que soy, uno de los problemas que tenía que afrontar a la hora de crear un proyecto tan simple como una página estática con varios archivos css y js era la necesidad de estar creando una y otra vez el “cascarón” del proyecto. Incluir los css y js en el header del documento index.html, en el caso de trabajar con un framework como Symfony2 o Phalcon, configurar el acceso a datos, las rutas en fin, todo lo necesario para comenzar a desarrollar la nueva App.

Al crear un commit con todos los ajustes iniciales hechos, me permite crear tantas plantillas nuevas necesite, pues aunque vaya por una etapa avanzada de desarrollo, me es posible volver a la primera versión, copiar los archivos tal y como están para otro lugar, y utilizarlos en el nuevo proyecto.

¡Para eso mejor tengo una copia en el HD de cada plantilla de proyecto, y cuando quiera reutilizarla la copio y comienzo a trabajar! Afirma usted.

Es verdad, pero este modo de hacerlo con Git te permite, con el uso del desarrollo en ramas (tema que veremos más adelante), tener n apps que realizan tareas totalmente diferentes utilizando los mismos archivos para todas. Esta característica de Git es la llamada “Git killer’s feature” o “la característica deslumbrante de Git”. Las personas que usan este VCS lo afirman así pues no hay otro VCS que realize el trabajo en ramas tan eficiente y cómodo como lo hace Git.
La otra razón para no hacer lo que planteas en la afirmación anterior es que al final esa plantilla la terminarás versionando con Git (ese es el objetivo ¿no?) entonces, qué más da copiarlo de ese proyecto que ya está versionado y configurado además para Git.

Ver y analizar el histórico del proyecto

La primera acción deseable es ver la lista de commits creada hasta el momento. El comando git log te permite hacerlo, y cuenta con una gran cantidad de opciones para filtrar lo que quieres ver y cómo lo quieres ver. He añadido par de commits al proyecto webapp, esta es la salida de la ejecución del comando anterior:

Ejecución del comando git log

Fig1: Ejecución del comando git log

Lo subrayado en rojo son los comentarios de cada commit. La serie de números y letras seguidas de la palabra commit es un Hash encriptado en SHA-1, que identifica a dicho commit. Como identificador, con este hash se puede obtener la información del commit asociado, así como cambiarse a la versión existente en dicho commit.

Para limitar la cantidad de información puedes añadir la opción -n, donde n es el número de commits que quieres que se muestren. Para ver en detalle cuáles fueron los cambios realizados en la última versión del proyecto, ejecuta el siguiente comando:

git log -1 -p

La opción -p indica a Git que debe mostrar el commit en modo diff (mostrar las diferencias de versiones) y el resultado se puede apreciar en la siguiente imagen:

Ver las diferencias del commit

Fig2: Diferencias de los commit

Añadí una línea roja a la imagen para indicarte que ese archivo “— a/README.md” es la versión anterior al commit, y la línea verde te muestra la nueva versión (“+++ b/README.md”). Más abajo se muestran las modificaciones que se hicieron al archivo. La línea en rojo con el signo de menos delante es información que se eliminó del archivo, en contraste, las líneas en verde indican lo que se añadió. Otra forma útil de ver el commit es en modo estadística, donde te muestra de cada commit un resumen de qué fue lo que se hizo:

git log -1 –stat

Puedes observar en la Fig3 un resumen (las últimas 2 líneas) especificando el/los archivos que fueron modificados, y la cantidad de líneas que se añádieron/eliminaron. En este caso “README.md | 3++-” significa que se añadieron 2 líneas y se eliminó una a ese fichero. La última línea también especifica la cantidad de eliminaciónes/modificaciones/añadidos, pero teniendo en cuenta todos los archivos, o sea, son cifras totales.

Log con estadísticas

Fig3: Log con estadísticas

Crear una salida personalizada

Git es tan flexible que te permite crear un informe personalizado para el comando log. Esto se logra mediante la opción –pretty que acepta varios valores para mostrar el commit como desees. Si solamente quieres ver por cada commit el comentario que se hizo, ejecuta:

git log --pretty=oneline

El valor format de la opción –pretty es el más flexible en cuanto a personalización se refiere, pues tiene muchos comodines para adaptar la salida. Probemos con los comodines %h (muestra el hash del commit abreviado), %an (nombre del autor), %ar (fecha relativa del commit) y %s (comentario del commit). El comando quedaría compuesto de esta forma:

git log --pretty=format:"%h - %an, %ar : %s"

Y arroja el siguiente resultado:

Log personalizado

Fig4: Log personalizado

Como puedes ver es bastante útil esta información, pues a parte de que puedes ver las cosas con  mejor orden, el identificador hash es más corto y lo puedes utilizar para cambiar hacia un commit en específico.

Volviendo al pasado

Hagamos eso, vamos a la primera versión del proyecto, para ello utilizaremos el último de los hash que aparecen en la salida del comando anterior, que corresponde al primer commit:

git checkout 55a5c5f

Con esto volvemos al estado inicial. Observa que si ejecutas git log nuevamente, solo te aparecerá en el historial un commit, dando la impresión que se volvió atrás en el tiempo. Puedes volver al “presente” haciendo la misma operación, pero especificando el hash del commit más reciente que tenías, el cual puedes consultar con el último “git log” que ejecutaste.

En este punto inicial, si comienzas a hacer cosas nuevas y guardas nuevas versiones, Git te advertirá que estos nuevos commits “los estás dejando atrás”, pues ya existe una línea de commits que estarías intentando sobre escribir, lo cual no es permitido.

Que no esté permitido no significa que sea una debilidad, significa que la forma de hacerlo no es sobreescribiendo los commits que ya existían, sino creando una nueva rama (branch) para la nueva línea de versiones. Este tema lo veremos más adelante, pero ya conoces que es posible hacerlo, y es una de las cosas que hacen de Git una maravilla.

Concluyendo

No me extraña que Git sea un software tan bueno, al fin y al cabo su creador es Linus Torvalds, que en su afán por versionar de forma eficiente las versiones del kernel Linux, ideó esta extraordinaria herramienta.

¿Sabías que hay muchas personas trabajando en el kernel Linux para que sea mejor cada día? En ese caso cabe preguntarse: ¿Cómo se gestionan estos procesos de colaboración? ¿Cómo una persona puede ver los aportes de las demás y cómo pueden contribuir con el proyecto? Bien, estos serán los temas a abordar en los próximos capítulos (que incluyen el trabajo con ramas) de “El increíble Git”. Mientras, te invito a que juegues con tus logs y viajes al pasado y vuelvas al presente cada vez que desees.