Node:Fusiones múltiples, Next:Crear una marca o rama sin una copia de trabajo, Previous:Fusión de cambios desde las ramas al tronco, Up:Ramas
A veces, una rama seguirá teniendo un desarrollo activo aún después de
que su contenido haya sido fusionado con el tronco. Por ejemplo, esto
puede suceder si se descubre un segundo fallo en la antigua distribución
pública y este fallo ha de ser corregido en la rama. Cabe la posibilidad
de que alguien no hubiese entendido la broma que hay en random.c, así
que tendría usted que añadir una línea explicándola:
floss$ pwd /home/loquesea/miproyecto_rama floss$ cat b-subdir/random.c /* Imprimir un número aleatorio. */ #include <stdio.h> void main () { printf ("Un número aleatorio.\n"); printf ("¿Ha entendido el chiste?\n"); } floss$
y enviar el cambio. Si también es necesario fusionar esa corrección en el
tronco, podría tener la tentación de utilizar el mismo comando "update"
de antes en la copia de trabajo presente en el tronco para llevar a cabo
la "re-fusión":
floss$ cvs -q update -d -j Release-1999_05_01-bugfixes RCS file: /usr/local/cvs/miproyecto/hello.c,v retrieving revision 1.5 retrieving revision 1.5.2.1 Merging differences between 1.5 and 1.5.2.1 into hello.c RCS file: /usr/local/cvs/miproyecto/b-subdir/random.c,v retrieving revision 1.2 retrieving revision 1.2.2.2 Merging differences between 1.2 and 1.2.2.2 into random.c rcsmerge: warning: conflicts during merge floss$
Como puede ver, este comando no ha tenido el efecto deseado: nos encontramos con un conflicto, a pesar de que la copia en el tronco no había sido modificada y, por tanto, no esperábamos encontrarnos ninguno.
El problema reside en que el comando "update" se ha comportado exactamente
de la forma descrita: ha intentado tomar todos los cambios habidos desde
la raíz de la rama y su extremo final, y a continuación fusionarlos tomando
como referencia la copia de trabajo actual. El único problema está en que
algunos de estos cambios ya habían sido fusionados desde esta copia de
trabajo, de ahí que surgiese el conflicto:
floss$ pwd /home/loquesea/miproyecto floss$ cat b-subdir/random.c /* Imprimir un número aleatorio. */ #include <stdio.h void main () { <<<<<<< random.c printf ("Un número aleatorio.\n"); ======= printf ("Un número aleatorio.\n"); printf ("¿Ha entendido el chiste?\n"); >>>>>>> 1.2.2.2 } floss$
Llegados a este punto, podría intentar resolver estos conflictos a mano, dado que no es difícil ver lo que es necesario hacer en cada fichero. Sin embargo, es todavía mejor tomar medidas desde el principio para evitar conflictos. Pasando dos opciones "-j" en lugar de una, obtendrá sólo los cambios habidos desde la última vez que hizo una fusión con el extremo final de la rama, en lugar de tener en consideración todos los cambios habidos en ella. La primera -j le da el punto inicial de la rama, y la la segunda es sólo el nombre de la rama, que implica su extremo final y más reciente.
La cuestión entonces es, ¿cómo puede especificar el punto de la rama
desde el que quizo la última fusión? Una forma de hacerlo sería indicar
una fecha junto con el nombre de la marca dispuesta en la rama. CVS
ofrece para ello una sintaxis especial:
floss$ cvs -q update -d -j "Release-1999_05_01-bugfixes:2 days ago" \ -j Release-1999_05_01-bugfixes RCS file: /usr/local/cvs/miproyecto/b-subdir/random.c,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 Merging differences between 1.2.2.1 and 1.2.2.2 into random.c floss$
Si el nombre de la rama va seguido de un signo de dos puntos y a continuación por una fecha en un formato válido para CVS, CVS incluirá solamente los cambios habidos después de esa fecha. De este modo, si sabe que la corrección original del fallo se envió a la rama hace tres días, el comando precedente fusionaría solamente la segunda corrección.
Una forma mejor de hacer esto, en este caso adelantándonos para tener
en cuenta este tipo de eventualidades, sería marcar la rama después de
implantar cada corrección (sólo una marca normal; no se trata de iniciar
una nueva rama ni nada parecido). Supongamos que después de corregir el
fallo en la rama y aplicar la corrección al repositorio, hacemos esto en
la copia de trabajo de la rama:
floss$ cvs -q tag Release-1999_05_01-bugfixes-correc1 T README.txt T hello.c T a-subdir/loquesea.c T a-subdir/subsubdir/fish.c T b-subdir/random.c floss$
De esa forma, cuando llegue el momento de fusionar el segundo cambio en el
tronco, podrá utilizar la marca que ha tenido la buena idea de colocar ahí
para delimitar la revisión anterior:
floss$ cvs -q update -d -j Release-1999_05_01-bugfixes-correc1 \ -j Release-1999_05_01-bugfixes RCS file: /usr/local/cvs/miproyecto/b-subdir/random.c,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 Merging differences between 1.2.2.1 and 1.2.2.2 into random.c floss$
Ni que decir tiene que este método es mucho mejor que intentar recordar
cuánto tiempo hace que hizo tal o cual modificación, pero sólo funcionará
si se acuerda de marcar la rama cada vez que la fusione con el tronco.
La lección aprendida aquí es, por tanto, ¡marcar pronto y a menudo! Es
mejor pecar de tener demasiadas marcas (siempre y cuando tengan nombres
lo suficientemente descriptivos) que de tener muy pocas. En estos últimos
ejemplos que le he dado no había ninguna necesidad de que la nueva marca
de la rama tuviese un nombre similar al de la marca de la rama en sí.
Si bien yo utilicé el nombre Release-1999_05_01-bugfixes-correc1
, también
podría haber sido correc1
; sin embargo, es preferible emplear el
primero, dado que contiene el nombre de la rama y por tanto no existirá
la posibilidad de que sea confundido con la marca de alguna otra rama.
(Recuerde que los nombres de las marcas son únicos dentro de los ficheros,
no dentro de las ramas. No puede tener dos marcas llamadas correc1
en el
mismo fichero, aunque se refieran a revisiones que se encuentran en
diferentes ramas.)