Descargar

Subversión para el control de Versiones (página 2)


Partes: 1, 2, 3, 4

Envíos atómicos

Una colección cualquiera de modificaciones o bien entra por completo al repositorio, o bien no lo hace en absoluto. Ésto permite a los desarrolladores construir y enviar los cambios como fragmentos lógicos e impide que ocurran problemas cuando sólo una parte de los cambios enviados lo hace con éxito.

Versionado de metadatos

Cada fichero y directorio tiene un conjunto de propiedades —claves y sus valores —asociado a él. Usted puede crear y almacenar cualquier par arbitrario de clave/valor que desee. Las propiedades son versionadas a través del tiempo, al igual que el contenido de los ficheros.

Elección de las capas de red

Subversión tiene una noción abstracta del acceso al repositorio, facilitando a las personas implementar nuevos mecanismos de red. Subversión puede conectarse al servidor HTTP Apache como un módulo de extensión. Ésto proporciona a Subversión una gran ventaja en estabilidad e interoperabilidad, y acceso instantáneo a las características existentes que ofrece este servidor—autenticación, autorización, compresión de la conexión, etcétera. También tiene disponible un servidor de Subversión independiente, y más ligero. Este servidor habla un protocolo propio, el cual puede ser encaminado fácilmente a través de un túnel SSH.

Manipulación consistente de datos

Subversión expresa las diferencias del fichero usando un algoritmo de diferenciación binario, que funciona idénticamente con ficheros de texto (legibles para humanos) y ficheros binarios (ilegibles para humanos). Ambos tipos de ficheros son almacenados igualmente comprimidos en el repositorio, y las diferencias son transmitidas en ambas direcciones a través de la red.

Ramificación y etiquetado eficientes

El coste de ramificación y etiquetado no necesita ser proporcional al tamaño del proyecto. Subversión crea ramas y etiquetas simplemente copiando el proyecto, usando un mecanismo similar al enlace duro. De este modo estas operaciones toman solamente una cantidad de tiempo pequeña y constante.

Hackability

Subversión no tiene un equipaje histórico; está implementado como una colección de bibliotecas compartidas en C con APIs bien definidas. Ésto hace a Subversión extremadamente fácil de mantener y reutilizable por otras aplicaciones y lenguajes.

Arquitectura de Subversión

edu.red

En un extremo se encuentra un repositorio de Subversión que conserva todos los datos versionados. Al otro lado, hay un programa cliente Subversión que administra réplicas parciales de esos datos versionados (llamadas "copias de trabajo"). Entre estos extremos hay múltiples rutas a través de varias capas de acceso al repositorio (AR). Algunas de estas rutas incluyen redes de ordenadores y servidores de red que después acceden al repositorio. Otras pasan por alto la red y acceden al repositorio directamente.

Componentes de Subversión

Subversión se compone de un número diferente de piezas. A continuación se presenta una visión general de estos componentes.

svn

El programa cliente de línea de comandos.

svnversion

Programa para informar del estado (en términos de revisiones de los elementos presentes) de una copia de trabajo.

svnlook

Una herramienta para inspeccionar un repositorio de Subversión.

svnadmin

Herramienta para crear, modificar o reparar un repositorio de Subversión.

svndumpfilter

Un programa para filtrar el formato de salida de volcado de repositorios Subversión.

mod_dav_svn

Un módulo para el servidor HTTP Apache usado para hacer que su repositorio esté disponible a otros a través de una red.

svnserve

Un servidor independiente, ejecutable como proceso demonio o invocable por SSH; otra manera de hacer que su repositorio esté disponible para otros a través de una red.

Conceptos Básicos

El repositorio

Subversión es un sistema centralizado para compartir información. La parte principal de Subversión es el repositorio, el cual es un almacén central de datos. El repositorio guarda información en forma de árbol de archivos—una típica jerarquía de archivos y directorios. Cualquier número de clientes puede conectarse al repositorio y luego leer o escribir en esos archivos. Al escribir datos, un cliente pone a disposición de otros la información; al leer datos, el cliente recibe información de otros.

Un sistema cliente/servidor típico

edu.red

El repositorio es una especie de servidor de archivos, pero no del tipo habitual. Lo que hace especial al repositorio de Subversión es que recuerda todos los cambios hechos sobre él: cada cambio a cada archivo, e inclusive cambios al propio árbol de directorios, tales como la adición, borrado y reubicación de archivos y directorios.

Cuando un cliente lee datos del repositorio, normalmente sólo ve la ultima versión del árbol de archivos. Sin embargo, el cliente también tiene la posibilidad de ver estados previos del sistema de archivos. Por ejemplo, un cliente puede hacer consultas históricas como, "¿Qué contenía este directorio el miércoles pasado?" Esta es la clase de preguntas que resulta esencial en cualquier sistema de control de versiones: sistemas que están diseñados para registrar y seguir los cambios en los datos a través del tiempo.

Modelos de versionado

La misión principal de un sistema de control de versiones es permitir la edición colaborativa y la compartición de los datos. Sin embargo, existen diferentes sistemas que utilizan diferentes estrategias para alcanzar este objetivo.

El problema de compartir archivos

Todos los sistemas de control de versiones tienen que resolver un problema fundamental: ¿Cómo permitirá el sistema a los usuarios el compartir información, pero al mismo tiempo impedirá que coincidan mutuamente de forma accidental? Es muy sencillo para los usuarios el sobreescribir accidentalmente los cambios de los demás en el repositorio.

La solución bloqueo-modificación-desbloqueo

Muchos sistemas de control de versiones utilizan un modelo de bloqueo-modificación-desbloqueo para atacar este problema. En un sistema como éste, el repositorio sólo permite a una persona modificar un archivo al mismo tiempo. Una persona debe "bloquear" primero el archivo para luego empezar a hacerle cambios. Si otra persona intenta bloquear el archivo, el repositorio rechazará la petición. Todo lo que puede hacer es leer el archivo y esperar que el primero termine sus cambios y deshaga el bloqueo. El problema con el modelo bloqueo-modificación-desbloqueo es que es un tanto restrictivo y a menudo se convierte en un obstáculo para los usuarios:

  • Bloquear puede causar problemas administrativos. Si una persona bloquea un archivo y se olvida de él. La situación termina causando muchas demoras innecesarias y pérdida de tiempo.

  • Bloquear puede causar una serialización innecesaria. Si una persona quiere editar el principio de un archivo y otra el final. Estos cambios no se solapan en absoluto. Ambos podrían editar el archivo simultáneamente sin grandes perjuicios, suponiendo que los cambios se combinaran correctamente. No hay necesidad de turnarse en esta situación.

  • Bloquear puede causar una falsa sensación de seguridad. Imaginemos que una persona bloquea y edita el archivo A, y otra bloquea y edita el archivo B al mismo tiempo. Pero suponga que A y B dependen uno del otro y que los cambios hechos a cada uno de ellos son semánticamente incompatibles. Súbitamente A y B ya no funcionan juntos. El sistema de bloqueo se mostró ineficaz a la hora de evitar el problema—sin embargo, y de algún modo, ofreció una falsa sensación de seguridad.

La solución copiar-modificar-mezclar

Subversión, CVS y otros sistemas de control de versiones utilizan un modelo del tipo copiar-modificar-mezclar como alternativa al bloqueo. En este modelo, el cliente de cada usuario se conecta al repositorio del proyecto y crea una copia de trabajo personal—una réplica local de los archivos y directorios del repositorio. Los usuarios pueden entonces trabajar en paralelo, modificando sus copias privadas. Finalmente, todas las copias privadas se combinan (o mezclan) en una nueva versión final. El sistema de control de versiones a menudo ayuda con la mezcla, pero en última instancia es un ser humano el responsable de hacer que ésto suceda correctamente.

Digamos que que dos personas crean sendas copias de trabajo del mismo proyecto, extraídas del repositorio. Ambos trabajan concurrentemente y hacen cambios a un mismo archivo A dentro de sus copias. La primera guarda sus cambios en el repositorio. Cuando la segunda intenta guardar sus cambios más tarde, el repositorio le informa de que su archivo A está desactualizado. En otras palabras, que el archivo A en el repositorio ha sufrido algún cambio desde que lo copió por última vez. Por tanto, la segunda persona le pide a su cliente que mezcle cualquier cambio nuevo del repositorio con su copia de trabajo del archivo A. Es probable que los cambios primeros no se solapen con los suyos; así que una vez que tiene ambos juegos de cambios integrados, se guarda la copia de la segunda persona de nuevo en el repositorio.

Que se solapen los cambios se conoce como conflicto y no suele suponer un gran problema. Los últimos cambios del repositorio se marca de algún modo para indicar que está en estado de conflicto

La solución copiar-modificar-mezclar puede sonar un tanto caótica, pero en la práctica funciona extremadamente bien. Los usuarios pueden trabajar en paralelo, sin tener que esperarse el uno al otro. Cuando trabajan en los mismos archivos, sucede que la mayoría de sus cambios concurrentes no se solapan en absoluto; los conflictos son poco frecuentes. El tiempo que toma resolver los conflictos es mucho menor que el tiempo perdido por un sistema de bloqueos.

Al final, todo desemboca en un factor crítico: la comunicación entre los usuarios. Cuando los usuarios se comunican pobremente, los conflictos tanto sintácticos como semánticos aumentan. Ningún sistema puede forzar a los usuarios a comunicarse perfectamente, y ningún sistema puede detectar conflictos semánticos. Por consiguiente, no tiene sentido dejarse adormecer por la falsa promesa de que un sistema de bloqueos evitará de algún modo los conflictos; en la práctica, el bloqueo parece inhibir la productividad más que otra cosa.

Funcionamiento

Copias de trabajo

Una copia de trabajo de Subversión 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: Subversión 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, Subversión 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, Subversión 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 Subversión 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 Subversión 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 Subversión 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.

edu.red

Para conseguir una copia de trabajo, debe ejecutar primero un check out de algún subárbol del repositorio. (crea una copia privada del proyecto). 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 Subversión 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 Subversión necesita, tal y como se mencionó anteriormente.

URLs del repositorio

A los repositorios de Subversión se puede acceder a través de diferentes métodos—en el disco local, o a través de varios protocolos de red. Sin embargo, la ubicación de un repositorio es siempre un URL. La tabla describe la correspondencia entre los diferentes esquemas de URL y los métodos de acceso disponibles.

URLs de Acceso al Repositorio

Esquema

Método de acceso

file:///

acceso directo al repositorio (en disco local)

http://

acceso vía protocolo WebDAV a un servidor Apache que entiende de Subversión

https://

igual que http://, pero con cifrado SSL.

svn://

acceso vía un protocolo personalizado a un servidor svnserve.

svn+ssh://

igual que svn://, pero a través de un túnel SSH.

En general, los URLs de Subversión utilizan la sintaxis estándar, permitiendo la especificación de nombres de servidores y números de puertos como parte del URL. Recuerde que el método de acceso file: es válido sólo para ubicaciones en el mismo servidor donde se ejecuta el cliente—de hecho, se requiere por convención que la parte del URL con el nombre del servidor esté ausente o sea localhost:

$ svn checkout file:///ruta/a/repositorio

.

$ svn checkout file://localhost/ruta/a/repositorio

.

Además, los usuarios del esquema file: en plataformas Windows necesitarán usar una sintaxis "estándar" extraoficial para acceder a repositorios que están en la misma máquina, pero en una unidad de disco distinta de la que el cliente esté utilizando en el momento. Cualquiera de las dos siguientes sintaxis para rutas de URL funcionarán siendo X la unidad donde reside el repositorio:

C:> svn checkout file:///X:/ruta/a/repositorio

.

C:> svn checkout "file:///X|/ruta/a/repositorio"

.

En la segunda sintaxis, es necesario encerrar el URL entre comillas para que la barra vertical no sea interpretada como una tubería.

Nótese que un URL usa barras de separación ordinarias aún cuando la forma de ruta nativa (no para URLs) en Windows utiliza barras invertidas.

Suponga que hace cambios a button.c. Puesto que el directorio .svn recuerda la fecha de modificación del archivo y su contenido original, Subversión es capaz de darse cuenta de que el archivo ha cambiado. Sin embargo, Subversión 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 Subversión:

$ 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, 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 su colaborador se deja sin cambios; Subversión solo modifica las copias de trabajo a petición del usuario.

Para tener su proyecto actualizado, su colaborador puede pedir a Subversión que proceda a actualizar su copia de trabajo, usando para ello el comando update de Subversión. Ésto incorporará los cambios hechos por usted en la copia de trabajo de su colaborador, así como otros cambios consignados desde que él hizo el check out.

$ pwd

/home/evelyn/calc

$ ls -A

.svn/ Makefile integer.c button.c

$ svn update

U button.c

La salida del comando svn update indica que Subversión actualizó el contenido de button.c. Observe que su colaborador no necesitó especificar qué archivos actualizar; Subversión 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. Subversión 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 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.

edu.red

Números de revisión global

