Mantenimiento del Repositorio

El mantenimiento de un repositorio Subversion puede ser una tarea que asuste, principalmente debido a las complejidades inherentes a sistemas que tienen un motor de base de datos. Para hacer bien este trabajo, basta con conocer las herramientas—qué son y cuándo y cómo usarlas. Esta sección le presentará las herramientas de administración que provee Subversion, y cómo utilizarlas para realizar tareas como migraciones de repositorios, actualizaciones, copias de seguridad y limpiezas.

Una caja de herramientas del Administrador

Subversion provee un conjunto de utilidades para crear inspeccionar, modificar y reparar sus repositorio. Estudiemos más de cerca cada una de estas herramientas. Más tarde, examinaremos brevemente otras incluidas en la distribución de la base de datos Berkeley que añaden funcionalidades específicas al motor de base de datos de las que no disponen las herramientas propias de Subversion.

svnlook

svnlook es una herramienta provista por Subversion para examinar las revisiones y transacciones realizadas en un repositorio. Este programa no intente en ningún momento cambiar el repositorio —es una utilidad de sólo lectura. svnlook es utilizada normalmente por los ganchos del repositorio para informar acerca de los cambios que se van a realizar ( en el caso del gancho pre-commit ) o que se acaban de hacer ( en el caso del gancho post-commit ) en el repositorio. Un administrador del repositorio puede usar esta herramienta para diagnosis.

svnlook tiene una sintaxis muy simple:

$ svnlook help
uso general. svnlook SUBCOMANDO RUTA_REPOS [PARAMS y OPCIONES ...]
Nota: todo subcomando que tome los parámetros '--revision' y '--transaction'
      actuará, si se lo invoca sin una de estas opciones, sobre la versión
      más reciente del repositorio.
Escriba "svn help <subcomando>" para ayuda en un subcomando específico.
…

Casi cada uno de los subcomandos de svnlook puede trabajar sobre una revisión o una transacción, imprimiendo información acerca del propio árbol, o de sus diferencias con respecto a la revisión anterior del repositorio. Usará la opciones --revision y --transaction para especificar qué revisión o transacción examinar respectivamente. Nótese que mientras los números de revisión se ven como números naturales, los nombres de transacción son cadenas alfanuméricas. Recuerde que el sistema de ficheros sólo permite navegar entre transacciones no confirmadas ( transacción que no han tenido como resultado una nueva revisión ). La mayoría de los repositorios no tendrán ese tipo de transacciones, porque las transacciones normalmente son confirmadas ( lo que evita que puedan ser examinadas ) o paradas y borradas.

En ausencia de las opciones --revision y --transaction, svnlook examinará la última revisión ( o HEAD ) del repositorio. Así que las siguientes órdenes hacen exactamente lo mismo cuando 19 es la última revisión del repositorio ubicado en /path/to/repos:

$ svnlook info /path/to/repos
$ svnlook info /path/to/repos --revision 19

La única excepción a estas reglas es el subcomando svnlook youngest, que no recibe opciones, y que simplemente escribe el número de revisión de HEAD.

$ svnlook youngest /path/to/repos
19

La salida de svnlook está diseñada para que sea, a la vez, legible por humanos y por máquinas. Cojamos como ejemplo la salida del subcomando info:

$ svnlook info /path/to/repos
sally
2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)
27
Added the usual
Greek tree.

La salida del subcomando info está definida como:

  1. El autor, seguido por un salto de línea.

  2. La fecha, seguida por un salto de línea.

  3. El número de caracteres en el mensaje de registro, seguido por un salto de línea.

  4. El mensaje de registro, seguido por un salto de línea.

Esta salida es legible para humanos, elementos como la fecha, se presentan usando una representación de texto en lugar de algo más oscuro ( como el número de nanosegundos desde que ). Pero esta salida es también legible por la máquina—debido a que el registro del mensaje puede contener muchas líneas y no tener un límite de tamaño, svnlook informa del tamaño del mensaje antes que el mismo mensaje. Esto permite a los y otros alrededor de este comando, tomar decisiones inteligentes acerca del mensaje de registro, como cuánta memoria reservarle, o al menos, cuántos bytes saltarse en el evento para que esta salida no sea el último bit de datos en el flujo.

Otro uso común de svnlook es ver realmente los contenidos de un árbol de revisión o de transacción. El comando svnlook tree presenta los directorios y fichero del árbol solicitado. Si añade la opción --show-ids, también enseñará los identificadores de nodos del sistema de ficheros de la revisión para cada una de las rutas (que, en general, es más útil para los desarrolladores que para los usuarios).

$ svnlook tree /path/to/repos --show-ids
/ <0.0.1>
 A/ <2.0.1>
  B/ <4.0.1>
   lambda <5.0.1>
   E/ <6.0.1>
    alpha <7.0.1>
    beta <8.0.1>
   F/ <9.0.1>
  mu <3.0.1>
  C/ <a.0.1>
  D/ <b.0.1>
   gamma <c.0.1>
   G/ <d.0.1>
    pi <e.0.1>
    rho <f.0.1>
    tau <g.0.1>
   H/ <h.0.1>
    chi <i.0.1>
    omega <k.0.1>
    psi <j.0.1>
 iota <1.0.1>

Una vez que haya visto el esquema de los ficheros y directorios de su árbol, podrá usar comandos como svnlook cat, svnlook propget, y svnlook proplist para profundizar en los detalles dichos elementos.

svnlook puede realizar otros tipos de consultas, presentando los subgrupos de información que mencionamos antes, informando acerca de qué rutas fueron modificadas en una revisión o transacción especificada, mostrando las modificaciones de textos o propiedades realizadas, etc ... A continuación hay una breve descripción de la actual lista de subcomandos aceptados por svnlook, y la salida de los mismos:

author

Dice el autor del árbol.

cat

Vuelca los contenidos de un fichero en el árbol.

changed

Da una lista de todos los ficheros y directorios que han sido modificados en el árbol.

date

Dice la fecha del árbol.

diff

Vuelca de ficheros modificados.

dirs-changed

Lista los directorios del árbol que han sido modificados, o aquellos en los que alguno de sus ficheros han sido modificados.

history

Presenta puntos interesantes en la historia de una ruta versionada ( lugares donde ha habido modificaciones o copias ).

info

Vuelca el autor, la fecha, el número de caracteres del mensaje de registro, y el mensaje de registro.

log

Dice el mensaje de registro del árbol.

propget

Dice el valor de una propiedad de una ruta en el árbol.

proplist

Vuelca los nombres y valores de las propiedades de rutas en el árbol.

tree

Vuelca el listado del árbol, revelando opcionalmente el identificador de la revisión de nodo de sistema de ficheros asociado a cada ruta.

uuid

Dice el identificador único de usuario del árbol.

