Suite de mes pérégrinations avec la migration git vers svn (1ère partie ici).
Elle n’a pas été de tout repos et a pris un peu de temps (d’où le délai entre la 1ère et la 2ème partie de ce post…)
Le workflow utilisé
Nous avons décidé de partir sur le workflow gitflow, en utilisant la branche “support”. En effet, le produit est déployé sur les serveurs des clients et les mises à jour se font à un rythme assez lent. Nous nous retrouvons donc à devoir réaliser la maintenance de nombreuses anciennes versions tout en développant les nouvelles fonctionnalités. Cette branche “support” permet donc de créer des patchs sur les anciennes versions, sans forcément les reporter sur les autres branches (le report doit se faire manuellement car la base de code peut avoir énormément changé entre temps).
Revue de code ?
Nous réalisons systématiquement des revues de code avant chaque commit, sans pour autant utiliser d’outil pour cela (on privilégie la communication en face à face 😉 ). La question s’est posée d’intégrer un outil comme gerrit pour s’assurer que cette revue de code était bien réalisée.
Finalement, pour simplifier la prise en main de git dans un premier temps, nous avons décidé de ne pas le mettre en place et de conserver notre fonctionnement actuel. On verra à l’usage si un outil est vraiment nécessaire !
Définition des projets “pilotes”
Après avoir fait le ménage dans la liste des projets pour ne conserver que les ceux qui étaient encore utilisés, nous avons définie une liste de projets qui serviraient de pilotes à cette migration (pour éviter l’effet big-bang et s’assurer que tout fonctionne bien).
Nous n’avons évidemment pas choisi le cœur de l’application, mais un outil qui permet de gérer les migrations et qui faisait des requêtes sur le serveur SVN. Étant donné qu’il fallait le modifier pour remplacer tous ces appels par des appels vers Git, le pilote était tout trouvé !
Pour réaliser ces appels vers le serveur Git, nous avons utilisé la librairie JGit.
Voici quelques exemples d’appels:
SVNCheckout => git.checkout().setName(« Nom de la branche »).call() ;
Checkout partiel: git.checkout().addPath("file1.txt").addPath("file2.txt").call();
SVNCommit => git.commit().setMessage(« blabla »).setCommitter(nom, email).call() ;
git.pull().call();
SVNAdd => git.add().call();
SVNList => utiliser RevWalk pour parcourir les fichiers
SVNLog => Récupérer les 10 derniers commits de la branche courante:
git.log().add(head).setMaxCount(10).call();
=> Entre 2 commits :
git.log().addRange(since, until).call();
SVNStatus => git.status().call() ;
SVNUpdate => git.pull().setRemote(URL).call();
La migration !
Pour simplifier cette migration (qui doit migrer une dizaine de projets), j’ai donc réalisé un petit script bash :
#!/bin/bash
# Migration SVN -> GIT
# Author : Cécilia Bossard (cecilia.bossard@timwi.com)
function migration(){
# Parametre 1 : nom projet
# Parametre 2 : URL svn
# Parametre 3 : derniere revision SVN a prendre en compte (facultatif)
echo 'Migration '$1
git svn clone $3 $2 --authors-file=users.txt --no-metadata -s $1
cd $1/.git
echo 'Creation tags'
git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done
echo 'Creation branches'
git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done
echo 'Nettoyage'
git config --remove-section svn-remote.svn
git config --remove-section svn
rm -r svn
git branch -D trunk
cd ../..
# Création d'un dossier "nu" partagé sur le serveur
git clone --bare $1 $1.git
rm -rf $1
cd $1.git
git config core.shareRepository true
cd ..
echo 'Fin migration '$1
}
migration nomProjet svn://svnabcd/nomProjetWeb/ -r33900
migration nomProjet2 svn://svnabcd/nomProjet2/
migration nomProjet3 svn://svnabcd/nomProjet3/
Plus qu’à exécuter le script sur le futur serveur et hop ! de beaux repos tout prêt 🙂
Je me suis en suite attelée à la formation des développeurs (de la théorie, et surtout des démos de l’utilisation des nouveaux outils).
Passage du serveur SVN en lecture seule
L’ultime étape de cette migration a consisté à passer le serveur SVN en lecture seule (pour éviter les commits accidentels sur ce serveur)
1ère chose : sauvegarde du serveur
> svnadmin dump <dépôt-svn> | gzip -9 > <fichier-de-sauvegarde>
Puis passage en lecture seule :
Modification du fichier conf/svnserve.conf du dépôt
anon-access = none
auth-access = read
Et voilà 🙂 Y’a plus qu’à ^^