Guía para el tratamiento de los repositorios.

Oscar Alfredo Leiva Salomón b4a6aa0cf0 test highlighting 6 tahun lalu
img 193915f080 Hotfix branches image 6 tahun lalu
pdf a2bd7a26a6 Add pdf and full image 6 tahun lalu
README.md b4a6aa0cf0 test highlighting 6 tahun lalu

README.md

Modelo de Ramificación Git

Tabla de Contenidos

Introducción

Esta es una guía del modelo de ramificación utilizado en Mercados Eléctricos de Centroamérica.

Ramas Principales

git branching model

Ramas Principales

El repositorio central contiene dos ramas principales con una duración infinita:

  • master
  • develop

Consideramos la rama origin/master como la rama principal, en donde el código fuente del HEAD siempre refleja un estado listo para producción.

Consideramos que la rama origin/develop es la rama principal don de el código fuente de HEAD siempre refleja un estado con los últimos cambios de desarrollo entregados para la próxima versión. Algunos lo llamarían la "rama de integración" ("integration branch"). Aquí es donde se compilan los realeases "nightly builds".

Cuando el código fuente en developalcanza un estado estable y esta listo para ser desplegado, todos los cambios deben ser de alguna forma unificados en master y tageados con un número de realease.

Por lo tanto, cada vez que hay un merge hacia master, esta versión es un realease de producción. En ese sentido, hay que ser bastante estrictos en que únicamente cambios testeados y sin bugs sean unidos a master. Se puede utilizar algún script Git hook para compilar y desplegar automáticamente a los servidores de producción cada vez que haya un commit en master.

Ramas de Soporte

Junto a las ramas principales, master y develop, el modelo de desarrollo utiliza una variedad de ramas de sporte para dar soporte al desarrollo paralelo entre los miembros del equipo, facil seguimiento de nuevos features, preparación para realeases o para ayudar en la correción rápida de problemas en la versión de producción. A diferencia de las ramas principales, estas tienen un tiempo de vida limitado, ya que eventualmente serán eliminadas.

Los diferentes tipos de ramas de soporte que se utilizan son:

  • ramas features
  • ramas realease
  • ramas hotfix

Cada uno de estos tipos de ramas tienen un propósito específico y estan sujetas a diferentes reglas, como de que rama se desprenden y hacia que ramas son unidas nuevamente.

Ramas feature

Pueden ramificarse de: develop

Deben hacer merge con: develop

Nombre: debe iniciar con feature-* no puede ser llamada master, develop, release-* o hotfix_*

Estas ramas se utilizan para desarrollar nuevas características para la próxima versión o para una futura versión. Al iniciar el desarrollo de una característica, la versión de destino en la que se incorporará esta característica puede ser descnocida en ese momento. La escencia de una rama feature es que existe mientras la característica esta en desarrollo, pero eventualmente se fusionará de nuevo con develop (para añadir definitivamente la característica al próximo lanzamiento) o se descartará (en caso de un experimento fallido).

Las ramas featuresuelen existir sólo en los repos de desarrolladores, no en origin.

feature brach

Creación de una rama feature

Cuando se inicie con una nueva característica, se creará una nueva rama a partir de develop.

$ git checkout -b feature-myfeature develop

Merge de una rama feature

Una vez finalizado el desarrollo de una nueva característica, se debe hacer un merge a develop para incorporar los cambios en un lanzamiento posterior.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

El flag --no-ff hace que el merge cree un nuevo commit, incluso si el merge se puede realizar con un fast-forward. Esto evita perder información sobre la historia de commits de una rama feature y agrupa todos los commits que añadieron la característica.

no fast-forward

En el segundo caso (plain), es imposible observar desde el hisotrial Git cuales commits han implementado la característica, tendríamos que leer los mensajes de log. Revertir una featurecompleta es muy dificil en esta situación, sin embargo es mas facil si se utiliza el flag --no-ff.

Ramas release

Pueden ramificarse de: develop

Deben hacer merge con: develop o master

Nombre: debe iniciar con release-* no puede ser llamada master, develop, feature-* o hotfix_*

Las ramas release son de ayuda para la preparación del lanzamiento de una nueva versión de producción. Permiten la correción de errores menores y la preparación de metadatos para una versión (número de versión, fechas de compilación, etc.). Al hacer todo este trabajo en una rama release, la rama de desarrollo se libera para recibir nuevas características para una versión posterior.

El momento clave para separarse a una nueva rama release es cuando develop(casi) refleja el estado deseado de la nueva versión. Por lo menos todas las características que están dirigidas a la versión que se va a lanzar deben fusionarse a develop en este momento. Todas las características destinadas a futuras versiones deben de esperar hasta que la rama releasese haya separado.

