SubversionTips

Todo lo que quiso saber de subversion y nunca se atrevió a preguntar ... #

Información general #

El FAQ de subversion puede encontrarse en http://subversion.tigris.org/faq.html

La referencia base de subversion puede encontrarse en el libro on-line http://svnbook.red-bean.com/

  • Otra referencia muy interesante de subversion puede encontrarse en el libro Pragmatic version control using Subversion.

Resumen de comandos #

command Description
'add' Adds files and directories.
'blame' (praise, annotate, ann) Shows author and revision information in-line for the specified files or URLs.
'cat' Outputs the contents of the specified files or URLs.
'checkout' (co) Checks out a working copy from a repository.
'cleanup' Recursively clean up the working copy.
'commit' (ci) Send changes from your working copy to the repository.
'copy' (cp) Copy a file or directory in a working copy or in the repository.
'delete' (del, remove, rm) Delete an item from a working copy of the repository.
'diff' (di) Display the differences between two paths.
'export' Exports a clean directory tree.
'help' Prints help text.
'import' Recursively commit a copy of local dir into a repository.
'info' Print information about PATHs.
'list' (ls) List directory entries in the repository.
'log' Displays commit log messages.
'merge' Apply the differences between two sources to a working copy path.
'mkdir' Create a new directory under version control.
'move' (mv, rename, ren) Move a file or directory.
'propdel' (pdel, pd) Remove a property from an item.
'propget' (pget, pg) Prints the value of a property.
'proplist' (plist, pl) Lists all properties.
'propset' (pset, ps) Sets a property on files, directories, or revisions.
'resolved' Remove conflicted state on working copy files or directories.
'revert' Undo all local edits.
'status' (stat, st) Print the status of working copy files and directories.
'switch' (sw) Update working copy to a different URL.
'update' (up) Updates your working copy.

Recoger los cambios del repositorio #

Para recoger los últimos cambios del repositorio:
$ svn update

Para recoger los cambios de una versión específica:

$ svn update -r <version>

Chequear los cambios pendientes en el repositorio con respecto a tu copia local #

Si quieres chequear los cambios en de tu copia local.
$ svn status

Si además quieres ver los cambios pendientes en el repositorio:

$ svn status --show-updates

Otras opciones posibles son

--verbose, -v       : prints extra information
--non-recursive, -N : operate in a single directory only
--no-ignore         : Disregard default and svn:ignore property ignores

Status de los ficheros #

  • U File was updated.
  • A File was added.
  • D File was deleted.
  • R File was replaced.
  • G File was merged.
  • C Conflicting changes.
  • ? Resource is not under version control.
  • ! Resource is missing or incomplete (removed by another tool than Subversion).

Ver las diferencias de un archivo #

Para ver las diferencias de un archivo de tu copia local con la copia del repositorio:
$ svn diff <archivo>

Para ver los cambios de tu copia local sin modificar con respecto a una versión posterior del repositorio.

$ svn diff -r HEAD <archivo>

Revertir una versión #

$ svn merge -r 27:26 .

Revertir los cambios (no commiteados) de la copia local #

$ svn revert

Enviar un email a una lista de usuarios tras hacer un commit #

En el server:

Suponiendo que el repositorio $SVNROOT esta en /srv/svn/ se edita el archivo de acciones post-commit

$ vim /srv/svn/hooks/post-commit

REPOS="$1"
REV="$2"
PATH=/usr/share/subversion/tools/hook-scripts
commit-email.pl "$REPOS" "$REV" <cesar at zylk.net> 

Ignorar ficheros en un directorio local #

Si quieres ignorar una serie de ficheros (por ejemplo *.py) en un directorio (no funciona en sus subdirectorios! solo se aplica a los ficheros en un directorio) haz:

$ svn propedit svn:ignore directorio

Esto te abre un editor y se introduce en cada linea una expresion regular de los ficheros a ignorar.

*.pyc
*.pyo
*.o

Luego se hace un commit

$ svn commit -m "Adding svn properties to directory"

Se pueden ver los cambios en los archivos que se ignoran mediante el comando:

$ svn status --no-ignore

Otra posibilidad para ignorar un archivo es la siguiente:

$ svn propset svn:ignore configuration.php /var/www/joomla/

NOTA: Si el archivo ha sido añadido al repositorio es necesario borrarlo (en ambos casos).

Por otro lado, otra posibilidad interesante es definir un archivo de ignores .ignore en el directorio en cuestión para que pueda ser aplicado por el grupo de trabajo.

El archivo .ignore contiene las expresiones a ignorar.

$ vim .ignore
*.pyc
*.pyo
*.o

$ svn commit -m "Adding .ignore to repository"
$ svn propset svn:ignore -F .ignore .
property 'svn:ignore' set on '.'
$ svn commit -m "Adding svn properties to directory"

Ignorar ficheros en todo el repositorio #

