2009-01-15 16 views
21

J'utilise un référentiel SVN pour mon travail de développement web. J'ai un site de développement mis en place qui tient une caisse du référentiel.Utilisation du hook post-commit SVN pour mettre à jour uniquement les fichiers qui ont été validés

J'ai mis en place un crochet post-commit SVN de sorte que chaque fois qu'un commit est faite au référentiel du site de développement est mis à jour:

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

Cela fonctionne bien, mais en raison de la taille du dépôt des mises à jour prend beaucoup de temps (environ 3 minutes), ce qui est plutôt frustrant quand on fait des engagements réguliers. Ce que je voudrais, c'est changer le hook post-commit pour seulement mettre à jour les fichiers/répertoires qui ont été validés mais je ne sais pas comment faire. La mise à jour du "répertoire commun le plus bas" serait probablement la meilleure solution, par ex.

Si les fichiers commis suivants:

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

Il mettra à jour le répertoire :/branches/feature_x/

Quelqu'un peut-il m'aider à créer une solution qui réalise cela?

Mise à jour:

  • Le dépôt et le site de développement sont situés sur le même serveur pour les problèmes de réseau ne doivent pas être impliqués.
  • L'utilisation du processeur est très faible, et les E/S devraient être correctes (il fonctionne sur un serveur dédié hi-spec)
  • Le site de développement est d'env. 7,5 Go de taille et contient env. 600.000 articles, cela est principalement dû à avoir de multiples branches/tags

Répondre

18

Vous pouvez utiliser svnlook dirs-changed et svn up -N mettre à jour que le contenu de chaque dossier changé:

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

Ou, si par -file pourrait être meilleur pour vous (en utilisant sed pour dépouiller les caractères d'action):

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

J'aime la solution sed. Mais comment pouvons-nous être sûrs de 4 caractères avant le chemin du nom de fichier? –

+1

@FelipeAlvarez Il n'y a aucune garantie que cela ne changera pas. Mais, à partir de maintenant (1.8.0), c'est [3 caractères] (https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L568) et [un espace] (https://github.com/apache/subversion/blob/1.8.0/subversion/svnlook/svnlook.c#L601), puis le chemin. –

1

Pour 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 

copie le dessus dans votre fichier de commandes post-commit hook (ou la fenêtre pour VisualSVN) et vous avez terminé - vous aurez le répertoire mis à jour exporté vers c: \

Vous pouvez essayer d'utiliser% 1 au lieu de c:/path/to/repo ci-dessus, mais j'ai trouvé que cela ne fonctionnait pas parce que VisualSVN donnait le chemin% 1 avec des séparateurs de chemin oblique et svnlook leur donnait des barres obliques . Cela ne semble pas fonctionner correctement, donc je code dur le chemin repo (j'ai les erreurs "Le nom du fichier, le nom du répertoire, ou la syntaxe de l'étiquette de volume est incorrect")

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

Merci beaucoup Ivo! – shady