Node:Vigilando fuentes de terceras partes (Derivaciones comerciales), Next:Exportar para distribución pública, Previous:Salir del limbo (Cómo trabajar con derivaciones y sobrevivir), Up:CVS avanzado
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).