También puedes hacer un cambio de la configuración global del cliente de subversion en:

$ vim ~/.subversion/config

y editar la línea global-ignores añadiendo los archivos que quieres ignorar, archivos de backup de los editores, precompilados de python, objetos de C....

global-ignores = *.o *.pyc *.pyo .*~ *~ .#* .DS_Store

El comportamiento en este caso si es recursivo. En cualquier caso los ignores se aplican a archivos que no se añadido en el repositorio. Es particularmente util definir alguna extension que te sirva de comodin como *.orig *.old *.new, de modo que pueda estar en tu copia local sin los continuos ? del svn sobre ese fichero.

Cómo cambiar un log de un commit? #

En el servidor hay que activar revprop-change. Contacta con tu administrador:

$ cd /path_to_repository/hooks
$ cp pre-revprop-change.tmpl pre-revprop-change
$ chmod +x pre-revprop-change

Desde el cliente:

$ svn propedit -r 261 --revprop svn:log

Otra posibilidad es cambiar el log directamente desde el servidor.

$ svnadmin setlog /srv/svn -r 261

Cómo hacer un backup del repositorio? #

Para hacer un dump de todo el repositorio y asumiendo que este se encuentra en /srv/svn/:

$ svnadmin dump /srv/svn > dumpfile.24032006

Para restaurarlo:

$ svnadmin create /home/cesar/svn-repos
$ svnadmin load /home/cesar/svn-repos < dumpfile.24032006

Otra posibilidad es hacer un backup incremental

$ svnadmin dump --incremental --revision 300:398 /srv/svn

Script incremental de backup del repositorio #

    1. El script ¡No está definida la referencia InterWiki en el fichero de propiedades para el Wiki "attachment"! :
El script diario:
#!Perl
#!/usr/bin/perl -w
#
# Excerpted from the book, "Pragmatic Version Control using Subversion"
#
# Perform a daily backup of a Subversion repository,
# using the previous most-recently-backed-up revision
# to create just an incremental dump.

$svn_repos = "/home/cesar/svn-repos";
$backups_dir = "/home/cesar/svn-backup";
$next_backup_file = "daily-incremental-backup." . `date +%Y%m%d`;

open(IN, "$backups_dir/last_backed_up");
$previous_youngest = <IN>;
chomp $previous_youngest;
close IN;

$youngest = `svnlook youngest $svn_repos`;
chomp $youngest;

if($youngest eq $previous_youngest) {
    print "No new revisions to back up.\n";
    exit 0;
}

# We need to backup from the last backed up revision
# to the latest (youngest) revision in the repository
$first_rev = $previous_youngest + 1;
$last_rev = $youngest;

print "Backing up revisions $first_rev to $last_rev...\n";
$svnadmin_cmd = "svnadmin dump --incremental " .
                "--revision $first_rev:$last_rev " .
                "$svn_repos > $backups_dir/$next_backup_file";
`$svnadmin_cmd`;

print "Compressing dump file...\n";
print `gzip -9 $backups_dir/$next_backup_file`;

open(LOG, ">$backups_dir/last_backed_up");
print LOG $last_rev;
close LOG;
    1. El script ¡No está definida la referencia InterWiki en el fichero de propiedades para el Wiki "attachment"!:
El script semanal:
#!VimColor
#!/usr/bin/perl -w
#
# Excerpted from the book, "Pragmatic Version Control using Subversion
#
# Perform a weekly backup of a Subversion repository,
# logging the most-recently-backed-up revision so an
# incremental script can be run other days.

$svn_repos = "/home/cesar/svn-repos";
$backups_dir = "/home/cesar/svn-backup";
$next_backup_file = "weekly-full-backup." . `date +%Y%m%d`;

$youngest = `svnlook youngest $svn_repos`;
chomp $youngest;

print "Backing up to revision $youngest\n";
`svnadmin dump $svn_repos > $backups_dir/$next_backup_file`;
print "Compressing dump file...\n";
print `gzip -9 $backups_dir/$next_backup_file`;

open(LOG, ">$backups_dir/last_backed_up");
print LOG $youngest;
close LOG;

Cómo iniciar un proyecto con subversion? #

Como root creamos el grupo de usuarios de svn y añadimos el usuario cesar al grupo:
$ groupadd svnusers
$ usermod -G svnusers cesar
$ usermod -G www cesar
Esto también puede hacerse modificando el archivo /etc/group.

Como usuario cesar, creamos el repositorio en el directorio del servidor /srv/svn:

$ cd /srv/
$ mkdir /srv/svn
$ chgrp svnusers /srv/svn
$ chown cesar /srv/svn
$ chmod g+w svn
$ chmod g+s svn
$ umask 002
$ svnadmin create /srv/svn

Importamos el proyecto inicial en el home. El proyecto se denomina zox. Creamos un directorio para la rama principal (trunk), para las ramas de desarrollo de los usuarios (branches) y para las releases del proyecto (tags):

