Node:Vigilando fuentes de terceras partes (Derivaciones comerciales), Next:, Previous:Salir del limbo (Cómo trabajar con derivaciones y sobrevivir), Up:CVS avanzado



Vigilando fuentes de terceras partes (Derivaciones comerciales)

De vez en cuando un sitio pudiera hacer un cambio local al código de un programa obtenido del exterior. Si la fuente exterior no incorpora los cambios locales (y habría muchas razones legítimas para no hacerlo), el sitio tiene que mantener sus cambios en cada actualización del software.

CVS puede ayudar en esta tarea a través de una característica conocida como derivaciones comerciales. De hecho, derivaciones comerciales está detrás de los ahora misteriosos dos finales argumentos de la orden cvs import; la etiqueta comercial y la de entrega final que vimos en Una introduccion a CVS.

He aquí como funciona. La importación inicial is como cualquier otra importación de un proyecto en CVS (excepto que tendrá que elegir la etiqueta comercial con un poco de cuidado):

floss$ pwd
/home/jrandom/theirproj-1.0
floss$ cvs import -m "Import of TheirProj 1.0" theirproj Them THEIRPROJ_1_0
N theirproj/INSTALL
N theirproj/README
N theirproj/src/main.c
N theirproj/src/parse.c
N theirproj/src/digest.c
N theirproj/doc/random.c
N theirproj/doc/manual.txt

No conflicts created by this import

floss$

Después debe obtener una copia de trabajo, hacer sus modificaciones locales y entregar:

floss$ cvs -q co theirproj
U theirproj/INSTALL
U theirproj/README
U theirproj/doc/manual.txt
U theirproj/doc/random.c
U theirproj/src/digest.c
U theirproj/src/main.c
U theirproj/src/parse.c
floss$ cd theirproj
floss$ emacs src/main.c src/digest.c
 ...
floss$ cvs -q update
M src/digest.c
M src/main.c
floss$ cvs -q ci -m "changed digestion algorithm; added comment to main"
Checking in src/digest.c;
/usr/local/newrepos/theirproj/src/digest.c,v  <--  digest.c
new revision: 1.2; previous revision: 1.1
done
Checking in src/main.c;
/usr/local/newrepos/theirproj/src/main.c,v  <--  main.c
new revision: 1.2; previous revision: 1.1
done
floss$

Un año más tarde la siguiente versión del programa llega de Ellos, S.A., y ustede debe incorporar sus cambios locales a ella. Los cambios de ellos y los suyos se sobreponen ligeramente. Ellos han añadido un nuevo fichero, modificado un par de ficheros que usted no tocó y otros dos que usted si modificó.

Primero tiene que hacer otra importación para obtener las nuevas fuentes. Casi todo estaba como en la importación inicial; usted está importando el mismo proyecto del repositorio y de la misma derivación comercial. La única diferencia es en la etiqueta de entrega final:

floss$ pwd
/home/jrandom/theirproj-2.0
floss$ cvs -q import -m "Import of TheirProj 2.0" theirproj Them THEIRPROJ_2_0
U theirproj/INSTALL
N theirproj/TODO
U theirproj/README
cvs import: Importing /usr/local/newrepos/theirproj/src
C theirproj/src/main.c
U theirproj/src/parse.c
C theirproj/src/digest.c
cvs import: Importing /usr/local/newrepos/theirproj/doc
U theirproj/doc/random.c
U theirproj/doc/manual.txt

2 conflicts created by this import.
Use the following command to help the merge:

       cvs checkout -jThem:yesterday -jThem theirproj

floss$

Dios mío; No hemos visto que CVS sea tan útil. Nos está diciendo que orden ejecutar para fusionar los cambios. Y casi está bien. En realidad el comando funciona (asumiendo que sustituye yesterday (ayer) por un intervalo de tiempo que incluya la primera primera importación pero no la segunda). Yo prefiero hacerlo mediante etiquetas de entrega final:

floss$ cvs checkout -j THEIRPROJ_1_0 -j THEIRPROJ_2_0 theirproj
cvs checkout: Updating theirproj
U theirproj/INSTALL
U theirproj/README
U theirproj/TODO
cvs checkout: Updating theirproj/doc
U theirproj/doc/manual.txt
U theirproj/doc/random.c
cvs checkout: Updating theirproj/src
U theirproj/src/digest.c
RCS file: /usr/local/newrepos/theirproj/src/digest.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
Merging differences between 1.1.1.1 and 1.1.1.2 into digest.c
rcsmerge: warning: conflicts during merge
U theirproj/src/main.c
RCS file: /usr/local/newrepos/theirproj/src/main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.2
Merging differences between 1.1.1.1 and 1.1.1.2 into main.c
U theirproj/src/parse.c
floss$

Observe como la importación nos indica que hay dos conflictos pero la fusión parece ver sólo uno. Esto es porque la idea de conflicto en CVS es un poco diferente que en las otras ocasiones. Básicamente la importación informa de conflictos cuando usted y el distribuidor modifican un fichero entre la última importación y esta. Sin embargo, cuando se fusiona o actualiza la definición de conflicto es la usual, cambios que se sobreponen. Cambios que no se sobreponen son fusionados de la forma normal y el fichero se marca como modificado.

Un diff verifica que sólo uno de los ficheros tiene conflictos:

floss$ cvs -q update
C src/digest.c
M src/main.c
floss$ cvs diff -c
Index: src/digest.c
===================================================================
RCS file: /usr/local/newrepos/theirproj/src/digest.c,v
retrieving revision 1.2
diff -c -r1.2 digest.c
*** src/digest.c        1999/07/26 08:02:18     1.2
-- src/digest.c        1999/07/26 08:16:15
***************
*** 3,7 ****
-- 3,11 ----
 void
 digest ()
 {
+ <<<<<<< digest.c
   printf ("gurgle, slorp\n");
+ =======
+   printf ("mild gurgle\n");
+ >>>>>>> 1.1.1.2
 }
Index: src/main.c
===================================================================
RCS file: /usr/local/newrepos/theirproj/src/main.c,v
retrieving revision 1.2
diff -c -r1.2 main.c
*** src/main.c  1999/07/26 08:02:18     1.2
-- src/main.c  1999/07/26 08:16:15
***************
*** 7,9 ****
-- 7,11 ----
 {
   printf ("Goodbye, world!\n");
 }
+
+ /* I, the vendor, added this comment for no good reason. */
floss$

A partir de aquí deberá resolver los conflictos como cualquier otra fusión:

floss$ emacs  src/digest.c  src/main.c
 ...
floss$ cvs -q update
M src/digest.c
M src/main.c
floss$ cvs diff src/digest.c
cvs diff src/digest.c
Index: src/digest.c
===================================================================
RCS file: /usr/local/newrepos/theirproj/src/digest.c,v
retrieving revision 1.2
diff -r1.2 digest.c
6c6
<   printf ("gurgle, slorp\n");
--
>   printf ("mild gurgle, slorp\n");
floss$

Entones entregue los cambios

floss$ cvs -q ci -m "Resolved conflicts with import of 2.0"
Checking in src/digest.c;
/usr/local/newrepos/theirproj/src/digest.c,v  <--  digest.c
new revision: 1.3; previous revision: 1.2
done
Checking in src/main.c;
/usr/local/newrepos/theirproj/src/main.c,v  <--  main.c
new revision: 1.3; previous revision: 1.2
done
floss$

y espere la próxima versión del distribuidor. (Por supuesto tendrá que comprobar que sus antiguas modificaciones todavía funcionan).