SubversionTips
Todo lo que quiso saber de subversion y nunca se atrevió a preguntar ... #
Tabla de Contenidos [-]
- 1 Todo lo que quiso saber de subversion y nunca se atrevió a preguntar ...
- 2 Información general
- 3 Resumen de comandos
- 4 Recoger los cambios del repositorio
- 5 Chequear los cambios pendientes en el repositorio con respecto a tu copia local
- 6 Status de los ficheros
- 7 Ver las diferencias de un archivo
- 8 Revertir una versión
- 9 Revertir los cambios (no commiteados) de la copia local
- 10 Enviar un email a una lista de usuarios tras hacer un commit
- 11 Ignorar ficheros en un directorio local
- 12 Ignorar ficheros en todo el repositorio
- 13 Cómo cambiar un log de un commit?
- 14 Cómo hacer un backup del repositorio?
- 15 Script incremental de backup del repositorio
- 16 Cómo iniciar un proyecto con subversion?
- 17 Cómo migrar un repositorio CVS a subversion?
- 18 Crear una rama
- 18.1 Creando una versión (tag)
- 19 Borrar todos los directorios "/.svn"
- 20 Creando externals
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.
- La reference card puede consultarse en http://www.cs.put.poznan.pl/csobaniec/Papers/svn-refcard.pdf
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 #
- El script ¡No está definida la referencia InterWiki en el fichero de propiedades para el Wiki "attachment"! :
#!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;
- El script ¡No está definida la referencia InterWiki en el fichero de propiedades para el Wiki "attachment"!:
#!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 cesarEsto 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.