Node:Fusionar repetidamente con la rama principal, Next:, Previous:Algunos principios para trabajar con derivaciones, Up:Salir del limbo (C�mo trabajar con derivaciones y sobrevivir)



Fusionar repetidamente con la rama principal

Supongamos que qsmith necesita hacer desarrollo en una derivaci�n para no desestabilizar la rama principal que comparte con jrandom. El primer paso es crear una rama nueva. Observe como primero qsmith crea una etiqueta normal (no-rama) en ese punto de la rama principal y despu�s crea la derivaci�n:

paste$ pwd
/home/qsmith/myproj
paste$ cvs tag Root-of-Exotic_Greetings
cvs tag: Tagging .
T README.txt
T foo.gif
T hello.c
cvs tag: Tagging a-subdir
T a-subdir/whatever.c
cvs tag: Tagging a-subdir/subsubdir
T a-subdir/subsubdir/fish.c
cvs tag: Tagging b-subdir
T b-subdir/random.c
paste$ cvs tag -b Exotic_Greetings-branch
cvs tag: Tagging .
T README.txt
T foo.gif
T hello.c
cvs tag: Tagging a-subdir
T a-subdir/whatever.c
cvs tag: Tagging a-subdir/subsubdir
T a-subdir/subsubdir/fish.c
cvs tag: Tagging b-subdir
T b-subdir/random.c
paste$

Etiquetar primero la rama principal podr�a servir para obtener alg�n d�a la rama principal en el momento de que la derivaci�n fue creada. Si tuviese que hacer eso deber�a haber un modo de referirse a esa instant�nea de la rama principal sin referirse a la derivaci�n. No puede usar la etiqueta de la derivaci�n ya que lo que obtendr�a es esa derivaci�n no las revisiones que forman la raiz del tronco. El �nico modo de hacer esto ser�a hacer una etiqueta de las revisiones de las que sale la derivaci�n. (Alguna gente que esta regla tan fielmente que consider� listarla como "principio n�mero 4 de ramificaci�n: Crear siempre una etiqueta no-derivaci�n en la posici�n de la derivaci�n." Sin embargo en algunos sitios no se usa y parece que lo hacen bien por lo que es una cuesti�n de gusto.) De ahora en adelante me referir� a esta etiqueta no-derivaci�n como etiqueta del punto de derivaci�n.

Observe que me he adherido a una convenci�n de nombres: La etiqueta del punto de derivaci�n empieza con Root-of- (Raiz-de-), y despu�s el nombre, que usar� subrayado en vez de gui�n para separar las palabras. Cuando la derivaci�n es creada su etiqueta acabar� con el sufijo -branch (rama) que le indicar� con s�lo mirar el nombre que es una derivaci�n. (La etiqueta del punto de derivaci�n Root-of-Exotic_Greetings no incluye el sufijo -branch porque no es una derivaci�n.) No tiene que usar esta convenci�n en particular pero desde luego es aconsejable usar alguna.

Por supuesto, he sido extra pedante. En peque�os proyectos donde cada uno sabe qui�n est� haciendo qu� y se pueden arreglar f�cilmente las confusiones estas convenciones no tienen que ser usadas. El que use la etiqueta del punto de derivaci�n o una estricta convenci�n de nombres para sus etiquetas depender� de la complejidad del proyecto y su esquema de derivaciones. (No olvide que siempre puede volver atr�s m�s tarde para actualizar viejas etiquetas y usar una nueva convenci�n; obtenga la versi�n de la vieja etiqueta, a�ada la nueva etiqueta y borre despu�s la antigua.)

Ahora qsmith puede empezar a trabajar con la derivaci�n:

paste$ cvs update -r Exotic_Greetings-branch
cvs update: Updating .
cvs update: Updating a-subdir
cvs update: Updating a-subdir/subsubdir
cvs update: Updating b-subdir
paste$

Hace algunos cambios a un par de ficheros y los entrega en la derivaci�n:

paste$ emacs README.txt a-subdir/whatever.c b-subdir/random.c
...
paste$ cvs ci -m "print greeting backwards, etc"
cvs commit: Examining .
cvs commit: Examining a-subdir
cvs commit: Examining a-subdir/subsubdir
cvs commit: Examining b-subdir
Checking in README.txt;
/usr/local/newrepos/myproj/README.txt,v  <--  README.txt
new revision: 1.14.2.1; previous revision: 1.14
done
Checking in a-subdir/whatever.c;
/usr/local/newrepos/myproj/a-subdir/whatever.c,v  <--  whatever.c
new revision: 1.3.2.1; previous revision: 1.3
done
Checking in b-subdir/random.c;
/usr/local/newrepos/myproj/b-subdir/random.c,v  <--  random.c
new revision: 1.1.1.1.2.1; previous revision: 1.1.1.1
done
paste$

Mientras tanto jrandom sigue trabajando en el tronco. Ella modifica dos o tres ficheros que qsmith toc�. Para ponerlo m�s dificil haremos sus cambios creen conflictos con el trabajo de qsmith:

floss$ emacs README.txt whatever.c
 ...
floss$ cvs ci -m "some very stable changes indeed"
cvs commit: Examining .
cvs commit: Examining a-subdir
cvs commit: Examining a-subdir/subsubdir
cvs commit: Examining b-subdir
Checking in README.txt;
/usr/local/newrepos/myproj/README.txt,v  <--  README.txt
new revision: 1.15; previous revision: 1.14
done
Checking in a-subdir/whatever.c;
/usr/local/newrepos/myproj/a-subdir/whatever.c,v  <--  whatever.c
new revision: 1.4; previous revision: 1.3
done
floss$

El conflicto no es aparente todav�a ya que ninguno de los desarrolladores ha intentado hacer la fusi�n de la derivaci�n con el tronco. Ahora jrandom hace la fusi�n:

floss$ cvs update -j Exotic_Greetings-branch
cvs update: Updating .
RCS file: /usr/local/newrepos/myproj/README.txt,v
retrieving revision 1.14
retrieving revision 1.14.2.1
Merging differences between 1.14 and 1.14.2.1 into README.txt
rcsmerge: warning: conflicts during merge
cvs update: Updating a-subdir
RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v
retrieving revision 1.3
retrieving revision 1.3.2.1
Merging differences between 1.3 and 1.3.2.1 into whatever.c
rcsmerge: warning: conflicts during merge
cvs update: Updating a-subdir/subsubdir
cvs update: Updating b-subdir
RCS file: /usr/local/newrepos/myproj/b-subdir/random.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
Merging differences between 1.1.1.1 and 1.1.1.1.2.1 into random.c
floss$ cvs update
cvs update: Updating .
C README.txt
cvs update: Updating a-subdir
C a-subdir/whatever.c
cvs update: Updating a-subdir/subsubdir
cvs update: Updating b-subdir
M b-subdir/random.c
floss$

Dos de los ficheros tienen conflictos. No importa, con su saber hacer jarandom resuelve los conflictos, entrega y etiqueta el tronco indicando una fusi�n con �xito.

floss$ emacs README.txt a-subdir/whatever.c
 ...
floss$ cvs ci -m "merged from Exotic_Greetings-branch (conflicts resolved)"
cvs commit: Examining .
cvs commit: Examining a-subdir
cvs commit: Examining a-subdir/subsubdir
cvs commit: Examining b-subdir
Checking in README.txt;
/usr/local/newrepos/myproj/README.txt,v  <--  README.txt
new revision: 1.16; previous revision: 1.15
done
Checking in a-subdir/whatever.c;
/usr/local/newrepos/myproj/a-subdir/whatever.c,v  <--  whatever.c
new revision: 1.5; previous revision: 1.4
done
Checking in b-subdir/random.c;
/usr/local/newrepos/myproj/b-subdir/random.c,v  <--  random.c
new revision: 1.2; previous revision: 1.1
done
floss$ cvs tag merged-Exotic_Greetings
cvs tag: Tagging .
T README.txt
T foo.gif
T hello.c
cvs tag: Tagging a-subdir
T a-subdir/whatever.c
cvs tag: Tagging a-subdir/subsubdir
T a-subdir/subsubdir/fish.c
cvs tag: Tagging b-subdir
T b-subdir/random.c
floss$

