Conceptos básicos de Git (parte 6)

30 de octubre de 2016
4 min. de lectura
Como hacer una presentación exitosa

Continuamos con el desarrollo de la serie “Esto es Git”, en la que describimos los conceptos básicos del manejo de versiones usando Git. En el capítulo anterior, vimos dos comandos muy útiles que nos proporciona Git: stash y cherry-pick. 

En esta ocasión vamos a ver una parte fundamental del uso de Git en la vida diaria: los flujos de trabajo o “workflows”. 

Flujo básico 

Se usa para desarrollos unipersonales o para desarrollos en los que se puede aprobar la versión del software de forma local y luego subirla a la rama remota Máster.

En este flujo, normalmente una sola persona hace cambios sobre el código y realiza pruebas localmente. Luego adiciona los cambios al Staging Area, hace commit y posteriormente push para adicionar los cambios al repositorio remoto.

Flujo centralizado o flujo estilo SVN 

Este flujo es muy común y es usado especialmente por desarrolladores haciendo la transición a Git desde un sistema de versionamiento centralizado como Subversion o CVS. Git no permite que se haga un push a la rama remota Máster (el símil del trunk en SVN) si alguien anteriormente ya ha hecho un push.

Flujo de rama de funcionalidad

Se sacan ramas para funcionalidades específicas a partir de la rama Máster. Una vez finalizada la funcionalidad, se integra a la rama Máster y se ejecuta un despliegue. Como consecuencia, NADIE debe trabajar directamente sobre la rama Máster. 

Si te encuentras haciendo alguna vez git push origin master … piénsalo dos veces, pues algo debes estar haciendo mal. 

Además de esto, es un hábito recomendado integrar continuamente los nuevos cambios realizados por los demás integrantes del equipo e integrados a la rama Master, a nuestra rama de funcionalidad.

Esto garantiza que tenemos nuestra rama actualizada y previene posibles conflictos y largas integraciones cuando integremos nuestra rama de funcionalidad de nuevo a Master. 

Nota: En los flujos anteriores, la rama Master representa efectivamente el código que hay en producción.

Por esta razón, todo lo que se integre a ésta debe ser probado, revisado y aprobado (cuando menos, alguien le debe dar su bendición) por todos los métodos posibles para asegurar la calidad. 

Flujo Github 

Este flujo es similar al flujo anterior, con la diferencia que para poder integrar la rama de funcionalidad en la que se está trabajando, se debe pasar por un Administrador de Integración quien es a su vez el encargado de integrar los cambios a la rama protegida Master. 

Este flujo se utiliza a menudo en proyectos Open Source o en GitHub, en donde las personas tienen repositorios propios (públicos) en los cuales crean copias exactas de los repositorios a los cuales quieren contribuir (fork).

Luego de esto, clonan sus repositorios públicos en repositorios privados/locales para hacer las modificaciones (se repite el flujo básico) y posteriormente se solicita al Administrador de Integración, a través de un Pull Request o Merge Request, que integre los cambios a la rama protegida del repositorio al cual se quiere contribuir. 

Flujo GitFlow 

Este flujo define un manejo más estricto de las ramas y agrega una rama de larga duración o long-running llamada Develop (que al igual que Master debe ser protegida) y algunas ramas de soporte como Feature, Release y Hotfix. 

Las ramas Feature se sacan de la rama Develop y deben contener el desarrollo específico de una funcionalidad. En ambientes de desarrollo ágiles y equipos scrum, es común que se use una rama de funcionalidad por historia de usuario.

Luego de terminado el desarrollo de la funcionalidad, ésta pasa a ser integrada nuevamente a Develop. Este paso, en la definición oficial del flujo, se hace a través de un merge (que se recomienda además sea con la opción –no-ff), pero en caso de estar trabajando con herramientas como Gitlab o GitHub, deben realizarse a través de un Pull/Merge request. Esto permite hacer una revisión de código antes de realizar la integración a la rama destino.

Las ramas de Release deben ser sacadas de Develop e integradas a las ramas Develop y Master.

Éstas ramas contienen un conjunto de funcionalidades (o ramas de Feature) que serán liberadas en producción con un nombre específico de la versión que se liberará, por ejemplo release-1.2. 

Una vez integradas a Master y Develop, ¡estas ramas deben morir! Luego de ello, se debe hacer el respectivo Tag en la rama Master, indicando que en ese punto se incluyeron nuevas funcionalidades con la versión especificada en la rama de Release.

Las ramas Hotfix deben ser sacadas de la rama Master (a partir de un Tag) e integradas a las ramas Develop y Master (si hay una rama de Release en la que aún se esté trabajando, se debe integrar en ella también). Son ramas útiles para realizar cambios en código que ya se encuentra en producción y que tienen que ser integrados inmediatamente, como la corrección de un bug crítico.

Luego de haber integrado la rama de Hotfix a las ramas necesarias, se debe eliminar. 

Flujo personalizado 

En conclusión y después de haber revisado algunos flujos utilizados en la industria, cabe mencionar que el mejor flujo es el que se adapta a las necesidades puntuales de la organización o equipo de trabajo.

Dicho esto, no se debe tener miedo de mutilar, agregar o incluso renombrar partes de uno de ellos, siempre y cuando se haga respetando los criterios de calidad de nuestro software.

Para terminar, he aquí algunas consideraciones generales acerca de los flujos mensionados: 

Entre más tiempo dure “viva” una rama sin hacer merge, más grande es el riesgo de tener conflictos a la hora de integrarla a otra rama o liberarla en un release. 

Una rama debe representar una tarea o solicitud simple y granular, ya sea una historia de usuario o una tarea dentro de una historia, la corrección de un bug, un requerimiento específico o una prueba de concepto. 

El proceso de revisión de código, ejecutado normalmente en los Merge request en Gitlab o Pull request en GitHub, debe ser el momento en el cual se discute la solución, se hacen comentarios, sugerencias y revisiones de par.

En otras palabras, es el momento en el cual haces que tu código se “ponga a prueba” por otros miembros del equipo (desarrolladores/comunidad). Esto hace más sencillo el trabajo colaborativo y garantiza que se cumplan las revisiones de código. 

Las ramas long-running o ramas protegidas del repositorio, deben contener siempre código que, cuando menos, compile correctamente. 

Hasta aquí este capítulo y la última entrega del episodio 1 de Git. Hemos visto un resumen de los flujos de trabajo en Git y su importancia dentro de los equipos de trabajo

Suscríbete