Es hora de movernos de lo abstracto a lo concreto. En esta sección mostraremos ejemplos reales de Subversion en la práctica.
Ya ha leído acerca de las copias de trabajo; ahora demostraremos cómo las crea y las usa el cliente de Subversion.
Una copia de trabajo de Subversion es un árbol de directorios corriente de su sistema de archivos local, conteniendo una colección de archivos. Usted puede editar estos archivos del modo que prefiera y si se trata de archivos de código fuente, podrá compilar su programa a partir de ellos de la manera habitual. Su copia de trabajo es su área de trabajo privada: Subversion nunca incorporará los cambios de otra gente o pondrá a disposición de otros sus cambios hasta que usted le indique explícitamente que lo haga.
Tras hacer algunos cambios a los archivos en su copia de trabajo y verificar que funcionan correctamente, Subversion le proporciona comandos para “publicar” sus cambios al resto de personas que trabajan con usted en su proyecto (escribiendo en el repositorio). Si las demás personas publican sus propios cambios, Subversion le proporciona comandos para mezclar estos cambios en su directorio de trabajo (leyendo del repositorio).
Una copia de trabajo también contiene algunos archivos extra,
creados y mantenidos por Subversion para ayudarle a ejecutar estos
comandos. En particular, cada directorio de su copia de trabajo
contiene un subdirectorio llamado .svn
, también
conocido como el directorio administrativo de
la copia de trabajo. Los archivos en cada directorio administrativo
ayudan a Subversion a reconocer qué archivos contienen cambios no
publicados y qué archivos están desactualizados con respecto al
trabajo hecho por los demás.
Un repositorio típico de Subversion contiene a menudo los archivos (o el código fuente) de varios proyectos; normalmente, cada proyecto es un subdirectorio en el árbol del sistema de archivos del repositorio. En esta disposición, la copia de trabajo de un usuario se corresponde habitualmente con un subárbol particular del repositorio.
Por ejemplo, suponga que usted tiene un repositorio que contiene
dos proyectos de software, paint
y
calc
. Cada proyecto reside en su propio subdirectorio
dentro del directorio raíz, tal como se muestra en Figura 2.6, “El sistema de archivos del repositorio”.
Para conseguir una copia de trabajo, debe ejecutar primero
un check out de algún subárbol del
repositorio. (El término inglés “check out” puede sonar como
si tuviera algo que ver con bloquear o reservar recursos, pero no es así;
tan sólo crea una copia privada del proyecto para usted). Por ejemplo, si
usted hace un check out de /calc
, obtendrá una copia de
trabajo como ésta:
$ svn checkout http://svn.example.com/repos/calc A calc A calc/Makefile A calc/integer.c A calc/button.c $ ls -A calc Makefile integer.c button.c .svn/
La lista de letras A indica que Subversion está añadiendo una
serie de elementos a su copia de trabajo. Usted ahora tiene una copia
personal del directorio /calc
del repositorio,
con una entrada adicional—.svn
—que
contiene la información extra que Subversion necesita, tal y como se
mencionó anteriormente.
Suponga que hace cambios a button.c
. Puesto
que el directorio .svn
recuerda la fecha de
modificación del archivo y su contenido original, Subversion es capaz de
darse cuenta de que el archivo ha cambiado. Sin embargo, Subversion no hará
públicos sus cambios hasta que usted no le diga explícitamente que lo haga.
El acto de publicar sus cambios es conocido comúnmente como
consignar (o registrar)
los cambios al repositorio.
Para publicar sus cambios a otros, usted puede utilizar el comando commit de Subversion:
$ svn commit button.c Sending button.c Transmitting file data . Committed revision 57.
Ahora sus cambios a button.c
han sido
consignados al repositorio; si otro usuario obtiene una copia de trabajo
de /calc
, podrá ver sus cambios en la última
versión del archivo.
Suponga que tiene un colaborador, Carmen, quien obtuvo una
copia de trabajo de /calc
al mismo tiempo
que usted. Cuando usted envía sus cambios sobre
button.c
, la copia de trabajo de Carmen se deja
sin cambios; Subversion solo modifica las copias de trabajo a
petición del usuario.
Para tener su proyecto actualizado, Carmen puede pedir a Subversion que proceda a actualizar su copia de trabajo, usando para ello el comando update de Subversion. Ésto incorporará los cambios hechos por usted en la copia de trabajo de Carmen, así como otros cambios consignados desde que ella hizo el check out.
$ pwd /home/sally/calc $ ls -A .svn/ Makefile integer.c button.c $ svn update U button.c
La salida del comando svn update
indica que Subversion actualizó el contenido de
button.c
. Observe que Carmen no necesitó
especificar qué archivos actualizar; Subversion usa la información
del directorio .svn
, junto con
información adicional del repositorio, para decidir qué archivos
necesitan una actualización.
Una operación svn commit puede publicar los cambios sobre cualquier número de ficheros y directorios como una única transacción atómica. En su copia privada, usted puede cambiar el contenido de los ficheros, crear, borrar, renombrar y copiar ficheros y directorios, y luego enviar el conjunto entero de cambios como si se tratara de una unidad.
En el repositorio, cada cambio es tratado como una transacción atómica: o bien se realizan todos los cambios, o no se realiza ninguno. Subversion trata de conservar esta atomicidad para hacer frente a posibles fallos del programa, fallos del sistema, problemas con la red, y otras acciones del usuario.
Cada vez que el repositorio acepta un envío, éste da lugar a un nuevo estado del árbol de ficheros llamado revisión. A cada revisión se le asigna un número natural único, una unidad mayor que el número de la revisión anterior. La revisión inicial de un repositorio recién creado se numera con el cero, y consiste únicamente en un directorio raíz vacío.
La Figura 2.7, “El repositorio” ilustra una manera interesante de ver el repositorio. Imagine un array de números de revisión, comenzando por el 0, que se extiende de izquierda a derecha. Cada número de revisión tiene un árbol de ficheros colgando debajo de él, y cada árbol es una “instantánea” del aspecto del repositorio tras cada envío.
Es importante observar que las copias de trabajo no siempre se corresponden con una revisión en particular del repositorio; pueden contener ficheros de varias revisiones diferentes. Por ejemplo, suponga que obtiene una copia de trabajo de un repositorio cuya revisión más reciente es la 4:
calc/Makefile:4 integer.c:4 button.c:4
Por el momento, esta copia de trabajo se corresponde
exactamente con la revisión 4 del repositorio. Sin embargo,
suponga que realiza un cambio a button.c
y lo publica. Suponiendo que no se han realizado otros envíos,
el suyo creará la revisión 5 del repositorio, y su copia
de trabajo aparecerá ahora así:
calc/Makefile:4 integer.c:4 button.c:5
Suponga que, en este punto, Carmen envía un cambio a
integer.c
, creando la revisión 6. Si
usted usa svn update para actualizar
su copia de trabajo, ésta se verá ahora como:
calc/Makefile:6 integer.c:6 button.c:6
Los cambios de Carmen sobre integer.c
aparecerán en su copia de trabajo y las modificaciones hechas
por usted seguirán presentes en button.c
.
En este ejemplo, el texto de Makefile
es
idéntico en las revisiones 4, 5 y 6, aunque Subversion marcará
su copia de trabajo de Makefile con la revisión 6 para indicar
que ya está actualizada. Por lo tanto, después de hacer una
actualización limpia en el directorio raíz de su copia
de trabajo, ésta se corresponderá generalmente con una
revisión del repositorio exactamente.
Para cada fichero de una copia de trabajo, Subversion registra
dos datos esenciales en el área administrativa
.svn/
:
revisión en la que está basado el fichero de la copia de trabajo (ésto se llama la revisión de trabajo del fichero), y
una marca de tiempo con la fecha de la última actualización del fichero desde el repositorio.
Con esta información, y comunicándose con el repositorio, Subversion puede conocer en cuál de los cuatro estados siguientes se encuentra el fichero de la copia de trabajo:
El fichero no ha sido modificado en la copia de trabajo ni se ha enviado ningún cambio sobre ese fichero al repositorio desde su revisión de trabajo. Un svn commit de ese fichero no hará nada, y un svn update del fichero tampoco hará nada.
El fichero ha sido modificado en la copia de trabajo pero no se ha enviado ningún cambio sobre ese fichero al repositorio desde su revisión base. Hay cambios locales que no han sido enviados al repositorio, por lo que un svn commit del fichero publicará con éxito sus cambios, y un svn update del fichero no hará nada.
El fichero no ha sido modificado en la copia de trabajo, pero sí en el repositorio. El fichero debería ser actualizado para sincronizarlo con la revisión pública. Un svn commit del fichero no hará nada, y un svn update del fichero introducirá los últimos cambios en su copia de trabajo.
El fichero ha sido modificado tanto en la copia de trabajo como en el repositorio. Un svn commit del fichero fallará dando un error de “desactualizado”. El fichero debe ser actualizado primero; un svn update intentará mezclar los cambios públicos con los cambios locales. Si Subversion no puede combinar los cambios de manera convincente automáticamente, dejará que sea el usuario el que resuelva el conflicto.
Todo ésto puede parecer un montón de cosas a tener en cuenta, pero el comando svn status le mostrará el estado de cualquier elemento de su copia de trabajo. Para obtener más información acerca de ese comando, vea “svn status”.
Por norma general, Subversion trata de ser tan flexible como sea posible. Un tipo especial de flexibilidad es la habilidad para tener dentro de una copia de trabajo números de revisión mixtos.
Para comenzar, puede que no esté completamente claro el por qué este tipo de flexibilidad se considera una característica y no un problema. Después de completar un envío al repositorio, los ficheros y directorios recién enviados se encuentran en una revisión de trabajo más reciente que el resto de la copia de trabajo. Parece un poco lioso. Tal como se mostró anteriormente, siempre se puede dejar una copia de trabajo en una única revisión de trabajo ejecutando svn update. ¿Por qué querría alguien deliberadamente tener una mezcla de revisiones de trabajo?
Suponiendo que su proyecto es lo suficientemente complejo, descubrirá que a veces es conveniente forzar la “desactualización” de ciertas partes de su copia de trabajo a una versión anterior; aprenderá cómo hacer ésto en el capítulo 3. Quizás quiera probar una versión anterior de un submódulo contenido en un subdirectorio, o tal vez quiera examinar una serie de versiones previas de un fichero en el contexto del último árbol.
Por mucho que usted haga uso de revisiones mixtas en su copia de trabajo, hay ciertas limitaciones asociadas a esta flexibilidad.
Primero, usted no puede publicar la eliminación de un fichero o directorio que no esté completamente actualizado. Si existe una versión más reciente en el repositorio, su intento de eliminación será rechazado para impedir que destruya accidentalmente cambios que aún no ha visto.
Segundo, usted no puede publicar los cambios en los metadatos de un directorio a menos que esté completamente actualizado. Aprenderá cómo adjuntar “propiedades” a elementos en el capítulo 6. Una revisión de trabajo de un directorio define un conjunto específico de entradas y propiedades, y por tanto enviar un cambio a una propiedad de un directorio desactualizado puede destruir las propiedades que no haya visto todavía.