Estrategia de branch y de merge con subversion

Introducción

El empleo de un sistema de control de versiones (SCM) es fundamental para el éxito de un proyecto de desarrollo de software.

Si no comprendes la importancia de un SCM mejor no sigas leyendo por que te resultará un lio.

Existen múltiples estrategias de preparación de un entorno de trabajo con respecto al control de versiones, sobre todo en cuanto a la creación de las ramas de desarrollo (branches).

Nosotros basaremos la creación de ramas de desarrollo en función de las tareas del proyecto, aquí mostramos una pequeña tabla de las distintas alternativas.

Tipo de Branch Se alinea con
A change request (or enhancement) Work breakdown structure (WBS)
A task (or an activity) Work breakdown structure (WBS)
A line of development for a particular (sub)project Work breakdown structure (WBS)
A specific integration effort for a (sub)project Work breakdown structure (WBS)
A particular release of a product Work breakdown structure (WBS)
A maintenance effort for a specific (sub)project Work breakdown structure (WBS)

El antiguo método de Branching que usabamos era el de Branchs en función de la Release. Los deasrrolladores trabajan en el trunk en el día a día, corrigiendo Bugs, nuevas características, etc … Cuando se decide que el código está listo para una release (por ejemplo la 1.0) se copia todo el trunk a una Branch nueva (/branches/RB_1_0). Los equipos de desarrollo continúan trabajando en paralelo (corrigiendo y testeando en la Release e implementando nuevas funcionalidades en el trunk) y realizan los merges necesarios en función de los Bugs encontrados.

En cuanto se finaliza de testear y afinar la release Branch (RB_1_0) se copia a una tag (/tags/REL_1_0) y se distribuye a los clientes. Este gráfico quizás aclare un poco este escenario.

Para evitar superposición de tareas y por lo tanto perdida de productividad, lo que haremos es aislar cada tarea como se muestra en la figura. Cada branch (rama de desarrollo) deben ser una tarea que lleve poco tiempo y se debe mezclar con la linea principal de desarrollo en poco tiempo; de otro modo el esfuerzo necesario para fusionar ambas versiones puede exceder en mucho los beneficios de esta estrategia.

Para trabajar con esta estrategia veamos la serie de comandos que usaríamos

Cremos la estructura del repositorio como haríamos normalmente (svn+ssh://dev.queres.es/opt/svn/proyectotest) :
trunk/modulo1/ (codigo)
branch/ (vacio al principio)
tags/ (vacio al principio)

Realizamos el desarrollo inicial sobre el trunk (o linea principal de desarrollo)

Supongamos que hemos realizado 3 commits en la raiz (TRUNK)
Creamos una branch de desarrollo de la tarea número 87 del trac (Ticket #87)
En el trunk hacemos:
$ svn copy trunk/modulo ->branch/TRY_87_modulo
$ svn commit (r4)

Trabajamos en la branch y en paralelo es probable que se modifique el trunk (de otras tareas).

Ahora iniciamos el merge de nuestra branch al trunk, resumiendo haremos lo siguiente:

  • Localizar la release del repositorio a partir de la cual dividimos nuestra branch
  • Cambiamos de directorio hasta el trunk
  • Actualizamos el trunk del repositorio (para asegurarnos tener la ultima version)
  • Realizamos el merge de la branch con el trunk en nuestro entorno de trabajo (HEAD)
  • Comprobamos que todo funciona correctamente (compilamos, testeamos, etc …)
  • Finalmente realizamos el commit en el trunk

Localizar la release del repositorio a partir de la cual nos separamos:

Desde nuestra branch (/testsvn/branches/TRY_87_modulo) vemos en el log que nos separamos de la linea principal en la Release4 (r4)

$ svn log –stop-on-copy -v
———————————————————————————-
r5 | vic | 2008-01-19 22:34:15 +0100 (sáb, 19 ene 2008) | 1 line
….
r4 | vic | 2008-01-19 22:31:21 +0100 (sáb, 19 ene 2008) | 1 line
Rutas cambiadas:
A /branches/TRY_87_CalculatorApp (de /trunk/modulo:3)

TRY_87 Creado
—————————————————-

Ahora realizamos el merge:
1.- Nos vamos a la trunk (cambiamos con svn switch, o con un simple cd al directorio de la trunk):
2.- Actualizamos a la ultima trunk
$ svn update
3.- Probamos lo que nos traerá de la branch (el dry-run hace que solo nos muestre lo que haría el merge, con lo que para traernos realmente los cambios no pondremos dry-run)
$ svn merge –dry-run -r 4:HEAD svn+ssh://dev.queres.es/opt/svn/proyectotest/branches/TRY_87_modulo

  • -r 4:HEAD (Merge de la r4 que es donde se separó nuestra branch del trunk hacia la HEAD que es nuestra copia de trabajo)
  • url (svn+ssh://…) indicamos la branch que vamos a mergear

4.- El anterior comando nos hace un merge de la branch en nuestro espacio de trabajo (NO EN EL REPOSITORIO)

Finalmente tras compilar y testear todo, hacemos un commit sobre la trunk:

$ svn commit

Nomenclatura

Nombraremos a las diferentes branches o Tags del subversion de la siguiente manera:

  • TRY_XXX (Branch que se crea para intentar arreglar el Ticket numero XX)
  • REL_X_Y_Z (Release número X_Y_Z, indica version en producción, se crea en la tag apropiada, ej /tags/REL_1_0)
  • RB_X_Y_Z (Version Candidata a Release X_Y_Z, se crea en la branch apropiada, ej. /branches/RB_1_0)

Referencias