Ramas e integraciones con Delphi parte II

14:56 0 Comments

En la primera parte hablamos de la parte más básica de utilizar the Plastic SCM con Delphi. Ahora nos vamos a centrar en cómo gestionar las ramas y las integraciones y en cómo Plastic maneja el código fuente de Delphi.

Creación de ramas

Mi patrón de ramas preferido utilizando Plastic SCM es el de rama por tarea así que es lo que voy a hacer ahora: crearé un par de ramas y trabajaré en paralelo modificando el mismo código de manera diferente como harían dos desarrolladores. No me importa dónde hago los cambios y dejo que Plastic reconcilie los cambios una vez que haya terminado, para eso están la gestión de ramas y las integraciones, ¿no?.

¿Qué hay que hacer para crear una nueva rama en Plastic? Muy fácil: no tiene nada que ver con los comandos antiguos de copiar o instrucciones raras (bueno, se puede escribir cm mkbr si te gusta trabajar en línea de comandos, por supuesto), simplemente tienes que ir al explorador de ramas, hacer botón derecho en la rama desde la que se quiera crear una nueva y seleccionar "crear rama hija". Entonces saldrá el diálogo de crear una rama intelignete:



¿Qué es una rama inteligente? Pues es simplemente una rama que es capaz de recordar su punto de partida. Para explicarlo de manera simple; se le dice a la rama dónde están las fuentes que se quieren modificar y más adelante se puede modificar esta localización. En mi ejemplo le dije a Plastic que creara una rama denominada task001 que partiese de la etiqueta que había creado anteriormente: initial_version.

Nota: no, no es necesario escribir guión bajo en vez de espacios en los nombres de las etiquetas, se podría escribir una versión inicial y sería un nombre de etiqueta válido, pero habiendo utilizado el viejo DOS durante años no te acostumbras a que pueda funcionar realmente... ;-)

Después de crear la nueva rama, puedes ver el explorador de ramas como en la figura inferior, y puedes utilizarlo además para cambiar a esa rama y empezar a trabajar con ella.



También se puede ver la información de las propiedades de la rama y comprobar un pequeño esquema que muestra cómo está configurada la rama.



Trabajando en la primera tarea

Centrémonos ahora en el primer trabajo que tenemos que realizar: modificar el formulario para que tenga una mejor presentación, una parte para editar más ancha y fondo en verde. También modificaremos el código asociado al botón OnClick para realizar una acción diferente como muestra la figura de abajo.



Ahora utilizaré otra herramiente muy útil desde el menú de control de código fuente: la herramienta de revisión de cambios. Utilizando esta opción obtengo los siguientes resultados que muestras cómo he modificado el código del Button1Click.



Así que ahora puedo proteger mis primeros cambios: he modificado los ficheros .dfm y .pas.



Me acabo de dar cuenta de que no me gusta el cambio que acabo de hacer en el código (creo que ni siquiera está funcionando), así que vuelvo a modificar el fichero .pas y escribo el siguiente código:



Lo bueno de utilizar una rama para cada tarea es que no te tienes que preocupar de cuántos commits (o protecciones) haces: simplemente proteges cuando quieras guardar una copia, el código no irá a la línea principal del proyecto así que no afecta a nadie incluso si los cambios intermedios no compilan, y se puede seguir usando el control de versiones como mecanismo de versionado.

Finalmente cambiaré el fondo del formulario para que parezca más feo con color verde.



¿Qué ha cambiado en el fichero .dfm? Lo bueno de .dfm (al menos desde la versión 2, si recuerdo bien, cuando se convertían de formato binario a texto) es que toda la interfaz gráfica está definida en formato de texto (si, ahora estamos todos acostumbrados, pero Delphi era capaz de hacerlo...¡hace diez años!), con lo que se pueden utilizar fácilmente las herramientas de diferencias y de integraciones.



¿Que apariencia tiene mi explorador de ramas después de trabajar en la misma rama?



Colocar un gráfico en el formulario

Bien, consideramos lo siguiente: antes de que termine con la primera tarea de programación un segundo desarrollador comienza también a trabajar en la aplicación. Él ha incluido un gráfico en el formulario.

Comenzará a trabajar desde la última versión estable de nuestra aplicación de testing, que era intial_version. Su explorador de ramas tendrá la siguiente apariencia:



Por favor, ten en cuenta que he activado los enlaces de parentesco para esta captura, por esto ahora se ven las líneas amarillas que señalan desde una rama hasta su punto de partida.

El desarrollador añade un gráfico en el formulario que tiene la siguiente apariencia:



Hay que tener en cuenta que no estoy viendo el fondo verde ni el resto de cambios que ha realizado el otro desarrollador en task001 porque estoy partiendo de la última línea base estable.

Bueno, puedo oir que alguna dice: “eh, pero entonces tendrás que reorganizar todo el dfm manualmente después de hacer los cambios en paralelo”. Creedme, esto no es así.