youngest

Dice el último número de revisión.

svnadmin

El programa svnadmin es el mejor amigo del administrador del repositorio. Además de darle la posibilidad de crear repositorios Subversion, le permite realizar varias operaciones de mantenimiento en ellos. La sintaxis de svnadmin es parecida a la de svnlook:

$ svnadmin help
uso general: svnadmin SUBCOMANDO RUTA_REPOS  [PARAMS y OPCIONES ...]
Escriba "svnadmin help <subcomando>" para ayuda sobre un subcomando.

Subcomandos disponibles:
   create
   deltify
   dump
   help (?, h)
…

Ya hemos mencionado antes el subcomando create de svnadmin ( ver “Creación y Configuración de Repositorios”). La mayoría de los demás subcomandos los veremos más adelante en en este capítulo. De momento, veamos por encima lo que cada uno de ellos nos ofrece.

create

Crear un nuevo repositorio Subversion.

deltify

Recorre un rango de revisiones específico, realizando la deltificación de predecesores en las rutas modificadas de esas revisiones. Si no se especifica ninguna revisión, este comando simplemente deltificará la revisión HEAD.

dump

Vuelca los contenidos del repositorio, agrupados por por un conjunto dado de revisiones, usando un formato portable de volcado.

hotcopy

Hace una copia en caliente de un repositorio. Puede ejecutar esta comando en cualquier momento, y hacer una copia segura del repositorio sin que se vea afectada por el hecho de que otros procesos estén accediendo al repositorio.

list-dblogs

Lista las rutas a los ficheros de registro de la base de datos Berkeley asociados al repositorio. Esta lista incluye todos los ficheros de registros—aquellos que están todavía en uso por Subversion, así como los que no lo están.

list-unused-dblogs

Lista las rutas de los ficheros de registro de la base de datos Berkeley asociados al repositorio, pero que han dejado de usarse. Puede borrar de forma segura estos ficheros del entorno del repositorio y archivarlos para el caso de tener que hacer una recuperación de algún evento catastrófico del repositorio.

load

Carga un grupo de revisiones en un repositorio desde un flujo de datos que utilice el mismo formato portable de información que el generado por el subcomando dump.

lstxns

Lista los nombres de las transacciones Subversion no confirmadas que existen actualmente en el repositorio.

recover

Realiza tareas de recuperación en un repositorio que lo necesite, generalmente tras un error fatal que haya impedido a un proceso cerrar limpiamente su comunicación con el repositorio.

rmtxns

Borra limpiamente del repositorio transacciones Subversion ( convenientemente nutrido por la salida del subcomando lstxns).

setlog

Sustituye el valor actual de la propiedad svn:log ( mensaje de confirmación ) de una transacción en particular en el repositorio con un nuevo valor.

verify

Verificar los contenidos del repositorio. Esto incluye, entre otras cosas, comparaciones de firmas de los datos versionados almacenados en el repositorio.

svndumpfilter

Debido a que Subversion almacena toda la información en un sistema de bases de datos opaco, intentar hacer cambios a mano no es nada recomendable, además de ser bastante complicado. Además, una vez que la información ha sido guardada en su repositorio, Subversion, en general, no tiene ninguna manera cómoda de borrarla. [20] Inevitablemente, habrá veces que querrá manipular el histórico de su repositorio. Podría necesitar eliminar todas la versiones de un fichero que se añadió accidentalmente ( y que no debería estar ahí por alguna razón). O quizás tiene varios proyectos compartiendo el mismo repositorio, y ha decidido separarlos cada uno en su propio repositorio. Para realizar este tipo de tareas, los administradores necesitan una representación de los datos más manejable—el formato de volcado.

El formato de volcado del repositorio Subversion es una representación legible por humanos de los cambios hechos a tus datos versionados a lo largo del tiempo. Utiliza el comando svnadmin dump para generar el volcado, y svnadmin load para poblar un nuevo repositorio con ellos ( ver “Migrando un repositorio”). Lo mejor del hecho de que el formato sea legible es que, si no te asusta, puedes revisarlo y modificarlo manualmente. Por supuesto, lo pero que es si tienes dos años de trabajo en un repositorio encapsulado en lo que se supone que será un fichero de volcado muy grande, llevará mucho, mucho tiempo el revisarlo y modificarlo.

A pesar de que no será la herramienta más usada a disposición del administrador, svndumpfilter tiene un producto muy peculiar con una funcionalidad muy útil—la posibilidad de modificar rápida y fácilmente esos datos de volcado actuando como un filtro basado en las rutas. Simplemente, diga una lista de rutas que quieres mantener, o una lista de rutas que no quieres mantener, luego, dirige tu volcado a través de este filtro. El resultado será un volcado modificado que contendrá sólo las rutas versionadas que ( explícita o implícitamente ) pediste.

La sintaxis de svndumpfilter es así:

$ svndumpfilter help
uso general: svndumpfilter SUBCOMANDO [ARGS & OPCIONES ...]
Escriba "svndumpfilter help <subcommand>" para obtener información sobre un subcomando específico.

Subcomandos disponibles:
   exclude
   include
   help (?, h)

Hay sólo dos subcomandos interesantes. Te permiten elegir entre una inclusión explícita o implícita de rutas en el flujo de información:

exclude

Excluye del flujo de datos del volcado a un grupo de rutas.

include

Permite sólo al grupo de rutas solicitado, pasar al flujo de datos del volcado.

Veamos un ejemplo realista acerca de qué uso le podría dar a este programa. Más tarde hablaremos ( ver “Escogiendo el esquema de repositorio”) del proceso de decisión del modelo de datos para su repositorio—un repositorio por proyecto o combinándolos, organizar todo el material dentro de su repositorio. A veces, después de que las nuevas revisiones comienzan a volar, te vuelves a pensar el modelo, y querrías hacer algunos cambios. Un cambio común es la decisión de mover proyectos que están compartiendo un sólo repositorio en un repositorio separado para cada proyecto.

Nuestro repositorio imaginario contiene tres proyectos: calc, calendar, y spreadsheet. Han estado en una modelo como este:

/
   calc/
      trunk/
      branches/
      tags/
   calendar/
      trunk/
      branches/
      tags/
   spreadsheet/
      trunk/
      branches/
      tags/

Para meter cada uno de estos tres proyectos en su repositorio respectivo, debemos primero hacer un fichero de volcado del repositorio completo:

$ svnadmin dump /path/to/repos > repos-dumpfile
* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
* Dumped revision 3.
…
$

Luego, pasar ese fichero de volcado a través del filtro, incluyendo cada vez, sólo uno de los directorios superiores, dando como resultado tres nuevos ficheros de volcado:

$ svndumpfilter include calc < repos-dumpfile > calc-dumpfile
…
$ svndumpfilter include calendar < repos-dumpfile > cal-dumpfile
…
$ svndumpfilter include spreadsheet < repos-dumpfile > ss-dumpfile
…
$

En este momento, debe tomar una decisión. Cada uno de sus ficheros de volcado creará un repositorio válido, pero mantendrá las rutas exactamente como estaban en el repositorio original. Esto significa que aunque tenga un repositorio exclusivamente para su proyecto calc, dicho repositorio tendrá todavía un directorio superior llamado calc. Si quiere que los directorios trunk, tags, y branches estén en la raíz del repositorio, necesitará editar los ficheros de volcado, cambiando las cabeceras Node-path y Copyfrom-path para conseguir que esa primera ruta calc/ no aparezca; además, deberá borrar la sección del volcado que crea el directorio calc. Será algo como:

Node-path: calc
Node-action: add
Node-kind: dir
Content-length: 0

Todo lo que queda por hacer ahora es crear sus tres nuevos repositorios, y cargar cada fichero de volcado en el repositorio correcto:

$ svnadmin create calc; svnadmin load calc < calc-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : button.c ... done.
…
$ svnadmin create calendar; svnadmin load calendar < cal-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : cal.c ... done.
…
$ svnadmin create spreadsheet; svnadmin load spreadsheet < ss-dumpfile
<<< Started new transaction, based on original revision 1
     * adding path : Makefile ... done.
     * adding path : ss.c ... done.
…
$

Ambos subcomandos de svndumpfilter aceptan opciones para decidir cómo tratar las revisiones vacías. Si una revisión dada sólo contenía cambios a rutas que fueron excluidas al filtrarlas, podría ser considerada como no interesante o incluso ignorada. Así que, para darle al usuario el control sobre qué hacer con esas revisiones, svndumpfilter tiene las siguientes opciones:

--drop-empty-revs

No generar ninguna revisión vacía— tan sólo ignorarlas.

--renumber-revs

Si las revisiones vacías son descartadas ( usando la opción --drop-empty-revs), cambiar los números de revisión de las restantes de tal manera que no haya huecos en la secuencia numérica.

--preserve-revprops

Si las revisiones vacías no son descartadas, preservar las propiedades de revisión ( mensaje de registro, autor, fecha, propiedades personalizadas, etc ... ) de dichas revisiones vacías. Por otra parte, las revisiones vacías sólo contendrán la marca de tiempo original, y un mensaje de registro generado indicando que esta revisión fue vaciada por svndumpfilter.

Mientras svndumpfilter puede ser muy útil, y un gran ahorrador de tiempo, desafortunadamente hay un par de problemas. Primero, esta utilidad es . Preste atención a si las rutas en su fichero de volcado se especifican con o sin barras al principio. Necesitará mirar las cabeceras Node-path y Copyfrom-path.

…
Node-path: spreadsheet/Makefile
…

Si las rutas tienen barras al principio, deberá incluir barras al principio en las rutas que quiera pasar a svndumpfilter include y svndumpfilter exclude ( si no las tienen, no debería incluirlas). Además, si su fichero de volcado tiene un uso inconsistente de estas barras por alguna razón, [21] probablemente debería normalizar esas rutas de tal manera que todas ellas tengan, o no tengan, barras al principio.

También las rutas copiadas pueden darle algunos problemas. Subversion soporta operaciones de copia en el repositorio, donde una nueva ruta se crea copiando otra ruta ya existente. Es posible que en algún momento de la vida de su repositorio, vd. haya copiado un fichero o un directorio desde alguna ubicación que svndumpfilter esté excluyendo a alguna otra que se esté incluyendo. Para conseguir que los datos volcados sean autosuficientes, svndumpfilter todavía necesita enseñar la adición de la nueva ruta—incluyendo los contenidos de los ficheros creados por la copia—y no representar dicha adición como una copia de una fuente que no existirá en el flujo filtrado de los datos de volcado. Pero debido a que el formato de volcado de repositorios Subversion sólo presenta lo modificado en cada revisión, los contenidos del origen de la copia podrían no estar disponibles para su lectura. Si sospechase que tiene alguna copia de este tipo en su repositorio, deberá repensar su grupo de rutas incluyentes y/o excluyentes.

svnshell.py

El árbol de código fuente de Subversion también trae una interfaz al repositorio tipo línea de comando. El script en Python svnshell.py (ubicado en tools/examples/ en el árbol de fuentes) usa las interfaces de lenguaje de Subversion (así que debe tenerlas correctamente compiladas e instaladas para que este script funcione) para conectar al repositorio y las librerías de sistema de ficheros.

Una vez iniciado, el programa se comporta de manera similar a una línea de comando, permitiéndole navegar a través de los directorios de su repositorio. Inicialmente se le posiciona en el directorio raíz de la revisión HEAD del repositorio, y se le muestra la línea de comando. Puede usar el comando help en cualquier momento para leer un listado de los comandos disponibles y su propósito.

$ svnshell.py /path/to/repos
<rev: 2 />$  help
Available commands:
  cat FILE     : dump the contents of FILE
  cd DIR       : change the current working directory to DIR
  exit         : exit the shell
  ls [PATH]    : list the contents of the current directory
  lstxns       : list the transactions available for browsing
  setrev REV   : set the current revision to browse
  settxn TXN   : set the current transaction to browse
  youngest     : list the youngest browsable revision number
<rev: 2 />$

Puede navegar por la estructura de directorios de su repositorio del mimo modo que lo haría con la línea de comando de Unix o Windows—usando el comando cd. En todo momento la línea de comando le mostrará qué revisión (prefijada por rev:) o transacción (prefijada por txn:) está examinando, y la ruta dentro de esa revisión o transacción. Puede cambiar la revisión o transacción actual con los comandos setrev y settxn respectivamente. Al igual que en una línea de comando de Unix, puede usar el comando ls para mostrar el contenido del directorio actual, y puede usar el comando cat para mostrar el contenido de un fichero.

Ejemplo 5.1. Usando svnshell para navegar por el repositorio

<rev: 2 />$ ls
   REV   AUTHOR  NODE-REV-ID     SIZE         DATE NAME
----------------------------------------------------------------------------
     1    sally <     2.0.1>          Nov 15 11:50 A/
     2    harry <     1.0.2>       56 Nov 19 08:19 iota
<rev: 2 />$ cd A
<rev: 2 /A>$ ls
   REV   AUTHOR  NODE-REV-ID     SIZE         DATE NAME
----------------------------------------------------------------------------
     1    sally <     4.0.1>          Nov 15 11:50 B/
     1    sally <     a.0.1>          Nov 15 11:50 C/
     1    sally <     b.0.1>          Nov 15 11:50 D/
     1    sally <     3.0.1>       23 Nov 15 11:50 mu