Mientras, qsmith no necesita esperar que termine la fusi�n para continuar el desarrollo si hace una etiqueta del conjunto de cambios que jrandom fusion� (m�s tarde, jrandom necesitar� saber el nombre de esta etiqueta; en general las derivaciones dependen de una frecuente y completa comunicaci�n entre los desarrolladores):

paste$ cvs tag Exotic_Greetings-1
cvs tag: Tagging .
T README.txt
T foo.gif
T hello.c
cvs tag: Tagging a-subdir
T a-subdir/whatever.c
cvs tag: Tagging a-subdir/subsubdir
T a-subdir/subsubdir/fish.c
cvs tag: Tagging b-subdir
T b-subdir/random.c
paste$ emacs a-subdir/whatever.c
 ...
paste$ cvs ci -m "print a randomly capitalized greeting"
cvs commit: Examining .
cvs commit: Examining a-subdir
cvs commit: Examining a-subdir/subsubdir
cvs commit: Examining b-subdir
Checking in a-subdir/whatever.c;
/usr/local/newrepos/myproj/a-subdir/whatever.c,v  <--  whatever.c
new revision: 1.3.2.2; previous revision: 1.3.2.1
done
paste$

Y por supuesto cuando qsmith haya hecho sus cambios tendr� que etiquetar:

paste$ cvs -q tag Exotic_Greetings-2
T README.txt
T foo.gif
T hello.c
T a-subdir/whatever.c
T a-subdir/subsubdir/fish.c
T b-subdir/random.c
paste$

Mientras todo esto sucede jrandom hace un cambio en un fichero distinto, uno que qsmith no ha tocado en sus ediciones:

floss$ emacs README.txt
 ...
floss$ cvs ci -m "Mention new Exotic Greeting features" README.txt
Checking in README.txt;
/usr/local/newrepos/myproj/README.txt,v  <--  README.txt
new revision: 1.17; previous revision: 1.16
done
floss$

En este momento qsmith ha entregado un nuevo cambio en su derivaci�n y jrandom ha entregado otro cambio no conflictivo en un fichero distinto del tronco. Observe que sucede cuando jrandom trata de fusionar desde la derivaci�n de nuevo:

floss$ cvs -q update -j Exotic_Greetings-branch
RCS file: /usr/local/newrepos/myproj/README.txt,v
retrieving revision 1.14
retrieving revision 1.14.2.1
Merging differences between 1.14 and 1.14.2.1 into README.txt
rcsmerge: warning: conflicts during merge
RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v
retrieving revision 1.3
retrieving revision 1.3.2.2
Merging differences between 1.3 and 1.3.2.2 into whatever.c
rcsmerge: warning: conflicts during merge
RCS file: /usr/local/newrepos/myproj/b-subdir/random.c,v
retrieving revision 1.1
retrieving revision 1.1.1.1.2.1
Merging differences between 1.1 and 1.1.1.1.2.1 into random.c
floss$ cvs -q update
C README.txt
C a-subdir/whatever.c
floss$

�Hay conflictos! �Esperaba esto?

El problema radica en el significado de fusionar. En Una introduccion a CVS expliqu� que cuando usted ejecuta

floss$ cvs update -j BRANCH

