SVN : Synchronisation de dépôts

Bonjour,

Aujourd’hui, petit tour sur SVN et la manière de débuter une synchronisation de dépôts.

De nombreux articles sont disponibles sur le net, dont la documentation de subversion. Mais souvent, ces explications sont basées sur des cas nominaux.
Je vais m’intéresser ici à un cas que j’ai rencontré et résolu, non sans difficultés.

Les contraintes :

  • Le dépôt initial contient d’autres projets que celui concerné par la synchronisation (et qui ne doivent donc pas être synchronisés)
  • Le dépôt source et la cible (la  copie réalisé avec cette synchronisation) sont situés sur deux serveurs différents.
  • Le projet que l’on souhaite synchroniser dispose d’un historique conséquent (140.000 révisions pour le trunk, une quinzaine de tags ainsi qu’une dizaine de branches).
  • L’arborescence du projet a été revue plusieurs fois, et totalement au cours de son histoire.
Les solutions proposées :

Après quelques recherches, on tombe rapidement sur trois solutions proposées dans la documentation Subversion et utilisées pour gérer ce type de demandes.


Le test des solutions :

  • svnadmin hotcopy
AvantagesInconvénients
Rapidité d’exécution (moins d’une heure d’exécution sur mon exemple)Copie machine-dépendante. La copie se base sur des fichiers systèmes. Exemple testé : Synchronisation entre un serveur windows 2008 vers un serveur windows 2012 en échec.
Obligation d’avoir accès à la machine source. Les chemins utilisés sont des chemins locaux. On ne peut pas employer d’URLs.

En détail : Cette commande a permis de créer une copie directe du dépôt, en un minimum de temps. Il m’a fallu cependant disposer des accès au serveur sur lequel était stocké le dépôt initial. Et malheureusement, en déposant cette copie sur le serveur cible, je me suis aperçu que la copie ne fonctionnait plus. Comme spécifié dans la documentation, elle est machine-dépendante. L’erreur rencontrée :

A savoir :

Deux raisons rencontrées à ce type d’erreur. Soit vous essayez de copier un dépôt directement sur une machine. Ou alors, vous tenter de le faire avec un synchronize mais avec une version de subversion différente de l’origine.
Le format correspondant à la valeur présente dans le fichier « format » situé à la racine du dépôt SVN. Ce fichier n’est pas modifiable et ne comporte qu’un chiffre comme donnée, allant de 1 à 6. A savoir que ces chiffres sont définis à la création du dépôt en fonction de la version de SVN :

FormatVersion
1Subversion 1.1+
2Subversion 1.4+
3Subversion 1.5+
4Subversion 1.6+
5Version de développement 1.7, retiré avant la version 1.7.0 final release
6Subversion 1.8+
  • svnsync initalize / synchronize
AvantagesInconvénients
Exécution possible à distance, uniquement avec les accès SVNLenteur d’exécution (environ 18h d’exécution dans notre exemple)
Gère la copie révision à révisionGère les commits un par un et risque d’échouer en cas de changement d’architecture du dépôt

En détail : je ne disposais pas à l’origine des accès au serveur sur lequel se trouvait le dépôt source. Il a tout de même été possible de lancer la synchronisation. Cependant, elle a échoué en tentant de synchroniser les commits liés aux modifications d’arborescence du projet. Il tentait synchroniser des dossiers qui n’existaient plus. Et cette erreur s’étant produite après une dizaine d’heures d’exécutions. Autant dire qu’une journée est rapidement perdue.

  • svnadmin dump / load
AvantagesInconvénients
Rapidité d’exécution en filtrant (1h30 avec notre exemple)Ne crée qu’une seule révision
Possibilité de créer un dump (sauvegarde dans un fichier plat) à partir de révisions spécifiques et de pouvoir filtrer ce dumpObligation d’avoir accès à la machine qui stock le dépôt. Les chemins utilisés sont des chemins locaux. On ne peut pas employer d’URL.

En détail : La création d’un dump semblait une bonne solution. Mais il faut y apporter quelques réserves. Tout d’abord, sur un dépôt de notre importance, il est obligatoire de filtrer (détaillé après) les révisions sauvegardées dans ce dump. En effet, à la première exécution du dump, la copie a excédé les 30Go (tout l’espace disque libre), entraînant un redémarrage du serveur. A première vue, la copie totale nécessiterait au minimum 300Go, si ce n’est plus.
Le filtrage a permis de réaliser une sauvegarde rapide du dump, que j’ai pu recharger sur le nouveau serveur. Mais arrivé là, je disposais bien d’une copie du dépôt mais à une révision 1. Cette solution a permis de disposer d’une copie, mais pas de pouvoir synchroniser directement les dépôts.

