Maintenance d'un dépôt

Assurer la maintenance d'un dépôt Subversion peut être intimidant, certainement parce que les systèmes qui comprennent une base de données sont complexes. Il faut pour cela connaître les outils — ceux dont on dispose, quand les utiliser et comment. Cette section vous présente les outils fournis par Subversion pour assurer l'administration du dépôt et décrit leur maniement pour réaliser des opérations telles que migrations de données, mises à jour, sauvegardes et nettoyages.

Boîte à outils de l'administrateur

Subversion fournit une poignée d'utilitaires pour créer, inspecter, modifier et réparer votre dépôt. Étudions de plus près chacun de ces outils. Ensuite, nous abordons rapidement quelques utilitaires inclus dans le gestionnaire de bases de données Berkeley DB qui fournissent des fonctionnalités spécifiques au magasin de données de votre dépôt qui ne sont pas assurées par les propres outils de Subversion.

svnadmin

Le programme svnadmin est le meilleur ami de l'administrateur de dépôts. En plus de fournir la possibilité de créer des dépôts Subversion, ce programme vous permet d'effectuer de nombreuses opérations de maintenance sur ces dépôts. La syntaxe de svnadmin est similaire à celle des autres programmes en ligne de commande de Subversion :

$ svnadmin help
usage général : svnadmin SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...]
Entrer 'svnadmin help <sous-commande>' pour une aide spécifique.
Entrer 'svnadmin --version' pour avoir la version et les modules de stockages.

Sous-commandes disponibles :
   crashtest
   create
   deltify
…

