Subversion en acción

Es hora de movernos de lo abstracto a lo concreto. En esta sección mostraremos ejemplos reales de Subversion en la práctica.

Copias de trabajo

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”.

Figura 2.6. El sistema de archivos del repositorio

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.

Revisiones

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.

Figura 2.7. El repositorio

El repositorio

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.

Cómo las copias de trabajo siguen la pista al repositorio

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:

Sin cambios y actualizado

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.

Modificado localmente y actualizado

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.

Sin cambios y desactualizado

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.

Modificado localmente y desactualizado

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.

Las limitaciones de las revisiones mixtas

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.