en una copia de trabajo, CVS fusiona en la copia de trabajo las diferencias entre la raiz BRANCH y su estado actual. El problema con este comportamiento es que, en esta situaci�n, la mayor�a de esos cambios ya hab�an sido incorporados al tronco la primera vez que jrandom hizo una fusi�n. Cuando CVS intent� fusionarlos de nuevo (sobre ellos mismos que es como estaban) se produce naturalmente un conflicto.

Lo que jrandom realmente quer�a hacer era fusionar en su copia de trabajo los cambios entre la m�s reciente fusi�n del tronco con su estado actual. Usted puede hacer esto usando dos -j indicadores para actualizar, como deber�a recordar en Una introduccion a CVS, siempre que sepa que revisi�n corresponde con cada indicador. Afortunadamente qsmith hiz� una etiqueta exactamente en el �ltimo punto de fusi�n (�hurra por planificar con antelaci�n!), por lo que esto no ser� problema. Primero veamos como jrandom puede devolver su copia de trabajo un estado limpio, desde el que puede rehacer la fusi�n:

floss$ rm README.txt a-subdir/whatever.c
floss$ cvs -q update
cvs update: warning: README.txt was lost
U README.txt
cvs update: warning: a-subdir/whatever.c was lost
U a-subdir/whatever.c
floss$

Ahora ella puede hacer la fusi�n, usando la etiqueta colocada convenientemente por qsmith.

floss$ cvs -q update -j Exotic_Greetings-1 -j Exotic_Greetings-branch
RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v
retrieving revision 1.3.2.1
retrieving revision 1.3.2.2
Merging differences between 1.3.2.1 and 1.3.2.2 into whatever.c
floss$ cvs -q update
M a-subdir/whatever.c
floss$

Mucho mejor. Los cambios de qsmith han sido incorporados a whatever.c; jrandom puede hacer una entrega y etiquetado:

floss$ cvs -q ci -m "merged again from Exotic_Greetings (1)"
Checking in a-subdir/whatever.c;
/usr/local/newrepos/myproj/a-subdir/whatever.c,v  <--  whatever.c
new revision: 1.6; previous revision: 1.5
done
floss$ cvs -q tag merged-Exotic_Greetings-1
T README.txt
T foo.gif
T hello.c
T a-subdir/whatever.c
T a-subdir/subsubdir/fish.c
T b-subdir/random.c
floss$

Incluso si qsmith hubiese olvidado etiquetar en el punto de fusi�n, las esperanzas no estar�a perdidas. Si jrandom supiese aproximadamente cuando hizo qsmith su primera entrega ella podr�a tratar de filtrar por la fecha:

floss$ cvs update -j Exotic_Greetings-branch:3pm -j Exotic_Greetings_branch

Aunque �til como �ltimo recurso, filtrar por fecha no es tan bueno porque selecciona los cambios basandose en los recuerdos de la gnete en vez de en designaciones que dependan del desarrollador. Si el primer conjunto de cambios fusionados de qsmith hubiera ocurrido en varias entregas en vez de s�lo una jrandom pudiera equivocadamente elegir una fecha u hora que tomara algunos de los cambios, pero no todos.

No es necesario que cada punto etiquetado en los cambios de qsmith sea enviado al repositorio un una simple entrega. Ocurri� as� casualmente en el ejemplo. En la vida real, qsmith pudo haber hecho varias entregas entre cada etiquetado. �l puede trabajar de forma aislada en su derivaci�n tanto como quiera. La raz�n de las etiquetas es registar sucesivos puntos en la derivaci�n donde considere que los cambios deban ser fusionados con la rama principal. Siempre que jrandom fusione usando dos indicadores -j y sea cuidadoso al usar las etiquetas de ramificaci�n de qsmith en el orden apropiado y una s�la vez por cada un la rama principal padecer el problema de la doble fusi�n.

Podr�an ocurrir conflictos, pero �stos ser�an de la inevitable clase que requiere resoluci�n humana; situaciones en las que tanto el tronco como la derivaci�n realizan cambios en la misma �rea de c�digo.