Aquí podéis ver el árbol de versiones en 3D que muestra el fichero dfm que contiene la definición de la GUI:



Si, se puede ver claramente que el desarrollador de task001 ha realizado dos cambios en el formulario, y el de task002 tan solo ha realizado uno... ¡en paralelo!

Y para que las cosas sean un poco más complicadas también voy a modificar el evento OnClick escribiendo el siguiente código:



Integración de cambios

Es el momento de integrar los cambios en la línea principal. En este momento tu desarrollo tiene la siguiente apariencia:



Ahora tan sólo hay que ir al explorador de ramas, seleccionar botón derecho en la rama principal y en "cambiar a rama".

Entonces elegimos task001, damos al botón derecho y seleccionamos "integrar desde esta rama", entonces Plastic mostrará el diálogo de merge:



Estos son los dos ficheros que han sido modificados en la rama task001. No habrá ningún tipo de conflicto ya que es la primera rama que estamos integrando y desde entonces se ha modificado Unit2.dfm, no Unit2.pas. En la columna de los contribuidores se puede ver que dos de ellos tienen Source como contribuidor, lo cuál significa que se han realizado cambios sólo en task001 y no en la rama principal.´

Damos a la opción de "merge all" y Plastic realiza la integración.

Después de que está terminada la integración los ficheros que se han visto afectados se quedan en estado desprotegido por lo que se pueden proteger, compilar el código y verificar que todo se ha realizado correctamente.



También se puede comprobar desde el árbol de versiones del fichero Unit2.pas:



Muestra una nueva flecha verde que significa que se ha realizado un merge.

Este es el modo en el que se almacena el seguimiento de las integraciones.

He construido la aplicación y esta es la apariencia una vez que se ha integrado task001 (bueno, hasta ahora sólo task001 está en la rama principal):



Y aquí se puede ver cómo queda el explorador de ramas después de la primera integración, y los ficheros están protegidos:



Integración de task002

Integrar task001 ha sido muy sencillo: los cambios realizados en la rama se copian en la rama principal, no se realiza una verdadera integración entre las distintas revisiones.

Pero ahora con la rama task002 las cosas son diferentes ya que se han modificado los mismos ficheros que en task001.

Si se abre el diálogo de merge dando al botón derecho en la rama task002 y seleccionando "merge desde esta rama" se verá lo siguiente:



¿Qué es diferente ahora?

Hay que tener en cuenta que la columna de los contribuidores ahora dice que los ficheros se han cambiado tanto en la rama principal (después de integrar task001) como en task002.

Realizamos la integración y comprobamos como el fichero dfm se integra de manera automática, lo cual es una buena noticia.

La integración del fichero .pas necesita algo de ayuda: si te acuerdas, modificamos exactamente el mismo método dos veces de dos maneras diferentes, así que Plastic no sabe exactamente cómo resolver el conflicto.

Aquí aparece la herramienta de merge de tres vías:



¿Qué hay aquí?

El panel origen muestra el fichero que se está integrando desde task002. El panel base muestra Unit2.pas como estaba antes de que se realizaran los cambios: como estaba en initial_version. Y finalmente el panel de la derecha, el fichero de destino, muestra the Unit2.pas como está ahora en tu espacio de trabajo después de haber integrado la rama task001.

El panel inferior es el que muestra los resultados y propone agrupas los tres bloques, que es algo que se tendrá que modificar.

Por favor, ten en cuenta que la herramienta de merge de tres vías está detectando 3 conflictos, pero ha resuelto dos de ellos de manera automática ya que no estaban afectando a las mismas líneas de código.
Yo decido quedarme con los cambios de las dos tareas pero no con el de la base:



Todo integrado

¿Qué apariencia tiene mi formulario después de la integración? Bien, pues como esperabamos tiene el fondo del color de la tarea task001, el botón y la opción de editar modificados y el gráfico incluido en la tarea task002 como se puede ver debajo:



Lo mejor aquí es que ambos desarrolladores han podido centrarse en los cambios que tenían que realizar sin preocuparse el uno del otro hasta que terminaron sus modificaciones, y entonces Plastic se ha ocupado de integrarlas.

El árbol de versiones del fichero Unit2.pas ahora será:



Conclusión

En mi humilde opinión Delphi es aún uno de los entornos de desarrollo más potentes que existe, y por supuesto que se beneficia de todas las ventajas de una buena gestión de ramas y de integraciones. Plastic se puede integrar con Delphi con ayuda de SourceConneXion y parece que forman un equipo estupendo trabajando juntos.

Claro que como desarrollador que ha utilizado duranto mucho tiempo Delphi (he trabajado bastante tiempo con Kylix), es siempre un placer el poder ver cómo el equipo de Delphi gestiona la evolución de su herramienta.

0 comentarios: