User Tools

Site Tools


informatica:linux:subversion

subversion svn control de versiones svnserve commit update merge

Subversion

Programa de cotrol de versiones.

http://svnbook.red-bean.com/nightly/en/index.html

Primeros pasos

En este ejemplo mostramos cómo poner en marcha 1 repositorio en subversion con 2 proyectos colgando del mismo.

1. Instalar subversion:

aptitude install subversion

2. Creamos el repositorio:

svnadmin create /home/repositorio_varios_proyectos/ 

3. Creamos la siguiente estructura para importar el primer proyecto:

/tmp/proyecto_1/trunk
/tmp/proyecto_2/branches
/tmp/proyecto_2/tags

4. Copiamos (si ya existen previamente) todos los ficheros del proyecto a importar al siguiente destino:

cp /ruta/proyecto /tmp/proyecto_1

5. Importamos el proyecto:

svn import /tmp/proyecto_1 file:///home/repositorio_varios_proyectos/proyecto_1 -m "Ingesta inicial"

6. Creamos el directorio donde bajar la copia de trabajo:

mkdir /home/proyecto_1

7. 'Descargamos' la última de ese proyecto del repositorio. Eso será nuestra copia de trabajo:

svn checkout file:///home/repositorio_varios_proyectos/proyecto_1/trunk

8. Tareas de ordenación

cd /home/proyecto_1/trunk
mv * ..
mv \.svn ..
cd ..
rm -fr trunk

9. Repetir los pasos 3-8 sustituyento 'proyecto_1' por 'proyecto_2'

Ciclo de trabajo

0. Descargar una copia de trabajo

  • svn co

1. Actualizar la copia de trabajo

  • svn update

2. Realizar cambios

  • svn add
  • svn delete
  • svn copy
  • svn move

3. Examinar cambios

  • svn status

Para ver los cambios de la copia local respecto al repositorio:

  • svn status –show-updates
  • svn diff

4. (Opcional) revertir cambios realizados

  • svn revert

5. Resolver conflictos (mezclar con otros cambios…)

  • svn update
  • svn resolve

6. Subir cambios al repositorio

  • svn commit

Conocer la estructura del repositorio

ANTECEDENTES

Tenemos un repositorio de subversion con varios proyectos y no recordamos ni la ruta completa ni los nombres de los distintos proyectos albergados en el repositorio

SOLUCIÓN

1. Crear un directorio de prueba:

mkdir /tmp/prueba

2. Meterse en él

cd /tmp/prueba

3. Descargar el repositorio entero. En mi caso mediante el acceso desde la misma máquina que alberga el repositorio:

svn co file:///ruta/repositorio_varios_proyectos/

4. Para listar los proyectos:

ls -la /tmp/prueba/repositorio_varios_proyectos

Subversion y apache

Apache >=2.4.x y subversion >=1.8.x

http://svnbook.red-bean.com/en/1.8/svn.serverconfig.httpd.html

1. Instalar paquetes

sudo aptitude update; sudo aptitude install apache2 subversion libapache2-svn

2. Habilitar módulo de apache:

sudo a2enmod dav
sudo a2enmod dav_lock
sudo a2enmod dav_fs

3. Reiniciar apache

sudo service apache2 restart

4. Crear una config de apache:

sudo vim /etc/apache2/conf-available/svn.conf

Con el siguiente contenido:

<Location /svn>
  DAV svn
  # Automatically map any "/svn/foo" URL to repository /var/svn/foo
  SVNParentPath /var/svn
</Location>

5. Ajustar permisos:

sudo chown -R www-data:root /var/svn

6. Cargar config de apache:

sudo a2enconf svn
sudo service apache2 reload

7. Probar:

http://svn.example.com/svn/project_1

Deberia ir a:

/var/svn/project_1

Apache <=2.2.x y subversion <=1.7.x

http://svnbook.red-bean.com/en/1.4/svn.serverconfig.httpd.html

Prerrequisitos:

1. Apache 2

aptitude install apache2 subversion libapache2-svn

2. Habilitar módulo mod_dav de apache:

http://httpd.apache.org/docs/2.0/mod/mod_dav.html

Forma elegante:

a2enmod dav
a2enmod dav_lock
a2enmod dav_fs

No es necesario:

a2enmod dav_svn

Al estilo compadre:

ln -s /etc/apache2/mods-available/dav.load /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/dav_lock.load /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/dav_fs.load /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/dav_fs.conf /etc/apache2/mods-enabled/

Reiniciar apache

apache2ctl restart

Para comprobar que los módulos están cargados, un phpinfo();

3. Editar httpd.conf y añadirle:

<Location /mi_repositorio>
  DAV svn
  SVNPath /ruta/abosulta/al/repositorio
</Location>

4. Reiniciar apache

apache2ctl restart

5. Cambiar los permisos para que el usuario www-data pueda acceder al repositorio de subversion, y así se puedan subir los cambios al repositorio:

chown -R www-data:root /ruta/abosulta/al/repositorio

EJEMPLO:

tenemos:

/home/usuario/repositorio_varios_proyectos

Y dentro de ese repositorio, 'proyecto_1'

/etc/apache2/httpd.conf así:

<Location /repositorio_varios_proyectos>
  DAV svn
  SVNPath /home/usuario/repositorio_varios_proyectos
</Location>

Para descargarnos una copia local de ese proyecto_1:

svn checkout http://localhost/repositorio_varios_proyectos/proyecto_1

Proteger repositorio usando contraseña

Vamos a mostrar dos aproximaciones:

A) UN SOLO USUARIO

B) UN GRUPO DE USUARIOS POR PROYECTO

En ambos casos damos por hecho que la máquina solo contiene un repositorio de subversion, pues en caso contrario la directiva 'SVNPath' debería ser 'SVNParentPath'.

A) UN SOLO USUARIO

Para proteger el repositorio de subversion con un usuario y una contraseña:

1. Crear un usuario:

(Si no existe un fichero de contraseñas de apache)

sudo htpasswd -c /ruta/fichero/contrasenyas mi_usuario

(Si ya existe)

sudo htpasswd /ruta/fichero/contrasenyas mi_usuario

2. Teclear 2 veces la contraseña

3. Editar /etc/apache2/httpd.conf y dejarlo tal que así:

<Location /mi_repositorio>
  DAV svn
  SVNPath /ruta/abosulta/al/repositorio
  AuthType Basic
  AuthName "Usuario y contrasenya para el repositorio de subversion"
  AuthUserFile /ruta/fichero/contrasenyas
  Require user mi_usuario
</Location>

4. (No sé si es necesario, supongo que si) apache2ctl restart

Para probar que funciona:

svn co --no-auth-cache --username mi_usuario http://localhost/mi_repositorio/proyecto_1
Reino de autentificación: <http://localhost> Usuario y contrasenya para el repositorio de subversion
Clave de 'mi_usuario': 

POSIBLES ERRORES

svn: El servidor envió un valor de devolución inesperado (500 Internal Server Error) en respuesta al requerimiento OPTIONS para 'http://localhost/mi_repositorio/proyecto_1'

Solución:

Verificar que la directiva AuthUserFile de /etc/apache2/httpd.conf coincide con la ruta al fichero de contraseñas que hemos usado para crear ese usuario (ver paso 1)

B) UN GRUPO DE USUARIOS POR PROYECTO

1. Creamos un par de usuarios:

(Si no existe un fichero de contraseñas de apache)

sudo htpasswd -c /ruta/fichero/contrasenyas usuario_1
sudo htpasswd /ruta/fichero/contrasenyas usuario_2

(Si ya existe)

sudo htpasswd /ruta/fichero/contrasenyas usuario_1
sudo htpasswd /ruta/fichero/contrasenyas usuario_2

2. Editar:

sudo vim /etc/apache2/httpd.conf

Y dejarlo tal que así:

ServerName localhost

<Location /subversion>
        DAV svn
        SVNPath /home/repositorio_varios_proyectos
        # our access control policy
        AuthzSVNAccessFile /ruta/fichero/reglas_subversion

        # only authenticated users may access the repository
        Require valid-user

        # how to authenticate a user
        AuthType Basic
        AuthName "Repositorio subversion"
        AuthUserFile /ruta/fichero/contrasenyas
</Location>

3. Grabar el archivo y salir

4. Crear el archivo de reglas:

sudo vim /ruta/fichero/reglas_subversion

Con el siguiente contenido:

[/proyecto_1]
@administradores = rw

[/proyecto_2]
@usuarios = rw

[groups]
administradores = usuario_1
usuarios = usuario_1,usuario_2

5. Grabar y salir. NO es necesario reiniciar apache

6. Probar:

svn co --no-auth-cache --username usuario_1 http://servidor.mine.nu/subversion/proyecto_1
svn co --no-auth-cache --username usuario_1 http://servidor.mine.nu/subversion/proyecto_2
svn co --no-auth-cache --username usuario_2 http://servidor.mine.nu/subversion/proyecto_1
svn co --no-auth-cache --username usuario_2 http://servidor.mine.nu/subversion/proyecto_2

El tercer comando NO debería funcionar, pues 'usuario_2' no tiene acceso a 'proyecto_1'