A diferencia de muchos otros sistemas de control de versiones, los números de revisión de Subversión se aplican a árboles enteros, no a ficheros individuales. Cada número de revisión selecciona un árbol completo, un estado particular del repositorio tras algún cambio publicado. Otra manera de ver ésto es que la revisión N representa el estado del sistema de ficheros del repositorio tras el envío de cambios N-ésimo. Cuando un usuario de Subversión habla de la "revisión 5 de foo.c", lo que realmente quiere decir es "foo.c tal como aparece en la revisión 5." Observe que en general, ¡las revisiones N y M de un fichero no tienen por qué ser diferentes necesariamente! Dado que CVS utiliza números de revisión para cada fichero.

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, un colega 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 su colega 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 Subversión 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, Subversión 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, Subversión 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 Subversión no puede combinar los cambios de manera convincente automáticamente, dejará que sea el usuario el que resuelva el conflicto.

El comando svn status le mostrará el estado de cualquier elemento de su copia de trabajo.

Las limitaciones de las revisiones mixtas

Por norma general, Subversión 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. 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. 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. 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.

Modo de trabajo

Ayuda

En cualquier momento, svn help describirá la sintaxis, los interruptores y el comportamiento del subcomando.

Import

Use svn import para importar un nuevo proyecto dentro de un repositorio Subversión.

Revisiones: números, palabras clave, y fechas

Una revisión es una "instantánea" de su repositorio en un momento particular en el tiempo. A medida que continué depositando y creciendo su repositorio, usted necesita un mecanismo para identificar estas instantáneas.

Especifique estas revisiones usando –revision (-r) junto con la revisión que quiera (svn –revision REV) o puede especificar un rango separando dos revisiones con dos puntos (svn –revision REV1:REV2). Y Subversión le deja referirse a estas revisiones por número, palabra clave, o fecha.

Números de revisión

Cuando usted crea un nuevo repositorio de Subversión, este comienza su vida como revisión cero y cada commit sucesivo incrementa el número de revisión en uno. Después de completar su commit, el cliente de Subversión le informa del nuevo número de revisión:

$ svn commit –message "Corrected number of cheese slices."

Sending sandwich.txt

Transmitting file data .

Committed revision 3.

Si en cualquier punto del futuro usted desea referirse a esta revisión, puede referirse a esta como "3".

Palabras clave de la revisión

El cliente de Subversión entiende un número de palabras clave de la revisión. Estas palabras clave pueden ser usadas en vez del número entero como argumento a la opción –revision, y son resueltos como números específicos de revisión por Subversión:

Cada directorio en su copia de trabajo contiene un subdirectorio administrativo llamado .svn. Para todos los ficheros en un directorio, Subversión mantiene una copia de cada fichero en el área administrativa. Esta copia es una copia no modificada (ninguna extensión de palabra clave, ninguna traducción del fin-de-linea) del fichero tal como existió en la última revisión (llamada la revisión "BASE") que usted actualizó a su copia de trabajo. Nos referimos a este fichero como copia prístina o versión basada en texto de su fichero, y este es siempre una copia byte-a-byte exacta del fichero tal como existe en el repositorio.

HEAD

La última revisión del repositorio.

BASE

La revisión "prístina" de un elemento en la copia de trabajo.

COMMITTED

La última revisión en la que un elemento cambió antes (o en) BASE.

PREV

La revisión justo anterior de la última revisión en la cual un elemento cambió. (Técnicamente, COMMITTED – 1.)

PREV, BASE, y COMMITTED pueden ser usadas para referirse a paths locales, pero no a URLs.

Aquí hay algunos ejemplos de palabras clave de revisión en acción.

$ svn diff –revision PREV:COMMITTED foo.c

# shows the last change committed to foo.c

$ svn log –revision HEAD

# shows log message for the latest repository commit

$ svn diff –revision HEAD

# compares your working file (with local mods) to the latest version

# in the repository.

$ svn diff –revision BASE:HEAD foo.c

# compares your "pristine" foo.c (no local mods) with the

# latest version in the repository

$ svn log –revision BASE:HEAD

# shows all commit logs since you last updated

$ svn update –revision PREV foo.c

# rewinds the last change on foo.c.

# (foo.c's working revision is decreased.)

Estas palabras clave le permiten realizar muchas operaciones comunes (y útiles) sin tener que mirar números específicos de revisión o recordar la revisión exacta de su copia de trabajo.

Fechas de revisión

Dondequiera que usted especifique un número de revisión o palabra clave de revisión, usted también puede especificar una fecha especificando la fecha dentro de llaves "{}". ¡Puede incluso tener acceso a un rango de cambios en el repositorio usando fechas y revisiones juntas!

Aquí hay ejemplos de los formatos de fecha que admite Subversión.

$ svn checkout –revision {2002-02-17}

$ svn checkout –revision {15:30}

$ svn checkout –revision {15:30:00.200000}

$ svn checkout –revision {"2002-02-17 15:30"}

$ svn checkout –revision {"2002-02-17 15:30 +0230"}

$ svn checkout –revision {2002-02-17T15:30}

$ svn checkout –revision {2002-02-17T15:30Z}

$ svn checkout –revision {2002-02-17T15:30-04:00}

$ svn checkout –revision {20020217T1530}

$ svn checkout –revision {20020217T1530Z}

$ svn checkout –revision {20020217T1530-0500}

.

Cuando especifique una fecha como revisión, Subversión encuentra la revisión más reciente en el repositorio con esta fecha:

$ svn log –revision {2002-11-28}

————————————————————————

r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines

.

¿Está Subversión un día anticipado?

Si usted especifica una fecha simple como revisión sin especificar una hora del día (por ejemplo 2002-11-27), puede pensar que Subversión le dará la última revisión que tuvo lugar el 27 de Noviembre. En cambio, usted recibirá una revisión del 26 de Noviembre, o incluso anterior. Recuerde que Subversión encontrará la revisión más reciente del repositorio con la fecha que usted da. Si da una marca de tiempo sin hora, como 2002-11-27, Subversión asume la hora como 00:00:00, así que buscando la revisión más reciente no devolverá nada del día 27.

Si quiere incluir el día 27 en su búsqueda, puede especificar el día 27 con la hora ({"2002-11-27 23:59"}), o justo el día siguiente ({2002-11-28}).

También puede especificar un rango de fechas. Subversión encontrará todas las revisiones entre ambas fechas, inclusive:

$ svn log –revision {2002-11-20}:{2002-11-29}

.

Como apuntamos, también puede mezclar fechas y revisiones:

$ svn log –revision {2002-11-20}:4040

Los usuarios deberían estar enterados de un subtlety que puede convertirse en un obstáculo al tratar con fechas en Subversión. Desde que la marca de tiempo de una revisión es guardada como una propiedad de la revisión— una propiedad sin versionar, modificable — la marca de tiempo de la revisión puede cambiarse para representar una falsificación completa de la verdadera cronología, o incluso borrarla totalmente. Esto causará estragos en la conversión interna fecha-a-revisión que Subversión realiza.

Descarga inicial

La mayoría del tiempo, comenzará usando un repositorio de Subversión haciendo un checkout de su proyecto. Descargando un repositorio crea una copia de este en en su maquina local. Esta copia contiene el HEAD (última revisión) del repositorio de Subversión que usted especifica en la línea de comandos:

$ svn checkout http://svn.collab.net/repos/svn/trunk

A trunk/subversión.dsw

A trunk/svn_check.dsp

A trunk/COMMITTERS

A trunk/configure.in

A trunk/IDEAS

.

Checked out revision 2499.

Esquema del repositorio

Aunque el ejemplo anterior descarga el directorio trunk , usted puede descargar fácilmente cualquier subdirectorio más profundo de un repositorio especificando el subdirectorio en la URL de descarga:

$ svn checkout http://svn.collab.net/repos/svn/trunk/doc/book/tools

A tools/readme-dblite.html

A tools/fo-stylesheet.xsl

A tools/svnbook.el

A tools/dtd

A tools/dtd/dblite.dtd

.

Checked out revision 2499.

Desde que Subversión usa un modelo "copie-modifique-fusione" en vez de "atar-modificar-desatar" usted ya puede comenzar a realizar cambios a los ficheros y directorios en su copia de trabajo local. Su copia local es justo como cualquier otra colección de ficheros y directorios en su sistema. Usted puede editarlos y cambiarlos, moverlos, usted puede incluso borrar la copia local entera y olvidarse de él.

Mientras que su copia de trabajo local es "justo como cualquier otra colección de ficheros y directorios en su sistema", usted necesita hacer saber a Subversión si va a cambiar cualquier cosa dentro de su copia local. Si desea copiar o mover un elemento en una copia local, debe usar svn copy o svn move en vez de los comandos copiar y mover proporcionados por su sistema operativo.

A menos que esté preparado para enviar al repositorio un nuevo fichero o directorio, o cambios a unos existentes, no hay necesidad de citar más sobre el servidor de Subversión que usted haya hecho.

¿Qué pasa con el directorio .svn?

Cada directorio en una copia de trabajo local contiene un área administrativa, un subdirectorio llamado .svn. Generalmente, el comando de listado de directorios no mostrará este subdirectorio, pero este es sin embargo un directorio importante. Sea lo que fuere lo que haga ¡no borre o cambie nada en el área administrativa! Subversión depende de esta para administrar su copia de trabajo local.

Mientras que usted puede descargar una copia de trabajo local con la URL del repositorio como único argumento, también puede especificar un directorio después de su URL del repositorio. Esto pone su copia de trabajo local dentro del nuevo directorio que usted nombra. Por ejemplo:

$ svn checkout http://svn.collab.net/repos/svn/trunk subv

A subv/subversión.dsw

A subv/svn_check.dsp

A subv/COMMITTERS

A subv/configure.in

A subv/IDEAS

.

Checked out revision 2499.

Esto pondrá su copia de trabajo local en un directorio llamado subv en vez de en un directorio llamado trunk como hemos hecho previamente.

Ciclo básico de trabajo

Las cosas más comunes que puede encontrarse haciendo con Subversión en el transcurso de un día de trabajo.

El típico ciclo de trabajo se parece a esto:

  • Actualizar su copia de trabajo local

  • svn update

  • Hacer cambios

  • svn add

  • svn delete

  • svn copy

  • svn move

  • Examinar sus cambios

  • svn status

  • svn diff

  • svn revert

  • Fusionarlos con los cambios de otros

  • svn merge

  • svn resolved

  • Enviar sus cambios al repositorios

  • svn commit

Actualizar su copia de trabajo local

Cuando se trabaja en un proyecto con un equipo, usted querrá actualizar su copia de trabajo local para recibir cualquier cambio hecho desde su última actualización por otros desarrolladores en el proyecto. Use svn update para aportar a su copia de trabajo local sincronización con la última revisión en el repositorio.

$ svn update

U foo.c

U bar.c

Updated to revision 2.

En este caso, alguien modificó foo.c y bar.c desde la última vez que usted actualizó, y Subversión ha actualizado su copia de trabajo local para incluir estos cambios.

Vamos a examinar la salida de svn update un poco más. Cuando el servidor envía cambios a su copia de trabajo local, una letra código se visualiza al lado del objeto para hacerle saber qué acciones realizó Subversión para traer su copia de trabajo local a la actualización:

U foo

El fichero foo fue Updated (recibidos cambios del servidor).

A foo

El fichero o directorio foo fue Added a su copia de trabajo local.

D foo

El fichero o directorio foo fue Deleted de su copia de trabajo local.

R foo

El fichero o directorio foo fue Replaced en su copia de trabajo local; esto es, foo fue borrado, y un nuevo objeto con el mismo nombre fue añadido. Mientras pueden tener el mismo nombre, el repositorio los considera objetos distintos con historiales distintos.

G foo

El fichero foo recibió nuevos cambios del repositorio, pero su copia local del fichero tenía sus modificaciones. O los cambios no se tocaron, o los cambios eran exactamente iguales que sus modificaciones locales, así que Subversión ha merGed satisfactoriamente los cambios del repositorio al fichero sin ningún problema.

C foo

El fichero foo recibió cambios Conflicting del servidor. Los cambios del servidor directamente se superpusieron sobre sus propios cambios en el fichero. Esta superposición necesita ser resuelta por usted.

Hacer cambios en su copia de trabajo local

Ahora puede conseguir trabajar y hacer cambios en su copia de trabajo local. Generalmente es más conveniente decidir un cambio particular (o un conjunto de cambios) a hacer, por ejemplo escribir una nueva característica, corregir un fallo, etc. Los comandos de Subversión que puede usar aquí son svn add, svn delete, svn copy, y svn move. Sin embargo, si usted está simplemente corrigiendo los archivos que están ya en Subversión, puede no necesitar utilizar ninguno de estos comandos hasta que envíe los cambios. Cambios que puede hacer a su copia de trabajo local:

Cambios en los ficheros

Esta es la clase más simple de cambio. No necesita decirle a Subversión que se propone a cambiar un fichero; simplemente haga los cambios. Subversión será capaz de detectar automáticamente qué archivos han sido cambiados.

Cambios en el árbol

Puede preguntar a Subversión que "marque" ficheros y directorios para el borrado planificado, la adición, la copia, o moverlos. Mientras estos cambios pueden ocurrir inmediatamente en su copia de trabajo local, ninguna adición o borrado sucederá en el repositorio hasta que envíe los cambios.

Para hacer cambios en los ficheros, use su editor de textos, procesador de textos, programa de gráficos, o cualquier herramienta que usaría normalmente. Subversión maneja ficheros binarios tan fácilmente como maneja archivos de texto y tan eficientemente también.

Aquí hay una descripción de los cuatro subcomandos de Subversión que usted usará más a menudo para hacer cambios del árbol

svn add foo