$ cd /home/cesar
$ mkdir tmp
$ cd tmp
$ mkdir zox
$ mkdir zox/trunk
$ mkdir zox/branches
$ mkdir zox/tags    
$ svn import . file:///srv/svn --message 'Import inicial de la estructura de directorios del proyecto zox'

Como usuario www importamos el proyecto /srv/www/zox/ en el trunk:

$ cd /srv/www/zox/
$ umask 002
$ svn import bcs file:///srv/svn/zox/trunk

Hacemos el primer checkout desde el servidor:

$ cd /home/cesar/zox/work/
$ umask 002
$ svn co file:///srv/svn/zox/trunk trunk

Comprobamos desde un cliente remoto:

$ svn co svn+ssh://lcpx04.wm.lc.ehu.es:/srv/svn/zox/trunk trunk

Cómo migrar un repositorio CVS a subversion? #

En primer lugar es necesario instalar los paquetes de subversion, cvs y cvs2svn (tambien rcs).

$ aptitude install subversion
$ aptitude install cvs
$ aptitude install cvs2svn

El repositorio de CVS que queremos migrar se encuentra en /home/zylk/cvsroot

Exportamos la variable de entorno $CVSROOT:

$ export CVSROOT=/home/zylk/cvsroot

y se comprueba desde un cliente local que el repositorio no está corrupto:

$ cd /tmp
$ cvs co src

Aplicamos la conversión:

$ cd
$ cvs2svn -s /home/zylk/svnroot /home/zylk/cvsroot

Los repositorios están situados en /home/zylk/cvsroot (CVS) y /home/zylk/svnroot (SUBVERSION)

Si dice que el repositorio de svn no existe:

$ svnadmin create /home/zylk/svnroot

Si se queja de los nombres de los archivos es necesario definir el encoding.

$ cvs2svn --encoding=latin1 -s /home/zylk/svnroot /home/zylk/cvsroot

cvs2svn Statistics:
------------------
Total CVS Files: 13882
Total CVS Revisions: 30428
Total Unique Tags: 61
Total Unique Branches: 20
CVS Repos Size in KB: 700115
Total SVN Commits: 2378
First Revision Date: Thu Nov 4 11:54:53 2004
Last Revision Date: Thu Jul 13 13:39:20 2006
------------------
Timings:
------------------
pass 1: 36 seconds
pass 2: 7 seconds
pass 3: 0 seconds
pass 4: 4 seconds
pass 5: 8 seconds
pass 6: 0 seconds
pass 7: 0 seconds
pass 8: 548 seconds
total: 606 seconds

Hago una prueba de que se exportado todo:

$ svn ls file:///home/zylk/svnroot/trunk
CVSROOT/
docs/
personal/
src/

Crear una rama #

Crear una rama o una línea paralela de desarrollo:

                           copy
----------------------------------------- tronco
                           |
                           |
                           ++++++++++++++ rama

En realidad es un copia a otro directorio del repositorio que puede ser sincronizada (merge).

svn copy 
https://svn.zylk.net:446/svn/src/z-proy/tknika/kzylkgestionformacion/ 
https://svn.zylk.net:446/svn/src/z-proy-int/java/portlets/kzylkgestionformacion_v2.0 
-m "Copiando rama a proyectos internos para el desarrollo de la version 2.0 del portlet"

Creando una versión (tag) #

Crear una versión no es más que crear una rama nueva cuyo nombre indica que se trata de una versión. En la copia se indica la revisión (-r1964), sino se indica coge la revisión HEAD.


svn copy https://svn.zylk.net:446/svn/src/z-proy/esle/efacturaCore -r1964 
https://svn.zylk.net:446/svn/src/z-proy/esle/sinadura-tags/v.1.2/efacturaCore 
-m"Tag de efactura Core version 1.2"

Más información sobre tags y estructura de svn: http://svnbook.red-bean.com/en/1.1/ch04s06.html

Borrar todos los directorios "/.svn" #

Se puede hacer un export pero a veces.....

$ find . -type d |grep "\.svn$" | xargs -n 1 rm -rf

Creando externals #

Como crear un enlace externo a otra ruta.

Tiene que hacerse sobre una copia local, se indica un directorio local donde vaya a ir el contenido de una ruta del svn. Este directorio local no tiene que existir, sino dará un error de bloqueo posteriormente al hacer un update. Se indica la ruta del svn (http://svn:.....). Se indica a qué directorio se aplica la propiedad (en este caso .) lo que implica que se aplica a la ruta versionada.


svn propset svn:externals "scripts https://svn.zylk.net:446/svn/src/z-proy/esle/sinadura-tags/scripts/" .

Se hace commit de la propiedad aplicada para que en una descarga posterior se descarguen las rutas externas. Para no descargar los externals de una ruta durante un checkout, existe la opción --ignore-externals.

Promedio (0 Votos)
Comentarios