Subversion: Notificaciones vía correo electrónico

Al darse un proceso de desarrollo colectivo es recomendable mantener una o varias listas de notificación acerca de los cambios hechos (commits) en el repositorio de código fuente. Para este tipo de actividades es muy útil emplear SVN::Notify.

SVN::Notify le ofrece un número considerable de opciones, a continuación resumo algunas de ellas.

  • Obtiene información relevante acerca de los cambios ocurridos en el repositorio Subversion.
  • Realiza análisis sobre la información recolectada y brinda la posibilidad de reconocer distintos formatos vía filtros (Ej. Textile, Markdown, Trac).
  • Puede obtener la salida tanto en texto sin formato como en XHTML.
  • Le brinda la posibilidad de construir correos electrónicos en base a la salida obtenida.
  • Permite el envío de correo, ya sea por el comando sendmail o SMTP.
  • Es posible indicar el método de autenticación ante el servidor SMTP.

Para instalar el SVN::Notify en sistemas Debian o derivados proceda de la siguiente manera:

# aptitude install libsvn-notify-perl

Una vez instalado SVN::Notify, es hora de definir su comportamiento. Aunque es posible hacerlo vía comando svnnotify y empotrarlo en un script escrito en Bash he preferido hacerlo en Perl, es más natural y legible hacerlo de este modo.

#!/usr/bin/perl -w

use strict;
use SVN::Notify;

my $path = $ARGV[0];
my $rev  = $ARGV[1];

my %params = (
    repos_path      => $path,
    revision        => $rev,
    handler         => 'HTML::ColorDiff',
    trac_url        => 'http://trac.example.com/project',
    filters         => ['Trac'],
    with_diff       => 1,
    diff_switches   => '--no-diff-added --no-diff-deleted',
    subject_cx      => 1,
    strip_cx_regex  => [ '^trunk/', '^branches/', '^tags/' ],
    footer          => 'Administrado por: BOFH ',
    max_sub_length  => 72,
    max_diff_length => 1024,
    from            => 'noreply@example.com',
    subject_prefix  => '[project]',
    smtp            => 'smtp.example.com',
    smtp_user       => 'example',
    smtp_pass       => 'example',
);

my $developers = 'dev@example.com';
my $admins     = 'admins@example.com';

$params{to_regex_map} = {
    $developers => '^trunk|^branches',
    $admins     => '^tags|^trunk'
};

my $notifier = SVN::Notify->new(%params);
$notifier->prepare;
$notifier->execute;

Si seguimos con el ejemplo indicado en el artículo anterior, Instalación básica de Trac y Subversion, este hook lo vamos a colocar en /srv/svn/project/hooks/post-commit, dicho fichero deberá tener permisos de ejecución para el Servidor Web Apache.

Con este sencillo script en Perl se ha logrado lo siguiente:

  • La salida se generará en XHTML.
  • Las diferencias de código serán resaltadas o coloreadas, esto es posible por el handler SVN::Notify::ColorDiff
  • El sistema de notificación está integrado a la sintaxis de enlaces de Trac. Por lo tanto, los commits que posean este tipo de enlaces serán interpretados correctamente. Ej. #123 changeset:234 r234 [/source]

Muestra del coloreado que ofrece SVN::Notify

Aunque el código es sucinto y claro, trataré de resumir cada uno de los parámetros utilizados.

repos_path
Define la ruta al repositorio Subversion, la cual es obtenida a partir del primer argumento que pasa Subversion al ejecutar el hook post-commit.
revision
El número de la revisión del commit actual. El número de la revisión se obtiene a partir del segundo argumento que pasa Subversion al ejecutar el hook post-commit
handler
Especifica una subclase de SVN::Notify que será utilizada para el manejo de las notificaciones. En el ejemplo se hace uso de HTML::ColorDiff, el cual permite colorear o resaltar la sintaxis del comando svnlook diff
trac_url
Este parámetro será usado para generar enlaces al Trac para los números de revisiones y similares en el mensaje de notificación.
filters
Especifica la carga de más módulos que terminan de difinir la salida de la notificación. En el ejemplo, se hace uso del filtro Trac, filtro que convierte el log del commit que cumple con el formato de Trac a HTML.
with_diff
Valor lógico que especifica si será o no incluida la salida del comando svnlook diff en la notificación vía correo electrónico.
diff_switches
Permite el pase de opciones al comando svnlook diff, en particular recomiendo utilizar --no-diff-deleted y --no-diff-added para evitar ver las diferencias para los archivos borrados y añadidos respectivamente.
subject_cx
Valor lógico que indica si incluir o nó el contexto del commit en la línea de asunto del correo electrónico de notificación.
strip_cx_regex
Acá se indican las expresiones regulares que serán utilizadas para eliminar información del contexto de la línea de asunto del correo electrónico de notificación.
footer
Agrega la cadena definida al final del cuerpo del correo electrónico de notificación
max_sub_length
Indica la longitud máxima de la línea de asunto del correo electrónico de notificación.
max_diff_length
Máxima longitud del diff (esté adjunto o en el cuerpo de la notificación).
from
Define la dirección de correo que será usada en la línea From. Si no se especifica será utilizado el nombre de usuario definido en el commit, esta información se obtiene vía el comando svnlook.
subject_prefix
Define una cadena de texto que será el prefijo de la línea correspondiente al asunto del correo electrónico de notificación.
smtp
Indica la dirección para el servidor SMTP que el cual se enviarán las notificaciones de correo electrónico. Si no se utiliza este parámetro, SVN::Notify utilizará el comando sendmail para el envío del mensaje.
smtp_user
El nombre de usuario para la autenticación SMTP.
smtp_pass
Contraseña para la autenticación SMTP
to_regex_map
Este parámetro contiene un hash que mantiene referencias de direcciones de correo electrónico contra expresiones regulares. La idea es enviar las notificaciones si y solo si el nombre de uno o más directorios son afectados por un commit y dicha ruta coincide con las expresiones regulares definidas. Este parámetro resulta muy útil en proyectos de desarrollo de software grandes y donde es posible disponer de varias listas de correo para informar a los desarrolladores interesados en secciones específicas.

Para mayor detalle de las opciones mencionadas previamente vea SVN::Notify, acá también encontrará más opciones de configuración.

Observación

Hasta ahora he encontrado que el coloreado o resaltado de la sintaxis no funciona en algunos sistemas Webmail, como por ejemplo Gmail, SquirrelMail. Sin embargo, en otros sistemas Webmail como RoundCube si funciona. Este comportamiento se presenta porque en sistemas como Gmail las hojas de estilos en cascada (CSS) internas no son aplicadas en la interfaz. Es por ello que en estos casos es necesario recurrir a la definición de estilos en línea.

Instalación básica de Trac y Subversion

En este artículo se pretenderá mostrarle el proceso de instalación de un ambiente de desarrollo que le permitirá hacerle seguimiento a su proyecto personal, de igual manera se le indicará el modo en el cual puede comenzar a utilizar un sistema de control de versiones. Todas las indicaciones mostradas en este documento han sido probadas en la distribución Debian GNU/Linux 5.0 (nombre código Lenny).

La herramienta de seguimiento o manejo del proyecto que se procederá a instalar es Trac, el sistema de control de versiones que se presentará será Subversion. Todo lo anterior se presentará vía Web haciendo uso del servidor Apache, de manera adicional se utilizará el servidor de bases de datos PostgreSQL como backend de Trac.

Dependencias

En primer lugar proceda a instalar las siguientes dependencias.

# aptitude install apache2 \
libapache2-mod-python \
postgresql \
subversion \
python-psycopg2 \
libapache2-svn \
python-subversion \
trac

La versión de Trac que se encuentra en los archivos de Debian Lenny es estable (0.11.1). Sin embargo, si usted compara esta versión con lo publicado en el sitio oficial de Trac, podrá encontrar que existen nuevas versiones estables de mantenimiento que contienen correcciones a errores de programación y algunas nuevas funcionalidades de bajo impacto, para el momento de la redacción de este artículo se encuentra la versión 0.11.7. Es recomendable que utilice el paquete trac desde el archivo backports de Debian.

# aptitude -t lenny-backports install trac

Si desea usar el paquete proveniente del archivo backports le recomiendo leer las instrucciones de uso de este repositorio de paquetes.

Con el fin de mantener este artículo lo más sencillo y conciso posible se describirá la versión que viene por defecto con la distribución utilizada en este caso.

Versión de desarrollo de Trac

Si desea conocer algunas características interesantes que se han agregado a Trac en las nuevas versiones, o si su interés particular es
examinar las bondades que le ofrece Trac en su versión de desarrollo puede hacer uso del comando pip, si no tiene instalado pip proceda como sigue:

# aptitude install python-setuptools
# easy_install pip

Proceda a instalar la versión de desarrollo de Trac.

# pip install https://svn.edgewall.org/repos/trac/trunk

Creación de usuario y base de datos

Antes de proceder con la instalación de Trac se debe establecer el usuario y la base de datos que se utilizará para trabajar.

En el siguiente ejemplo el usuario de la base de datos PostgreSQL que utilizará Trac será trac_user, su contraseña será trac_passwd. El uso de la contraseña lo del usuario trac_user lo veremos más tarde al proceder a configurar el ambiente de Trac.

# su postgres
$ createuser \
--no-superuser \
--no-createdb \
--no-createrole \
--pwprompt \
--encrypted trac_user
Enter password for new role:
Enter it again:
CREATE ROLE

Nótese que se debe utilizar el usuario postgres (u otro usuario con los privilegios necesarios) del sistema para proceder a crear los usuarios.

Ahora procedemos a crear la base de datos trac_dev, cuyo dueño será el usuario trac_user.

$ createdb --encoding UTF8 --owner trac_user trac_dev

Ambiente de Trac

Creamos el directorio /srv/www que será utilizado para prestar servicios Web, para mayor referencia acerca de esta elección se le recomienda leer el documento Filesystem Hierarchy Standard en su versión 2.3.

$ sudo mkdir -p /srv/www
$ cd /srv/www

Generamos el ambiente de Trac. Básicamente se deben contestar ciertas preguntas como:

  • Nombre del proyecto.
  • Enlace con la base de datos que se utilizará.
  • Sistema de control de versiones a utilizar (por defecto será SVN).
  • Ubicación absoluta del repositorio a utilizar.
  • Ubicación de las plantillas de Trac.

En el siguiente ejemplo se omitirán los comentarios brindados por el comando trac-admin.


# trac-admin project initenv
Creating a new Trac environment at /srv/www/project

...

Project Name [My Project]> Demo

...

Database connection string [sqlite:db/trac.db]>
postgres://trac_user:trac_passwd@localhost:5432/trac_dev

...

Repository type [svn]>

...

Path to repository [/path/to/repos]> /srv/svn/project

...

Templates directory [/usr/share/trac/templates]>

Creating and Initializing Project
 Installing default wiki pages

...

---------------------------------------------------------
Project environment for 'Demo' created.

You may now configure the environment by editing the file:

  /srv/www/project/conf/trac.ini

...

Congratulations!

Se ha culminado la instalación del ambiente de Trac, ahora procederemos a crear el ambiente de subversion.

Subversion: Sistema Control de Versiones

La puesta a punto del sistema de control de versiones es bastante sencilla, se resume en los siguientes pasos.

Creación del espacio para prestar el servicio SVN, de igual manera se seguirá los lineamientos planteados en el FHS v2.3 mencionado previamente.

# mkdir -p /srv/svn

Seguidamente crearemos el proyecto subversion project y haremos un importe inicial con la estructura básica de un proyecto de desarrollo de software.

$ cd /srv/svn
# svnadmin create project
$ mkdir -p /tmp/project/{trunk,tags,branches}
$ tree /tmp/project/
/tmp/project/
├── branches
├── tags
└── trunk
# svn import /tmp/project/ \
file:///srv/svn/project/ \
-m 'Importe inicial'

Adding         /tmp/project/trunk
Adding         /tmp/project/branches
Adding         /tmp/project/tags

Committed revision 1.

Apache: Servidor Web

Es hora de configurar los sitios virtuales que utilizaremos tanto para Trac como para subversion.

A continuación se presenta la configuración básica de Trac.

# cat > /etc/apache2/sites-available/trac.example.com <<EOF
> <VirtualHost *>
> ServerAdmin webmaster@localhost
> ServerName trac.example.com
> CustomLog /var/log/apache2/trac.example.com/access.log combined
> ServerSignature Off
> ErrorLog /var/log/apache2/trac.example.com/error.log
> LogLevel warn
> DocumentRoot /srv/www/project
> <Location />
> SetHandler mod_python
> PythonInterpreter main_interpreter
> PythonHandler trac.web.modpython_frontend
> PythonOption TracEnv /srv/www/project
> PythonOption TracUriRoot /
> </Location>
> </VirtualHost>
> EOF

Ahora veamos la configuración básica de nuestro proyecto subversion.

# cat > /etc/apache2/sites-available/svn.example.com <<EOF
> <VirtualHost *>
> ServerAdmin webmaster@localhost
> ServerName svn.example.com
> CustomLog /var/log/apache2/svn.example.com/access.log combined
> ServerSignature Off
> ErrorLog /var/log/apache2/svn.example.com/error.log
> LogLevel warn
> DocumentRoot /srv/svn/project
> <Location />
> DAV svn
> SVNPath /srv/svn/project
> </Location>
> </VirtualHost>
> EOF

De acuerdo a la configuración mostrada es necesario crear los directorios /var/log/apache2/svn.example.com y /var/log/apache2/trac.example.com para mantener por separado el registro de accesos y errores de los sitios virtuales recién creados. De
lo contrario no podremos iniciar el servidor Web Apache.

# mkdir /var/log/apache2/{svn,trac}.example.com

Activamos el módulo DAV necesario para cumplir con la configuración mostrada para el sitio virtual svn.example.com.

# a2enmod dav

Activamos los sitios virtuales recién creados.

# a2ensite trac.example.com
# a2ensite svn.example.com

Como la puesta en marcha y configuración de un servidor DNSescapa a los fines de este artículo, simplemente definiremos los hosts en la tabla estática que se encuentra definida en el archivo /etc/hosts de la siguiente manera.

# cat >> /etc/hosts <<EOF
> 127.0.0.1 trac.example.com trac
> 127.0.0.1 svn.example.com svn
> EOF

Finalmente debemos forzar la recarga de la configuración del servidor Web Apache, esto con el fin de cargar el módulo DAV y los sitios virtuales definidos, es decir, trac.example.com y svn.example.com.

# /etc/init.d/apache2 force-reload

¡Felicitaciones!, ya puede ir a su navegador favorito y colocar cualquiera de los sitios virtuales que acaba de definir.

Recomendaciones

Una vez que haya llegado a este sección deberá comenzar a modificar adecuadamente los permisos para el usuario y grupo www-data (Servidor Web Apache) para que escriba en las ubicaciones que sea necesario tanto en Trac como en subversion.

La configuración de Trac podrá encontrarla en /srv/www/project/conf/trac.ini, para mayor detalle acerca de la configuración de este fichero se le recomienda leer el documento TracIni.

Si en su proyecto prevé que participarán otras personas, es recomendable establecer notificaciones de tickets y cambios en el
repositorio subversion, para esto último deberá revisar el hook post-commit y la documentación del paquete libsvn-notify-perl que le ofrece una extraordinaria cantidad de opciones.

Conozca el entorno de Trac y Subversion. Si desea agregar nuevas funciones a su instalación le recomiendo visitar el sitio Trac Hacks.

Espero poder mostrarles en próximos artículos algunas configuraciones más avanzadas en Trac, incluyendo la instalación, configuración y uso de plugins.

Consideraciones para el envío de cambios en Subversion

Hoy día pareciese que los sistemas de control de versiones centralizados están pasando de moda ante la aparición de sistemas de control de versiones descentralizados poderosos como Git, del cual espero poder escribir en próximos artículos. Sin embargo, puede que la adopción de estos sistemas descentralizados tarden en controlar el mundo de los SCM, al menos por ahora las métricas de ohloh.net indican que Subversion sigue siendo bastante empleado, mayor detalle en el artículo Subversion – As Strong As Ever.

En este artículo se expondrán algunas políticas que suelen definirse para la sana convivencia entre colaboradores de un proyecto de desarrollo de software, estas reglas no solo aplican a Subversion en particular, son de uso común en otros sistemas de control de versiones centralizados.

