Usando darcs en aleph

Introducción

Este pequeño documento habla de cómo usar darcs de forma práctica, y cómo almacenar el/los repositorios en aleph (aunque en realidad sirve para cualquier cuenta ssh pública, como la provista por sourceforge.net, cualquier GForge o lugares por el estilo).

Vamos a asumir que se conoce un poquito de darcs, y se está algo familiarizado con Linux o algún sistema tipo UNIX, dado que lo que vamos a mostrar es bastante específico a esos sistemas operativos desde allí (aunque si usan aleph no debería resultarles demasiado loco).
Para los que usan Windows, si se dan un mínimo de maña muchas de las cosas (si no todas) las deberían poder hacer utilizando Cygwin e instalando los programas correspondientes (que están todos).

Hay muchas formas distintas de hacer lo que nosotros mostramos acá, cada una con sus ventajas y desventajas, y en la mayoría de los casos es una cuestión de preferencia cual usar. Como éste es un documento práctico, no se van a hacer salvedades mostrando las maneras alternativas o justificando las elecciones mas allá de donde se crea necesario; cualquier aclaración de esta índole por favor preguntar directamente a los autores.

Momento! Qué es aleph?

aleph es un servidor de la facultad que provee distintos servicios. Cualquier persona con una cuenta de e-mail de la facultad tiene acceso a aleph y sus servicios, entre los cuales está tanto ssh como ftp, cosas que serán muy útiles para poder montar un repositorio público de darcs, ya que se provee acceso web sobre todo el contenido almacenado en el directorio public_html del usuario.

Plan de trabajo

Antes de empezar a mostrar comandos, pensemos primero bien como vamos a trabajar. Nuestra idea es dar un caso de uso de un grupo de personas que están desarrollando sobre el mismo proyecto (caso típico de un TP grupal), y que quieren usar darcs como SCM distribuido para coordinar y administrar su código y/o documentación.

Lo primero que vamos a plantear es que cada persona tenga su propio repositorio, además de haber una encargada de tener y administrar el repositorio para entregar.
Cada integrante generara cambios sobre su propio repositorio, y luego serán incorporados al repositorio para entregar de dos maneras: o enviándole por mail los mismos al responsable, o avisándole que haga un pull del repositorio personal. Por esto, al menos el repositorio para entregar debe ser disponible públicamente, para que los integrantes del grupo puedan sincronizar con el.

Publicando un repositorio en aleph

Hoy en día, aleph no tiene el darcs instalado (ya hemos solicitado que lo instalen pero no nos dieron bola, tal vez si mandás un mail pidiéndolo se dan cuenta que es necesario y lo agregan =), por lo que no podremos manipular repositorios directamente en el. En su lugar, deberemos trabajar en cualquier maquina que lo tenga instalado (en nuestras casas podemos usar Fiubbix de no tener Linux, aunque seria lo mas recomendable; o sino usando las compus disponibles en el LABI, en el primer piso, que todas las del L4 cuentan con darcs).
El hecho de que sea distribuido nos da una enorme ventaja, que es que podemos usar cualquier compu con darcs para desarrollar, no importa si tiene el código ahí o no, puesto que lo que hacemos es clonar el repositorio que publicamos en aleph, trabajar localmente y luego enviamos los cambios según haga falta.

Así que ahora que estamos convencidisimos de que lo necesitamos, vamos a ver como publicar un repositorio en aleph. Vamos a pensar que ya tenemos el repositorio creado, mas o menos con la siguiente estructura jerárquica:

tp1/
    repos/
        tp1-alberto/
	    _darcs/
	    archivo1
	    archivo2
	    ...

Lo que nosotros queremos hacer es poder publicar nuestro repositorio, que acá llamamos tp1-alberto (yo me llamo Alberto, por eso lo llamo así) en aleph.

Para esto, creamos un directorio ~/public_html/repos en el cual vamos a poner nuestros repositorios. El nombre ~/public_html es importante porque ahí es donde están los archivos que se publicaran en nuestra pagina personal de aleph. Entonces, en aleph, hacemos:

[usuario@aleph usuario]$ mkdir -p ~/public_html/repos
[usuario@aleph usuario]$

Ahora queremos copiar nuestro directorio tp1-alberto a ~/public_html/repos/, para lo cual hay muchos mecanismos. Acá vamos a usar uno que se llama rsync, porque se basa en un programa que se llama así, que esta incluido en todas las distribuciones conocidas (y no tanto) de Linux, y en aleph.

Lo que hace rsync es copiar por la red un directorio de un origen a un destino, con la característica especial que en lugar de pasar tooooodo cada vez, si en el destino ya existe algo, solo copia lo que hace falta para dejarlo igualito al origen. Esto optimiza bastante el tiempo que tardamos en copiar, y resulta muy piola para lo que queremos hacer.

En caso de no disponer rsync se puede usar ftp (o incluso scp) para subir las cosas, con la obvia desventaja de tener que copiar todo entero cada vez.

Entonces, para enviar el repositorio, corremos en nuestra compu:

compu$ cd tp1/repos
compu$ rsync --rsh=ssh -vrzltP --delete tp1-alberto alberto@aleph.fi.uba.ar:./public_html/repos/
Nos pide nuestra clave para entrar a aleph
Password:
Acá nos muestra que cosas copia
[...]
compu$

Los primeros cuatro parámetros modifican cosas particulares de la copia que no vamos a detallar por ser cosas especificas de rsync. Así como esta anda, y si les interesa saber mejor que es cada una (es una buena idea) pueden consultar el manual del rsync. Después viene el directorio origen, en este caso tp1-alberto, y el destino, incluyendo el usuario, de la forma: usuario@server:directorio_remoto. En nuestro ejemplo, el usuario seria alberto, el server aleph.fi.uba.ar y el directorio ./public_html/repos.

Con esto copiamos el repositorio local a aleph, haciendo que este públicamente disponible en http://www.fi.uba.ar/~alberto/repos/tp1-alberto/.

Como vemos, la linea del rsync es bastante larga, fea y difícil de recordar, por lo que además de recurrir a esta pagina si no se la acuerdan, pueden armarse un script que ejecute eso por ustedes. Yo suelo ponerlo en el directorio repos, y llamarlo update.

Entonces, redondeando, lo que vamos a hacer, en lugar de trabajar en aleph directamente, siempre es trabajar sobre un repositorio local, y enviarlo a aleph periódicamente para que puedan verlo los demás o bajarlo nosotros si nos cambiamos de maquina, que era lo que buscábamos en un principio.

Haciendo cosas con nuestro repositorio

Ahora que el repositorio es accesible públicamente, vamos a ver un par de cosas que podemos hacer con el.

Para empezar, vamos a ver como clonarlo, cosa que puede ser útil en muchas circunstancias, por ejemplo si estando en la facu se nos ocurre una idea re copada para implementar, entonces salimos corriendo al LABI, nos sentamos en una compu de la L4 y queremos traernos nuestro repositorio para desarrollar.

Esto lo hacemos con el comando:

compu$ darcs get http://www.fi.uba.ar/~alberto/repos/tp1-alberto
Copying patch 23 of 23... done!
Applying patches to the "working" directory...
..............................................
Finished getting.
compu$

Ahí vamos a tener en el directorio tp1-alberto un clon del repositorio publicado. Ahora en nuestro rapto de inspiración hacemos algunos cambios con sus correspondientes records, y nos damos cuenta que teníamos que estar en clase hace 20 minutos, por lo que queremos enviar estos cambios de nuevo a aleph, para no perderlos. Entonces, simplemente, volvemos a hacer el rsync como hicimos antes:

compu$ rsync --rsh=ssh -vrzltP --delete tp1-alberto alberto@aleph.fi.uba.ar:./public_html/repos/
Password:
[...]
compu$

Vamos a ver que copia muchos menos archivos, puesto que solo va a copiar lo que nosotros modificamos.