Acceder a repositorio de subversion desde dentro de un proxy

ANTECEDENTES

Queremos acceder a un repositorio de Subversion que está configurado con Apache desde una máquina que está dentro de un cortafuegos.

Como toda conexión http, requerirá pasarle el usuario y la contraseña del proxy

SOLUCIÓN

1. nano /home/mi_usuario/.subversion/servers

2. Añadir las siguientes lineas:

http-proxy-host = mi_proxy
http-proxy-port = puerto_proxy
http-proxy-username = usuario_proxy
http-proxy-password = contrasenya

3. Grabar y salir

4. Probar:

svn co http://url/repositorio/subversion/proyecto

Acceder a repositorio vía svn

0. Previo: mapear el puerto 3690 TCP del router (si lo hubiera) al servidor

(A partir de aquí como 'root')

1. Creamos el fichero de configuración:

mkdir /etc/subversion/conf
nano /etc/subversion/conf/svnserve.conf

Con el siguiente contenido:

[general]
password-db = contrasenyas
realm = "Repositorio subversion vía svnserve"

# No se permite la conexión de usuarios anónimos
anon-access = none

# Los usuarios autentificados pueden leer y escribir
auth-access = write

2. Grabamos y salimos

3. Creamos el fichero de contraseñas:

nano /etc/subversion/conf/contrasenyas

Con el siguiente contenido:

[users]
mi_usuario = contrasenya

4. Grabamos y salimos

5. Damos permisos:

chmod 600 /etc/subversion/conf/svnserve.conf /etc/subversion/conf/contrasenyas

6. Arrancamos el servidor:

svnserve -d --config-file=/etc/subversion/conf/svnserve.conf -r /home/repositorio_varios_proyectos&

7. Para acceder:

svn co --no-auth-cache --username mi_usuario svn://ip_maquina_repositorio/proyecto_1/trunk

POSIBLES ERRORES

  • svn: La conexión de red se cerró inesperadamente

El servidor svnserve no está levantado y/o no está mapeado el puerto

Si se quieren añadir nuevos usuarios:

1. Editar el archivo de contraseñas:

nano /etc/subversion/conf/contrasenyas

2. Anyadir la nueva entrada debajo del bloque '[users]':

[users]
mi_usuario = contrasenya
mi_usuario_2 = contrasenya_2

3. Matar el proceso actual de svnsserve:

ps ax | grep svnserve
3038 ?        Ss     0:00 svnserve -d --config-file=/etc/subversion/conf/svnserve.conf -r /mnt/disco_1/datos/repositorio_varios_proyectos
kill -9 3038

4. Volver a arrancar snvserve:

svnserve -d --config-file=/etc/subversion/conf/svnserve.conf -r /mnt/disco_1/datos/repositorio_varios_proyectos&

Acceder a repositorio vía svn+ssh

No requiere tener levantado svnserve. Basta con:

svn co --no-auth-cache svn+ssh://usuario@ip_servidor_subversion/var/subversion/proyecto_1/trunk

Donde '/var/subversion' es la ruta completa al repositorio de subversion. Pedirá usuario y contraseña de una cuenta de usuario de la máquina donde esté ubicado el repositorio de subversion

Información del repositorio

ANTECEDENTES

Tenemos un repositorio de subversion con varios proyectos y no recordamos ni la ruta completa ni los nombres de los distintos proyectos albergados en el repositorio

SOLUCIÓN

1. Crear un directorio de prueba:

mkdir /tmp/prueba

2. Meterse en él

cd /tmp/prueba

3. Descargar el repositorio entero. En mi caso mediante el acceso desde la misma máquina que alberga el repositorio:

svn co file:///ruta/repositorio_varios_proyectos/

4. Para listar los proyectos:

ls -la /tmp/prueba/repositorio_varios_proyectos

ANTECEDENTES

Tenemos una copia local de un proyecto, pero no recordamos de qué repositorio depende

SOLUCIÓN

1. cd /ruta/copia_local

2.

svn info | grep URL
URL: http://mi_url/subversion/proyecto_1/trunk

Ramas

NOTA Para que el comando 'svn merge' funcione, es necesario que cliente y servidor tengan la versión 1.5+

Normalmente los proyectos de subersion siguen el siguiente estándar:

/proyecto_1/trunk
/proyecto_1/branches
/proyecto_1/tags

Supongamos el siguiente esquema:

/proyecto_1/trunk/file.txt
/proyecto_1/branches
/proyecto_1/tags

Supongamos que siempre queremos que en '/trunk' esté una versión estable del proyecto, por ejemplo la '0.6'.

Ahora queremos empezar a trabajar en la versión 0.7, para que una vez finalizada, la reintegremos al tronco.

PROCEDIMIENTO

Crear una rama:

1. En el pc cliente:

svn copy http://mi_repositorio/proyecto_1/trunk \
http://mi_repositorio/proyecto_1/branches/version_0_7 \
-m "proyecto1 - creo rama branches/version_0_7"

2. (En el pc 'cliente') Descargamos una copia de trabajo del proyecto:

svn co http://mi_repositorio/proyecto_1/

3. Trabajo en file.txt:

cd branches/version_0_7
vim file.txt

4. Subo los cambios:

svn commit -m "proyecto1 - branches/version_0_7 cambio 1"

5. Sigo trabajando en file.txt:

cd branches/version_0_7
vim file.txt

6. Subo los cambios:

svn commit -m "proyecto1 - branches/version_0_7 cambio 2"

7. Si ahora quiero mezclar branches/version_0_7 → trunk tengo que buscar la revision en la que cree la rama:

svn log --verbose --stop-on-copy http://mi_repositorio/proyecto_1/branches/version_0_7

Tomar la ultima revision, por ejemplo supongamos que es la 23

8. Ir a trunk y ver la revision actual:

cd ../../trunk
svn info

Supongamos que es la 25

9. Mezclar

svn merge -r 23:25 http://mi_repositorio/proyecto_1/branches/version_0_7

10. Actualizar repositorio

svn commit -m "proyecto1 - mezclado branches/version_0_7 -> trunk"

11. Comprobar los cambios

mkdir /tmp/aux2
cd /tmp/aux2
svn co http://mi_repositorio/proyecto_1/trunk
cd trunk
vim file.txt

http://svnbook.red-bean.com/en/1.1/ch04s04.html

Mezclando ramas

Supongamos el siguiente esquema:

http://mi_repositorio/proyecto_1/trunk
http://mi_repositorio/proyecto_1/branches/version_1_0

Estamos trabajando en la version 1.0, pero nos consta que paralelamente se están resolviendo errores menores en la versión 'estable', alojada en 'trunk'. Periódicamente nos debemos traer a 'branches/version_1_0' los cambios que se hayan podido producir en 'trunk'. Para ello:

0. (Opcional) Configurarnos un editor externo para poder ver los cambios con mayor comodidad

1. Nos metemos en el interior de la copia de trabajo donde reside 'branches/version_1_0':

cd /directorio/local/branches/version_1_0

2. Lanzamos el comando para traernos los cambios desde 'trunk':

svn merge   http://mi_repositorio/proyecto_1/trunk

Nos irán apareciendo una serie de ficheros que entran en conflicto. Sistemáticamente:

2.1 Editar el fichero: 'e' + 'enter'

Si hemos seguido el paso 0, se debería de haber abierto un editor externo, en el ejemplo 'scite' con el contenido. La sintaxis es básica (no es textual):

<<<<<<<< branches
$V = $A + $C;
========
$V = $A + $C - $D;
>>>>>>>> trunk

Debemos pues ver las dos versiones, la nuestra (entre '«««<' y '======') y la de 'trunk' (entre '=======' y '»»»'). Puede aparecer varias veces a lo largo del mismo fichero, una por cada cambio que subversion detecte.

Depuramos el código, grabamos y cerramos la ventana.

2.2 A la pregunta que nos hace: 'r' + 'enter'

Así el mismo ciclo hasta concluir con todos los cambios.

3. Subir los cambios al repositorio 'branches/version_1_0':

scn commit -m "Versión 1.0 actualizada con los cambios de trunk"

Editor externo

Para que en lugar de vim o nano nos abra otro editor:

(Con el usuario con el que se esté operando en la copia de trabajo)

1. Exportar la variable:

export SVN_EDITOR="/usr/bin/scite"

NOTA: como toda variable global, se vacía al cerrar sesión

Ignorar cambios en directorios

Cuando en symfony creamos un proyecto se crea una estructura de directorios, entre los cuales encontramos:

/cache
/log

Cuando se ejecuta ese proyecto, es decir, las páginas web que contiene, el motor de symfony va escribiendo archivos en esos directorios.

Supongamos que nosotros NO queremos ni subir ni descargar esos archivos:

1. (Desde dentro de la copia de trabajo) Actualizamos por si las moscas:

svn update

2. Eliminamos de subversion los archivos contenidos en esos directorios:

svn remove cache/*
svn remove log/*

3. Subimos los cambios al repositorio:

svn co -m "Borrados cache/ y log/"

4. Eliminamos de nuestra copia de trabajo esos archivos:

rm -fr cache/* log/*

5. Ignoramos esos directorios mediante el uso de propiedades:

svn propedit svn:ignore cache/

Se nos abrirá un editor de textos.

6. Tecleamos el contenido del archivo, que en este caso es todos los archivos:

7. Guardamos y salimos

Repetir los pasos 5-7 sustituyendo 'cache' por 'log'

8. Subimos los cambios al repositorio:

svn commit -m "Ignorados cache/ y log/"

Borrar un directorio del repositorio

1. (Como root)

svn delete file://ruta/repositorio/proyecto/trunk/dir_1

Copia de seguridad

svnadmin hotcopy /ruta/mi/repositorio /ruta/repositorio_copia_seguridad

Teóricamente después se puede mover/ruta/repositorio_copia_seguridad como un directorio más en otra máquina, y configurando su acceso:

  • svn:… Ya tenemos el mismo repositorio levantado Para exportar el repositorio (útil cuando hay conflictos de versiones): svnadmin dump /ruta/repositorio > volcado_repositorio.dbd Para importarlo: svnadmin create /ruta/nuevo_repositorio svnadmin load /ruta/nuevo_repositorio < volcado_repositorio.dbd ===== Errores ====== *svn: Error analizando parámetros *svn: Could not open the requested SVN filesystem *svn: Server sent unexpected return value (403 Forbidden) in response to OPTIONS request for 'http://peluca.mine.nu/subversion/facsimile' *svn: Se esperaba un formato de FS entre 1 y '3', se encontró '4' Se está intentando acceder a un repositorio de una versión de subversión posterior (1.6) a la instalada (1.5). Solución: 1. Desde una máquina con una versión de subversión igual a la del repositorio (1.6): svnadmin dump /ruta/repositorio > volcado_repositorio.dbd 2. Desde el servidor con la versión antigua (1.5) creamos un nuevo repositorio limpio: svnadmin create /ruta/nuevo_repositorio 3. Cargamos el volcado generado en el paso 1: svnadmin load /ruta/nuevo_repositorio < volcado_repositorio.dbd ===== Descargar un solo archivo ====== svn update http://repositorio_subversion/proyecto/mi_archivo.c ===== Listar revisiones ====== *Nota* puede requerir primero: svn update Y luego: svn log ===== Comprobar si existen versiones nuevas en el repositorio ====== <code> svn st -u –no-auth-cache –username=USER Authentication realm: <http://URL_REPOSITORY> xxx Repository Password for 'USER': * 225051 generic-ci/generic-service-check.sh * 225051 generic-ci/generic-service-remove.sh * file2.sh * 225051 . Status against revision: 234242 </code> * 225051 → existe una nueva version en el servidor ===== Merge inverso o revertir a una revision concreta ====== * *PROBLEMA* queremos eliminar las ultimas x revisiones de un proyecto 1. Listar las revisiones <code> cd /ruta/copia/local svn log ———————————————————————— r1132 | root | 2012-06-18 15:45:06 +0200 (Mon, 18 Jun 2012) | 1 line back without symlinks ———————————————————————— r1131 | usuario | 2012-06-18 15:07:16 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks sudo ———————————————————————— r1130 | usuario | 2012-06-18 15:05:41 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks ssh ———————————————————————— r1129 | usuario | 2012-06-18 15:04:50 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks module puppet cont and snmp ———————————————————————— r1128 | usuario | 2012-06-18 15:03:26 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks module puppet ———————————————————————— r1127 | usuario | 2012-06-18 14:58:34 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks module ntp ———————————————————————— r1126 | usuario | 2012-06-18 14:52:25 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks module nfs ———————————————————————— r1125 | usuario | 2012-06-18 14:46:01 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks module apt ———————————————————————— r1124 | usuario | 2012-06-18 14:42:23 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks test 3 ———————————————————————— r1123 | usuario | 2012-06-18 14:40:23 +0200 (Mon, 18 Jun 2012) | 1 line puppet symlinks test 2 ———————————————————————— r1122 | usuario | 2012-06-18 14:38:53 +0200 (Mon, 18 Jun 2012) | 1 line test symlinks puppet ———————————————————————— r1121 | root | 2012-06-18 14:25:24 +0200 (Mon, 18 Jun 2012) | 1 line Initial feed ———————————————————————— </code> 2. Queremos volver a la version inicial (r1121): sudo svn merge -r1132:1120 . 3. Hacemos el commit: svn commit -m 'revert to r1120' ===== Copiar directorio evitando .svn ====== sudo rsync -r –exclude=.svn /ruta/origen /ruta/destino
informatica/linux/subversion.txt · Last modified: 2015/04/13 20:19 (external edit)