<rev: 2 /A>$ cd D/G 
<rev: 2 /A/D/G>$ ls
   REV   AUTHOR  NODE-REV-ID     SIZE         DATE NAME
----------------------------------------------------------------------------
     1    sally <     e.0.1>       23 Nov 15 11:50 pi
     1    sally <     f.0.1>       24 Nov 15 11:50 rho
     1    sally <     g.0.1>       24 Nov 15 11:50 tau
<rev: 2 /A>$ cd ../..
<rev: 2 />$ cat iota
This is the file 'iota'.
Added this text in revision 2.

<rev: 2 />$ setrev 1; cat iota
This is the file 'iota'.

<rev: 1 />$ exit
$

Como puede ver en el ejemplo anterior, puede indicar múltiples comandos en una única línea separados por puntos y comas. Además, la línea de comando entiende los conceptos de rutas relativas y absolutas, y entenderá los componentes de ruta especiales . y ...

El comando youngest muestra la versión más joven. Lo cual es útil para determinar el rango válido de revisiones que puede usar como argumentos del comando setrev—se le permite navegar por todas las revisiones (le recordamos que son nombradas por números) entre 0 y la más joven inclusive. Determinar la transacción navegable válida no es tan bonito. Use el comando lstxns para obtener un listado de las transacciones que puede consultar. El listado de las transacciones navegables es el mismo listado que el devuelto por svnadmin lstxns y el mismo listado que es válido para ser usado con la opción --transaction de svnlook.

Una vez haya acabado de usar la línea de comando, puede salir de manera limpia usando el comando exit. Alternativamente, puede mandar un carácter de fin de línea—Control-D (aunque algunas distribuciones de Python para Win32 usan en su lugar la convención de Windows de Control-Z).

Utilidades de la base de datos Berkeley

