Esta entrada no pretende ser una guía completa de subversion, solo una guía rápida para comenzar a trabajar con esta potente herramienta.
Introducción
Muchos proyectos están migrando de Svn a Git ya que Git les aporta una serie de ventajas, principalmente que Git es distribuido (SVN es centralizado). Git parece ser claramente mejor para proyectos grandes y, sobre todo, con mucha gente.
La alternativa a svn+trac sería git+gitorious. Aunque Git parece ser mejor que Svn en algunos aspectos, trac sigue siendo mejor que gitorious.
Aquí tenemos una guía de Git para usuarios de svn.
Antes de empezar
Para organizar los proyectos se suele asumir por convenio crear tres directorios por proyecto:
- Trunk: Directorio de un repositorio bajo el cual se encuentran los directorios y ficheros de nuestro proyecto.
- Tag: Directorio bajo el cual se almacenan las diferentes versiones o releases de nuestro software.
- Branches: Directorio donde se almacenan ramas de nuestro proyecto (por ejemplo, para pruebas de concepto).
Las reglas de oro del trabajo con sistemas de versiones, son dos:
- Nunca harás un commit de código que no compile o tenga errores: Si lo haces, cuando otro programador haga un update su código también tendrá esos errores y por tanto no compilará.
- Siempre harás un update antes de empezar a trabajar sobre el código. De esta manera, te aseguras de estar trabajando siempre sobre la última versión del código.
Dicho esto queda recordar que subversion usa por defecto el puerto 3690.
Los comandos principales (hay más) de svn son:
- Status: Nos indica la situación de nuestra copia local respecto al proyecto en el repositorio.
- Import: Comando utilizado para subir al repositorio la estructura inicial de nuestro proyecto.
- Checkout (co): Comando para descargar en un PC un proyecto desde un repositorio.
- Update (up): Comando que nos permite actualizar nuestro proyecto en local desde el repositorio central.
- Add: Comando utilizado para añadir un fichero a nuestro proyecto. No es subido al repositorio hasta que se indique con el comando “commit”. El comando add solo deja “marcado” ese fichero o directorio como parte del repositorio.
- Delete: Comando que permita marcar un fichero o directorio para ser eliminado del respositorio.
- Commit (ci): Comando que nos permite subir al repositorio todos los cambios hechos sobre un proyecto en local.
- Log: Consulta el trabajo realizado con un repositorio
SERVIDOR SUBVERSION
Primero debemos instalar subversion:
# aptitude install subversion
Crear un repositorio
Generamos un directorio para el repositorio (gestionado por svn, el servidor)
$ mkdir repositorio
$ cd repositorio
Creamos un proyecto, para estos ejemplos usaremos un proyecto llamado “ANA”
$ svnadmin create ANA
Configuramos el acceso. Una configuración habitual es lectura a todo el mundo y escritura a los autorizados.
$ vi ANA/conf/svnserve.conf
[general] anon-access = read auth-access = write realm = My First Repository password-db = passwd
Generamos los usuarios con permiso de escritura. Las claves van en texto claro, por tanto deberíamos cuidar los permisos de este fichero.
$ vi ANA/conf/passwd
[users] harry = harryssecret sally = sallyssecret
Lanzamos el servidor
$ svnserve -d -r /path_de_repositorio/
El parámetro ‘-d’ hace que el servidor se ponga en modo “demonio”.
El parámetro ‘-r’ indica la ruta al repositorio. Si no usamos el parámetro -r, los clientes deben indicar siempre la ruta completa de la carpeta, con los problemas que conlleva de comodidad (ruta muy larga), seguridad (publicidad de la estructura de directorios) y administración (cambios en el sistema de archivos).
CLIENTE SVN
Para trabajar con un servidor mediante ssh:
SVN+SSH: Conectar con un servidor svn mediante ssh
Puesta en marcha
Importar un repositorio
Si trabajamos con un servidor preinstalado podemos, como clientes, crear proyectos a partir de unas fuentes pre-existentes mediante “import”:
$ svn import nuevoProyecto http://urlDelRepositorio/ -m “Importacion inicial”
Esto requiere de una configuración un poco más compleja en el servidor.
Creando un nuevo proyecto a partir de fuentes anteriores
En el equipo en que vamos a programar (puede ser el mismo que el servidor) generamos un directorio para la copia local -copia de trabajo- (las fuentes con que trabajamos)
$ mkdir copia_local
$ cd copia_local
Tomamos las fuentes del proyecto (CheckOut – co)
$ svn co svn://localhost/ANA
En la revisión 0.
Copiamos en el nuevo directorio los ficheros fuente del proyecto (si existían).
$ cd ANA
$ cp -R /ruta_fuentes_anteriores/* .
Añadimos los ficheros al proyecto
$ svn add *
Actualizamos la información local sobre los ficheros. Nos indica todos los ficheros que están marcados para ser añadidos al repositorio.
$ svn status
A fichero1 A fichero2 ... En la revisión 0.
Hacemos commit (ci) de las modificaciones y dejamos una nota o mensaje (-m)
$ svn ci -m “Importacion inicial”
Uso y disfrute
Lo primero que se debe hacer al empezar a programar es actualizar las fuentes (ver reglas de oro), para asegurarnos que disponemos de la última versión:
$ cd /ruta_copia_local/ANA
$ svn update
Al acabar (si el programa no compila no has acabado -ver reglas de oro-):
– Comprobamos los cambios que tenemos pendientes con:
$ svn status
– Hacemos los ajustes necesarios (svn add, svn delete… ver más adelante).
– Guardamos los cambios con un comentario indicando los cambios realizados.
$ svn ci -m “Cambios blablablabla”
Veamos algunas de las funciones más habituales.
Añadir ficheros
Ya hemos visto en la importación como añadir ficheros, pero lo vamos a volver a ver con un poco más de detalle.
Generamos un nuevo fichero:
$ touch kk
Consultamos la información de los ficheros locales
$ svn status
? kk
La única diferencia con el repositorio es que hay un fichero kk que no conoce
Añadimos el fichero kk al proyecto
$ svn add kk
A kk
Consultamos la información de los ficheros locales
$ svn status
A kk
La única diferencia con el repositorio es que hay un fichero kk por añadir
Hacemos commit (ci) del fichero y dejamos una nota o mensaje (-m)
$ svn ci -m “Prueba add kk”
Añadiendo kk Transmitiendo contenido de archivos . Commit de la revisión 1.
Modificar ficheros
Modificamos el fichero de prueba
$ vi kk
Consultamos la información de los ficheros locales
$ svn status
M kk
La única diferencia con el repositorio es que hay un fichero kk por modificar
Podemos ver las diferencias entre el fichero local y el del repositorio
$ svn diff kk
Index: kk =================================================================== --- kk (revisión: 1) +++ kk (copia de trabajo) @@ -1,2 +1,3 @@ #Llalala +#lilililili #lelele
Hacemos commit (ci) del fichero y dejamos una nota o mensaje (-m)
$ svn ci -m “Prueba kk modificado”
Commit de la revisión 2.
Consultamos la información de los ficheros locales
$ svn status
No hay diferencias con el repositorio
Conflictos con ficheros
Si existen varios desarrolladores, puede ocurrir un conflicto al “subir” un fichero que haya sido modificado desde que hicimos el update.
$ svn ci -m “Forzamos conflicto”
Enviando kk svn: Falló el commit (detalles a continuación): svn: Desactualizado: 'kk' en transacción '5-1'
$ svn status
M ejemplo2.py
Podemos abreviar ‘update’ como ‘up’
$ svn up
C ejemplo2.py Actualizado a la revisión 3.
Al encontrar el conflicto, SVN genera 4 ficheros, uno con el conflicto, el local, el de la revisión anterior (r2) y el de la nueva revisión (r3).
$ ls -l
... -rw-r--r-- 1 guimi guimi 111 2007-07-09 19:51 kk -rw-r--r-- 1 guimi guimi 49 2007-07-09 19:51 kk.mine -rw-r--r-- 1 guimi guimi 29 2007-07-09 19:51 kk.r2 -rw-r--r-- 1 guimi guimi 57 2007-07-09 19:51 kk.r3
Tras corregir el conflicto, indicamos que lo hemos resuelto:
$ vi kk
$ svn resolved ejemplo2.py
Se resolvió el conflicto de 'ejemplo2.py'
Al marcar el conflicto como resuelto, SVN borra los ficheros de resolución.
Volvemos a realizar el commit.
$ svn ci -m “Conflicto resuelto”
Borrar ficheros
Probamos a borrar un fichero de nuestro disco duro
$ rm kk
Consultamos la información de los ficheros locales
$ svn status
! kk
La diferencia con el repositorio es que localmente falta un fichero
Si actualizamos la información del repositorio…
$ svn update
Se restituyó 'kk' En la revisión 2.
…recuperamos el fichero borrado.
Para eliminar un fichero del proyecto debemos indicar al sistema que lo elimine del repositorio.
Quitamos un fichero del proyecto (y lo borramos de nuestro disco duro)
$ svn delete kk
Quitamos otro fichero del repositorio, pero mantenemos la copia local
$ svn delete –keep-local kk2
Consultamos la información de los ficheros locales
$ svn status
D kk D kk2
La única diferencia con el repositorio es que hay dos fichero por eliminar.
Hacemos commit (ci) de las modificaciones y dejamos una nota o mensaje (-m)
$ svn ci -m “Borrado de ficheros”
Eliminando kk Eliminando kk2 Commit de la revisión 3.
Renombrar ficheros
$ svn mv kk ejemplo
A ejemplo D kk
$ svn status
D kk A + ejemplo
$ svn commit –message “Cambio de nombre”
Eliminando ejemplo1.py Añadiendo ejemplo2.py Commit de la revisión 3.
Consultar el trabajo realizado
Vemos todo el trabajo que hemos realizado
$ svn log
------------------------------------------------------------------------ r4 | guimi | 2012-02-07 20:52:05 +0100 (mar 07 de feb de 2012) | 1 line Prueba del kk ------------------------------------------------------------------------ r3 | guimi | 2012-02-07 20:51:39 +0100 (mar 07 de feb de 2012) | 1 line Prueba add kk ------------------------------------------------------------------------ r2 | guimi | 2012-02-07 20:39:46 +0100 (mar 07 de feb de 2012) | 1 line Prueba ------------------------------------------------------------------------ r1 | guimi | 2012-02-07 20:33:02 +0100 (mar 07 de feb de 2012) | 1 line Importacion inicial ------------------------------------------------------------------------
podemos consultar el trabajo que hemos realizado respecto a un fichero concreto, por ejemplo AndroidManifest.xml
$ svn log AndroidManifest.xml
------------------------------------------------------------------------ r1 | (sin autor) | 2012-02-07 20:33:02 +0100 (mar 07 de feb de 2012) | 1 line Importacion version inicial 0.1.5-Beta ------------------------------------------------------------------------