Cómo ser un Super Desarrollador: introducción a git-flow (Parte 1)

Git es, sin duda alguna, el sistema de control de versiones más utilizado en la actualidad. Gracias a su tremendo poder y flexibilidad, el trabajo en equipo dejó de ser un dolor de cabeza.

Git es, para los programadores, — ¡spoilers a la vista! — lo que el traje de Batman es para Bruce Wayne.

(¡Vamos! A todos nos gusta Batman. Pero hay que reconocer que tiene mucha ayuda con su traje)

El principal poder de Git reside en su capacidad de generar copias: es un clonador serial. Gracias a estas copias (aka. ramas), podemos generar duplicados exactos de nuestro trabajo e introducir cambios sin miedo a romper nada del original. Si algo falla o nos arrepentimos, podemos volver exactamente al punto de inicio.

Pero todo gran poder, conlleva una gran responsabilidad. Y así como Git puede ser un aliado, también puede convertirse en un enemigo. Por eso, es recomendable seguir ciertas convenciones que nos ahorrarán muchos problemas y nos facilitarán nuestro trabajo.

Para eso, existe una herramienta que pone en práctica y automatiza estas convenciones, y nos simplifica aún más el trabajo: git-flow.

Git-flow es un conjunto de extensiones para Git, basado en el modelo de ramificaciones de Vincent Driessen, que nos facilita el trabajo con nuestros repositorios.

Básicamente, git-flow agrega comandos de alto nivel que, por detrás, usan los comandos tradicionales de Git.

En esta primera parte del post , explicaremos los principios básicos de git-flow. Más adelante, en las siguientes partes, aprenderemos a usar sus comandos y veremos ejemplos.

El centro en torno al cual gira git-flow son las ramas.

Todo en git-flow son ramas.

Y si hay ramas que merecen destacarse, esas son Master y Develop. Todo lo que nosotros hagamos como desarrolladores terminará, tarde o temprano, en alguna de estas ramas:

  • Develop: la rama que contiene las features a incluir en una próxima salida a producción (pasando por test previamente). Todos los desarrollos que hagamos — nuevos módulos, refactorings, etc. — se guardarán en Develop, a la espera de salir a producción.
  • Master: la rama que contiene el código que está en producción. A esta rama, sólo debe llegar código que está en — o está listo para estar en — producción.

Nunca — ¡pero nunca eh! — deberías modificar código directamente en alguna de estas dos ramas. A continuación veremos el porqué, ¡pero después no digas que no te lo dije!

Para trabajar con git-flow, hay tres conceptos importantes que aprender: feature, hotfix y release.

una feature no es otra cosa que una rama de Git con una copia exacta del contenido de Develop

Recuerdas que dijimos que Develop era intocable? Pues precisamente, para poder realizar cambios sobre lo que está en Develop, lo que hacemos es generar una copia exacta de su contenido y lo metemos en una nueva rama que llamamos feature.

El propósito de las features es desarrollar nuevas funcionalidades del proyecto, en un ambiente controlado, de forma tal de que, una vez que estén listos para agregarse a una futura versión, se agreguen a Develop.

Y hacerlo de esta forma tiene dos ventajas principales:

A lo que te preguntarás: por qué no podemos trabajar directamente sobre Develop?
Para entender esto, consideremos un escenario en el que un grupo de personas trabaja colaborativamente sobre un proyecto. El encargado del proyecto te asigna el desarrollo de un nuevo módulo y tú le dedicas varias jornadas de trabajo. Justo unos días antes de terminar el módulo, el encargado del proyecto decide que, finalmente, ese módulo no será necesario.
Si hubiésemos trabajado directamente sobre Develop, borrar esos cambios probablemente generaría muchos conflictos y rompería el código de algún otro miembro del equipo que se haya descargado los cambios. Además, seguramente tendríamos que eliminar o comentar código manualmente, lo que empeoraría aún más la situación.
Por el contrario, si trabajamos en una rama aislada o feature, simplemente podemos descartar esa rama, sin afectar a Develop. O bien, podríamos dejarla en stand by por si en un futuro próximo vuelve a retomarse la idea de integrar el módulo en cuestión.
Al usar una rama separada, los desarrollos están más controlados y pasan por una serie de revisiones más minuciosas antes de mergearse con Develop. Imagina que si todos trabajasen sobre la misma rama, podrían generarse conflictos: dos personas modificando la misma porción de código o alguien borrando cosas que otro necesitaba.
Con las features, nos aseguramos que los desarrollos están controlados y no vamos a afectar el trabajo de otro miembro del equipo. Sumado a esto, si trabajamos bien, las features deberían atravesar una serie de pruebas exhaustivas antes de mergearse a Develop.

Los nombres de todas las features comienzan con la palabra feature seguido de una barra invertida y la referencia que nosotros querramos usar para identificarla. Ejemplos de nombres de features podrían ser:

  • feature/ADD_FACEBOOK_AUTHENTICATION
  • feature/change_user_database_field
  • feature/RemoveCvvFromCreditCardModel