Es exactamente al comienzo de una rama releaseque se le asigna un número de versión para el próximo lanzamiento, no antes. Hasta ese momento, develop reflejaba los cambios para la "proxima versión", pero no esta claro cuando la esa "proxima versión" se convertirá en 0.3 o 1.0, por ejemplo, hasta que se inicia la rama release. Esta decisión se toma al inicio de cada rama release y se lleva a cabo mediante las reglas del proyecto sobre el número de versión.

Creación de una rama release

Las ramas release son creadas a partir de develop. Por ejemplo, si la versión en producción vigente es 1.1.5 y tenemos un nuevo lanzamiento con cambios grandes. El estado de develop esta listo para la "proxima versión" y hemos decidido que será la versión 1.2 (en vez de 1.1.6 o 2.0). Entonces, creamos una nueva rama con un nombre que refleje el número de la versión nueva:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

Depues de crear la nueva rama, incrementamos el número de versión. En el ejemplo, bump-version.sh es un script ficticio que cambia algunos archivos en la copia para reflejar la nueva versión. (Por supuesto este cambio puede ser manual, el punto es que algunos archivos han cambiado.) Luego, se realiza un commit con los cambios y la nueva versión.

Esta nueva rama puede existir por algún tiempo, hasta que el lanzamiento sea realizado. Durante este tiempo, se pueden realizar correción de errores pequeños. Añadir nuevas características a esta rama esta estrictamente prohibido. Si es necesario, estos deben ser unidos primero a develop y esperar por un nuevo release.

Finalizando una rama release

Cuando esta rama este lista para convertirse en un lanzamiento oficial, primero se deben realizar algunas tareas. Primero, la rama release debe unirse a master (dado que cada commit en master es un nuevo lanzamiento por definición). Luego, ese commit en master debe ser tageado para referencias futuras. Finalmente, los cambios realizados en la rama release deben ser unidos con develop, para que los futuros releases tambien incorporen la correción de errores.

Los primeros dos pasos se muestran a continuación:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

El lanzamiento se ha realizado, y ha sido tageado para futuras referencias.

Para mantener los cambios hechos en la rama release, necesitamos hacer un merge con develop.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

Este paso probablemente causara conflictos. Y eso sucede, se deben corregir y hacer el commit corresondiente.

Ahora se ha finalizado el trabajo en la rama release y esta puede ser eliminada, ya que no es necesaria.

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

Ramas hotfix

Pueden ramificarse de: master

Deben hacer merge con: develop y master

Nombre: debe iniciar con hotfix-* no puede ser llamada master, develop, feature-* o release-*

Las ramas hotfix son muy similares a las ramas release, en el sentido que también estan pensadas para preparar un nuevo lanzamiento de producción, aunque no esté planificado. Surgen de la necesidad de acturar inmediateamente sobre el estado no deseado de una versión de producción en vivo. Cuando un fallo crítico en una versión de producción debe resolverse inmediatamente, una rama hotfix puede separarse de la etiqueta correspondiente en masterque marca la versión de producción.

hotfix

La escencia es que el trabajo de los miebros del equipo, en la rama develop puede continuar, mientras que otra persona está preprando una solución rápida de producción.

Creación de una rama hotfix

Las ramas hotfixson creadas a partir de master. For ejemplo, digamos que la versión actual de producción es la 1.2 y está teniendo problemas por un bug. Pero los cambios en la rama develop son inestables. Entonces debemos crear una nueva rama hotfixy solucionar el problema:

:::bash
$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

No se nos debe olvidar incrementar el número de versión despues de crear la nueva rama.

Luego de arreglar el fallo en la aplicación, se realiza el commit (puede ser un commit o varios).

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

Finalizando una rama hotfix

Al finalar de corregir el fallo, la rama hotfix se debe unir nuevamente a master, pero tambien debe de ser unida a develop, con el objeto de asegurar que la corrección del fallo esté incluido en el próximo lanzamiento. Este proceso es exactament igual que el realizado con las ramas release.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

Luego, se debe incluir el cambio en develop:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

La única excepción a la regla es que, cuando una rama release existe actualmente, los cambios de hotfix necesitan ser fusionados en esa rama release, en lugar de develop.

Volver a unir la corrección de fallos en la rama release resultará finalmente en que la corrección de fallos se fusione también en develop, cuando la rama release esté terminada.

Si el trabajo en develop requiere inmediatamente esta corrección de errores y no puede esperar a que la rama de la versión esté terminada, puede fusionar con seguridad la corrección de errores en develop.

Finalmente, eliminamos la rama hotfix:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).