Programa añadir foo al repositorio. Cuando haga su próximo envío, foo se convertirá en hijo de su directorio padre. Fíjese que si foo es un directorio, todo por debajo de foo será programado para la adición. Si solo quiere añadir el propio foo, pase la opción –non-recursive (-N).

svn delete foo

Programa borrar foo del repositorio. Si foo es un fichero, se borrará inmediatamente de su copia de trabajo local. Si foo es un directorio, este no es borrado, pero Subversión lo programa para borrarlo. Cuando envíe sus cambios, foo será borrado de su copia de trabajo y del repositorio.

svn copy foo bar

Crea un nuevo objeto bar como duplicado de foo. bar es automáticamente programado para la adición. Cuando bar es añadido al repositorio en el siguiente envío de cambios, su historia de copia es registrada (como que originalmente viene de foo).svn copy no crea directorios intermedios.

svn move foo bar

Este comando funciona exactamente igual que svn copy foo bar; svn delete foo. Esto es, se programa bar para la adición como una copia de foo, y se programa foo para la eliminación. svn move no crea directorios intermedios.

Cambiando el repositorio sin una copia de trabajo

Tiene que enviar cualquier cambio que usted haga en orden para que el repositorio refleje estos cambios. Esto no es enteramente cierto —hay algunos usos-casos que inmediatamente envían los cambios del árbol al repositorio. Esto sucede solamente cuando un subcomando está operando directamente sobre una URL, al contrario que sobre una ruta de la copia-local . En particular, usos específicos de svn mkdir, svn copy, svn move, y svn delete pueden trabajar con URLs.

Las operaciones de URL se comportan de esta manera porque los comandos que manipulan en una copia de trabajo pueden usar la copia de trabajo como una clase de "área de estancamiento"para preparar sus cambios antes de enviarlos al repositorio. Los comandos que operan sobre URLs no tienen este lujo, así cuando usted opera directamente sobre una URL, cualquiera de las acciones anteriores representa un envío inmediato.

Examine sus cambios

Una vez que haya terminado de hacer cambios, necesita enviarlos al repositorio, pero antes de hacerlo, generalmente es buena idea echar un vistazo a lo que ha cambiado exactamente. Examinando sus cambios antes de que los envíe, puede hacer un mensaje de informe de cambios más exacto. También puede descubrir que ha cambiado inadvertidamente un fichero, y esto le da la posibilidad de invertir esos cambios antes de enviarlos. Además, esta es una buena oportunidad para revisar y escudriñar cambios antes de publicarlos. Usted puede ver exactamente qué cambios ha hecho usando svn status, svn diff, y svn revert. Generalmente usará los primeros dos comandos para descubrir qué ficheros han cambiado en su copia de trabajo local, y después quizá el tercero para invertir algunos (o todos) de esos cambios.

Subversión ha sido optimizado para ayudarle con esta tarea, y es capaz de hacer muchas cosas sin comunicarse con el repositorio. En particular, su copia de trabajo local contiene una copia "prístina" secreta almacenada de cada fichero de versión controlado dentro del área .svn. Debido a esto, Subversión puede rápidamente mostrarle cómo sus ficheros de trabajo han cambiado, o incluso permitirle deshacer sus cambios sin contactar con el repositorio.

svn status le dará toda la información que necesita sobre qué ha cambiado en su copia de trabajo local.