Analice bien los cambios hechos antes de enviarlos

Cualquier cambio en la línea base de su proyecto puede traer consecuencias, tome en cuenta que los demás desarrolladores obtendrán sus cambios una vez que estén en el repositorio centralizado. Si usted no se preocupó por validar que todo funcionara correctamente antes de enviar sus cambios, es probable que algún compañero le recrimine por su irresponsabilidad, esto afecta de cierta forma el anillo de confianza entre los colaboradores del proyecto.

Nunca envíe cambios que hagan fallar la construcción del proyecto

Siempre verifique que su proyecto compile, si el proyecto presenta errores debido a los cambios hechos por usted atiendalos inmediatamente, evite los errores de sintaxis, tenga siempre presente respetar las políticas de estilo de código definidas para su proyecto.

Si ha ingresado nuevos ficheros o directorios al proyecto recuerde ejecutar el comando svn add para programar la adición en Subversion, si omite este paso es posible que su copia de trabajo funcione o compile, pero la del resto de sus compañeros no, evite de nuevo ser recriminado por los demás colaboradores del proyecto.

Si su proyecto pretende ser multiplataforma, trate de imaginar las consecuencias de sus cambios bajo otro sistema operativo o arquitectura. Por ejemplo, he visto más de una vez este tipo de error:

path = "dir/subdir/fichero.txt" # Malo
path = os.path.join(os.path.dirname(__file__),
                    'dir', 'subdir', 'fichero.txt') # Correcto

Pruebe los cambios antes de hacer el envío

Antes de realizar un envío al repositorio centralizado actualice su copia de trabajo (svn up), verifique que las pruebas unitarias, regresión de su proyecto arrojan resultados positivos, de igual manera haga pruebas funcionales del sistema.

Al momento de hacer la actualización de su copia de trabajo tome nota de los ficheros editados por los demás colaboradores del proyecto, verifique que no existan conflictos, nuevos ficheros que no haya considerado, entre otros. Una vez que haya solventado la actualización de su copia de trabajo, construya (su proyecto tiene un sistema de autoconstrucción, ¿verdad?) el paquete, inicie su aplicación que contiene los cambios locales y asegúrese que el comportamiento obtenido sea igual al esperado.

Promueva un histórico de cambios descriptivo

El histórico de cambios debe ser comprensible por cualquier colaborador del proyecto solamente con la información suministrada en dicho registro, evite depender de información fuera del contexto del envío de cambios. Se le recomienda colocar toda la información importante que no pueda obtenerse a partir de un svn diff del código fuente.

¿Está corrigiendo un error?

Si usted está reparando un error en la aplicación que se encuentra presente en la rama principal de desarrollo (trunk), considere seriamente portar esa reparación a otras ramas de desarrollo (branches) en el caso que su proyecto posea una versión estable que requiere actualmente de mantenimiento. Trate en lo posible de aprovechar el mismo commit para enviar la corrección de la rama principal de desarrollo (trunk) y las ramas de mantenimiento.

Si el error fue reportado a través del sistema de seguimiento de errores (usted mantiene un sistema de seguimiento de errores, ¿verdad?), agregue en el registro del mensaje de envío el número del ticket, boleto o reporte que usted está atendiendo. Seguidamente proceda a cerrar el ticket o boleto en el sistema de seguimiento de errores.

No agregue ficheros generados por otras herramientas al repositorio

No agregue ficheros innecesarios al repositorio, el origen de estos ficheros suele ser:

  • Proceso de autoconstrucción (Ej. distutils, autotools, scons, entre otros).
  • Herramientas de verificación de calidad del código (Ej. PyLint, CppLint, entre otros).
  • Herramientas para generar documentación (Ej. Doxygen, Sphinx, entre otros).

Estos ficheros generados por otras herramientas no es necesario versionarlos, puede considerarlos cache, este tipo de datos son localmente generados como resultado de operaciones I/O o cálculos, las herramientas deben ser capaces de regenerar o restaurar estos datos a partir del código presente en el repositorio central.

Realice envíos atómicos

Recuerde que SVN le brinda la posibilidad de enviar más de un fichero en un solo commit. Por lo tanto, envíe todos los cambios relacionados en múltiples ficheros, incluso si los cambios se extienden a lo largo de varios directorios en un mismo commit. De esta manera, se logra que SVN se mantenga en un estado compatible antes y después del commit.