Au début de ce chapitre (dans la section intitulée « Création d'un dépôt »), nous vous avons présenté la sous-commande svnadmin create. La plupart des autres sous-commandes svnadmin sont couvertes plus loin dans ce chapitre. Vous pouvez également consulter la section intitulée « svnadmin » pour une liste complète des sous-commandes et des fonctionnalités qu'elles apportent.

svnlook

svnlook est un outil de Subversion pour examiner les différentes révisions et transactions (qui sont des révisions en cours de création) dans un dépôt. Aucune modification n'est faite au dépôt par cet outil. svnlook est généralement utilisé par les procédures automatiques du dépôt pour signaler les changements qui vont être propagés (dans le cas de la procédure automatique pre-commit) ou qui viennent d'être propagés (dans le cas de la procédure automatique post-commit). Un administrateur peut être amené à utiliser cet outil à des fins de diagnostic.

La syntaxe de svnlook est particulièrement simple :

$svnlook help
usage général : svnlook SOUS_COMMANDE CHEMIN_DÉPÔT [ARGS & OPTIONS...]
Note : Quand --revision ou --transaction ne sont pas précisées, les sous-
       commandes qui en ont besoin utilisent la révision la plus récente.
Entrer 'svnlook help <sous-commande>' pour une aide spécifique.
Entrer 'svnlook --version' pour avoir la version et les modules de stockage.
…

La plupart des sous-commandes svnlook peuvent être appliquées soit à une révision soit à une arborescence de transaction, affichant les informations à propos de l'arborescence elle-même ou les différences par rapport à la révision précédente du dépôt. Pour spécifier quelle révision ou quelle transaction examiner, utilisez respectivement les options --revision (-r) et --transaction (-t). En l'absence des options --revision (-r) ou --transaction (-t), svnlook examine la révision la plus récente (la révision HEAD) du dépôt. Ainsi, les deux commandes suivantes font exactement la même chose si la révision la plus récente du dépôt situé à l'emplacement /var/svn/depot porte le numéro 19  :

$ svnlook info /var/svn/depot
$ svnlook info /var/svn/depot -r 19

Signalons une exception à ces règles concernant les sous-commandes : la sous-commande svnlook youngest ne prend aucune option et affiche simplement le numéro de la révision la plus récente du dépôt :

$ svnlook youngest /var/svn/depot
19
$
[Note] Note

Gardez à l'esprit que les seules transactions que vous pouvez examiner sont celles qui n'ont pas été propagées. La plupart des dépôts ne comportent pas de transactions de ce type parce que les transactions sont habituellement soit propagées (auquel cas vous devriez y avoir accès sous la forme de révisions via l'option --revision (-r)), soit annulées et supprimées.

La sortie de svnlook est conçue pour être à la fois lisible par un humain et analysable par une machine. Prenons, par exemple, la sortie de la sous-commande svnlook info :

$ svnlook info /var/svn/depot
sally
2002-11-04 09:29:13 -0600 (lun. 04 nov. 2002)
27
J'ai ajouté le traditionnel
Arbre grec.
$

La sortie de svnlook info est constituée des éléments suivants, par ordre d'apparition :

  1. L'auteur, suivi d'un passage à la ligne.

  2. La date, suivie d'un passage à la ligne.

  3. Le nombre de caractères du message de propagation, suivi d'un passage à la ligne.

  4. Le message de propagation lui-même, suivi d'un passage à la ligne.

Cette sortie est lisible par un humain, ce qui veut dire que les éléments tels que la date sont représentés par du texte simple au lieu d'un obscur code (comme le nombre de nanosecondes depuis le passage aux nouveaux francs). Mais cette sortie est aussi analysable par une machine — parce que le message de propagation peut comporter plusieurs lignes et n'est pas limité en taille, svnlook affiche la longueur du message avant le message lui-même. Cela permet aux scripts et autres utilitaires faisant appel à cette commande de prendre des décisions opportunes à propos du message de propagation, comme savoir combien de mémoire allouer pour le message ou au moins savoir combien d'octets sauter dans le cas où les données affichées par svnlook ne sont pas les dernières données du flux.

svnlook peut répondre à un tas d'autres requêtes : afficher des sous-ensembles des informations précédemment citées, lister récursivement les arborescences suivies en versions des répertoires, lister les chemins modifiés lors de telle révision ou transaction, afficher les différences de contenu et de propriétés pour les fichiers et répertoires,  etc. Reportez-vous à la section intitulée « svnlook » pour la liste complète des fonctionnalités offertes par svnlook.

svndumpfilter

Bien que ce ne soit pas l'outil le plus utilisé mis à disposition de l'administrateur, svndumpfilter fournit une fonctionnalité d'un genre très particulier qui est d'une grande utilité : la possibilité de modifier rapidement et facilement des flux de l'historique du dépôt Subversion en agissant en tant que filtre sur les chemins.

La syntaxe de svndumpfilter est la suivante :

$ svndumpfilter help
usage général : svndumpfilter SOUS_COMMANDE [ARGS & OPTIONS ...]
Entrer 'svndumpfilter help <sous-commande>' pour l'aide spécifique.
Entrer 'svndumpfilter --version' pour avoir le numéro de version du programme.

Sous-commandes disponibles :
   exclude
   include
   help (?, h)

Il n'y a que deux sous-commandes intéressantes : svndumpfilter exclude et svndumpfilter include. Elles vous permettent de choisir entre l'inclusion implicite et l'inclusion explicite des chemins dans le flux. Vous en saurez plus sur ces sous-commandes et sur l'utilité si particulière de svndumpfilter plus loin dans ce chapitre, dans la section intitulée « Filtrage de l'historique d'un dépôt ».

svnsync

Le programme svnsync, apparu dans la version 1.4 de Subversion, fournit toutes les fonctionnalités requises pour faire fonctionner un miroir en lecture seule d'un dépôt Subversion. Ce programme a une et une seule fonction : transférer l'historique d'un dépôt vers un autre dépôt. Et, bien qu'il y ait différentes manières de faire, sa force réside dans sa capacité de travailler à distance : les dépôts « source » et « destination » peuvent être sur deux ordinateurs différents et svnsync sur un troisième.

Comme vous vous en doutez, svnsync possède une syntaxe très proche des autres programmes déjà mentionnés dans ce chapitre :

$svnsync help
usage général : svnsync SOUS_COMMANDE DÉPÔT [ARGS & OPTIONS ...]
Entrer 'svnsync help <sous-commande>' pour une aide spécifique.
Entrer 'svnsync --version' pour la version et les modules d'accès (RA).

Sous-commandes disponibles :
   initialize (init)
   synchronize (sync)
   copy-revprops
   help (?, h)
$

Nous revenons en détail sur la réplication de dépôts avec svnsync plus loin dans ce chapitre (voir la section intitulée « Réplication d'un dépôt »).

fsfs-reshard.py

Bien qu'il ne fasse pas officiellement partie des outils Subversion, le script fsfs-reshard.py (situé dans le répertoire tools/server-side du code source de Subversion) est un outil particulièrement utile à l'administrateur pour optimiser les performances de dépôts Subversion utilisant un magasin de données FSFS. Les dépôts FSFS contiennent des fichiers qui décrivent les changements apportés dans une seule révision et des fichiers qui contiennent les propriétés de révision associées à une seule révision. Les dépôts créés avec Subversion avant la version 1.5 conservent ces fichiers dans deux répertoires : un pour chaque type de fichiers. Au fur et à mesure des révisions propagées dans le dépôt, Subversion dépose de plus en plus de fichiers dans ces deux répertoires — au bout d'un certain temps, le nombre de fichiers dans chaque répertoire peut devenir particulièrement élevé. On a pu constater dans cette situation des problèmes de performances sur certains systèmes de fichiers en réseau.

Subversion 1.5 crée les dépôts FSFS en utilisant un schéma légèrement différent pour lequel ces deux répertoires sont répartis (sharded en anglais, d'où le nom du script) dans plusieurs sous-répertoires. Cela peut réduire de façon drastique le temps de recherche d'un de ces fichiers et, en conséquence, améliorer la performance globale de Subversion pour la lecture du dépôt. Le nombre de sous-répertoires utilisés pour héberger ces fichiers est d'ailleurs configurable et c'est là qu'intervient le script fsfs-reshard.py. Le script remanie la structure du dépôt pour se conformer au nombre de sous-répertoires demandés. C'est particulièrement utile pour convertir un vieux dépôt Subversion vers le nouveau schéma réparti de Subversion 1.5 (ce que Subversion ne fait pas automatiquement pour vous) ou pour modifier cette valeur dans un dépôt déjà réparti.

Utilitaires Berkeley DB

Si vous utilisez un dépôt avec une base Berkeley DB, à la fois les données et la structure de votre système de fichiers suivis en version résident dans un ensemble de tables de la base de données qui sont situées dans le sous-répertoire db/ de votre dépôt. Ce sous-répertoire est un répertoire d'environnement classique de base de données Berkeley DB et n'importe quel outil de base de données Berkeley, généralement fourni avec la distribution Berkeley, peut y être utilisé.

Pour un usage quotidien, ces outils ne sont pas nécessaires. La plupart des fonctionnalités dont les dépôts Subversion ont besoin ont été dupliquées dans l'outil svnadmin. Par exemple, svnadmin list-unused-dblogs et svnadmin list-dblogs fournissent un sous-ensemble des fonctionnalités offertes par l'utilitaire db_archive de Berkeley DB et svnadmin recover reproduit les utilisations courantes de l'utilitaire db_recover.

Cependant, il reste quelques utilitaires Berkeley DB que vous pourriez trouver utiles. Les programmes db_dump et db_load fonctionnent avec, pour la lecture et l'écriture respectivement, un format de fichier personnalisé qui décrit les clés et les valeurs d'une base de données Berkeley DB. Puisque les bases de données Berkeley DB ne sont pas portables d'une architecture de machine à une autre, ce format est utile pour transférer les bases de données entre deux machines, indépendamment de l'architecture et du système d'exploitation. Comme nous le décrivons plus loin dans ce chapitre, vous pouvez aussi utiliser svnadmin dump et svnadmin load pour faire la même chose, mais db_dump et db_load peuvent accomplir certaines tâches tout aussi bien et beaucoup plus vite. Ils peuvent aussi être utiles si un expert Berkeley DB, pour une raison ou pour une autre, doit manipuler les données directement dans la base de données d'un dépôt BDB (les utilitaires Subversion ne le vous permettent pas). De plus, l'utilitaire db_stat peut fournir des informations utiles sur l'état de votre environnement Berkeley DB, y compris des statistiques détaillées concernant les sous-systèmes de verrouillage et de stockage.

Pour davantage d'informations sur la suite d'outils Berkeley DB, consultez la documentation en ligne sur le site Internet d'Oracle, dans la section Berkeley DB : http://www.oracle.com/technology/documentation/berkeley-db/db/ (ce site est en anglais).

Correction des messages de propagation

Parfois un utilisateur se trompe dans son message de propagation (une faute d'orthographe ou une coquille, par exemple). Si le dépôt est configuré (en utilisant la procédure automatique pre-revprop-change, voir la section intitulée « Mise en place des procédures automatiques ») pour accepter les modifications de ce message après la fin de la propagation, l'utilisateur peut corriger son message à distance en utilisant svn propset (voir svn propset). Cependant, en raison de la possibilité de perte d'information irrémédiable, les dépôts Subversion ne sont pas configurés, par défaut, pour autoriser les modifications de propriétés non suivies en versions — sauf de la part d'un administrateur.

Si un administrateur est amené à changer un message de propagation, il peut le faire avec svnadmin setlog. Cette commande change le message de propagation (la propriété svn:log) d'une révision donnée du dépôt, la nouvelle valeur étant lue dans un fichier.

$ echo "Voici le nouveau message de propagation, en version corrigée" > nouveau-message.txt
$ svnadmin setlog mon-depot nouveau-message.txt -r 388

La commande svnadmin setlog, par défaut, possède les mêmes garde-fous pour empêcher de modifier des propriétés non suivies en versions qu'un client distant — les procédures automatiques pre- et post-revprop-change sont toujours activées et doivent donc être configurées afin d'accepter ce type de changement. Mais un administrateur peut contourner ces protections en passant l'option --bypass-hooks à la commande svnadmin setlog.

[Avertissement] Avertissement

Souvenez-vous cependant que, en contournant les procédures automatiques, vous êtes susceptible de ne pas activer certaines actions telles que la notification par email du changement des propriétés, la sauvegarde par les systèmes qui surveillent les propriétés non suivies en versions, etc. En d'autres termes, faites particulièrement attention aux changements que vous apportez et à la manière dont vous le faites.

Gestion de l'espace disque

Bien que le coût de stockage ait diminué de manière drastique ces dernières années, l'utilisation de l'espace disque reste une des préoccupations de l'administrateur qui doit suivre en versions de grandes quantités de données. Chaque élément de l'historique de chaque donnée stockée dans un dépôt actif doit être sauvegardé ailleurs, peut-être même de nombreuses fois dans le cas de sauvegardes tournantes. Il est utile de savoir quelles données d'un dépôt Subversion doivent rester sur le site de production, lesquelles doivent être sauvegardées et lesquelles peuvent être supprimées sans risque.

Économie d'espace disque

Pour garder un dépôt petit, Subversion utilise la différenciation (ou « stockage différentiel ») à l'intérieur du dépôt lui-même. La différenciation implique l'encodage de la représentation d'un groupe de données sous la forme d'un ensemble de différences avec un autre groupe de données. Si les deux groupes de données sont très similaires, la différenciation économise de l'espace pour le groupe différencié — au lieu de prendre le même espace que les données originales, le groupe occupe juste l'espace nécessaire pour dire : « je ressemble à l'autre groupe de données là-bas, sauf pour les deux ou trois changements qui suivent ». Au final, l'espace occupé par l'ensemble des données du dépôt — c'est-à-dire le contenu des fichiers suivis en versions — est beaucoup plus petit que la représentation textuelle originale de ces données. Et pour les dépôts créés avec Subversion en version 1.4 ou plus, l'espace économisé est encore plus important — les représentations textuelles des fichiers sont à présent elles-mêmes compressées.

[Note] Note

Comme toutes les données sujettes à différenciation dans un dépôt BDB sont stockées dans un unique fichier de la base de données, réduire la taille des données stockées ne réduit pas instantanément la taille du fichier de base de données lui-même. Le gestionnaire de base de données Berkeley DB garde néanmoins une trace des zones non-utilisées du fichier de base de données et utilise ces zones avant d'augmenter la taille du fichier de base de données. Ainsi, même si la différenciation n'économise pas immédiatement de la place, cela ralentit de façon drastique la croissance de la base de données.

Suppression des transactions mortes

Bien que rares, il y a des circonstances dans lesquelles le déroulement d'une propagation Subversion peut mal se terminer, laissant derrière elle dans le dépôt des restes de cette tentative de propagation : une transaction inachevée et toutes les modifications de fichiers et de répertoires associées. Il peut y avoir plusieurs raisons à cet échec : l'utilisateur a peut-être brutalement interrompu l'opération côté client ou bien une coupure réseau s'est peut-être produite au milieu de l'opération. Quoi qu'il en soit, des transactions mortes peuvent apparaître. Elles ne sont pas dangereuses mais elles consomment inutilement de l'espace disque. Un administrateur consciencieux se doit néanmoins de les supprimer.

Vous pouvez utiliser la commande svnadmin lstxns pour obtenir la liste des noms des transactions non encore réglées :

$ svnadmin lstxns mon-depot
19
3a1
a45
$

Chaque élément de la sortie de cette commande peut être passé en argument de svnlook (avec l'option --transaction (-t)) pour déterminer qui est à l'origine de la transaction, quand elle a eu lieu et quels types de changements ont été effectués — ces informations sont très utiles pour savoir si on peut supprimer la transaction sans arrière pensée ! Si vous décidez effectivement de supprimer la transaction, son nom peut être passé à svnadmin rmtxns qui fera le nettoyage adéquat. En fait, svnadmin rmtxns peut directement prendre en entrée la sortie de svnadmin lstxns !

$ svnadmin rmtxns mon-depot `svnadmin lstxns mon-depot`
$

Si vous utilisez ces deux sous-commandes ainsi, vous devriez envisager de rendre votre dépôt temporairement indisponible pour les clients. De cette manière, personne ne peut initier une transaction légitime avant que le nettoyage n'ait commencé. L'exemple Exemple 5.1, « txn-info.sh (lister les transactions inachevées) » contient quelques lignes de script shell qui peuvent produire les informations relatives à chaque transaction inachevée de votre dépôt.

Exemple 5.1. txn-info.sh (lister les transactions inachevées)

#!/bin/sh

### Produit les informations relatives à toutes les transactions
### inachevées d'un dépôt Subversion

DEPOT="${1}"
if [ "x$DEPOT" = x ] ; then
  echo "utilisation: $0 CHEMIN_VERS_LE_DEPOT"
  exit
fi

for TXN in `svnadmin lstxns ${DEPOT}`; do
  echo "---[ Transaction ${TXN} ]-------------------------------------------"
  svnlook info "${DEPOT}" -t "${TXN}"
done

La sortie produite par ce script est, en bref, la concaténation des différents groupes d'informations fournis par svnlook info (voir la section intitulée « svnlook ») et ressemble à ceci :

$ txn-info.sh mon-depot
---[ Transaction 19 ]-------------------------------------------
sally
2001-09-04 11:57:19 -0500 (mar. 04 sep. 2001)
0
---[ Transaction 3a1 ]-------------------------------------------
harry
2001-09-10 16:50:30 -0500 (lun. 10 sep. 2001)
39
Tentative de propagation dans un réseau pourri
---[ Transaction a45 ]-------------------------------------------
sally
2001-09-12 11:09:28 -0500 (mer. 12 sep. 2001)
0
$

Une transaction initiée depuis longtemps correspond en général à une propagation qui a été interrompue ou qui a échoué. L'horodatage de la transaction peut fournir des informations intéressantes — par exemple, quelle est la probabilité qu'une transaction commencée il y a neuf mois soit toujours active ?

En résumé, la décision de supprimer une transaction ne doit pas être prise à la légère. D'autres sources d'informations — comme les journaux d'Apache sur les erreurs et les accès, les journaux opérationnels de Subversion, l'historique des révisions Subversion, etc. — peuvent aider à la prise de décision. Et bien sûr, l'administrateur peut toujours entrer en contact (par email, par exemple) avec l'auteur d'une transaction qui semble abandonnée pour vérifier que c'est bien le cas.

Purge des fichiers de journalisation inutilisés de Berkeley DB

Jusqu'à il y a peu, les plus gros consommateurs d'espace disque pour les dépôts Subversion basés sur BDB étaient les fichiers de journalisation dans lesquels le gestionnaire Berkeley DB effectue les pré-écritures avant de modifier la base de données elle-même. Ces fichiers recensent toutes les actions menées pour modifier la base de données, étape par étape ; alors que les fichiers de la base de données, à un instant donné, ne reflètent qu'un état particulier, les fichiers de journalisation contiennent l'ensemble de tous les changements opérés entre chaque état successif. Ainsi, ils peuvent grossir assez rapidement.

Heureusement, à partir de la version 4.2 de Berkeley DB, l'environnement de la base de données est capable de supprimer ses propres fichiers non utilisés automatiquement. Tout dépôt créé en utilisant svnadmin compilé avec la version 4.2 de Berkeley DB (ou suivantes) est configuré pour supprimer automatiquement les fichiers de journalisation. Si vous ne voulez pas activer cette fonctionnalité, passez simplement l'option --bdb-log-keep à la commande svnadmin create. Si vous oubliez de le faire ou si vous changez d'avis plus tard, éditez simplement le fichier DB_CONFIG qui se trouve dans le répertoire db de votre dépôt, commentez la ligne qui contient la directive set_flags DB_LOG_AUTOREMOVE puis lancez svnadmin recover sur votre dépôt pour que le changement de configuration prenne effet. Reportez-vous à la section intitulée « Configuration de la base de données Berkeley DB » pour plus d'informations sur la configuration du gestionnaire de bases de données.

Sans suppression automatique des fichiers de journalisation, les journaux vont s'accumuler au fur et à mesure de l'utilisation de votre dépôt. Cela peut être considéré comme une fonctionnalité du gestionnaire de bases de données — vous devez être capable de recréer entièrement votre base de données en utilisant uniquement vos fichiers de journalisation, c'est pourquoi ceux-ci sont utiles pour le rétablissement de la base après une catastrophe. Mais en général, vous voudrez archiver les fichiers de journalisation qui ne sont plus utilisés par la base de données et ensuite les enlever du disque pour conserver de l'espace libre. Utilisez la commande svnadmin list-unused-dblogs pour avoir la liste des fichiers de journalisation inutilisés :

$ svnadmin list-unused-dblogs /var/svn/depot
/var/svn/depot/log.0000000031
/var/svn/depot/log.0000000032
/var/svn/depot/log.0000000033
…
$ rm `svnadmin list-unused-dblogs /var/svn/depot`
## espace disque récupéré !
[Avertissement] Avertissement

Les dépôts BDB qui utilisent les fichiers de journalisation pour les sauvegardes ou les rétablissements après incident ne doivent pas activer la suppression automatique des fichiers de journalisation. La reconstruction des données d'un dépôt à partir des fichiers de journalisation ne peut être effectuée que si tous les fichiers de journalisation sont accessibles. Si quelques fichiers de journalisation sont supprimés du disque avant que le système de sauvegarde n'ait pu les copier ailleurs, l'ensemble incomplet des fichiers de journalisation est totalement inutile.

Rétablissement de bases de données Berkeley DB

Comme indiqué dans la section intitulée « Berkeley DB », un dépôt Berkeley DB peut se retrouver bloqué s'il n'est pas arrêté proprement. Quand cela arrive, un administrateur doit faire revenir la base de données en arrière jusque dans un état cohérent. Ceci ne concerne cependant que les dépôts BDB — si vous utilisez FSFS, vous n'êtes pas concerné. Et pour ceux qui utilisent Subversion 1.4 avec Berkeley DB version 4.4 ou plus, vous constaterez que Subversion est devenu beaucoup plus résilient face à ce type de problème. Certes, mais des plantages de dépôts Berkeley DB arrivent encore et un administrateur doit savoir comment réagir dans de telles circonstances.

Pour protéger les données du dépôt, le gestionnaire Berkeley DB utilise un mécanisme de verrouillage. Ce mécanisme s'assure que les éléments de la base de données ne sont pas modifiés en même temps par plusieurs utilisateurs et que chaque processus voit les données dans un état cohérent lors de la lecture de la base de données. Quand un processus a besoin de modifier quelque chose dans la base de données, il vérifie d'abord l'existence d'un verrou sur les données concernées. Si les données ne sont pas verrouillées, le processus les verrouille, effectue les changements qu'il veut puis déverrouille les données. Les autres processus sont obligés d'attendre que le verrou soit libéré avant d'être autorisés à accéder aux données de cette zone (ceci n'a rien à voir avec les verrous que vous, utilisateur, pouvez appliquer sur les fichiers suivis en versions dans le dépôt ; nous essayons de lever l'ambiguïté créée par l'emploi de cette terminologie commune dans l'encadré Les trois types de « verrous ».)

Au cours de l'utilisation de votre dépôt Subversion, des erreurs fatales ou des interruptions peuvent empêcher un processus de supprimer des verrous qu'il a placés dans la base de données. Cela conduit à des plantages du magasin de données. Lorsque cela arrive, toutes les tentatives d'accès au dépôt se soldent par un échec (puisque chaque nouvel arrivant attend que le verrou se libère, ce qui n'est pas prêt d'arriver).

Si cela arrive à votre dépôt, ne paniquez pas. Le système de fichiers Berkeley DB tire parti des transactions de la base de données, des points de contrôle et de la journalisation préalable à toute écriture pour garantir que seuls les événements les plus catastrophiques[34] soient à même de détruire définitivement un environnement de base de données. Un administrateur suffisamment paranoïaque conserve des sauvegardes des données du dépôt dans un endroit distinct, mais attendez un peu avant de vous diriger vers l'armoire de rangement des sauvegardes.

Appliquez plutôt la recette suivante pour tenter de « faire repartir » votre dépôt :

  1. Assurez-vous qu'aucun processus n'accède au dépôt (ou ne tente de le faire). Pour les dépôts en réseau, cela implique d'arrêter le serveur HTTP Apache ou le démon svnserve.

  2. Prenez l'identité de l'utilisateur qui possède et gère le dépôt. C'est important, puisque rétablir un dépôt avec un autre utilisateur peut modifier les droits d'accès des fichiers du dépôt de telle manière que votre dépôt soit toujours inaccessible même après la remise en service.

  3. Lancez la commande svnadmin recover /var/svn/depot. Vous devriez obtenir une sortie du genre :

    Verrou du dépôt acquis.
    Patientez ; le rétablissement du dépôt peut être long...
    
    Fin du rétablissement.
    La dernière révision du dépôt est 19
    

    Cette commande peut durer plusieurs minutes.

  4. Redémarrez le processus serveur.

Cette procédure fonctionne dans presque tous les cas de plantage. Faites attention à ce qu'elle soit lancée par l'utilisateur qui possède et gère la base de données, pas par root. La procédure de rétablissement peut impliquer de récréer en partant de zéro certains fichiers de la base de données (de la mémoire partagée, par exemple). Un rétablissement par root créerait ces fichiers avec root comme propriétaire, ce qui veut dire que même après que vous ayez rétabli l'accès à votre dépôt, les utilisateurs de base n'y auront pas accès.

Si la procédure précédente, pour une raison ou pour une autre, ne fait pas repartir votre dépôt, vous devez faire deux choses. D'abord, mettez de côté votre répertoire de dépôt cassé (par exemple en le renommant depot.CASSE) puis restaurez la dernière sauvegarde de votre dépôt. Ensuite, envoyez un email à la liste de diffusion des utilisateurs de Subversion () et décrivez votre problème en détail. L'intégrité des données fait partie des sujets à très haute priorité pour les développeurs Subversion.

Migration des données d'un dépôt

Un système de fichiers Subversion a ses données réparties dans les fichiers du dépôt d'une manière que seuls les développeurs Subversion eux-mêmes comprennent (et s'y intéressent). Il peut cependant y avoir des circonstances qui obligent à copier ou déplacer l'ensemble (ou une partie) des données d'un dépôt à un autre.

Subversion fournit cette fonctionnalité par le biais des flux de déchargement du dépôt. Un flux de déchargement de dépôt (« fichier dump » ou dump file en anglais, quand il est stocké dans un fichier sur le disque) est un format de fichier portable, contenant des données brutes, qui décrit les différentes révisions de votre dépôt — ce qui a été modifié, par qui, quand, etc. Ce fichier dump est le principal mécanisme utilisé pour réorganiser des historiques de versions — en partie ou en totalité, avec ou sans modification — entre des dépôts. Et Subversion fournit les outils nécessaires à la création et au chargement de ces fichiers dump : les sous-commandes svnadmin dump et svnadmin load respectivement.

[Avertissement] Avertissement

Bien que le format des fichiers dump de Subversion contienne des parties lisibles par les humains et une structure familière (elle ressemble au format décrit par la RFC 822, utilisé pour la plupart des emails), ce n'est pas un format de fichier purement textuel. C'est un format de fichier binaire, très sensible aux modifications faites à son contenu. Par exemple, de nombreux éditeurs de textes corrompent le fichier en convertissant les caractères de fin de ligne.

Il existe de nombreuses raisons de décharger et recharger les données d'un dépôt Subversion. Aux premiers temps de Subversion, la principale raison était l'évolution de Subversion lui-même. Au fur et à mesure que Subversion gagnait en maturité, des changements faits sur les schémas des magasins de données sous-jacents entraînaient des problèmes de compatibilité avec les versions précédentes du dépôt, ce qui obligeait les utilisateurs à décharger les données de leurs dépôts en utilisant la version précédente de Subversion puis à recharger ces données dans un dépôt tout neuf créé avec la nouvelle version de Subversion. Il n'y a pas eu de changement de schéma de ce type depuis la version 1.0 de Subversion et les développeurs ont promis de ne pas forcer les utilisateurs à décharger et recharger leurs dépôts lors du passage d'une version mineure à une autre (comme par exemple entre la version 1.3 et la version 1.4) de Subversion. Mais il existe néanmoins des raisons de décharger et recharger ses données, comme le redéploiement d'un dépôt Berkeley DB sur un nouveau système d'exploitation ou sur une architecture CPU différente, la migration du magasin de données de Berkeley DB à FSFS et réciproquement ou (comme nous le voyons dans ce chapitre à la section intitulée « Filtrage de l'historique d'un dépôt ») la purge de données suivies en version de l'historique du dépôt.

[Note] Note

Le format de déchargement des dépôts Subversion ne décrit que l'évolution des éléments suivis en version. Il ne contient pas d'information sur les transactions inachevées, les verrous utilisateurs sur les chemins du système de fichiers, la configuration personnalisée du dépôt ou du serveur (y compris les procédures automatiques) et ainsi de suite.

Quelle que soit la raison pour laquelle vous voulez migrer votre historique de dépôt, l'utilisation des sous-commandes svnadmin dump et svnadmin load est simplissime. svnadmin dump affiche un intervalle de révisions du dépôt, chacune utilisant le format des fichiers dump Subversion. Le fichier dump est envoyé sur la sortie standard tandis que les messages d'information sont envoyés sur la sortie d'erreur. Ceci vous permet de rediriger le flux standard vers un fichier tout en visualisant ce qui se passe dans votre terminal. Par exemple :

$svnlook youngest mon-depot
26
$ svnadmin dump mon-depot > fichier-dump
* Révision 0 déchargée.
* Révision 1 déchargée.
* Révision 2 déchargée.
…
* Révision 25 déchargée.
* Révision 26 déchargée.

A la fin de la procédure, vous obtiendrez un fichier unique (fichier-dump dans l'exemple précédent) qui contient toutes les données stockées dans votre dépôt pour l'intervalle de révisions demandé. Notez que svnadmin dump lit les arborescences des révisions du dépôt de la même manière que tout autre processus « lecteur » (par exemple svn checkout), vous pouvez donc sans risque lancer cette commande à n'importe quel moment.

La commande jumelle, svnadmin load, recherche dans l'entrée standard la structure d'un fichier dump Subversion puis insère les révisions déchargées dans le dépôt de destination spécifié. Elle fournit elle aussi des informations sur le déroulement de l'opération, cette fois en utilisant la sortie standard :

$ svnadmin load nouveau-depot < fichier-dump
<<< Début d'une nouvelle transaction basée sur la révision 1
       * ajout de : A ... fait.
       * ajout de : A/B ... fait.
       …
  ------- Révision 1 propagée (commit) >>>

  <<< Début d'une nouvelle transaction basée sur la révision 2
       * édition de : A/mu ... fait.
       * édition de : A/D/G/rho ... fait.

  ------- Révision 2 propagée (commit) >>>

  …

  <<< Début d'une nouvelle transaction basée sur la révision 25
       * édition de : A/D/gamma ... fait.

  ------- Révision 25 propagée (commit) >>>

  <<< Début d'une nouvelle transaction basée sur la révision 26
       * ajout de : A/Z/zeta ... fait.
       * édition de : A/mu ... fait.

  ------- Révision 26 propagée (commit) >>>

Le résultat d'un chargement est l'ajout de nouvelle révisions à un dépôt — comme si vous faisiez des propagations vers ce dépôt avec un client Subversion classique. De la même manière que pour une propagation, vous pouvez utiliser les procédures automatiques pour effectuer des actions particulières avant et après chaque propagation faite par la procédure de chargement. En passant les options --use-pre-commit-hook et --use-post-commit-hook (respectivement) à svnadmin load, vous demandez à Subversion d'exécuter les procédures automatiques pré-propagation et post-propagation (respectivement) pour chaque révision chargée. Un exemple d'utilisation de ces options est de s'assurer que les révisions chargées passent par les mêmes étapes de validation qu'une propagation normale. Bien sûr, utilisez ces options avec prudence — si votre script post-propagation envoie des emails à une liste de diffusion pour chaque nouvelle propagation, vous ne voulez peut-être pas envoyer des centaines voire des milliers d'emails de notification à la suite vers cette liste ! Vous pouvez en apprendre davantage sur l'utilisation des procédures automatiques dans la section intitulée « Mise en place des procédures automatiques ».

Notez que puisque svnadmin utilise l'entrée et la sortie standards pour le déchargement et le rechargement, les administrateurs les plus intrépides peuvent tenter des choses du genre (peut-être même en utilisant différentes versions de svnadmin de chaque côté de la barre verticale |) :

$ svnadmin create nouveau-depot
$ svnadmin dump vieux-depot | svnadmin load nouveau-depot

Par défaut, le fichier dump prend beaucoup de place — beaucoup plus que le dépôt lui-même. C'est parce que, par défaut, chaque version de chaque fichier est écrite en entier dans le fichier dump. C'est le comportement le plus simple et le plus rapide et cela convient bien si vous redirigez le flux de données directement vers un autre processus (comme un programme de compression, de filtrage ou de chargement). Mais si vous créez un fichier dump dans une optique de stockage à long terme, vous voudrez sans doute économiser de l'espace disque en utilisant l'option --deltas. Avec cette option, les révisions successives des fichiers sont écrites en tant que différences binaires et compressées — de la même manière que pour le stockage des fichiers dans le dépôt. Cette option ralentit le processus mais le fichier résultant a une taille beaucoup plus proche de celle du dépôt original.

Nous avons mentionné auparavant que svnadmin dump affiche un intervalle de révisions. Pour spécifier une révision unique ou un intervalle à décharger, utilisez l'option --revision (-r). Si vous omettez cette option, toutes les révisions existantes sont affichées :

$ svnadmin dump mon-depot -r 23 > rev-23.fichier-dump
$ svnadmin dump mon-depot -r 100:200 > revs-100-200.fichier-dump

Au fur et à mesure que Subversion décharge chaque nouvelle révision, il n'affiche que le minimum d'informations nécessaire à un futur chargement pour re-générer la révision à partir de la précédente. En d'autres termes, pour n'importe quelle révision du fichier dump, seuls les éléments ayant subi une modification dans cette révision apparaissent dans le fichier dump. La seule exception à cette règle est la première révision qui est déchargée par la commande svnadmin dump courante.

Par défaut, Subversion n'exprime pas la première révision déchargée sous forme de différences à appliquer à la révision précédente. En effet, il n'y a pas de révision précédente dans le fichier dump ! Et puis Subversion ne peut pas connaître l'état du dépôt dans lequel les données vont être chargées (si jamais elles le sont). Pour s'assurer que la sortie de chaque exécution de svnadmin dump est suffisante, la première révision déchargée est, par défaut, une représentation complète de chaque répertoire, de chaque fichier et de chaque propriété de cette révision du dépôt.

Vous pouvez toujours modifier ce comportement par défaut. Si vous ajoutez l'option --incremental quand vous déchargez le dépôt, svnadmin compare la première révision déchargée à la révision précédente du dépôt — de la même manière qu'il traite toutes les autres révisions qui sont déchargées. Il affiche alors la première révision de la même manière que le reste des révisions dans l'intervalle demandé — en ne mentionnant que les changements contenus dans cette révision. L'avantage est que vous pouvez créer plusieurs petits fichiers dump qui peuvent être chargés les uns à la suite des autres au lieu d'un unique gros fichier. Par exemple :

$ svnadmin dump mon-depot -r 0:1000 > fichier-dump1
$ svnadmin dump mon-depot -r 1001:2000 --incremental > fichier-dump2
$ svnadmin dump mon-depot -r 2001:3000 --incremental > fichier-dump3

Ces fichiers dump peuvent maintenant être chargés dans un nouveau dépôt avec la séquence de commandes suivante :

$ svnadmin load nouveau-depot < fichier-dump1
$ svnadmin load nouveau-depot < fichier-dump2
$ svnadmin load nouveau-depot < fichier-dump3

Une autre astuce consiste à utiliser l'option --incremental pour ajouter un nouvel intervalle de révisions à un fichier dump existant. Par exemple, vous pouvez avoir une procédure automatique post-commit qui ajoute simplement à un fichier dump le contenu de la révision qui a déclenché la procédure. Ou alors vous pouvez avoir un script qui tourne la nuit pour ajouter à un fichier dump les données de toutes les révisions qui ont eu lieu depuis le dernier lancement du script. Ainsi, svnadmin dump est une manière de réaliser des sauvegardes des changements de votre dépôt au fil du temps, dans l'éventualité d'un plantage système ou de toute autre événement catastrophique.

Les fichiers dump peuvent aussi être utilisés pour fusionner le contenu de différents dépôts en un seul dépôt. En utilisant l'option --parent-dir de svnadmin load, vous pouvez spécifier un nouveau répertoire racine virtuel pour la procédure de chargement. Ainsi, si vous avez des fichiers dump pour trois dépôts — disons fichier-dump-calc, fichier-dump-cal et fichier-dump-tab — vous pouvez commencer par créer un nouveau dépôt pour les héberger tous :

$ svnadmin create /var/svn/projets
$

Ensuite, créez dans le dépôt les nouveaux répertoires qui vont encapsuler le contenu de chacun des trois dépôts précédents :

$ svn mkdir -m "Racines initiales des projets" \
      file:///var/svn/projets/calc \
      file:///var/svn/projets/calendrier \
      file:///var/svn/projets/tableur
Révision 1 propagée.
$

Enfin, chargez chaque fichier dump dans le répertoire correspondant du nouveau dépôt :

$ svnadmin load /var/svn/projets --parent-dir calc < fichier-dump-calc
…
$ svnadmin load /var/svn/projets --parent-dir calendrier < fichier-dump-cal
…
$ svnadmin load /var/svn/projets --parent-dir spreadsheet < fichier-dump-tab
…
$

Mentionnons une dernière façon d'utiliser les fichiers dump de Subversion — la conversion depuis un système de stockage différent ou depuis un autre système de gestion de versions. Comme le format des fichiers dump est, pour sa plus grande partie, lisible par un humain, il devrait être relativement facile de décrire des ensembles de modifications — chaque ensemble constituant une nouvelle révision — en utilisant ce format de fichier. En fait, l'utilitaire cvs2svn (voir la section intitulée « Conversion d'un dépôt CVS vers Subversion ») utilise le format dump pour représenter le contenu d'un dépôt CVS, de manière à pouvoir copier ce contenu dans un dépôt Subversion.

Filtrage de l'historique d'un dépôt

Puisque Subversion stocke votre historique du suivi de versions en utilisant, au minimum, des algorithmes de différenciation binaire et de la compression de données (le tout, en option, dans un système de gestion de bases de données complètement opaque). Il est maladroit, et en tous cas fortement déconseillé, d'essayer de le modifier manuellement, sachant qu'en plus c'est assez difficile. Et une fois que des données ont été stockées dans votre dépôt, Subversion ne fournit généralement pas de moyen simple pour enlever ces données[35]. Mais, inévitablement, il y a des cas où vous voulez manipuler l'historique de votre dépôt. Par exemple pour supprimer tous les occurrences d'un fichier qui a été accidentellement ajouté au dépôt (alors qu'il ne devrait pas y être)[36]. Ou bien lorsque vous avez plusieurs projets qui partagent le même dépôt et que vous décidez de leur attribuer chacun le leur. Pour accomplir ce genre de tâches, les administrateurs ont besoin d'une représentation des données de leurs dépôts plus souple et plus facile à gérer : les fichiers dump Subversion.

Comme indiqué précédemment dans la section intitulée « Migration des données d'un dépôt », le format des fichiers dump Subversion est une représentation lisible par les humains des modifications apportées au cours du temps aux données suivies en versions. Utilisez la commande svnadmin dump pour extraire les données et svnadmin load pour les charger dans un nouveau dépôt. Le gros atout de l'aspect « lisible par les humains » des fichiers dump est que, si vous y tenez, vous pouvez en inspecter le contenu et le modifier. Bien sûr, la contrepartie est que, si vous avez un fichier dump d'un dépôt actif depuis plusieurs années, cela vous prendra un certain temps pour en inspecter manuellement le contenu et le modifier, un temps certain même.

C'est là qu'intervient svndumpfilter. Ce programme agit comme un filtre sur les chemins pour les flux de déchargement/chargement d'un dépôt. Vous n'avez qu'à lui fournir une liste de chemins que vous voulez conserver ou une liste de chemins que vous voulez éliminer et ensuite rediriger le flux de dump de vos données à travers ce filtre. Vous obtenez un flux modifié qui ne contient que les données suivies en versions des chemins que vous avez demandés (explicitement ou implicitement).

Prenons un exemple concret d'utilisation de ce programme. Précédemment dans ce chapitre (voir la section intitulée « Stratégies d'organisation d'un dépôt »), nous avons décrit le processus de décision permettant de choisir l'organisation des données de votre dépôt (utiliser un dépôt par projet ou les combiner, comment organiser les répertoires au sein du dépôt, etc.). Mais il peut arriver qu'après un certain nombre de révisions vous repensiez votre organisation et vouliez la modifier. Une modification classique est de déplacer plusieurs projets qui partagent le même dépôt vers des dépôts propres à chacun d'eux.

Notre dépôt imaginaire contient trois projets : calc, calendrier et tableur. Ils se trouvent côte à côte comme ceci :

/
   calc/
      trunk/
      branches/
      tags/
   calendrier/
      trunk/
      branches/
      tags/
   tableur/
      trunk/
      branches/
      tags/

Pour placer ces trois projets dans leur dépôts propres, nous commençons par décharger tout le dépôt :

$ svnadmin dump /var/svn/depot > fichier-dump-depot
* Révision 0 déchargée.
* Révision 1 déchargée.
* Révision 2 déchargée.
* Révision 3 déchargée.
…
$

Ensuite, nous passons ce fichier dump à travers le filtre, en n'incluant à chaque fois qu'un seul répertoire racine. Nous obtenons trois nouveaux fichiers dump :

$ svndumpfilter include calc < fichier-dump-depot > fichier-dump-calc
…
$ svndumpfilter include calendrier < fichier-dump-depot > fichier-dump-cal
…
$ svndumpfilter include tableur < fichier-dump-depot > fichier-dump-tab
…
$

C'est le moment de prendre une décision. Chacun de vos fichiers dump générera un dépôt valide, mais il conservera les chemins exactement comme ils étaient dans le dépôt original. Cela veut dire que même si vous obtenez un dépôt propre à votre projet calc ce dépôt aura toujours un répertoire racine calc. Si vous voulez que les répertoires trunk, tags et branches soient placés à la racine de votre dépôt, vous devez alors éditer les fichiers dump, en modifiant les en-têtes Node-path et Node-copyfrom-path pour qu'ils ne contiennent plus de référence au répertoire calc/. Vous devez également supprimer la section des données qui crée le répertoire calc. Elle ressemble à ceci :

Node-path: calc
Node-action: add
Node-kind: dir
Content-length: 0

[Avertissement] Avertissement

Si vous envisagez d'éditer à la main le fichier dump pour enlever un répertoire à la racine, assurez-vous que votre éditeur n'est pas configuré pour convertir les caractères de fin de ligne vers le format natif (par exemple de \r\n vers \n), sinon le contenu ne serait plus conforme aux métadonnées. Cela corromprait le fichier dump de manière irréversible.

Tout ce qu'il reste à faire à présent, c'est de créer vos trois nouveaux dépôts et de charger chaque fichier dump dans le bon dépôt, en ignorant l'UUID contenu dans chaque flux dump :

$ svnadmin create calc
$ svnadmin load --ignore-uuid calc < fichier-dump-calc
<<< Début d'une nouvelle transaction basée sur la révision 1
     * ajout de : Makefile ... fait.
     * ajout de : bouton.c ... fait.
…
$ svnadmin create calendrier
$ svnadmin load --ignore-uuid calendrier < fichier-dump-cal
<<< Début d'une nouvelle transaction basée sur la révision 1
     * ajout de : Makefile ... fait.
     * ajout de : cal.c ... fait.
…
$ svnadmin create tableur
$ svnadmin load --ignore-uuid tableur < fichier-dump-tab
<<< Début d'une nouvelle transaction basée sur la révision 1
     * ajout de : Makefile ... fait.
     * ajout de : tableur.c ... fait.
…
$

Les deux sous-commandes svndumpfilter possèdent des options pour décider comment traiter les révisions « vides ». Si une révision donnée ne contient que des modifications concernant des chemins qui ont été filtrés, cette révision dorénavant vide peut être considérée comme inintéressante voire indésirable. Pour permettre à l'utilisateur de décider que faire de telles révisions, svndumpfilter propose les options suivantes :

--drop-empty-revs

Ne générer aucune révision vide ; elles sont tout simplement ignorées.

--renumber-revs

Si les révisions vides sont ignorées (avec l'option --drop-empty-revs), changer les numéros de révision restants pour qu'il n'y ait pas de trous dans la séquence de numérotation.

--preserve-revprops

Si les révisions vides ne sont pas ignorées, garder les propriétés de la révision (message de propagation, auteur, date, propriétés personnalisées, etc.) pour ces révisions vides. Autrement les révisions vides ne contiennent que l'horodatage original et un message expliquant que c'est à cause de svndumpfilter que cette révision est vide.

Alors que svndumpfilter peut s'avérer très utile et permet de gagner énormément de temps, il est affublé malheureusement de deux chausse-trappes. D'abord, cet utilitaire est extrêmement sensible à la sémantique des chemins. Prêtez attention à la manière dont sont spécifiés les chemins dans votre fichier dump, avec ou sans barre oblique (/) initiale. Regardez pour cela les en-têtes Node-path et Node-copyfrom-path.

…
Node-path: tableur/Makefile
…

Si les chemins ont une barre oblique initiale, vous devez inclure des barres obliques au début de chaque chemin que vous indiquez à svndumpfilter include et svndumpfilter exclude (et s'ils n'en ont pas, n'incluez pas de barre oblique au début). Pour aller plus loin, si votre fichier dump contient à la fois des chemins avec et des chemins sans barre oblique initiale, pour quelque raison que ce soit[37], vous devrez probablement normaliser les chemins en adoptant une des deux conventions.

En outre, les chemins qui ont été copiés peuvent vous donner quelques soucis. Subversion supporte les opérations de copie dans le dépôt, c'est-à-dire quand un nouveau chemin est créé par la copie d'un autre chemin qui existe déjà. Il est possible qu'à un certain moment de la vie de votre dépôt, vous ayez copié un fichier ou un répertoire d'un endroit que svndumpfilter a exclu vers un endroit qui est inclus. Pour rendre les données du dump cohérentes, svndumpfilter doit bien inclure l'ajout du nouveau chemin — y compris le contenu de tous les fichiers créés par la copie — mais en tant que copie d'un chemin source qui n'existe pas dans le flux des données filtrées. Mais puisque le format dump de Subversion ne contient que ce qui a été modifié dans chaque révision, le contenu de la source de la copie risque de ne pas être disponible. Si vous êtes susceptible d'avoir la moindre copie de ce type dans votre dépôt, vous devrez peut-être repenser votre ensemble de chemins à inclure/exclure, pour y inclure aussi les chemins qui ont servi de sources à des opérations de copie qui vous posent problème.

Enfin, svndumpfilter effectue un filtrage des chemins pour le moins littéral. Si vous essayez de copier l'historique d'un projet dont la racine est trunk/mon-projet et de le déplacer dans son propre dépôt, vous utiliserez évidemment la commande svndumpfilter include pour conserver tous les changements dans et sous trunk/mon-projet. Mais le fichier dump résultant ne fait aucune hypothèse sur le dépôt dans lequel vous allez charger ces données. En particulier, les données déchargées peuvent commencer par la révision qui a ajouté le répertoire trunk/mon-projet mais ne pas contenir les directives pour créer le répertoire trunk lui-même (parce que trunk ne correspond pas au filtre utilisé). Vous devez vous assurer que tous les répertoires à la présence desquels le flux de données déchargées s'attend existent réellement dans le dépôt destination, avant d'essayer de charger le flux de données à l'intérieur.

Réplication d'un dépôt

Divers scénarios montrent l'intérêt d'avoir un dépôt Subversion dont l'historique des versions est exactement le même que celui d'un autre dépôt. Le plus évident est probablement celui de maintenir un dépôt de secours, utilisé quand le dépôt principal est inaccessible en raison d'un problème matériel, d'une coupure réseau ou de tout autre souci de ce type. D'autres scénarios comprennent le déploiement de dépôts redondants pour distribuer la charge sur plusieurs serveurs, les mises à niveau transparentes et d'autres encore.

Depuis la version 1.4, Subversion fournit un programme pour gérer de tels scénarios : svnsync. Il fonctionne essentiellement en demandant au serveur Subversion de « rejouer » les révisions, une par une. Il utilise ces informations sur les révisions pour répéter une propagation identique sur un autre dépôt. Aucun des deux dépôts n'a besoin d'être accessible localement sur la machine où svnsync tourne : ses paramètres sont des URL de dépôt et tout le travail est effectué via les interfaces d'accès au dépôt (Repository Access en anglais, ou RA) de Subversion. Tout ce dont il a besoin est un accès en lecture au dépôt source et un accès en lecture/écriture au dépôt de destination.

[Note] Note

Quand vous utilisez svnsync sur un dépôt source distant, le serveur Subversion de ce dépôt doit être en version 1.4 ou supérieure.

Supposons que vous voulez réaliser un miroir d'un de vos dépôts ; il vous faut alors disposer d'un dépôt destination vide qui servira de miroir. Ce dépôt cible peut utiliser n'importe quel magasin de données disponible (voir la section intitulée « Choix du magasin de données »), mais il ne doit comporter aucun historique. Le protocole utilisé par svnsync pour transmettre les informations de révision est particulièrement sensible aux divergences entre les historiques suivies en versions de la source et de la destination. Pour cette raison, bien que svnsync ne puisse pas exiger que le dépôt destination soit en lecture seule[38], autoriser des modifications d'historique sur le dépôt destination par un mécanisme externe autre que le processus de réplication mène droit au désastre.

[Avertissement] Avertissement

Ne modifiez pas le dépôt miroir de sorte que son historique de version diffère de celui du dépôt source. Les seules propagations et modifications de propriétés de révisions qui doivent avoir lieu sur ce dépôt miroir sont celles effectuées par l'outil svnsync.

Une autre exigence concernant le dépôt destination est que le processus svnsync doit être autorisé à modifier les propriétés de révision. Comme svnsync fonctionne dans le cadre du système des procédures automatiques du dépôt, l'état par défaut du dépôt (qui consiste à interdire les modifications des propriétés de révision, voir pre-revprop-change) n'est pas suffisant. Vous devez activer explicitement la procédure automatique pre-revprop-change et votre script doit autoriser svnsync à définir et à modifier les propriétés de révision. Une fois ces dispositions prises, vous êtes parés pour commencer la réplication des révisions du dépôt.

[Astuce] Astuce

Il est de bon ton de mettre un place un contrôle d'accès pour autoriser le processus de réplication de votre dépôt à faire ce qu'il a à faire tout en interdisant aux autres utilisateurs de modifier le contenu de votre dépôt miroir.

Examinons maintenant l'utilisation de svnsync dans un scénario classique de réplication. Nous saupoudrons le discours de quelques recommandations pratiques que vous êtes libre d'ignorer si elles ne sont pas nécessaires ou pas applicables à votre environnement.

Pour rendre service aux excellents développeurs de notre système de gestion de versions favori, nous allons répliquer le dépôt public qui contient le code source de Subversion et mettre ce miroir à disposition sur Internet, sur une machine différente de celle qui héberge le dépôt original. Cet hôte distant possède une configuration globale qui autorise les accès anonymes en lecture mais requiert une authentification pour modifier les dépôts (pardonnez-nous de passer rapidement sur les détails de la configuration du serveur Subversion pour le moment, mais ces aspects sont traités en profondeur dans le Chapitre 6, Configuration du serveur.). Et pour rendre l'exemple plus intéressant, et uniquement pour cela, nous piloterons la réplication depuis une troisième machine — en l'occurrence, celle que nous sommes en train d'utiliser.

Dans un premier temps, nous allons créer le dépôt qui servira de miroir. Cette étape et les deux suivantes requièrent l'accès à la ligne de commande de la machine sur laquelle le miroir sera hébergé. Toutefois, une fois que ce dépôt sera complètement configuré, nous n'aurons plus besoin d'y avoir accès directement.

$ ssh admin@svn.exemple.com \
      "svnadmin create /var/svn/miroir-svn"
admin@svn.exemple.com's password: ********
$

À ce stade, nous disposons d'un dépôt et, en raison de la configuration de notre serveur, ce dépôt est accessible directement depuis Internet. Maintenant, puisque nous ne voulons pas que quoi que ce soit modifie notre dépôt en dehors du processus de réplication, nous devons trouver un moyen de distinguer ce processus des autres prétendants aux propagations. Pour ce faire, nous utilisons un identifiant d'utilisateur dédié à notre processus. Seules les propagations et les modifications de propriétés de révisions effectuées par l'identifiant spécial id-sync sont autorisées.

Nous allons utiliser le système de procédures automatiques du dépôt à la fois pour autoriser le processus de réplication à faire ce qu'il doit faire et pour garantir qu'il soit le seul à le faire. Nous implémentons donc deux des procédures automatiques du dépôt : pre-revprop-change et start-commit. Le script pre-revprop-change est présenté dans l'Exemple 5.2, « Procédure automatique pre-revprop-change du dépôt miroir » et, pour résumer, vérifie que l'utilisateur qui essaie de modifier les propriétés est bien notre utilisateur id-sync. Si c'est bien le cas, la modification est autorisée ; sinon, elle est refusée.

Exemple 5.2. Procédure automatique pre-revprop-change du dépôt miroir

#!/bin/sh

USER="$3"

if [ "$USER" = "id-sync" ]; then exit 0; fi

echo "Seul l'utilisateur id-sync est autorisé à modifier les propriétés de révision." >&2
exit 1

Voilà pour les modifications des propriétés de révision. Maintenant nous devons nous assurer que seul l'utilisateur id-sync est autorisé à propager de nouvelles révisions dans le dépôt. Ce que nous allons faire en utilisant une procédure automatique start-commit telle que celle présentée dans l'Exemple 5.3, « Procédure automatique start-commit du dépôt miroir ».

Exemple 5.3. Procédure automatique start-commit du dépôt miroir

#!/bin/sh

USER="$2"

if [ "$USER" = "id-sync" ]; then exit 0; fi

echo "Seul l'utilisateur id-sync est autorisé à effectuer des propagations." >&2
exit 1

Après avoir installé nos procédures automatiques et s'être assuré qu'elles sont exécutables par le serveur Subversion, nous en avons terminé avec l'installation de notre dépôt miroir. Maintenant, nous allons effectivement lancer la réplication.

La première chose à faire avec svnsync est d'enregistrer dans notre dépôt destination le fait qu'il sera un miroir du dépôt source. Nous utilisons donc la sous-commande svnsync initialize. Nous fournissons des URL qui pointent vers les répertoires racines des dépôts destination et source, respectivement. Dans Subversion 1.4, c'est obligatoire — seule la réplication de dépôts complets est permise. Dans Subversion 1.5, cependant, vous pouvez aussi utiliser svnsync pour répliquer uniquement des sous-arborescences du dépôt.

$ svnsync help init
initialize (init): usage : svnsync initialize DEST_URL SOURCE_URL

Initialise un dépôt destination pour être synchronisé à partir
d'un autre dépôt.
…
$ svnsync initialize http://svn.exemple.com/miroir-svn \
                     http://svn.collab.net/repos/svn \
                     --sync-username id-sync --sync-password mdp-sync
Propriétés copiées pour la révision 0.
$

Notre dépôt destination se rappelle maintenant qu'il est un miroir du dépôt public du code source Subversion[39]. Notez que nous avons fourni un identifiant et un mot de passe en arguments à svnsync — c'était exigé par la procédure automatique pre-revprop-change de notre dépôt miroir.

[Note] Note

Dans Subversion 1.4, les valeurs assignées aux options --username et --password de svnsync étaient utilisées pour l'authentification à la fois par le dépôt source et par le dépôt destination. Cela posait des problèmes quand ces valeurs n'étaient pas exactement les mêmes pour les deux dépôts, particulièrement quand le mode non-interactif était utilisé (avec l'option --non-interactive).

Ce problème a été résolu dans la version 1.5 de Subversion avec l'introduction de deux nouvelles paires d'options. Utilisez --source-username et --source-password pour vous authentifier auprès du dépôt source ; utilisez --sync-username et --sync-password pour vous authentifier auprès du dépôt destination (les vieilles options --username et --password existent encore pour assurer la compatibilité mais nous en déconseillons l'usage).

Abordons maintenant la partie amusante. En une seule sous-commande, nous pouvons demander à svnsync de copier toutes les révisions qui n'ont pas encore été répliquées du dépôt source vers le dépôt destination[40]. La sous-commande svnsync synchronize fouille dans les propriétés de révision spéciales du dépôt destination pour déterminer aussi bien de quel dépôt source il est le miroir que la dernière révision qui a été répliquée, en l'occurrence la révision 0. Ensuite, elle interroge le dépôt source pour savoir quelle est la dernière révision propagée dans ce dépôt. Enfin, elle demande au dépôt source de commencer à envoyer toutes les révisions entre la révision 0 et la dernière révision. Au moment où svnsync reçoit la réponse du dépôt source, elle commence la retransmission des révisions vers le dépôt destination en tant que nouvelles propagations.

$ svnsync help synchronize
synchronize (sync): usage : svnsync synchronize URL_DEST

Transfère toutes les révisions en attente vers la destination,
à partir de la source avec laquelle elle a été initialisée.
…
$ svnsync synchronize http://svn.exemple.com/miroir-svn
Transmission des données ........................................
Révision 1 propagée.
Propriétés copiées pour la révision 1.
Transmission des données ..
Révision 2 propagée.
Propriétés copiées pour la révision 2.
Transmission des données .....
Révision 3 propagée.
Propriétés copiées pour la révision 3.
…
Transmission des données ..
Révision 23406 propagée.
Propriétés copiées pour la révision 23406.
Transmission des données .
Révision 23407 propagée.
Propriétés copiées pour la révision 23407.
Transmission des données ....
Révision 23408 propagée.
Propriétés copiées pour la révision 23408.
$

Il est intéressant de noter ici que, pour chaque révision répliquée, il y a d'abord propagation de la révision dans le dépôt destination, puis des changements de propriétés ont lieu. C'est parce que la propagation initiale est effectuée par (et donc attribuée à) l'utilisateur id-sync et qu'elle est horodatée lors de la création de la nouvelle révision. Et aussi parce que les interfaces d'accès au dépôt Subversion n'autorisent pas la définition de propriétés de révision au sein d'une propagation. C'est pourquoi svnsync fait suivre la réplication par une série de modifications de propriétés qui copient dans le dépôt destination toutes les propriétés de révision trouvées dans le dépôt source pour cette révision. Cela a également pour effet de corriger l'auteur et l'horodatage de la révision pour être cohérent avec le dépôt source.

Notez également que svnsync documente tout ce qu'il fait en détail, afin de pouvoir être interrompu ou redémarré sans remettre en cause l'intégrité des données répliquées. Si une panne réseau survient pendant la réplication d'un dépôt, relancez simplement la commande svnsync synchronize et elle reprendra tranquillement là où elle s'était arrêtée. En fait, au fur et à mesure que de nouvelles révisions apparaissent dans le dépôt source, c'est précisément ce qu'il faut faire pour conserver votre miroir à jour.

Le procédé est cependant peu élégant. Comme les propriétés des révisions Subversion peuvent être modifiées n'importe quand dans la vie du dépôt et comme elles ne conservent pas de trace des modifications effectuées, les processus de réplication doivent faire particulièrement attention à ces propriétés. Si vous avez déjà répliqué les quinze premières révisions d'un dépôt et que quelqu'un modifie une propriété de révision concernant la révision 12, svnsync ne sait pas qu'il faut revenir en arrière et modifier la copie de la révision 12. Vous devez le lui indiquer manuellement en utilisant la sous-commande svnsync copy-revprops (ou à l'aide d'autres outils), ce qui re-réplique toutes les propriétés de révision pour une révision particulière ou un ensemble de révisions.

$ svnsync help copy-revprops
copy-revprops: usage: svnsync copy-revprops URL_DEST [REV[:REV2]]

Copie les propriétés de révision pour l'intervalle donné vers la destination
à partir de la source avec laquelle elle a été initialisée.
…
$ svnsync copy-revprops http://svn.exemple.com/miroir-svn 12
Propriétés copiées pour la révision 12.
$

C'en est fini pour la présentation rapide de la réplication de dépôt. Vous voudrez sûrement automatiser un certain nombre de choses autour de ce processus. Par exemple, alors que notre exemple présentait une mise en place « tirer-et-pousser », vous êtes susceptible de vouloir que ce soit le dépôt source qui pousse les modifications vers un ou plusieurs miroirs prédéfinis lors de l'exécution des procédures automatiques post-commit et post-revprop-change. Ceci permettrait au miroir d'être à jour presque en temps réel.

En outre, et bien que ce ne soit pas très utilisé, svnsync sait répliquer des dépôts pour lesquels l'identifiant qu'il utilise pour s'authentifier n'a que des droits partiels en lecture. Il copie simplement les parties du dépôt qu'il est autorisé à voir. Un tel miroir n'est clairement pas une bonne solution de sauvegarde.

Avec Subversion 1.5, svnsync a acquis la capacité de répliquer uniquement un sous-ensemble d'un dépôt plutôt que le dépôt entier. La procédure pour configurer et assurer la maintenance d'un tel miroir est exactement la même que pour répliquer un dépôt entier, excepté lors du passage de l'URL du dépôt source à svnsync init : vous spécifiez l'URL d'un sous-répertoire à l'intérieur du dépôt. La synchronisation du miroir ne copie que les modifications relatives à l'arborescence sous le répertoire indiqué. Notez quand même quelques restrictions sur cette fonction : premièrement, vous ne pouvez pas répliquer plusieurs sous-répertoires disjoints du dépôt source vers un unique dépôt miroir — vous devez dans ce cas répliquer un répertoire parent qui est commun à tous les répertoires que vous voulez répliquer ; deuxièmement, la logique de filtrage est entièrement basée sur le chemin d'accès donc, si le sous-répertoire que vous répliquez a été renommé par le passé, votre miroir ne contiendra que les révisions depuis lesquelles il a le nom indiqué dans l'URL que vous avez spécifiée. Et, de la même manière, si le sous-répertoire source est renommé dans le futur, le processus de synchronisation ne répliquera plus les données à partir du moment où l'URL que vous avez spécifiée ne sera plus valide.

En ce qui concerne les interactions entre les utilisateurs et les dépôts ainsi que les miroirs, il est possible d'avoir une seule copie de travail qui interagisse avec un dépôt et son miroir, mais vous devez faire quelques manipulations pour y arriver. D'abord, vous devez vous assurer que le dépôt source et le dépôt miroir ont bien le même identifiant unique UUID (ce qui n'est pas le cas par défaut). Reportez-vous à la section intitulée « Gestion des identifiants uniques (UUID) des dépôts » plus loin dans ce chapitre pour plus de détails à ce sujet.

Une fois que les deux dépôts ont le même identifiant unique, vous pouvez utiliser svn switch avec l'option --relocate pour faire pointer votre copie de travail vers le dépôt de votre choix ; cette procédure est décrite dans svn switch. Cette manœuvre est potentiellement dangereuse si le miroir et le dépôt original ne sont pas étroitement synchronisés : une copie de travail à jour, pointant vers le dépôt source, que l'on ferait pointer vers un miroir non à jour, est perdue devant l'absence soudaine de révisions qu'elle s'attend à trouver et elle renvoie des erreurs dans ce sens. Si cela arrive, vous pouvez refaire pointer votre copie de travail vers le dépôt original et soit attendre que le dépôt miroir se mette à jour, soit faire revenir en arrière votre copie de travail jusqu'à un numéro de révision dont vous savez qu'il est présent dans le dépôt miroir, puis retenter le changement de dépôt.

Enfin, soyez conscient que la réplication fournie par svnsync, basée sur les révisions, n'est rien de plus que de la simple réplication de révisions. Seules les informations incluses dans le format de fichier dump des dépôts Subversion peuvent être répliquées. Ainsi, svnsync possède les mêmes limitations que les flux de chargement/déchargement Subversion et n'inclut donc pas les procédures automatiques, la configuration du dépôt et du serveur, les transactions inachevées ni les informations relatives aux verrous posés par les utilisateurs sur les chemins du dépôt.

Sauvegarde d'un dépôt

En dépit des nombreux progrès de la technologie depuis l'avènement de l'informatique moderne, une chose reste certaine : le pire n'est jamais très loin. L'alimentation électrique tombe en panne, les réseaux subissent des coupures, les mémoires vives crament, les disques durs flanchent, et ce même pour le plus consciencieux des administrateurs. Nous en venons donc maintenant à un sujet très important : comment réaliser des copies de sauvegarde des données de votre dépôt.

Les administrateurs de dépôts Subversion disposent de deux méthodes de sauvegarde : la complète et l'incrémentale. Une sauvegarde complète d'un dépôt implique de récupérer d'un seul coup toutes les informations nécessaires pour reconstruire complètement ce dépôt dans le cas d'une catastrophe. Habituellement, cela consiste à dupliquer, littéralement, la totalité du répertoire du dépôt (ce qui inclut l'environnement Berkeley DB ou FSFS). Les sauvegardes incrémentales sont plus restreintes : elles ne sauvegardent que les données du dépôt qui ont changé depuis la sauvegarde précédente.

Pour ce qui concerne les sauvegardes complètes, l'approche naïve pourrait sembler satisfaisante. Mais à moins d'interdire temporairement tout accès au dépôt, une simple copie récursive du répertoire risque de créer une sauvegarde corrompue. Dans le cas d'une base de données Berkeley DB, la documentation décrit un certain ordre de copie des fichiers qui garantit une copie de sauvegarde valide. Un ordre similaire existe avec les données FSFS. Mais vous n'avez pas à implémenter ces algorithmes vous-même, puisque l'équipe de développement de Subversion l'a déjà fait pour vous. La commande svnadmin hotcopy prend soin de tout ça afin de réaliser une copie à chaud de votre dépôt. Et son invocation est aussi triviale que la commande Unix cp ou qu'une copie sous Windows :

$ svnadmin hotcopy /var/svn/depot /var/svn/depot-sauvegarde

La sauvegarde générée est un dépôt Subversion totalement fonctionnel, capable de prendre immédiatement la place de votre dépôt en production si les choses tournent au vinaigre.

Lors de la copie d'un dépôt Berkeley DB, vous pouvez même ordonner à svnadmin hotcopy de purger les fichiers de journalisation inutilisés (voir la section intitulée « Purge des fichiers de journalisation inutilisés de Berkeley DB ») du dépôt original une fois la copie terminée. Ajoutez simplement l'option --clean-logs à la ligne de commande :

$ svnadmin hotcopy --clean-logs /var/svn/depot-bdb /var/svn/depot-bdb-sauvegarde

Des outils additionnels existent également autour de cette commande. Le répertoire tools/backup du code source de Subversion contient le script hot-backup.py. Ce script ajoute de la gestion de sauvegardes par-dessus svnadmin hotcopy, permettant de ne garder que les dernières sauvegardes (le nombre de sauvegardes à conserver est configurable) de chaque dépôt. Il gère automatiquement les noms des répertoires sauvegardés pour éviter les collisions avec les précédentes sauvegardes et élimine par rotation les sauvegardes les plus anciennes. Même si vous réalisez aussi des sauvegardes incrémentales, cette commande vous servira peut-être régulièrement. Par exemple, vous pouvez utiliser hot-backup.py dans un outil permettant le lancement différé de commandes (tel que cron sur les systèmes Unix) afin de le lancer toutes les nuits (ou à tout autre intervalle de temps qui vous convient mieux).

Quelques administrateurs utilisent un autre mécanisme de sauvegarde basé sur la génération et le stockage de flux dump des dépôts. Nous avons décrit dans la section intitulée « Migration des données d'un dépôt » comment utiliser svnadmin dump avec l'option --incremental pour réaliser une sauvegarde incrémentale d'une révision ou d'un intervalle de révisions donné. Et bien sûr, vous pouvez réaliser une sauvegarde complète en omettant l'option --incremental dans la commande. Cette méthode comporte certains avantages, entre autres que le format de vos informations sauvegardées est flexible (il n'est pas lié à une plateforme, à un type de magasin de données ou à une version particulière de Subversion ou de Berkeley DB). Mais cette flexibilité a un coût, à savoir le temps de restauration des données, qui en plus augmente avec chaque nouvelle révision propagée dans le dépôt. Aussi, comme c'est le cas pour un tas d'autres méthodes de sauvegarde, les modifications sur les propriétés de révision qui sont effectuées après une sauvegarde de ladite révision ne sont pas prises en compte par l'utilisation de flux de dump incrémentaux ne se chevauchant pas. C'est pourquoi nous recommandons de ne pas se reposer uniquement sur le type de sauvegarde basé sur les fichiers dump.

Comme vous pouvez le constater, chaque type de sauvegarde a ses avantages et ses inconvénients. La méthode la plus facile est de loin la sauvegarde à chaud complète, qui fournit toujours une copie conforme et fonctionnelle de votre dépôt. En cas d'accident sur votre dépôt de production, vous pouvez effectuer une restauration à partir de votre sauvegarde par une simple copie récursive de répertoire. Malheureusement, si vous maintenez plusieurs sauvegardes de votre dépôt, chaque sauvegarde consomme autant d'espace disque que votre dépôt en production. Les sauvegardes incrémentales, en revanche, sont plus rapides à réaliser et prennent moins de place. Mais le processus de restauration peut s'avérer pénible, avec souvent plusieurs sauvegardes incrémentales à appliquer. D'autres méthodes ont leurs propres bizarreries. Les administrateurs doivent trouver le juste milieu entre le coût des sauvegardes et le coût de la restauration.

Le programme svnsync (voir la section intitulée « Réplication d'un dépôt ») fournit en fait une approche médiane assez pratique. Si vous synchronisez régulièrement un miroir en lecture seule avec votre dépôt principal, ce miroir en lecture seule se révèle être un bon candidat pour prendre le relais du dépôt défaillant en cas de besoin. Le principal inconvénient de cette méthode est que seules les données suivies en versions sont synchronisées — les fichiers de configuration du dépôt, les verrous utilisateurs sur les chemins ou d'autres éléments stockés physiquement dans le répertoire du dépôt mais pas dans le système de fichiers virtuel du dépôt ne sont pas pris en charge par svnsync.

Quelle que soit la méthode de sauvegarde utilisée, les administrateurs doivent savoir comment les modifications des propriétés non suivies en versions des révisions sont prises en compte (ou pas). Puisque ces modifications elles-mêmes ne créent pas de nouvelles révisions, elles n'activent pas les procédures automatiques post-commit ni même éventuellement les procédures automatiques pre-revprop-change et post-revprop-change[41]. Et puisque vous pouvez modifier les propriétés de révision sans respecter l'ordre chronologique (vous pouvez changer n'importe quelle propriété de révision à n'importe quel moment), une sauvegarde incrémentale des dernières révisions pourrait ne pas intégrer la modification d'une propriété de révision qui faisait partie d'une sauvegarde précédente.

En règle générale, seuls les plus paranoïaques ont besoin de sauvegarder le dépôt entier, disons, à chaque propagation. Cependant, en considérant qu'un dépôt donné possède des mécanismes de redondance autres avec une certaine granularité (tels que des e-mails envoyés à chaque propagation ou des fichiers dumps incrémentaux), réaliser une copie à chaud de la base de données, dans le cadre des sauvegardes nocturnes quotidiennes des systèmes, est une bonne pratique d'administration. Ce sont vos données, protégez-les autant que vous le voulez.

Bien souvent, la meilleure approche de sauvegarde d'un dépôt consiste à ne pas mettre tous ses œufs dans le même panier, en utilisant une combinaison des méthodes décrites ici. Les développeurs Subversion, par exemple, sauvegardent le code source de Subversion chaque nuit en utilisant hot-backup.py et effectuent une copie distante par rsync de ces sauvegardes complètes ; ils conservent plusieurs archives de tous les emails de notification des propagations et des changements de propriétés ; ils ont également des miroirs maintenus par divers volontaires qui utilisent svnsync. Votre solution peut ressembler à cela, mais elle doit être adaptée à vos besoins et maintenir l'équilibre entre commodité et paranoïa. Et quoi que vous fassiez, vérifiez la validité de vos sauvegardes de temps en temps (à quoi servirait une roue de secours crevée ?). Bien que tout ceci n'empêche pas votre matériel de subir les affres du destin[42], cela vous aidera certainement à vous sortir de ces situations délicates.

Gestion des identifiants uniques (UUID) des dépôts

Chaque dépôt Subversion possède un identifiant unique (Universally Unique IDentifier en anglais ou UUID). Cet UUID est utilisé par les clients Subversion pour vérifier l'identité d'un dépôt quand les autres formes de vérification ne sont pas satisfaisantes (telles que l'URL du dépôt qui peut varier avec le temps). La plupart des administrateurs de dépôt n'ont jamais (ou très rarement) à se préoccuper des UUID autrement que comme d'un détail d'implémentation bas niveau de Subversion. Parfois, cependant, il faut prêter attention à ce détail.

En règle générale, les UUID de vos dépôts de production doivent être uniques. C'est le but, après tout, des UUID. Mais il y a des cas où vous voulez que les UUID de deux dépôts soient identiques. Par exemple, quand vous faites une copie de sauvegarde d'un dépôt, vous voulez que cette sauvegarde soit une réplique exacte de l'original afin que dans le cas où vous restaureriez la sauvegarde pour remplacer le dépôt de production, ceci soit transparent pour les utilisateurs. Quand vous déchargez et chargez l'historique d'un dépôt (comme décrit précédemment dans la section intitulée « Migration des données d'un dépôt »), vous devez décider si vous incluez l'UUID dans le flux de données déchargées (le fichier dump) qui va dans le nouveau dépôt. Les circonstances vous imposeront la marche à suivre.

Il y a plusieurs façons de faire pour attribuer (ou modifier) un UUID à un dépôt, le cas échéant. Avec Subversion 1.5, il suffit d'utiliser la commande svnadmin setuuid. Si vous fournissez un UUID explicite à cette sous-commande, elle valide le format de l'UUID et fixe l'identifiant unique du dépôt à cette valeur. Si vous omettez l'UUID, un nouvel UUID est généré automatiquement pour votre dépôt.

$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$ svnadmin setuuid /var/svn/depot   # créer un nouvel UUID
$ svnlook uuid /var/svn/depot
3c3c38fe-acc0-11dc-acbc-1b37ff1c8e7c
$ svnadmin setuuid /var/svn/depot \
           cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec  # restaure l'ancien UUID
$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Pour ceux qui utilisent une version de Subversion antérieure à 1.5, ces tâches sont un peu plus compliquées. Vous pouvez attribuer explicitement un UUID en redirigeant le flux d'un fichier dump qui comporte le nouvel UUID avec la commande svnadmin load --force-uuid CHEMIN-DU-DEPOT.

$ svnadmin load --force-uuid /var/svn/depot <<EOF
SVN-fs-dump-format-version: 2

UUID: cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
EOF
$ svnlook uuid /var/svn/depot
cf2b9d22-acb5-11dc-bc8c-05e83ce5dbec
$

Faire générer un nouvel UUID à une ancienne version de Subversion n'est pas aussi simple. La meilleure façon de faire est certainement de trouver un moyen de générer un UUID puis d'affecter explicitement cet UUID au dépôt.



[34] Par exemple, disque dur + gros aimant à côté = désastre.

[35] C'est d'ailleurs pour cela que vous utilisez un système de gestion de versions, non ?

[36] Des suppressions délibérées et avisées de données suivies en versions peuvent effectivement être justifiées par des cas d'utilisation réels. C'est pourquoi une fonctionnalité « d'oblitération » est une des fonctionnalités les plus demandées pour Subversion et les développeurs de Subversion espèrent pouvoir la fournir bientôt.

[37] Bien que svnadmin dump ait une politique cohérente concernant la barre oblique initiale (aussi appelée « slash » — il ne l'inclut pas), d'autres programmes qui génèrent des fichiers dump sont susceptibles de ne pas être aussi cohérents.

[38] En fait, le dépôt ne peut pas être complètement en lecture seule, sinon svnsync lui-même aurait du mal à y copier l'historique des révisions.

[39] NdT : il s'agit ici de l'ancienne adresse du dépôt Subversion.

[40] Nous avertissons le lecteur que, bien qu'il lui suffise de quelques secondes pour lire ce paragraphe et l'exemple qui suit, le temps nécessaire pour réaliser une opération de réplication est, disons, un peu plus long.

[41] La commande svnadmin setlog peut être utilisée de manière à contourner les procédures automatiques.

[42] Vous savez, le fameux « concours de circonstances », celui auquel vous êtes arrivé premier.