En este ejemplo puede ver todos los códigos de estado diferentes que svn status puede devolver. (Observe que el texto que sigue a # en el siguiente ejemplo no es impreso realmente por svn status.)

$ svn status

L abc.c # svn has a lock in its .svn directory for abc.c

M bar.c # the content in bar.c has local modifications

M baz.c # baz.c has property but no content modifications

X 3rd_party # this dir is part of an externals definition

? foo.o # svn doesn't manage foo.o

! some_dir # svn manages this, but it's either missing or incomplete

~ qux # versioned as dir, but is file, or vice versa

I .screenrc # this file is ignored

A + moved_dir # added with history of where it came from

M + moved_dir/README # added with history and has local modifications

D stuff/fish.c # this file is scheduled for deletion

A stuff/loot/bloo.h # this file is scheduled for addition

C stuff/loot/lump.c # this file has conflicts from an update

S stuff/squawk # this file or dir has been switched to a branch

.

En este formato de salida svn status impresa cinco columnas de caracteres, seguidos por varios caracteres de espacio en blanco, seguido por un nombre de fichero o directorio. La primera columna dice el estado de un fichero o directorio y/o su contenido. Los códigos impresos aquí son:

A file_or_dir

El fichero o directorio file_or_dir ha sido programado para la adición en el repositorio.

C file

El fichero file está en un estado de conflicto. Esto es, los cambios recibidos del servidor durante una actualización se solapan con cambios locales que usted tiene en su copia de trabajo. Debe resolver este conflicto antes de enviar sus cambios al repositorio.

D file_or_dir

El fichero o directorio file_or_dir ha sido programado para la supresión del repositorio.

M file

El contenido del fichero file ha sido modificado.

X dir

El directorio dir está sin versionar, pero está relacionado con una definición externa de Subversión.

? file_or_dir

El fichero o directorio file_or_dir no está bajo control de versiones. Puede silenciar la marca de pregunta pasando la opción –quiet (-q) a svn status, o o poniendo la característica svn:ignore en el directorio padre.

! file_or_dir

El fichero o directorio file_or_dir está bajo el control de versiones pero falta o está de alguna manera incompleto. El objeto puede faltar si se ha borrado usando un comando ajeno a Subversión. En el caso de un directorio, puede estar incompleto si ha interrumpido una descarga o una actualización. Un rápido svn update repondrá el fichero o el directorio desde el repositorio, o svn revert file restaurará un archivo que falta.

~ file_or_dir

El fichero o directorio file_or_dir está en el repositorio como un tipo de objeto, pero actualmente está en su copia de trabajo como otro tipo. Por ejemplo, Subversión pudo tener un fichero en el repositorio, pero usted borró el fichero y creó un directorio en su lugar, sin usar los comandos svn delete o svn add.

I file_or_dir

Subversión está "ignorando" el fichero o directorio file_or_dir, probablemente porque usted se lo dijo.

La segunda columna dice el estado de las propiedades de un fichero o un directorio. Si aparece una M en la segunda columna, entonces las propiedades han sido modificadas, si no un espacio en blanco será impreso.

La tercera columna solo mostrará un espacio en blanco o una L la cual significa que Subversión ha bloqueado el objeto en el área de trabajo .svn. Usted verá una L si ejecuta svn status en un directorio donde un svn commit esté en progreso—quizás cuando esté editando el informe de cambios. Si Subversión no se está ejecutando, entonces probablemente Subversión fue interrumpido y el bloqueo necesita ser eliminado ejecutando svn cleanup .

La cuarta columna solo mostrará un espacio blanco o un + el cual significa que el fichero o directorio está programado para ser añadido o modificado con historial adicional adjunto. Esto ocurre típicamente cuando usted svn move o svn copy un fichero o directorio. Si usted ve A  +, esto significa que el objeto está programado para la adición-con-historial. Este puede ser un fichero, o la raíz de un directorio copiado. + significa que el objeto es parte de un subárbol programado para la adición-con-historial, p.e.algún padre fue copiado,and it's just coming along for the ride. M  + significa que el objeto es parte de un subárbol programado para la adición-con-historial, y este tiene modificaciones locales. Cuando envíe los cambios, primero el padre será añadido-con-historial (copiado), lo que significa que este fichero existirá automáticamente en la copia. Entonces las modificaciones locales serán enviadas al repositorio.

La quinta columna solo mostrará un espacio en blanco o una S. Esto significa que el fichero o directorio ha sido movido de la ruta del resto de la copia de trabajo (usando svn switch) a una rama.

Si usted pasa una ruta específica a svn status, este le dará información acerca de ese objeto solamente:

$ svn status stuff/fish.c

D stuff/fish.c

svn status también tiene una opción –verbose (-v), el cuál le mostrará el estado de todos los objetos en su copia de trabajo, incluso si este no ha sido cambiado:

$ svn status –verbose

M 44 23 evelyn README

44 30 evelyn INSTALL

M 44 20 harry bar.c

44 18 ira stuff

44 35 harry stuff/trout.c

D 44 19 ira stuff/fish.c

44 21 evelyn stuff/things

A 0 ? ? stuff/things/bloo.h

44 36 harry stuff/things/gloo.c

Esta es la "forma larga" de salida de svn status. La primera columna permanece igual, pero la segunda columna muestra la revisión de trabajo del fichero. La tercera y cuarta columna muestra la revisión en la cuál el objeto cambió por última vez, y quién lo cambió.

Ninguna de las invocaciones anteriores a svn status contactaba con el repositorio, trabajan solo localmente comparando los metadatos en el directorio .svn con la copia de trabajo local. Finalmente está la opción –show-updates (-u), la cual contacta con el repositorio y añade información acerca de las cosas que están fuera-de-fecha:

$ svn status –show-updates –verbose

M * 44 23 evelyn README

M 44 20 harry bar.c

* 44 35 harry stuff/trout.c

D 44 19 ira stuff/fish.c

A 0 ? ? stuff/things/bloo.h

Status against revision: 46

Observe los dos asteriscos: si usted ejecutara svn update en este punto, usted podría recibir cambios para README y trout.c. Esto le dice cierta información muy útilmdash;necesitará actualizar y coger los cambios del servidor para README antes de enviar sus cambios, o el repositorio rechazará su envío por estar fuera-de-fecha.

svn diff

Otra manera de examinar sus cambios es con el comando svn diff. Puede descubrir exactamente cómo ha modificado cosas ejecutando svn diff sin argumentos, el cual imprime los cambios de los ficheros en formato unificado del diff:

$ svn diff

Index: bar.c

===================================================================

— bar.c (revision 3)

+++ bar.c (working copy)

@@ -1,7 +1,12 @@

+#include

+#include

+#include

+

+#include

int main(void) {

– printf("Sixty-four slices of American Cheese…n");

+ printf("Sixty-five slices of American Cheese…n");

return 0;

}

Index: README

===================================================================

— README (revision 3)

+++ README (working copy)

@@ -193,3 +193,4 @@

+Note to self: pick up laundry.

Index: stuff/fish.c

===================================================================

— stuff/fish.c (revision 1)

+++ stuff/fish.c (working copy)

-Welcome to the file known as 'fish'.

-Information on fish will be here soon.

Index: stuff/things/bloo.h

===================================================================

— stuff/things/bloo.h (revision 8)

+++ stuff/things/bloo.h (working copy)

+Here is a new file to describe

+things about bloo.

El comando svn diff produce esta salida comparando sus ficheros de copia de trabajo contra la copia "prístina" almacenada en el área .svn. Los ficheros programados para la adición se visualizan como texto-añadido, y los ficheros programados para la eliminación son visualizados como texto eliminado.

La salida es visualizada en formato unificado del diff. Esto es, las lineas quitadas son empezadas con un – y las lineas añadidas son empezadas con un +. svn diff también imprime el nombre del fichero e información útil para el programa patch, así que puede generar "parches" redireccionando la salida del diff a un fichero:

$ svn diff > patchfile

Usted puede, por ejemplo, mandar por email el fichero de parche a otro desarrollador para la revisión o testeo antes de enviarlo.

svn revert

Ahora suponga que usted ve la salida del diff anterior, y se da cuenta que sus cambios a README son un error; quizás accidentalmente tecleó ese texto en el fichero equivocado en su editor

Esta es una oportunidad perfecta para usar svn revert.

$ svn revert README

Reverted 'README'

Subversión invierte el fichero a un estado pre-modificado reescribiéndolo con la copia "prístina" almacenada en el área .svn. Pero también observar que svn revert puede deshacer cualquier operación programada—por ejemplo, usted puede decidir que no quiere añadir un nuevo fichero después de todo:

$ svn status foo

? foo

$ svn add foo

A foo

$ svn revert foo

Reverted 'foo'

$ svn status foo

? foo

svn revert ITEM tiene exactamente el mismo efecto que suprimiendo ITEM de su copia de trabajo local y después ejecutando svn update -r BASE ITEM. Sin embargo, si está revirtiendo un fichero, svn revert tiene una diferencia muy considerable—no tiene que comunicarse con el repositorio para reponer su fichero.

O quizás usted quito equivocadamente un fichero del control de versión:

$ svn status README

README

$ svn delete README

D README

$ svn revert README

Reverted 'README'

$ svn status README

README

Estos tres comandos (svn status, svn diff, y svn revert) pueden ser usados sin ningún acceso de red. Esto lo hace sencillo para administrar sus cambios-en-progreso cuando usted está en alguna parte sin una conexión de red.

Subversión hace esto manteniendo almacenes privados de versiones prístinas de cada fichero versionado dentro del área administrativa .svn. Esto permite a Subversión reportar—y revertir—modificaciones locales a esos ficheros sin acceso de red. Este almacén (llamado el "texto-base") también permite a Subversión mandar las modificaciones locales del usuario durante un envío al servidor como un delta comprimido (o "diferencial") contra la versión prístina. Tener este almacén es un beneficio tremendo—incluso si usted tiene una conexión de red rápida, es mucho más rápido mandar solamente los cambios del fichero al servidor antes que el fichero entero. A primera vista, esto puede no parecer tan importante, pero imagine la repercusión si usted intenta enviar un cambio de una línea a un fichero de 400MB ¡ y tiene que enviar el fichero entero al servidor!

Resolver conflictos

(fusionando los cambios de otros)

Ya hemos visto cómo svn status -u puede predecir conflictos. Suponga que ejecuta svn update y ocurren algunas cosas interesantes

$ svn update

U INSTALL

G README

C bar.c

Updated to revision 46.

Los códigos U y G no son causa para la inquietud; esos ficheros absorbieron limpiamente los cambios del repositorio. Los ficheros marcados con una U no contienen cambios locales pero fueron actUalizados con cambios del repositorio. La G representa merGed, lo que significa que el fichero tenía para comenzar cambios locales, pero los cambios que venían del repositorio no se solaparon de ninguna manera.

Pero la C representa conflicto. Esto significa que los cambios del servidor se solapan con los suyos propios, y ahora tiene que elegir manualmente entre ellos.

Siempre que ocurra un conflicto, ocurren tres cosas para ayudarle a notar y resolver ese conflicto:

  • Subversión imprime una C durante la actualización, y recuerda que el fichero está en un estado de conflicto.

  • Subversión coloca marcas de conflicto—secuencias especiales de texto que delimitan los "lados" del conflicto—en el fichero para demostrar visualmente las áreas solapadas.

  • Para cada fichero en conflicto, Subversión coloca tres ficheros extra en su copia de trabajo local:

filename.mine

Este es su fichero como existió en su copia de trabajo antes de que usted actualizara su copia de trabajo—esto es, sin marcas de conflicto. Este fichero tiene su últimos cambios y nada más.

filename.rOLDREV

Este es el fichero que era la revisión BASE antes de que usted actualizará su copia de trabajo. Esto es, el fichero que usted descargó antes de que hiciera su última edición.

filename.rNEWREV

Este es el fichero que su cliente de Subversión recibió del servidor justo cuando usted actualizó su copia de trabajo. Este fichero corresponde con la revisión HEAD del repositorio.

Aquí OLDREV es el número de revisión del fichero en su directorio .svn y NEWREV es el número de revisión del HEAD del repositorio.

Por ejemplo, Evelyn hace cambios al fichero sandwich.txt en el repositorio. Harry acaba de cambiar el fichero en su copia de trabajo y lo ha enviado. Evelyn actualiza su copia de trabajo antes de enviarlo y recibe un conflicto:

$ svn update

C sandwich.txt

Updated to revision 2.

$ ls -1

sandwich.txt

sandwich.txt.mine

sandwich.txt.r1

sandwich.txt.r2

En este punto, Subversión no le permitirá enviar el fichero sandwich.txt hasta que los tres ficheros temporales sean borrados.

$ svn commit –message "Add a few more things"

svn: Commit failed (details follow):

svn: Aborting commit: '/home/evelyn/svn-work/sandwich.txt' remains in conflict

Si obtiene un conflicto, necesita hacer una de tres cosas:

  • Fusionar el texto en conflicto "a mano" (examinando y editando las marcas de conflicto dentro del fichero).

  • Copiar uno de los ficheros temporales sobre su fichero de trabajo.

  • Ejecutar svn revert para eliminar todos sus cambios locales.

Una vez que usted haya resuelto el conflicto, necesita dejar que Subversión lo sepa ejecutando svn resolved. Esto borrará los tres ficheros temporales y Subversión no considerará por más tiempo que el fichero está en estado de conflicto.

$ svn resolved sandwich.txt

Resolved conflicted state of 'sandwich.txt'

Fusionando conflictos a mano

Aquí tiene un ejemplo. Debido a una falta de comunicación, usted y Evelyn, su colaboradora, editan el fichero sandwich.txt en el mismo momento. Evelyn envía sus cambios, y cuando usted va a actualizar su copia de trabajo, obtiene un conflicto y vamos a tener que editar sandwich.txt para resolver los conflictos. Primero, miremos el fichero:

$ cat sandwich.txt

Top piece of bread

Mayonnaise

Lettuce

Tomato

Provolone

> .r2

Creole Mustard

Bottom piece of bread

Las líneas de signos menor-que, y signos mayor-que son marcas de conflictos, y no son parte de los datos en conflicto actuales. Generalmente usted querrá asegurarse que estén borrados del fichero antes de su próximo envío. El texto entre las dos primeras marcas están compuestas por los cambios que usted hizo en el área conflictiva:

> .r2

Generalmente usted no deseará borrar las marcas de conflicto y los cambios de Rally ella se sorprenderá terriblemente cuando llegue el sandwich y no sea lo que ella quería. Aquí es donde usted coge el teléfono o anda a través de la oficina y le explica a Evelyn que no puede tomar sauerkraut de un deli Italiano. Una vez usted esté de acuerdo con los cambios deberá comprobarlos, editar su fichero y borrar las marcas de conflicto

Top piece of bread

Mayonnaise

Lettuce

Tomato

Provolone

Salami

Mortadella

Prosciutto

Creole Mustard

Bottom piece of bread

Ahora ejecute svn resolved, y está listo para enviar sus cambios:

$ svn resolved sandwich.txt

$ svn commit -m "Go ahead and use my sandwich, discarding Evelyn's edits."

Recuerde, si alguna vez está confuso mientras edita el fichero conflictivo, siempre puede consultar los tres ficheros que Subversión crea para usted en su copia de trabajo—incluyendo su fichero como estaba antes de que usted actualizara. Incluso puede usar una herramienta interactiva de fusión de una third-party para examinar esos tres ficheros.

Copiando un fichero en su fichero de trabajo

Si obtiene un conflicto y decide que quiere rechazar sus cambios, simplemente usted puede copiar uno de los ficheros temporales creados por Subversión sobre el fichero en su copia de trabajo:

$ svn update

C sandwich.txt

Updated to revision 2.

$ ls sandwich.*

sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1

$ cp sandwich.txt.r2 sandwich.txt

$ svn resolved sandwich.txt

Punting: Usando svn revert

Si obtiene un conflicto, y al examinarlo decide que quiere rechazar sus cambios y empezar su edición de nuevo, simplemente invierta sus cambios:

$ svn revert sandwich.txt

Reverted 'sandwich.txt'

$ ls sandwich.*

sandwich.txt

Observe que cuando usted invierte un fichero conflictivo, no tiene que ejecutar svn resolved.

Ahora usted está listo para enviar sus cambios. Observe que svn resolved, al contrario de la mayoría de los otros comandos que nos hemos ocupado en este capitulo, requiere un argumento. En cualquier caso, debe tener cuidado y solo ejecutar svn resolved cuando esté seguro que ha arreglado el conflicto en su fichero—una vez los ficheros temporales son borrados, Subversión le dejará enviar el fichero incluso si todavía tiene marcas de conflicto.

Enviar sus cambios

¡Finalmente! Su edición está terminada, ha fusionado todos los cambios del servidor, y está listo para enviar sus cambios al repositorio.

El comando svn commit envía todos sus cambios al repositorio. Cuando usted envía un cambio, necesita proveer un mensaje de registro, describiendo su cambio. Su mensaje de registro será adjuntado a la nueva revisión que ha creado. Si su mensaje de registro es breve, puede querer proveerlo en la línea de comando usando la opción –message (o -m):

$ svn commit –message "Corrected number of cheese slices."

Sending sandwich.txt

Transmitting file data .

Committed revision 3.

Sin embargo, si ha estado componiendo su mensaje de registro mientras trabaja, puede querer decirle a Subversión que coja el mensaje de un fichero pasando el nombre de fichero con la opción –file :

$ svn commit –file logmsg

Sending sandwich

Transmitting file data .

Committed revision 4.

Si usted falla en especificar cualquiera de las opciones –message o –file, entonces Subversión lanzará automáticamente su editor favorito (según lo definido en la variable de entorno $EDITOR) para redactar un mensaje de registro.

Si está en su editor escribiendo un mensaje de registro y decide que quiere cancelar su envío, usted puede quitar su editor sin guardar los cambios. Si ya ha guardado su mensaje de registro, simplemente borre el texto y salve otra vez.

$ svn commit

Waiting for Emacs…Done

Log message unchanged or not specified

a)bort, c)ontinue, e)dit