Recuerde asegurarse al enviar un cambio al repositorio central reflejar un solo propósito, el cual puede ser la corrección de un error de programación o bug, agregar una nueva funcionalidad al sistema, ajustes de estilo del código o alguna tarea adicional.

Separe los ajustes de formato de código de otros envíos

Ajustar el formato del código, como la sangría, los espacios en blanco, el largo de la línea incrementa considerablemente los resultados del diff, si usted mezcla los cambios asociados al ajuste de formato de código con otros estará dificultando un posterior análisis al realizar un svn diff.

Haga uso intensivo de la herramienta de seguimiento de errores

Trate en lo posible de crear enlaces bidireccionales entre el conjunto de cambios hechos en el repositorio de subversion y la herramienta de seguimientos de errores tanto como sea posible.

  • Trate de hacer una referencia al id o número del ticket al cual está dando solución desde su mensaje de registro o log previo a realizar el commit.
  • Cuando agregue información o responda a un ticket, ya sea para describir su avance o simplemente para cerrar el ticket, indique el número o números de revisión que atienden o responden a dichos cambios.

Indique en el registro de envío el resultado del merge

Cuando usted está enviando el resultado de un merge, asegúrese de indicar sus acciones en el registro de envío, tanto aquello que fue fusionado como los números de revisiones que fueron tomadas en cuenta. Ejemplo:

Fusión de las revisiones 10:40 de /branches/foo a /trunk.

Tenga claro cuando es oportuno crear una rama

Esto es un tema polémico. Sin embargo, dependiendo del proyecto en el que esté involucrado usted puede definir una estrategia o mezcla de ellas para manejar el desarrollo del proyecto. Generalmente puede encontrar lo siguiente:

Los proyectos que requieren un alto manejo y supervisión recurren a estrategias de siempre crear ramas, acá puede encontrarse que cada colaborador crea o trabaja en una rama privada para cada tarea de codificación. Cuando el trabajo individual ha finalizado, algún responsable, ya sea el fundador del proyecto, un revisor técnico, analiza los cambios hechos por el colaborador y hace la fusión con la línea principal de desarrollo. En estos casos la rama principal de desarrollo suele ser bastante estable. Sin embargo, este modo de trabajo conlleva normalmente a crear mayores conflictos en la etapa de fusión o merge, además, las labores de fusión bajo este esquema son constantemente requeridas.

Existe otro enfoque que permite mantener una línea base de desarrollo estable, el cual consiste en crear ramas de desarrollo solo cuando se ameritan. Sin embargo, esto requiere que los colaboradores tengan mayor dominio del uso de Subversion y una constante comunicación entre ellos. Además de aumentar el número de pruebas antes de cada envío al repositorio centralizado.

Estudie, analice las distintas opciones y defina un método para la creación de ramas en su proyecto. Una vez definido, es sumamente importante que cada colaborador tenga clara esta estrategia de trabajo.

Las estrategias antes mencionadas y otras más pueden verse en detalle en:

Los sistemas de control de versiones no substituyen la comunicación entre los colaboradores

Por último pero no menos importante, los sistemas de control de versiones no substituyen la comunicación entre los desarrolladores o colaboradores del proyecto de software. Cuando usted tenga planes de hacer un cambio que pueda afectar una cantidad de código considerable en su proyecto, establezca un control de cambios, haga un análisis de las posibles consecuencias o impacto de los mismos, difunda esta información a través de una lista de discusión (usted mantiene una lista de discusión para desarrolladores, ¿verdad?) y espere la respuesta, preocupaciones, sugerencias de los demás colaboradores, quizá juntos se encuentre un modo más eficaz de aplicar los cambios.

Referencias:

subversion: Recuperar cambios y eliminaciones hechas

Muchos compañeros de trabajo y amigos en general que recién comienzan con el manejo de sistemas de control de versiones centralizados, en particular subversion, regularmente tienen inquietudes en cuanto al proceso de recuperación de cambios una vez que han sido enviados al repositorio, así como también la recuperación de ficheros y directorios que fueron eliminados en el pasado. Trataré de explicar algunos casos en base a ejemplos para que se tenga una idea más clara del problema y su respectiva solución.