un hotfix es una rama con una copia exacta del contenido de Master

Siguiendo con los ejemplos, imagina que la versión que está ejecutándose en producción tiene algún bug que debe ser corregido en forma inmediata. Esa versión es idéntica a lo que está en la rama Master, por lo que estaría bien poder trabajar sobre el código de dicha rama.

Pero, recuerdas que dijimos que Master era intocable? Pues precisamente, para poder realizar cambios sobre lo que está en Master y corregir el bug en producción, lo que hacemos es generar una copia exacta de su contenido y lo metemos en una nueva rama que llamamos hotfix. De esta forma, evitamos trabajar directamente sobre el código que está en Master, y volvemos a trabajar en un “ambiente” controlado.

Cuando estemos seguros de haber corregido el bug, podemos cerrar el hotfix para que se agregue a Master.

Pero basta sólo con agregarlo a Master?

Pensemos en el siguiente caso: alguien del equipo encuentra un bug en la versión que se está ejecutando en producción, que hace que la aplicación deje de funcionar aleatoriamente. Si sólo corrigiéramos el bug en Master, todos los nuevos desarrollos que se hagan en Develop estarían haciéndose sobre una versión que contiene ese bug. Por tal motivo, siempre que cerremos un hotfix, el merge se debe hacer con Master y con Develop. ¡Grábatelo a fuego!

Al igual que ocurre con las features, los nombres de todos los hotfix comienzan con la palabra hotfix seguido de una barra invertida. A continuación, se agrega la referencia que nosotros querramos usar para identificar ese hotfix. Ejemplos de nombres de hotfix podrían ser:

  • hotfix/1.10.1
  • hotfix/missing_param_in_login_function
  • hotfix/AddDefaultValueToUserDocumentType
una release es una rama con una copia exacta del contenido de Develop, que está lista (o casi) para ser subida a Producción.

Supongamos que hemos estado trabajando por unas semanas con nuevos desarrollos. Todos los miembros del equipo trabajamos en sendas features — ¡bien por todos! — , y luego fusionamos esos cambios en Develop. Llega el momento en que el encargado del proyecto (o cualquiera del equipo) decide que es hora de mandar todos esos nuevos cambios a Producción. Para ello, lo que hacemos es abrir una release.

Una release es el pasaje de Develop a Master.

Alguien del equipo genera la release, que no es otra cosa que una copia de Develop, y la publica en un entorno de pruebas. La idea es someterla a unas últimas revisiones antes de mandarla a producción.

Pero supongamos que entre esas revisiones, se encuentra un bug menor que surge de los nuevos cambios, y que es mejor que no llegue a Producción. Entonces, lo que hacemos es solucionar el bug directamente en la release y volvemos a probar. Cuando estamos seguros de que ya está ok para subirse a Producción, fusionamos la release con Develop y Master.

  • Con Master porque es de donde sale nuestro código a producción
  • Con Develop porque queremos que los próximos desarrollos se correspondan con lo que, a partir de ahora, va a estar en Master.

Recuerda que ese bug que solucionamos directamente en la release todavía está presente en la rama Develop, por lo que al fusionar la release estamos seguros de que el bug también se va a corregir en dicha rama.

Finalmente, sólo resta publicar la nueva versión en Producción a partir del contenido de Master.

Aprender a usar Git no implica, únicamente, aprender comandos y entender lo que hacen. También requiere aprender una forma de trabajar. Y git-flow es la herramienta perfecta para ayudarnos en nuestro trabajo. Aquí te dejo la hoja de referencias de git-flow por si quieres saber algo más.

Aún así, no olvides que todo lo que hacemos con git-flow, también se podría hacer con comandos puros de Git. Simplemente, es una capa de abstracción que nos obliga a seguir un flujo apropiado de trabajo y nos ayuda a trabajar mejor en nuestros proyectos.

Qué te ha parecido este artículo?

¿Usas alguna otra herramienta en tus repositorios o tienes alguna idea para sugerir? Nos encantaría leer tus comentarios al respecto.

Este artículo es parte de una serie de artículos generados por Unagi.

Somos una empresa de software enfocada en el desarrollo de soluciones web que ayuden a nuestros clientes a mejorar lo que ya hacen bien. Nuestro equipo está formado por un grupo de ingenieros y licenciados con más de 10 años de experiencia acumulada, y somos felices haciendo lo que hacemos. Estamos abiertos a nuevas experiencias, y nos encantan los desafíos.

Si tienes alguna consulta o quieres conocer más sobre nosotros, puedes enviarnos una consulta desde el sitio web de Unagi. Tenemos amplia experiencia en el desarrollo de soluciones a medida y nos encantaría ayudarte a desarrollar tu negocio.


Originally published at medium.com on July 10, 2017.