Node:Ver lo que Ud. (y otros) han hecho - comandos Update y Diff, Next:CVS y argumentos implícitos, Previous:Hacer un cambio, Up:Un día con CVS
Hasta ahora nos hemos referido a la "actualización" como una forma de
traer a su copia de trabajo los cambios que se han realizado en el
repositorio, es decir, como una manera de obtener los cambios hechos
por otras personas. Sin embargo, la actualización es un proceso algo
más complejo que esto, puesto que compara el estado global de su copia
de trabajo con el estado del proyecto que se encuentra en el repositorio.
Incluso si nada ha cambiado en el repositorio desde que se obtuvo la
copia, puede que algo en la copia de trabajo sí lo haya hecho, y
"update" también le mostrará esto:
floss$ cvs update cvs update: Updating . M hello.c cvs update: Updating a-subdir cvs update: Updating a-subdir/subsubdir cvs update: Updating b-subdir
La "M" al lado de hello.c significa que el fichero ha sido modificado desde que se obtuvo la copia, y que las modificaciones no se han enviado aún al repositorio.
A veces, todo lo que necesita es simplemente saber qué ficheros ha
editado. Sin embargo, si desea echar un vistazo más de cerca a los
cambios, puede solicitar un informe detallado en formato diff. El
comando diff compara los ficheros que puedan haberse modificado en
la copia de trabajo con sus homónimos en el repositorio, mostrando
a continuación cualquier posible diferencia:
floss$ cvs diff cvs diff: Diffing . Index: hello.c =================================================================== RCS file: /usr/local/cvs/miproyecto/hello.c,v retrieving revision 1.1.1.1 diff -r1.1.1.1 hello.c 6a7 > printf ("¡Adiós, mundo!\n"); cvs diff: Diffing a-subdir cvs diff: Diffing a-subdir/subsubdir cvs diff: Diffing b-subdir
Aunque un poco liosa, esta información es útil, si bien todavía hay un montón de ruido ahí. Para empezar, puede ignorar la mayor parte de las líneas del comienzo, dado que sólo hacen referencia al nombre del fichero del repositorio e indican el número de la última revisión enviada al mismo. Son datos útiles en otras circunstancias (las veremos en detalle más adelante), pero no las necesita cuando sólo quiere hacerse una idea de los cambios que se han hecho en la copia de trabajo.
Una molestia más seria a la hora de leer el diff es que CVS anuncia su
entrada en escena a medida que va entrando en cada directorio durante la
actualización. Esto puede ser útil durante largas actualizaciones en
grandes proyectos, puesto que le da una idea del tiempo que va a necesitar
el comando, pero ahora mismo lo único que hace es molestarle mientras
intenta interpretar lo que está leyendo. Así pues, digámosle a CVS que
no diga nada sobre su trabajo, con la opción global -Q (de "Que te
calles", obviamente):
floss$ cvs -Q diff Index: hello.c =================================================================== RCS file: /usr/local/cvs/miproyecto/hello.c,v retrieving revision 1.1.1.1 diff -r1.1.1.1 hello.c 6a7 > printf ("¡Adiós, mundo!\n");
Mejor - al menos, parte del ruido ha desaparecido. Sin embargo, el diff
es aún difícil de leer. Le está diciendo que en la línea 6 se añadió una
línea nueva (que se convirtió en la línea 7) cuyo contenido es:
printf ("¡Adiós, mundo!\n");
El signo ">" que precede a la línea en el diff le dice que esta línea está presente en la nueva versión del fichero, pero no en la antigua.
Sin embargo, el formato podría ser aún más legible. Muchas personas
encuentran el formato "de contexto" de diff más fácil de leer, porque
muestra menos líneas de contexto delimitando los cambios. Los diffs de
contexto pueden generarse pasando a diff la opción -c:
floss$ cvs -Q diff -c Index: hello.c =================================================================== RCS file: /usr/local/cvs/miproyecto/hello.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 hello.c *** hello.c 1999/04/18 18:18:22 1.1.1.1 --- hello.c 1999/04/19 02:17:07 *************** *** 4,7 **** ---4,8 -- main () { printf ("¡Hola, mundo!\n"); + printf ("¡Adiós, mundo!\n"); }
¡Esto sí está claro! Incluso si no está acostumbrado a leer diffs de contexto, un vistazo a esta información mostrará de forma bastante obvia lo que ha sucedido: se añadió una nueva línea (el + en la primera columna significa que se ha añadido una línea) entre la línea que imprime "¡Hola, mundo!" y la llave final.
No es necesario que seamos capaces de interpretar perfectamente los diffs
de contexto (esto es trabajo para el programa "patch"), pero le será útil
tomarse un tiempo para adquirir al menos una cierta familiaridad con el
formato. Las primeras dos líneas (después del rollo del comienzo) son
*** hello.c 1999/04/18 18:18:22 1.1.1.1 --- hello.c 1999/04/19 02:17:07
y le dicen qué se está comparando con qué. En este caso, la revisión 1.1.1.1 de hello.c se está comparando con una versión modificada del mismo fichero (motivo por el cual no aparece número alguno de revisión en la segunda línea, porque los cambios de la copia de trabajo no se han enviado todavía al repositorio). Las líneas de asteriscos y guiones identifican secciones situadas más adelante en el fichero de diferencias. Más adelante, una línea de asteriscos seguida de una franja de valores precede a una sección del fichero original. Después, una línea de guiones, con una franja de números de línea nuevos y potencialmente distintos, precede a una sección del fichero modificado. Estas secciones están organizadas por pares: por un lado la parte del fichero antiguo, y por otro lado la parte del fichero nuevo.
Nuestro fichero de diferencias tiene uno de estos pares:
*************** *** 4,7 **** --- 4,8 -- main () { printf ("¡Hola, mundo!\n"); + printf ("¡Adiós, mundo!\n"); }
La primera sección del par está vacía, lo que significa que no se ha eliminado nada del fichero original. La segunda sección indica que, en el lugar correspondiente del nuevo fichero, se ha añadido una nueva línea, que aparece marcada con un signo "+". (Cuando el diff cita partes de ficheros, se reserva las primeras dos columnas a la izquierda para códigos especiales, como el "+", así que el trozo entero aparenta estar justificado a la izquierda con dos espacios. Esta justificación extra desaparece, por supuesto, cuando se aplica el fichero de diferencias.)
La franja de números de líneas muestra el alcance del par de diferencias, incluyendo líneas de contexto. En el fichero original, el par estaba en las líneas 4 a la 7; en el nuevo fichero, son las líneas 4 a la 8 debido a la nueva línea que se ha añadido. Fíjese en que el fichero de diferencias no necesita enseñar ninguna cosa del fichero original puesto que no se ha eliminado nada; sólo nos ha mostrado la franja afectada y ha continuación ha saltado a la segunda sección del par de diferencias.
Aquí hay otro diff de contexto, procedente esta vez de un proyecto real mío:
floss$ cvs -Q diff -c Index: cvs2cl.pl =================================================================== RCS file: /usr/local/cvs/kfogel/code/cvs2cl/cvs2cl.pl,v retrieving revision 1.76 diff -c -r1.76 cvs2cl.pl *** cvs2cl.pl 1999/04/13 22:29:44 1.76 --- cvs2cl.pl 1999/04/19 05:41:37 *************** *** 212,218 **** # can contain uppercase and lowercase letters, digits, '-', # and '_'. However, it's not our place to enforce that, so # we'll allow anything CVS hands us to be a tag: ! /^\s([^:]+): ([0-9.]+)$/; push (@{$symbolic_names{$2}}, $1); } } -- 212,218 -- # can contain uppercase and lowercase letters, digits, '-', # and '_'. However, it's not our place to enforce that, so # we'll allow anything CVS hands us to be a tag: ! /^\s([^:]+): ([\d.]+)$/; push (@{$symbolic_names{$2}}, $1); } }
El signo de exclamación indica que la línea marcada difiere del fichero antiguo al nuevo. Dado que no hay ningún signo "+" o "-", sabemos que el número total de líneas del fichero sigue siendo el mismo.
Éstas son otras diferencias de contexto del mismo proyecto, esta vez un poco
más complejas:
floss$ cvs -Q diff -c Index: cvs2cl.pl =================================================================== RCS file: /usr/local/cvs/kfogel/code/cvs2cl/cvs2cl.pl,v retrieving revision 1.76 diff -c -r1.76 cvs2cl.pl *** cvs2cl.pl 1999/04/13 22:29:44 1.76 --- cvs2cl.pl 1999/04/19 05:58:51 *************** *** 207,217 **** } else # we're looking at a tag name, so parse & store it { - # According to the Cederqvist manual, in node "Tags", "Tag - # names must start with an uppercase or lowercase letter and - # can contain uppercase and lowercase letters, digits, '-', - # and '_'. However, it's not our place to enforce that, so - # we'll allow anything CVS hands us to be a tag: /^\s([^:]+): ([0-9.]+)$/; push (@{$symbolic_names{$2}}, $1); } - 207,212 -- *************** *** 223,228 **** --- 218,225 -- if (/^revision (\d\.[0-9.]+)$/) { $revision = "$1"; } + + # Esta línea ha sido añadida, lo admito, sólo para este ejemplo de diff. # If have file name but not time and author, and see date or # author, then grab them:
Este fichero diff tiene dos pares de diferencias. En el primero se han eliminado cinco líneas (estas líneas se muestran sólo en la primera sección del par, y la cuenta de líneas de la segunda sección indica que tiene menos líneas). Una línea continua de asteriscos hace las veces de delimitador entre pares, y en el segundo par vemos que se han añadido dos líneas: una línea en blanco y un comentario inútil. Observe cómo los números de línea compensan el efecto del par anterior. En el fichero original, la franja del segundo par iba desde 223 hasta 228; en el nuevo fichero, dado que la eliminación tuvo lugar en el primer par, la franja de líneas abarca desde la 218 hasta la 225.
Enhorabuena, en este momento tiene posiblemente toda la experiencia que necesita para poder interpretar ficheros de diferencias.