2009-01-15 25 views
21

Estoy usando un repositorio SVN para mi trabajo de desarrollo web. Tengo un sitio de desarrollo configurado que contiene un checkout del repositorio.Utilizando el enganche SVN post-commit para actualizar solo los archivos que se han confirmado

He establecido un SVN post-commit gancho de modo que cada vez que un compromiso se hace al repositorio del sitio de desarrollo se actualiza:

cd /home/www/dev_ssl 
/usr/bin/svn up 

Esto funciona bien, pero debido al tamaño del repositorio las actualizaciones tomar un largo tiempo (aproximadamente 3 minutos) que es bastante frustrante cuando se realizan confirmaciones regulares. Lo que me gustaría es cambiar el gancho post-commit para actualizar solo aquellos archivos/directorios que se han comprometido, pero no sé cómo hacer esto. La actualización del "directorio común más bajo" probablemente sea la mejor solución, p.

Si la comisión de los archivos de seguimiento:

  • /branches/feature_x/images/logo.jpg
  • /branches/feature_x/css/screen.css

Sería actualizar el directorio :/branches/feature_x/

¿Alguien me puede ayudar a crear una solución que logre esto?

actualización:

  • El repositorio y sitio de desarrollo se encuentran en el mismo servidor para problemas de red no deben estar involucrados.
  • El uso de CPU es muy bajo, y las E/S deberían estar bien (se está ejecutando en un servidor dedicado de alta especificación)
  • El sitio de desarrollo es de aprox. 7.5 GB de tamaño y contiene aprox. 600.000 artículos, esto se debe principalmente a que tienen múltiples ramas/etiquetas

Respuesta

18

Es posible utilizar svnlook dirs-changed y svn up -N para actualizar sólo el contenido de cada carpeta cambiaron:

cd /home/www/dev_ssl 
svnlook dirs-changed [REPOS] -r [REV] | xargs /usr/bin/svn up -N 

O, si por -file podría ser mejor para usted (usando sed para despojar a los personajes de acción):

svnlook changed [REPOS] -r [REV] | sed "s/^....//" | xargs /usr/bin/svn up 
+0

me gusta la solución sed. Pero, ¿cómo podemos estar seguros de 4 caracteres antes de la ruta al nombre del archivo? –

+1

@FelipeAlvarez No hay garantía de que no cambie. Pero, a partir de ahora (1.8.0), son [3 caracteres] (https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L568) y [un espacio] (https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L601), luego la ruta. –

1

Para Windows:

for /F "eol=¬ delims=¬" %%A in ('svnlook dirs-changed %1 -r %2') do svn export "file:///c:/path/to/repo/%%A" "c:/svn_exports/%%A" --force 

copiar el anterior en su post-commit archivo por lotes gancho (o ventana de VisualSVN) y ya está - obtendrá el directorio actualizado exportó a c: \

Podría intentar usar% 1 en lugar de c:/ruta/hacia/repositorio anterior, pero descubrí que no funcionó porque VisualSVN da la ruta% 1 con separadores de ruta de acceso de retroceso y svnlook los proporciona con barras diagonales inversas . Esto no parece funcionar bien, así que codifiqué la ruta del repositorio (obtuve los errores "El nombre del archivo, nombre de directorio o sintaxis de etiqueta de volumen es incorrecta")

10
#!/bin/bash 

REPOS="$1" 
REV="$2" 

# A - Item added to repository 
# D - Item deleted from repository 
# U - File contents changed 
# _U - Properties of item changed; note the leading underscore 
# UU - File contents and properties changed 

# Files and directories can be distinguished, as directory paths are displayed with a trailing "/" character. 

LOOK=/usr/local/svn/bin/svnlook 
SVN=/usr/local/svn/bin/svn 
DEV=/var/www/test 

cd /var/tmp/svn 
    for changes in `$LOOK changed $REPOS | awk '{print $1 "=" $2;}'`; 
    do 
     len=${#changes} 
     idx=`expr index "$changes" =`; 
     directory=${changes:$idx}; 
     action=${changes:0:$idx-1}; 
     if [ ${changes:len-1} = '/' ] 
     then 
      case "$action" in 
       "A") \ 
        mkdir --mode=775 -p $DEV/$directory; 
        chown nobody:nobody $DEV/$directory; 
        chmod 775 $DEV/$directory; 
        ;; 
       "D") \ 
        rmdir $DEV/$directory; 
        ;; 
      esac 
     else 
      case "$action" in 
       "A"|"U"|"UU") \ 
        $SVN export --force --non-interactive -r HEAD -q file://$REPOS/$directory; 
        BASE=`basename $directory`; 
        DIR=`dirname $directory`; 
        chown nobody:nobody $BASE; 
        chmod 775 $BASE; 
        mkdir --mode=775 -p $DEV/$DIR; 
        cp -f --preserve=ownership $BASE $DEV/$DIR; 
        unlink $BASE; 
        ;; 
       "D") \ 
        rm -f $DEV/$directory; 
        ;; 
      esac 
     fi 
    done 

exit 0 
+0

Gracias Ivo gran script! – shady

Cuestiones relacionadas