La solution employée :

Etant donné que chacune de ces solutions prises séparément n’offrait que des demi-solutions, j’en ai couplé deux afin de bénéficier de leurs différents avantages. La solutions en étapes :

  • Création d’un dump du dépôt pour une révision spécifique (la dernière en date).

svnadmin dump C:/ RepoCopy -r 140000 > dumpRepo140000.dump

Le fait de commencer à cette révision permet de conserver l’historique complet des changements SVN en évitant les problèmes de rechargement du dépôt causés par les modifications d’architecture.
On indique le chemin du dépôt pour lequel on souhaite créer un dump : C:/ RepoCopy.
L’option –r permet de spécifier la révision ou l’intervalle de révision concerné par ce dump.
On spécifie le chemin et nom du fichier en sortie : dumpRepo140000.dump.

  • Filtrage du dump pour retirer les projets qui ne concernaient pas cette demande.
svndumpfilter include projet < dumpRepo140000.dump > dumpfileFilter.dump

On indique le nom des dossiers de ce dépôt à inclure (ou exclure si l’on souhaite). Ici on ne conserve que le dossier « projet »
On spécifie le nom du dump à filter : dumpRepo140000.dump
Et le nom du dump en sortie de filtre : dumpfileFilter.dump

  • Création (svnadmin create ou utilisation d’un outil tel que TortoiseSVN) et initialisation du dépôt. Cette initialisation fournira la configuration qui permettra la synchronisation ultérieur

svnsync initialize –allow-non-empty file:///D:/SynchroSVN/RepoFiltre http://192.168.1.10/svnrepo/projet –source-username userNameSource –source-password passwordSource –sync-username userNameCible –sync-password passwordCible

L’option –allow-non-empty vous permettra d’initialiser le dépôt si vous avez oublié de le faire avant d’exécuter la commande load
On y spécifie l’URL du dépôt cible sur lequel va être chargé cette révision : file:///D:/SynchroSVN/RepoFiltre
Ainsi que l’url du dépôt source et les informations de connexion des deux dépôts (login / password).

  • Chargement du dump dans le nouveau dépôt

svnadmin load –bypass-prop-validation D:/SynchroSVN/RepoFiltreTest < capsante-dumpfileFilterTest

L’option –bypass-prop-validation permet d’ignorer la validation de propriété. (Notre chargement échouait à cause d’une validation impossible en lien avec les évolutions d’architectures du dépôt).
On spécifie le chemin du dépôt sur lequel va être chargé le dump, puis le dump lui-même.

  • Montée de révision du dump

A ce niveau, on dispose à présent d’un nouveau dépôt, copie conforme de l’ancien, à la révision 140.000, avec une particularité. Si l’on consulte ce nouveau dépôt, il se trouve être à la révision 1. Ce point est bloquant pour la synchronisation, car pour synchroniser deux dépôts, ils doivent être à la même révision.
Une petite manipulation est nécessaire pour modifier la révision courante du dépôt et obtenir celle désirée.

Dans le dossier ./db/revs, on dispose d’un dossier « 0 », contenant deux fichiers « 0 » et « 1 ».
Ce dossier regroupe un ensemble de 1000 révisions (de 0 à 999). Le dossier « 1 » regrouperait celles allant de 1000 à 1999 par exemple. Et chacun de ces fichiers correspond donc à une révision. Nous allons donc créer un dossier « 140 », correspondant à l’ensemble des révisions allant de 140.000 à 140.999. Dans ce dossier, il suffit de copier les fichiers « 0 » et « 1 » (et les renommer si l’on souhaite avancer par exemple directement vers une révision intermédiaire).

La même étape est à reproduire pour le dossier ./db/revprops, qui correspond aux commentaires des différents commits effectués sur le dépôt.

Et enfin, il faut modifier le fichier ./db/current pour lui indiquer la version courante, à savoir 140.000.
A la consultation, le dépôt doit à présent apparaitre à la révision 140.000.

  • Lancement de la synchronisation entre les deux dépôts.

svnsync sync file:/// D:/SynchroSVN/RepoFiltreTest –source-username userNameSource –source-password passwordSource –sync-username userNameCible –sync-password passwordCible

En conclusion

Il n’existe pas de solution unique aux problèmes que l’on peut rencontrer sur SVN. Cependant, on dispose de nombreux outils pour réussir à les résoudre ou au moins les contourner.
Il ne faut pas hésiter à utiliser les différentes solutions possibles et les mixer sans pourtant en oublier les éternels problèmes de versions.

En espérant que cela pourra vous servir.