a

$

El repositorio no sabe ni cuida si sus cambios tienen algún sentido en su totalidad; solo comprueba para asegurarse que nadie haya cambiado cualquiera de los mismos ficheros que usted mientras usted no miraba. Si alguien ha hecho esto, el envío entero fallará con un mensaje informándole que uno o más de sus ficheros está fuera-de-fecha:

$ svn commit –message "Add another rule"

Sending rules.txt

svn: Commit failed (details follow):

svn: Out of date: 'rules.txt' in transaction 'g'

En este punto, necesita ejecutar svn update, ocupándose con cualquier fusión o conflicto que resulte y procure enviarlo otra vez.

Eso cubre el ciclo básico de trabajo para usar Subversión. Hay muchas otras características en Subversión que usted puede usar para administrar su repositorio y copia de trabajo, pero puede pasar fácilmente usando solo los comandos que hemos visto hasta ahora en este capítulo.

Examinando el historial

Como hemos mencionado anteriormente, el repositorio es como una máquina del tiempo. Este mantiene un expediente de cada cambio enviado, y le permite explorar este historial examinando versiones anteriores de ficheros y directorios así como los metadatos que los acompañan. Con un único comando de Subversión, puede descargar el repositorio (o restaurar una copia de trabajo existente) exactamente como era en cualquier fecha o número de revisión en el pasado. Sin embargo, a veces solo desea mirar al pasado en vez de ir al pasado.

