Git commits

Mario González - Blog sobre desarrollo web

Aprender Git (III): Qué es un commit (y qué no)

| ,

En los dos primeros artículos de la serie Aprender Git hemos visto algunos conceptos fundamentales de este sistema de control de versiones y hemos aprendido a instalarlo y configurarlo. Es momento de recogerse las mangas y empezar a trabajar con él. En este artículo vamos a aprender qué es realmente un commit y qué tenemos que tener en cuenta a la hora de crear uno.

¿Qué es un commit?

Un commit es, básicamente, una fotografía de la carpeta de nuestro proyecto en un momento determinado. Cuando hacemos un commit, estamos congelando el estado de todos los ficheros y subdirectorios, y guardando la instantánea en un histórico. Al comenzar a usar Git, un error muy común es tenerlo como un simple sistema de backups: una práctica habitual al principio es pensar en los commits como un CTRL-S masivo sobre todos nuestros archivos. “Voy a ir guardando esto para que no se pierda” nunca debería ser el pensamiento que preceda a la creación de un commit.

Cuando usamos un sistema de control de versiones en un proyecto, uno de los objetivos que perseguimos es mantener un registro de los cambios que se han producido en el código a través del tiempo. No sólo queremos tener un backup de nuestros archivos, queremos poder mirar hacia atrás y ver cómo ha ido mutando o avanzando nuestro código. Para ello, Git nos va a mostrar un listado de los cambios que ha sufrido el código, es decir, una línea temporal donde iremos viendo diferentes puntos o hitos, cada uno de ellos acompañados de un mensaje descriptivo. Cada uno de esos hitos será un commit, y Git no creará automáticamente esos hitos: somos nosotros los que tenemos que decidir cuándo es momento de crear un commit.

¿Cuándo es el mejor momento para crear un commit?

¿Cada cuánto tiempo deberíamos crear un commit ? ¿Al acabar la jornada? ¿Tres veces a la semana? En realidad no deberíamos usar una medida temporal. Deberíamos crear un commit cuando queramos añadir un nuevo hito al listado de cambios del proyecto. Por tanto, tenemos que pensar en cómo será el histórico del proyecto dentro de unas semanas o meses, y decidir si entre toda la maraña de cambios que se han ido registrando debería aparecer un punto con el estado actual de nuestro código.

Si me piden cambiar en bloque todos los logotipos del footer de una web y tardo dos días en hacerlo, lo lógico es que cree un commit cuando haya modificado todas las imágenes. Crear un commit por cada imagen alargaría el histórico innecesariamente, y crear un commit simplemente al acabar cada jornada o antes de salir a desayunar no aporta ninguna información sobre los cambios que ha sufrido el código. Si dos meses después un revisor de código necesita volver a cómo estaba el proyecto después de cambiar los logotipos, de nada le servirá volver a un commit que fue motivado por la hora del café.

No hay, por tanto, recetas que nos indiquen cuándo se crean los commits. Debemos decidir cuándo el estado actual del proyecto tiene entidad suficiente como para aparecer en un probablemente largo árbol cronológico de cambios. Si utilizamos gestores de tareas, podemos asociar los commits a tareas, aunque dependiendo de la metodología que usemos, la relación entre commit y tarea no tendrá por qué ser 1:1. Si las tareas están muy atomizadas y son muy pequeñas, lo más seguro es que tengamos un commit por tarea, pero si las tareas incluyen varios cambios en el código, acabaremos teniendo varios commits por cada tarea.

¿Y qué mensaje escribo en el commit?

Elegir un buen mensaje para un commit es, junto a escribir comentarios en el código, una de las tareas más incómodas para los desarrolladores. Nos gusta picar código pero nos da mucha pereza describirlo.

Volvamos a pensar en el revisor de código que mira el histórico de cambios dentro de dos meses (o nosotros mismos buscando un bug). ¿Cómo encontrar algo en un árbol de cambios donde cada commit va acompañado de mensajes como “Cambios”, “Nuevos estilos”, “CSS”, “Borrado” o “Estilos botón”? Al crear un commit tenemos la responsabilidad de describir los cambios que estamos fotografiando. Y a la hora de describirlos tenemos que intentar que los mensajes no sean ni demasiado sintéticos ni demasiado largos.

Un mensaje muy sintetizado, por ejemplo, “Cabecera” (cuando escuchéis una voz diciendo “sí, yo me acordaré de lo que va en este commit”, no le hagáis ningún caso) no ayudará a diferenciar un commit en un listado con cientos de ellos. Un mensaje muy largo, por ejemplo, “Mario cambia el modificador de accesibilidad de las propiedades de la clase Conector para arreglar el bug de error de conexión a la base de datos”, hará la búsqueda más lenta y ensuciará el gráfico del histórico (nota: no hace falta que pongas tu nombre en los mensajes, el commit ya lleva tu nombre asociado). 

Para los dos ejemplos anteriores podríamos escribir “Cabecera sticky y cambio de posición en la top bar” y “Visibilidad protected para las propiedades de la clase Conector” (la información de que el commit es un fix la podemos añadir con una etiqueta).

Si tras hacer un commit te das cuenta de que podrías mejorar el mensaje, siempre puedes utilizar git commit --amend, que te abrirá un editor de texto con el mensaje que habías escrito y te permitirá modificarlo. Recuerda que esto sólo se puede hacer con el último commit.

¿Qué información contiene un commit?

Un commit, como decíamos antes, guarda una instantánea del estado de un proyecto (en cuanto a directorios y ficheros) en un momento determinado. Por tanto, un commit internamente almacena referencias a archivos y directorios. Sin embargo, cuando le preguntemos a Git qué contiene un commit, nos dará una información mucho más útil: qué cambios se han introducido en el código respecto al commit anterior.

Visualización por consola de los cambios que introduce un commit
Visualización en Sourcetree de los cambios que introduce un commit

Además, un commit también almacena el autor (quién ha creado el commit), la fecha y de qué commit proviene.

¿Y si tengo algunas cosas terminadas y otras por terminar?

A veces nuestro código tiene algunas tareas ya cerradas, que nos indican que ya podemos hacer un commit, pero tiene otras partes a medias. Lo ideal es que un commit refleje cambios cerrados, y para ello Git nos ofrece la opción de elegir qué partes del código irán al commit y qué otras no. En el siguiente artículo veremos cómo se prepara un commit y qué herramientas tenemos para decidir qué archivos entran en un commit y cuáles se quedan fuera, o cómo podemos incluir en un commit una parte de código de un archivo, dejando otras partes del mismo archivo fuera del commit.

Aquí os dejo el índice de artículos de la serie Aprender Git por si queréis ver el resto de contenidos:

¿Qué opinas?

Tu dirección de correo electrónico no será publicada. * Campos obligatorios