Toda la estructura y datos versionados de su sistema de ficheros viven en un conjunto de tablas de la base de datos Berkeley dentro del subdirectorio db de su repositorio. Este subdirectorio es un directorio de entorno de base de datos Berkeley habitual, y por lo tanto puede ser usado con cualquiera de las herramientas de la base de datos Berkeley (puede ver su documentación en la página web de SleepyCat, http://www.sleepycat.com/).

Para un uso diario de Subversion, estas herramientas son innecesarias. La mayor parte de la funcionalidad típicamente requerida por los repositorios Subversion ha sido duplicada en la herramienta svnadmin. Por ejemplo, svnadmin list-unused-dblogs y svnadmin list-dblogs realizan un conjunto de lo que proporciona el comando db_archive de Berkeley, y svnadmin recover engloba los casos de uso habituales de la utilidad db_recover.

Aunque todavía hay algunas herramientas de la base de datos Berkeley que puede encontrar útiles. Los programas db_dump y db_load escriben y leen, respectivamente, un fichero de formato propio que describe las claves y valores de la base de datos Berkeley. Dado que las bases de datos Berkeley no son portables entre arquitecturas diferentes, este formato es útil para transferir las bases de datos de una máquina a otra, sin importar su arquitectura o sistema operativo. Además, la utilidad db_stat proporciona información útil sobre el estado de su entorno de base de datos Berkeley, incluyendo estadísticas detalladas sobre los bloqueos y subsistemas de almacenamiento.

Limpieza del repositorio

En general su repositorio Subversion requerirá poca atención una vez lo haya configurado a su gusto. No obstante, hay ocasiones en las que podría necesitar la asistencia manual de un administrador. La utilidad svnadmin proporciona algunas funcionalidades provechosas para realizar tareas como

  • modificar mensajes de informes de cambios,

  • eliminar transacciones muertas,

  • recuperar repositorios tocados, y

  • migrar el contenido de un repositorio a otro.

Quizás el subcomando de svnadmin más usado sea setlog. Cuando una transacción es guardada en el repositorio y ascendida a categoría de revisión, el mensaje del informe de cambios asociado con esa nueva revisión (y proporcionado por el usuario) se almacena como una propiedad no versionada adjunta a la propia revisión. En otras palabras, el repositorio sólo recuerda el último valor de la propiedad, y descarta valores anteriores.

A veces el usuario cometerá errores (ortográficos o quizás información equivocada) en sus informes de cambios. Si configura el repositorio (usando los ganchos pre-revprop-change y post-revprop-change; vea “Scripts de enganche”) para permitir modificaciones sobre el mensaje de informe de cambios de revisiones existentes, entonces el usuario puede corregir su informe remotamente usando el comando propset del programa svn (vea Capítulo 9, Referencia completa de Subversion). No obstante, debido al peligro potencial de perder información para siempre, los repositorios Subversion se configuran por defecto para impedir cambios a propiedades no versionadas—excepto para el administrador.

Si un informe de cambios necesita ser cambiado por un administrador, puede ejecutar svnadmin setlog. Éste comando modifica el mensaje de informe de cambios (la propiedad svn:log) de una revisión concreta de un repositorio, leyendo el nuevo valor del fichero proporcionado.

$ echo "Here is the new, correct log message" > newlog.txt
$ svnadmin setlog myrepos newlog.txt -r 388

El comando svnadmin setlog a secas sigue estando limitado por las mismas protecciones que impiden a los usuarios remotos modificar propiedades no versionadas—los ganchos pre- y post-revprop-change siguen ejecutándose, y por lo tanto debe configurar el repositorio para permitir cambios de esta naturaleza. Pero un administrador puede saltarse estas protecciones pasando el parámetro --bypass-hooks al comando svnadmin setlog.

[Aviso] Aviso

Recuerde, no obstante, que al ignorar los ganchos, probablemente esté evitando acciones como notificaciones automáticas por correo informando de cambios a propiedades, sistemas de copias de seguridad que siguen los cambios de propiedades sin versionar, etc, etc. En otras palabras, sea muy cuidadoso con lo que vaya a cambiar, y cómo lo cambia.

Otro uso habitual de svnadmin es comprobar que en el repositorio no hay transacciones pendientes—posiblemente muertas. En el caso de que una transacción falle, ésta normalmente se anula. Es decir, la propia transacción y cualquier dato asociado con ella (y sólo con ella) es eliminada del repositorio. No obstante, ocasionalmente ocurre un fallo de tal modo que la limpieza de la transacción no se llega a realizar nunca. Esto podría pasar por varias razones: quizás la operación del cliente fue terminada de manera poco elegante por el usuario, quizás ocurrió un fallo de red durante la operación, etc. En cualquier caso, estas transacciones muertas sólo molestan en el repositorio y consumen recursos.

Puede usar el comando lstxns de svnadmin's para obtener un listado de los nombres de las transacciones actuales de relevancia.

$ svnadmin lstxns myrepos
19
3a1
a45
$

Cada elemento del listado mostrado puede ser usado con svnlook (y su opción --transaction) para determinar quién creó la transacción, cuándo fue creada, qué tipos de cambios fueron realizados en la transacción—en otras palabras, si la transacción es o nó una candidata segura para ser eliminada. En caso de serlo, el nombre de la transacción puede ser usado con svnadmin rmtxns, que realizará la limpieza de la transacción. ¡De hecho, el subcomando rmtxns puede usar directamente como entrada la salida de lstxns!

$ svnadmin rmtxns myrepos `svnadmin lstxns myrepos`
$

Si usa estos subcomandos de éste modo, debería considerar desactivar temporalmente el acceso al repositorio por parte de sus clientes. Así, nadie podrá comenzar una transacción legítima antes de que comience con la limpieza. Lo que viene a continuación es un poco de shell-scripting que puede generar rápidamente la información sobre cada transacción pendiente de su repositorio:

Ejemplo 5.2. txn-info.sh (Informe de transacciones pendientes)

#!/bin/sh

### Generate informational output for all outstanding transactions in
### a Subversion repository.

SVNADMIN=/usr/local/bin/svnadmin
SVNLOOK=/usr/local/bin/svnlook

REPOS="${1}"
if [ "x$REPOS" = x ] ; then
  echo "usage: $0 REPOS_PATH"
  exit
fi

for TXN in `${SVNADMIN} lstxns ${REPOS}`; do 
  echo "---[ Transaction ${TXN} ]-------------------------------------------"
  ${SVNLOOK} info "${REPOS}" --transaction "${TXN}"
done

Puede ejecutar el script anterior usando /ruta/a/txn-info.sh /ruta/al/repositorio. La salida es básicamente la concatenación de varios bloques de salida de svnlook info (vea “svnlook”), y tendrá el siguiente aspecto:

$ txn-info.sh myrepos
---[ Transaction 19 ]-------------------------------------------
sally
2001-09-04 11:57:19 -0500 (Tue, 04 Sep 2001)
0
---[ Transaction 3a1 ]-------------------------------------------
harry
2001-09-10 16:50:30 -0500 (Mon, 10 Sep 2001)
39
Trying to commit over a faulty network.
---[ Transaction a45 ]-------------------------------------------
sally
2001-09-12 11:09:28 -0500 (Wed, 12 Sep 2001)
0
$

Habitualmente, si descubre una transacción muerta que no tiene adjunto un informe de cambios, se trata del resultado de una operación fallida de actualización (o de estilo similar). Estas operaciones usan transacciones de Subversion internamente para emular el estado de una copia de trabajo local. Dado que éstas transacciones no tienen como propósito ser almacenadas, Subversion no requiere que tengan un mensaje de informe de cambios. Las transacciones que tienen informes de cambios son casi con total seguridad algún tipo de operación de almacenamiento fallida. Además, la fecha de una transacción puede proporcionar información interesante—por ejemplo, ¿qué probabilidades hay de que una operación que comenzase hace nueve meses todavía esté activa?

En resumen, no debe tomar a la ligera las decisión de limpieza de transacciones. Puede emplear varias fuentes de información—incluyendo los registros de acceso y errores de Apache, los registros de transacciones Subversion completadas con éxito, etc— durante la toma de decisiones. Finalmente, un administrador siempre puede comunicarse con el autor de una transacción aparentemente muerta (vía email, por ejemplo) para verificar que la transacción está, de hecho, en un estado zombi.

Gestionando el espacio de almacenamiento

Mientras que el coste del almacenamiento ha caído de manera increíble durante los últimos años, el espacio en disco sigue siendo un motivo de preocupación válido para los administradores que buscan versionar grandes cantidades de datos. Cada byte adicional consumido por el repositorio en vivo es un byte que debe ser almacenado en una copia de seguridad, quizás múltiples veces como parte de una política de rotado periódico de copias de seguridad. Dado que el principal medio de almacenamiento de un repositorio de Subversion es un complejo sistema de bases de datos, es útil saber qué piezas deben permanecer en el servidor activo, cuáles deben ser almacenadas en una copia de seguridad, y cuáles pueden ser eliminadas.

Hasta hace poco, el mayor culpable en cuanto al uso de disco duro por parte de un repositorio de Subversion eran los fichero de registro que usaba la base de datos Berkeley para realizar sus pre-escrituras antes de modificar realmente los ficheros de la base de datos. Éstos ficheros capturan todas las acciones tomadas durante la ruta que modifica el estado de la base de datos— si los ficheros de la base de datos reflejan en cualquier momento un estado determinado, los ficheros de registro contienen todos los cambios entre diferentes estados. Como tales, pueden comenzar a acumularse rápidamente.

Afortunadamente, y comenzando con la versión 4.2 de la base de datos Berkeley, el entorno de la base de datos tiene la capacidad para borrar sus propios ficheros de registro obsoletos sin necesidad de procedimientos externos. Cualquier repositorio creado usando svnadmin, el cual se compila contra la versión 4.2 o superior de la base de datos Berkeley, será configurado automáticamente para borrar sus ficheros de registros. Si no quiere activar esta característica, simplemente pase la opción --bdb-log-keep al comando svnadmin create. Si olvida hacer esto, o cambia de opinión posteriormente, puede editar el fichero DB_CONFIG ubicado en el directorio db de su repositorio, comentar la línea que contiene la directiva set_flags DB_LOG_AUTOREMOVE, y entonces ejecutar svnadmin recover sobre su repositorio para forzar los cambios de configuración. Vea “Configuración de la base de datos Berkeley” para más información sobre la configuración de la base de datos.

Sin mecanismo de algún tipo que elimine los ficheros de registro, éstos se acumularán a medida que use el repositorio. Esto es en cierto sentido una característica del sistema de base de datos—debería ser capaz de recrear su base de datos por completo sin usar nada más que los ficheros de registro, así que éstos pueden ser útiles en recuperaciones de la base de datos tras una catástrofe. Pero habitualmente querrá archivar los ficheros de registro que la base de datos Berkeley ya no usa, y entonces eliminarlos del disco para conservar espacio. Use el comando svnadmin list-unused-dblogs para obtener un listado de los ficheros de registro no usados:

$ svnadmin list-unused-dblogs /path/to/repos
/path/to/repos/log.0000000031
/path/to/repos/log.0000000032
/path/to/repos/log.0000000033

$ svnadmin list-unused-dblogs /path/to/repos | xargs rm
## disk space reclaimed!

Para mantener el tamaño del repositorio tan pequeño como sea posible, Subversion usa la deltificación (o bien, almacenamiento deltificado) dentro del propio repositorio. La deltificación conlleva codificar la representación de un bloque de datos como una colección de diferencias contra otro bloque de datos. Si dos piezas son muy similares, la deltificación proporcionará ganancias de almacenamiento para los bloques deltificados—en lugar de tomar tanto espacio como el tamaño de los datos originales, tomará justo lo necesario para decir, tengo casi el mismo aspecto de este otro bloque de datos de ahí, excepto por las siguientes diferencias. De manera más específica, cada vez que una nueva versión de un fichero es enviada al repositorio, Subversion codifica la versión anterior (en realidad, varias versiones anteriores) como un delta contra la nueva versión. El resultado es que la mayor parte de los datos que suelen ocupar espacio—en concreto, los contenidos de los ficheros versionados—se almacenan con un tamaño mucho menor que la representación original completa (fulltext) de esos datos.

[Nota] Nota

Dado que todos los datos del repositorio Subversion sujetos a la deltificación se almacenan en un único fichero de base de datos Berkeley, reducir el tamaño de los valores almacenados no reducirá necesariamente el tamaño de éste fichero. La base de datos Berkeley no obstante mantendrá un registro interno de áreas internas sin usar de la base de datos, y usará esas áreas primero antes de volver a redimensionar el tamaño del fichero de la base de datos. Así que aunque la deltificación no produce ganancias de espacio inmediatas, puede enlentecer drásticamente el crecimiento futuro de la base de datos.

Restauración del repositorio

Para poder proteger sus datos en el repositorio, el motor de la base de datos usa un mecanismo de bloqueo. Éste se asegura de que no hay porciones de la base de datos modificadas simultáneamente por múltiples clientes de la base de datos, y que cada proceso ve los datos en un estado correcto cuando éstos son leídos. Cuando un proceso necesita cambiar algo en la base de datos, primero comprueba la existencia de un bloqueo en los datos objetivo. Si los datos no están bloqueados, el proceso los bloquea, hace los cambios que desea realizar, y desbloquea los datos. Esto obliga a otros procesos a esperar hasta que se elimine el bloqueo antes de que se les permita continuar accediendo a esa sección de la base de datos.

A lo largo del uso de su repositorio Subversion, los errores fatales (como quedarse sin espacio en disco duro o sin memoria) o las interrupciones pueden evitar que un proceso tenga la oportunidad de eliminar los bloqueos que inició sobre la base de datos. El resultado es que el motor de la base de datos del sistema se wedged. Cuando esto ocurre, cualquier intento de acceso al repositorio se bloqueará de manera indefinida (dado que cada nuevo cliente estará esperando a que los bloqueos desaparezcan—lo cual no va a ocurrir).

Primero, si esto ocurre en su repositorio, no se preocupe. El sistema de ficheros de Subversion tiene la ventaja de usar transacciones, puntos de control y ficheros de registro pre-escritura para asegurarse de que sólo los eventos más catastróficos [22] pueden destruir de manera permanente el entorno de la base de datos. Un administrador de repositorio suficientemente paranoico estará haciendo copias de seguridad del repositorio en otra máquina separada de alguna manera, pero todavía no es el momento de llamarle para que realice la restauración de una cinta.

En segundo lugar, use la siguiente receta para intentar unwedge su repositorio:

  1. Asegúrese de que no hay procesos accediendo (o intentando acceder) al repositorio. Para repositorios en red, esto también significa tener que desconectar el servidor HTTP Apache.

  2. Conviértase en el usuario que posee y gestiona el repositorio. Esto es importante, dado que recuperar el repositorio poseyendo el usuario erróneo puede alterar los permisos de los ficheros del repositorio de tal modo que será inaccesible incluso después de haberlo unwedged.

  3. Ejecute el comando svnadmin recover /ruta/al/repositorio. Debería ver algo como esto:

    Please wait; recovering the repository may take some time...
    
    Recovery completed.
    The latest repos revision is 19.
    

    Este comando puede tardar muchos minutos en completar su tarea.

  4. Rearranque el servidor Subversion.

Este procedimiento corrige casi todos los casos de bloqueos del repositorio. Asegúrese de ejecutar este comando como el usuario a quien le pertenece la base de datos y la gestiona, no basta con ser root. Parte del proceso de recuperación puede conllevar la regeneración de varios ficheros de bases de datos (por ejemplo, regiones de memoria compartidas). Al realizar la recuperación como root, éstos ficheros tendrán sus permisos, lo cual significa que incluso cuando recupere la conexión con el repositorio, los usuarios normales no serán capaces de acceder a él.

Si el procedimiento anterior, por alguna razón, no consigue desbloquear su repositorio, debería hacer dos cosas. En primer lugar, mueva su repositorio estropeado a otro lugar y recupere la última copia de seguridad que tenga del mismo. Entonces, envíe un correo electrónico a la lista de usuarios de Subversion (en ) describiendo su problema con todo detalle. Para los desarrolladores de Subversion mantener la integridad de los datos es una prioridad extremadamente alta.

Migrando un repositorio

Un sistema de ficheros de Subversion almacena sus datos repartidos por varias tablas de bases de datos de una forma generalmente comprensible (y sólo de interés) para los propios desarrolladores de Subversion. No obstante, pueden darse las circunstancias adecuadas que requieran que todos los datos, o un subconjunto de los mismos, sean recopilados en un fichero único, portable, y de formato simple. Subversion proporciona tal mecanismo implementado como la pareja de subcomandos de svnadmin: dump y load.

La razón más común para volcar y recargar un repositorio de Subversion es por cambios en el propio Subversion. A medida que Subversion madura, hay momentos en los que hace falta realizar cambios al esquema del motor de la base de datos que hacen a Subversion incompatible con versiones anteriores de su repositorio. La acción recomendada para actualizarse atravesando una de estas barreras de incompatiblidad es relativamente simple:

  1. Usando su actual versión de svnadmin, vuelque su repositorio a ficheros de volcado.

  2. Actualícese a la nueva versión de Subversion.

  3. Mueva sus viejos repositorios a otra parte, y cree nuevos repositorios vacíos en su lugar usando su nuevo svnadmin.

  4. Otra vez con su svnadmin nuevo, cargue sus ficheros de volcado en sus repositorios recién creados respectivamente.

  5. Finalmente, asegúrese de copiar en los nuevos repositorios cualquier personalización realizada en los antiguos, incluyendo los ficheros DB_CONFIG y los ficheros de ganchos. Le recomendamos que preste atención a las notas de lanzamiento de la nueva versión de Subversion para comprobar si algún cambio desde su última actualización afecta a esos ficheros de ganchos u opciones de configuración.

svnadmin dump generará en su salida un rango de revisiones del repositorio usando el formato propio de Subversion para volcar el sistema de ficheros. El volcado formateado será enviado al flujo estándar de salida, mientras que los mensajes informativos son enviados al flujo estándar de errores. Esto le permite redirigir el flujo de salida estándar a un fichero mientras observa el estado del volcado en su terminal. Por ejemplo:

$ svnlook youngest myrepos
26
$ svnadmin dump myrepos > dumpfile
* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
…
* Dumped revision 25.
* Dumped revision 26.

Al final del proceso tendrá un único fichero (dumpfile según el ejemplo anterior) que contendrá todos los datos almacenados en su repositorio en el rango de revisiones especificado. Tenga en cuenta que svnadmin dump lee los árboles de versiones del repositorio igual que cualquier otro proceso lector (por ejemplo, svn checkout). Así que es seguro ejecutar este comando en cualquier momento.

El otro subcomando de la pareja, svnadmin load, procesa el flujo estándar de entrada como un fichero de volcado de repositorio de Subversion, y reproduce de manera efectiva esas revisiones volcadas en el repositorio destino durante la operación. También proporciona mensajes informativos, esta vez usando el flujo de salida estándar:

$ svnadmin load newrepos < dumpfile
<<< Started new txn, based on original revision 1
     * adding path : A ... done.
     * adding path : A/B ... done.
     …
------- Committed new rev 1 (loaded from original rev 1) >>>

<<< Started new txn, based on original revision 2
     * editing path : A/mu ... done.
     * editing path : A/D/G/rho ... done.

------- Committed new rev 2 (loaded from original rev 2) >>>

…

<<< Started new txn, based on original revision 25
     * editing path : A/D/gamma ... done.

------- Committed new rev 25 (loaded from original rev 25) >>>

<<< Started new txn, based on original revision 26
     * adding path : A/Z/zeta ... done.
     * editing path : A/mu ... done.

------- Committed new rev 26 (loaded from original rev 26) >>>

Dado que svnadmin usa la los flujos estándar de entrada y salida para el volcado de repositorio y el proceso de carga, las personas que se sientan atrevidas pueden probar algo como ésto (quizás usando diferentes versiones de svnadmin en cada lado de la tubería):

$ svnadmin create newrepos
$ svnadmin dump myrepos | svnadmin load newrepos

Hemos mencionado anteriormente que svnadmin dump genera un rango de revisiones. Use la opción --revision para indicar que quiere volcar una revisión concreta, o un rango. Si omite esta opción, todas las revisiones existentes del repositorio serán volcadas.

$ svnadmin dump myrepos --revision 23 > rev-23.dumpfile
$ svnadmin dump myrepos --revision 100:200 > revs-100-200.dumpfile

A medida que Subversion vuelca cada revisión nueva, muestra la información justa para permitir a un cargador futuro recrear esa revisión basándose en la anterior. En otras palabras, para cualquier revisión dada en el fichero de volcado, sólo aparecerán los elementos que cambiaron en ella. La única excepción a esta regla es la primera revisión volcada por el comando svnadmin dump actual.

Por defecto, Subversion no expresará la primera revisión volcada como las meras diferencias aplicables sobre la revisión anterior. Para empezar, ¡es que no hay revisión anterior alguna en el fichero de volcado! Y en segundo lugar, Subversion no puede saber el estado del repositorio en el cual los datos volcados serán cargados (si este hecho llega a producirse). Para asegurarse de que la salida de cada ejecución de svnadmin dump es autosuficiente, la primera revisión volcada es por defecto una representación completa de cada directorio, fichero, y propiedad en esa revisión del repositorio.

No obstante, puede cambiar este comportamiento por defecto. Si añade la opción --incremental cuando vuelque su repositorio, svnadmin comparará la primera versión volcada del repositorio contra la revisión anterior del repositorio, igual que trata cualquier otra revisión volcada. Entonces mostrará la primera revisión exactamente igual que el resto de las revisiones del rango de volcado—mencionando únicamente los cambios ocurridos en esa revisión. El beneficio de esto es que puede crear varios ficheros de volcado menores que pueden ser cargados secuencialmente, en lugar de un único fichero grande, siguiendo estos pasos:

$ svnadmin dump myrepos --revision 0:1000 > dumpfile1
$ svnadmin dump myrepos --revision 1001:2000 --incremental > dumpfile2
$ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3

Estos ficheros de volcado podrían ser cargados en un nuevo repositorio usando la siguiente secuencia de comandos:

$ svnadmin load newrepos < dumpfile1
$ svnadmin load newrepos < dumpfile2

$ svnadmin load newrepos < dumpfile3

Otro truco interesante que puede realizar con la opción --incremental consiste en añadir a un fichero de volcado existente un nuevo rango de revisiones volcadas. Por ejemplo, digamos que tiene un gancho post-commit que simplemente añade el volcado del repositorio de la versión única que despertó la ejecución del gancho. O quizás tenga un script que se ejecute por las noches para añadir los datos del fichero de volcado de todas las revisiones que fueron añadidas al repositorio desde la última vez que fue ejecutado el script. Usados de este modo, los comandos svnadmin dump y load pueden ser valiosos aliados para realizar copias de seguridad de su repositorio a lo largo del tiempo en caso de un fallo de sistema o algún otro evento catastrófico.

El formato de volcado también puede ser usado para fusionar los contenidos de varios repositorios diferentes en uno único. Al usar la opción --parent-dir de svnadmin load, puede especificar un nuevo directorio virtual para el proceso de carga. Lo cual significa que si tiene ficheros de volcados para tres repositorios, digamos calc-dumpfile, cal-dumpfile, y ss-dumpfile, puede crear primero un nuevo repositorio para almacenarlos todos:

$ svnadmin create /path/to/projects
$

Entonces, cree nuevos directorios en el repositorio que encapsularán los contenidos de cada uno de los tres repositorios anteriores:

$ svn mkdir -m "Initial project roots" \
      file:///path/to/projects/calc \
      file:///path/to/projects/calendar \
      file:///path/to/projects/spreadsheet
Committed revision 1.
$ 

Por último, cargue los ficheros de volcado individuales en sus ubicaciones respectivas del nuevo repositorio:

$ svnadmin load /path/to/projects --parent-dir calc < calc-dumpfile
…
$ svnadmin load /path/to/projects --parent-dir calendar < cal-dumpfile
…
$ svnadmin load /path/to/projects --parent-dir spreadsheet < ss-dumpfile
…
$

Mencionaremos un último uso del formato de volcado de repositorio de Subversion—conversión desde un formato de almacenamiento diferente o sistema de control de versiones. Dado que el fichero de volcado es, en su mayor parte, legible por un humano, [23] debería ser relativamente sencillo describir un conjunto genérico de cambios—cada uno de ellos debería ser descrito como una nueva revisión—usando este formato de fichero. De hecho, la utilidad cvs2svn.py (vea “Convirtiendo un repositorio de CVS a Subversion”) usa el formato de volcado para representar el contenido de un repositorio CVS para que sus contenidos pueden ser trasladados a un repositorio Subversion.

Copias de seguridad del repositorio

A pesar de numerosos avances tecnológicos desde el nacimiento de la computadora moderna, hay una cosa que se entiende con cristalina claridad—a veces, las cosas van muy, pero que muy mal. Pérdidas de corriente, fallos de conectividad en la red, RAM corrupta y discos duros estropeados son un mero avance del mal que el Destino puede desatar sobre incluso el administrador más concienzudo. Y por lo tanto, llegamos a un tema muy importante—cómo hacer copias de seguridad de los datos de su repositorio.

En general hay dos tipos de métodos de copia de seguridad disponibles para los administradores de repositorios de Subversion—incrementales y completos. Hemos discutido en una sección anterior de este capítulo cómo usar svnadmin dump --incremental para realizar copias de seguridad incrementales (vea “Migrando un repositorio”). Esencialmente, la idea es realizar en un momento dado copias de seguridad de los cambios realizados desde la última vez que se hizo la copia de seguridad anterior.

Una copia de seguridad completa del repositorio es casi una copia literal del directorio que contiene todo el repositorio (lo cual incluye el entorno de la base de datos Berkeley). Ahora, a no ser que desactive temporalmente todo el acceso a su repositorio, ejecutar un simple copiado recursivo del directorio conlleva el riesgo de generar una copia de seguridad errónea, dado que alguien podría estar modificando la base de datos.

Afortunadamente, los documentos de la base de datos Berkeley de Sleepycat describen un orden concreto en el cual se pueden copiar los ficheros de la base de datos de tal modo que se garantice una copia de seguridad válida. Y aun mejor, usted no necesita implementar ese algoritmo por su cuenta, porque el equipo de desarrolladores de Subversion ya lo ha hecho. El script hot-backup.py que puede encontrar en el directorio tools/backup/ de la distribución de código fuente de Subversion. Usando como parámetros la ruta al repositorio y a la ubicación de la copia de seguridad, hot-backup.py—que realmente no es más que un envoltorio más inteligente sobre el comando svnadmin hotcopy— realizará los pasos necesarios para realizar una copia de seguridad en caliente del repositorio—sin necesitar en absoluto tener que impedir el acceso al mismo—y después borrará los ficheros de registro sin usar de Berkeley de su repositorio activo actual.

Incluso si también dispone de una copia de seguridad incremental, quizás quiera ejecutar también este programa de manera habitual. Por ejemplo, podría considerar añadir hot-backup.py a un programa de planificación (como por ejemplo cron en sistemas Unix). O, si prefiere soluciones de copias de seguridad con alta granularidad, podría hacer que su gancho post-commit llame hot-backup.py (vea “Scripts de enganche”), lo cual provocará una nueva copia de seguridad de su repositorio con cada nueva versión. Simplemente añada el script hooks/post-commit a su directorio activo del repositorio:

(cd /path/to/hook/scripts; ./hot-backup.py ${REPOS} /path/to/backups &)

La copia de seguridad resultante es un repositorio de Subversion completamente funcional, capaz de reemplazas su repositorio activo en caso de que algo vaya muy mal.

Ambos métodos de copias de seguridad son beneficiosos. La copia de seguridad completa es de lejos la más sencilla, la que siempre resultará ser una réplica de su repositorio perfectamente funcional. Le recordamos que esto significa que si algo malo le ocurre a su repositorio activo, puede recuperar su copia de seguridad con un simple copiado recursivo de directorios. Desafortunadamente, si está manteniendo múltiples copias de seguridad de su repositorio, estas copias completas acabarán ocupando la misma cantidad de espacio de disco que su repositorio activo.

Las copias de seguridad incrementales usando el formato de volcado del repositorio son excelentes para tener a mano si el esquema de la base de datos cambia entre sucesivas versiones del propio Subversion. Dado que para actualizar su repositorio al nuevo esquema es necesario que haga un volcado y carga completa del repositorio, es muy conveniente tener la mitad de ese proceso (la parte del volcado) realizada. Desafortunadamente, la creación—y recuperación—de copias de seguridad incrementales tarda mucho más, dado que cada revisión es reproducida en el fichero de volcado o el repositorio.

En ambos escenarios, los administradores del repositorio necesitan estar atentos a cómo las modificaciones de propiedades de revisión no versionadas afectan a sus copias de seguridad. Dado que estos cambios no generan por sí mismos nuevas revisiones, no activarán ganchos post-commit, y quizás ni siquiera los ganchos pre-revprop-change y post-revprop-change. [24] Y dado que puede cambiar las propiedades de revisión sin respetar su orden cronológico—puede cambiar cualquier propiedad de revisión en cualquier momento—una copia de seguridad incremental de las últimas pocas revisiones quizás no capture la modificación de una propiedad de revisión que fue incluida como parte de una copia de seguridad anterior.

Hablando de manera general, sólo los realmente paranoicos necesitarían hacer una copia de seguridad de su repositorio completo, digamos que, cada vez que se realiza un cambio. No obstante, asumiendo que un repositorio determinado tiene funcionando otros mecanismos de redundancia con relativa granularidad (como correos electrónicos por modificación), una copia de seguridad en caliente de la base de datos sería algo que un administrador de repositorio querría incluir como parte de una copia de seguridad de sistema nocturna. Para la mayoría de los repositorios, los correos archivados con cambios son suficiente fuente de redundancia, al menos para los últimos cambios. Pero son sus datos—protéjalos tanto como desee.

A menudo, la mejor estrategia para realizar copias de seguridad es aquella que diversifique. Puede aprovechar combinaciones de copias de seguridad completas e incrementales, y adicionalmente archivos de correo con los cambios. Los desarrolladores de Subversion, por ejemplo, realizan una copia de seguridad del repositorio de código fuente tras cada nueva revisión, y mantienen un archivo de todas las notificaciones por correo electrónico de cambios y modificaciones de propiedades. Su solución podría ser similar, pero debería estar orientada a las necesidades y ese delicado balance entre la conveniencia y la paranoia. Y aunque nada de todo esto le ayude a salvar su hardware del puño de hierro del Destino, [25] ciertamente debería ayudarle a recuperarse tras uno de esos momentos.



[20] Esto, de todas maneras, es una característica, y no un error.

[21] Mientras svnadmin dump tiene una política consistente de barras—no incluirlas— otros programas que generan datos de volcado puede no ser tan consistentes.

[22] Ej: disco duro + enorme electroimán = desastre.

[23] El formato de volcado de repositorio de Subversion recuerda al formato RFC-822, el mismo tipo de formato usado para la mayor parte del correo electrónico.

[24] svnadmin setlog puede ser invocado de un modo que evita por completo el mecanismo de ganchos.

[25] Ya sabe—el término genérico para sus erráticos dedos.