En el primero de los casos se tiene recuperar la revisión previa a la actual, suponga que usted mantiene un repositorio de recetas, una de ellas en particular es la ensalada caprese, por error o descuido añadió el ingrediente Mostaza tipo Dijón a la lista, si usted posee siquiera un lazo con italinos sabe que está cometiendo un error que puede devenir en escarnio público, desprecio e insultos.

~/svn/wc/trunk$ svn diff -r 2:3 ${URL}/trunk/caprese
Index: caprese
===================================================================
--- caprese	(revision 2)
+++ caprese	(revision 3)
@@ -7,3 +7,4 @@
  - Albahaca fresca
  - Aceite de oliva
  - Pimienta
+ - Mostaza tipo Dijon

Note que el comando anterior muestra las diferencias entre las revisiones 2 y 3 del repositorio, en el resumen se puede apreciar que en la revisión 3 ocurrió el error. Un modo rápido de recuperarlo es como sigue.

~/svn/wc/trunk$ svn merge -c -3 ${URL}/trunk/caprese
--- Reverse-merging r3 into 'caprese':
U    caprese

En este caso particular se están aplicando las diferencias entre las revisiones consecutivas a la copia de trabajo. Es hora de verificar que los cambios hechos sean los deseados:

~/svn/wc/trunk$ svn status
M      caprese
~/svn/wc/trunk$ svn diff
Index: caprese
===================================================================
--- caprese	(revision 3)
+++ caprese	(working copy)
@@ -7,4 +7,3 @@
  - Albahaca fresca
  - Aceite de oliva
  - Pimienta
- - Mostaza tipo Dijon

Una vez verificado enviamos los cambios hechos al repositorio a través de comando svn commit.

Seguramente usted se estará preguntando ahora que sucede si las revisiones del ficheros no son consecutivas como en el caso mostrado previamente. En este caso es importante hacer notar que la opción -c 3 es equivalente a -r 2:3 al usar el comando svn merge, en nuestro caso particular -c -3 es equivalente a -r 3:2 (a esto se conoce como una fusión reversa), substituyendo la opción -c (o --changes) en el caso previo obtenemos lo siguiente:

~/svn-tests/wc/trunk$ svn merge -r 3:2 ${URL}/trunk/caprese
--- Reverse-merging r3 into 'caprese':
U    caprese

Referencias: svn help merge, svn help diff, svn help status.

Recuperando ficheros o directorios eliminados

Una manera bastante sencilla de recuperar ficheros o directorios eliminados es haciendo uso de comando svn cp o svn copy, una vez determinada la revisión del fichero o directorio que desea recuperar la tarea es realmente sencilla:

~/svn-tests/wc/trunk$ svn cp ${URL}/trunk/panzanella@6 panzanella
A         panzanella

En este caso se ha duplicado la revisión 6 del fichero panzanella en la copia de trabajo local, se ha programado para su adición incluyendo su historial, esto último puede verificarse en detalle al observar el signo ‘+’ en la cuarta columna del comando svn status.

~/svn-tests/wc/trunk$ svn status
A  +   panzanella

Referencias: svn help copy, svn help status.

Charla: Subversion

El día de mañana, 23 de septiembre, desde las 11:00 a.m. hasta el mediodía, en el salón OS-02 (nivel sótano, cerca del cafetín de la facultad de ingeniería), sector La Hechicera, Nicolás Ruiz estará conversando acerca de subversion, el cual es un sistema de control de versiones de software.

Subversión es un sistema de control de versiones diseñado para la nueva generación de repositorios para desarrollo de software. Ha sido propuesto para reemplazar al tradicional CVS para el desarrollo de software libre, pero puede ser empleado para el registro sistemático de archivos de documentos y los llamados binarios, no solamente las fuentes de software. En esta charla conoceremos características importantes y poco visibles de la implantación y uso de subversion.

Por cierto, la entrada es libre y gratuita.

Estaré a partir de las 10:00 a.m. en el sitio de reunión, espero poder colaborar en algo. Ya para culminar, debo dar las gracias al profesor Jacinto Dávila por la invitación.