Hay varios comandos que pueden proporcionarle datos históricos del repositorio:

svn log

Le muestra amplia información: mensajes de registro unidos a las revisiones, y que ruta de fichero cambió en cada revisión.

svn diff

Le muestra los detalles específicos de cómo cambió un fichero en un cierto plazo.

svn cat

Este se utiliza para recuperar cualquier fichero tal como existió en un un número de revisión particular y lo muestra en su pantalla.

svn list

Muestra los ficheros en un directorio para cualquier revisión dada.

svn log

Para descubrir información sobre la historia de un fichero o directorio, use el comando svn log. svn log le proporcionará un registro de quién hizo cambios a un fichero o directorio, en qué revisión cambió, la hora y fecha de esa revisión, y, si fue proporcionado, el mensaje de registro que acompañaba al envío.

$ svn log

————————————————————————

r3 | evelyn | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line

Added include lines and corrected # of cheese slices.

————————————————————————

r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line

Added main() methods.

————————————————————————

r1 | evelyn | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line

Initial import

————————————————————————

Observe que los mensajes de registro son impresos en orden cronológico inverso por defecto. Si desea ver un rango diferente de revisiones en un orden particular, o solo una única revisión, pase la opción –revision (-r):

$ svn log –revision 5:19 # shows logs 5 through 19 in chronological order

$ svn log -r 19:5 # shows logs 5 through 19 in reverse order

$ svn log -r 8 # shows log for revision 8

También puede examinar el historial de registro de un único fichero o directorio. Por ejemplo:

$ svn log foo.c

.

$ svn log http://foo.com/svn/trunk/code/foo.c

.

Ésto mostrará los mensajes de registro solo para esas revisiones en las cuales el fichero de trabajo (o URL) cambió.

Si desea aún más información sobre un fichero o directorio, svn log también toma una opción –verbose (-v). Porque Subversión le permite mover y copiar ficheros y directorios, es importante poder seguir cambios de la ruta del fichero en el sistema de ficheros, así en modo detallado, svn log incluirá una lista de rutas de fichero cambiadas en una revisión en su salida:

$ svn log -r 8 -v

————————————————————————

r8 | evelyn | 2002-07-14 08:15:29 -0500 | 1 line

Changed paths:

M /trunk/code/foo.c

M /trunk/code/bar.h

A /trunk/code/doc/README

Frozzled the sub-space winch.

————————————————————————

¿Por qué svn log me da una respuesta vacía?

Después de trabajar con Subversión un poco, la mayoría de los usuarios tendrán algo como esto:

$ svn log -r 2

————————————————————————

$

A primer vistazo, esto parece como un error. Pero recuerde que mientras las revisiones son repository-wide, svn log funciona sobre una ruta en el repositorio. Si no provee ninguna ruta de fichero, Subversión usa el directorio de trabajo actual como destino por defecto. En consecuencia, si usted está trabajando en un subdirectorio de su copia de trabajo y procurando registrar una revisión en la cual ni ese directorio ni cualquiera de sus hijos fue cambiado, Subversión le dará un registro vacío. Si desea ver qué cambió en esa revisión, intente indicando svn log directamente en lo más alto del URL de su repositorio, como en svn log -r 2 http://svn.collab.net/repos/svn.

svn diff

Ya hemos visto svn diff antes—éste muestra las diferencias de fichero en un formato unificado del diff; fue utilizado para mostrar las modificaciones locales hechas a nuestra copia de trabajo antes de enviarlas al repositorio.

De hecho, resulta que hay tres usos distintos para svn diff:

  • Examinar cambios locales

  • Comparar su copia de trabajo con la del repositorio

  • Comparar repositorio con repositorio

Examinando cambios locales

Como hemos visto, invocando svn diff sin argumentos comparará sus ficheros de trabajo con las copias "prístinas" almacenadas en el área .svn:

$ svn diff

Index: rules.txt

===================================================================

— rules.txt (revision 3)

+++ rules.txt (working copy)

Partes: 1, 2, 3, 4
 Página anterior Volver al principio del trabajoPágina siguiente