Node:Fusionar repetidamente con la rama principal, Next:La Aproximaci�n de la Cola de Milano -- Fusionar dentro y fuera de la rama principal, Previous:Algunos principios para trabajar con derivaciones, Up:Salir del limbo (C�mo trabajar con derivaciones y sobrevivir)
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.