También pueden poner el script update en, por ejemplo, ~/public_html/repos/update de manera tal de poder bajarlo en la PC y ejecutarlo, para no tener que recordar toda esa línea de comandos.

Esto también lo usamos cuando desarrollamos en nuestra casa, después de que hacemos records localmente y estamos satisfechos con como va quedando nuestro repositorio, podemos ir actualizando el que tenemos en aleph por si nuestros compañeros lo quieren ir chusmeando, o si queremos que el responsable del repositorio para entregar (a quien vamos a llamar Reinaldo, de REsponsable) incorpore alguno de nuestros cambios.

Haciendo cosas con los demás

Ahora supongamos que queremos integrar en nuestro repositorio local los cambios que introdujo Reinaldo en el repositorio para entregar; o sea, que vamos a hacer un pull del suyo, que lo tiene en http://www.fi.uba.ar/~reinaldo/repos/tp1-entrega, con
compu$ darcs pull http://www.fi.uba.ar/~reinaldo/repos/tp1-entrega

Una vez que nosotros hayamos publicado nuestro repositorio, le podemos pedir a Reinaldo que incorpore nuestros cambios al repositorio para entregar, entonces el tendría que correr

reinaldo$ darcs pull http://www.fi.uba.ar/~alberto/repos/tp1-alberto

Siempre hay que acordarse que cuando queremos que los cambios de nuestro repositorio se hagan visibles y públicos tenemos que sincronizarlo con aleph, como ya mostramos. Por eso, en el ejemplo de recién, cuando Reinaldo haya terminado de incorporar los cambios nuestros en el repositorio de el, seria conveniente que sincronice para que los otros compañeros nuestros puedan enterarse e incorporar los cambios cuando hagan un pull de Reinaldo.

También es importante que nosotros sincronicemos con Reinaldo de forma periódica, así siempre estamos trabajando con una base actualizada y similar a la que se va a entregar. Además, muchas veces nos interesa poder revisar lo que hicieron nuestros compañeros, o construir sobre ello. Por eso es bueno que Reinaldo vaya avisando al grupo por mail u otro mecanismo a medida que va incorporando cosas, para que todos se enteren como van los demás, y sepan que conviene hacer un pull.

Pasando los cambios por email

En lugar de avisarle a Reinaldo que haga un pull de nuestro repositorio, podemos pasarle los cambios por mail si nos queda mas cómodo (quizás los que usan Windows pueden preferir este mecanismo). Para ello vamos a usar el comando darcs send que envía un mail directamente o, si le pasamos un parámetro, nos da un archivo para que podamos adjuntar. Luego, quien lo reciba usara darcs apply para incorporar los cambios a su repositorio.

Vamos a ver primero como hacer para obtener el archivo que debemos adjuntar. Nuestro objetivo es obtener un archivo adjunto con los cambios que estén en nuestro repositorio pero no en el de Reinaldo. Para hacer esto, corremos:

compu$ darcs send -o /tmp/para_reinaldo http://www.fi.uba.ar/~reinaldo/repos/tp1-entrega
Acá nos pregunta uno por uno que cambios queremos enviar y
cuales no, ajustando automáticamente los que dependen entre si.
[...]
compu$
Luego, usamos nuestro programa de mail para enviarle a Reinaldo el archivo /tmp/para_reinaldo. Una vez enviado podemos borrar el archivo tranquilamente, dado que no se usa para nada mas que para esto, no tiene referencias al repositorio ni nada por el estilo.

Ahora que sabemos como mandarle los cambios, vamos a ver como hacemos para, cuando nos mandan cambios a nosotros, incorporarlos en nuestro repositorio.

Supongamos que nos llego el mail con el archivo adjunto, el cual grabamos en /tmp/para_aplicar. Entonces vamos a nuestro repositorio y le decimos al darcs que incorpore los cambios que están en ese archivo, con el comando:

compu$ darcs apply /tmp/para_aplicar
Finished applying...
compu$
Y listo! Esos cambios fueron incorporados (y ya podemos borrar /tmp/para_aplicar).