Accueil Nos publications Blog [Devoxx FR 2013] Fast Forward : Comment migrer un gros projet de svn à git

[Devoxx FR 2013] Fast Forward : Comment migrer un gros projet de svn à git

Git  est de plus en plus utilisé. Les nouveaux projets open source sont versionnés sous git, les anciens migrent vers git, les hébergeurs de code tel que Bitbucket ou GitHub gèrent git et quand on pousse du code sur une plateforme de cloud, c’est généralement sous git. Bref, git s’impose pour les projets présents et futurs.

Mais qu’en est-il de nos projets en entreprise qui sont sous subversion (svn) ? Devons-nous rester sous ce gestionnaire de source ? Passer à un DVCS ? Et si on franchit le pas, comment subir cette migration sans (trop) de douleur ? C’est à ces différentes questions que  Renaud Bruyeron , CTO d’Ekino, et  Thomas Carzusan , architecte chez Ekino, ont répondu à travers leurs Tools In Action nommés “Fast Forward : Comment migrer un gros projet de svn à git”.

Pourquoi quitter Subversion ?

Subversion permet de créer des branches facilement, mais travailler avec une multitude de branches est coûteux. Généralement les projets utilisent donc une branche par version qui est ensuite reversée dans le tronc (trunk). Les différentes fonctionnalités seront développées sur la branche d’une version (exemple: deal2gether-4.2.x), et une fonctionnalité verra ses commits entrecoupés par d’autres commits d’autres fonctionnalités. C’était un des besoins d’Ekino : avoir la possibilité de gérer des “features branch”, pour avoir l’ensemble des commits d’une fonctionnalité, et c’est ce qu’offre git.

Migration vers git

 Deux outils sont disponibles pour migrer un repository subversion vers git.

  • git-svn  : de base avec git, il permet une communication bidirectionnelle entre subversion et git (un commit svn pourra être propagé sur un repo git).
  • svn2git  : gem ruby s’appuyant sur git-svn mais faisant un peu de ménage après un import.

C’est ce dernier qui a été retenu pour la migration. En effet, il transpose mieux les repositories svn en repositories git. Typiquement, il crée une branche “master” pour le trunk, des branches pour les branches, et forcément, des tags git pour les tags svn. A contrario, git-svn laisse les tags subversion en tant que branche git et garde une branche avec le nom trunk !

Etant donné le nombre conséquent de repositories chez Ekino (environs 200) et la répétitivité des actions à effectuer pour migrer d’un système de source à un autre, les opérations ont été scriptées. Mais l’importation reste longue, d’autant plus si elle est faite séquentiellement sur les dépôts. Pour accélérer cette migration, l’import a été parallélisé : les dépôts ont été traités 4 par 4. De plus, pour simplifier le tout, ces opérations ont été lancées dans des périodes non ouvrées avec une approche “big bang” :  le vendredi, les développeurs utilisent svn, à leur retour, le lundi, c’est sous git qu’ils poussent leurs modifications.

Un code freeze a tout de même été opéré pour ne pas avoir à importer les derniers changements non commités d’un système à un autre. Si des reliquats devaient tout de même être migrés, un simple copier-coller d’un système à un autre suffit à résoudre la différence, quitte à perdre l’historique, qui de toute façon ne courrait que sur un ou deux jours pour ces modifications.

Meta-repository

Comment choisir l’organisation cible de ces dépôts ? Cela dépendra de plusieurs facteurs, comme la sécurité, la dépendance entre les dépôts, …. Ekino a choisi la solution d’un ensemble de repositories chapeautés par un meta-repository. Ce dernier contiendra les références vers les dépôts dont il a la charge.

Quels outils pour créer ce super dépôt ? Plusieurs solutions ont été étudiées.

  • git submodule  : de base dans git, et permet de pointer vers un commit spécifique. (enfin, ça, c’était avant la version 1.8.2 de git)
  • git external  : ne fait pas partie de git et permet de pointer cette fois sur une branche.
  • repo  : wrapper python, remplaçant complètement git, permettant notamment de propager des modifications liées à plusieurs dépôts en un seul commit.
  • git subtree  : de base dans git (depuis la version 1.7.11) , permet de fusionner un repository distant avec son repository dans un répertoire spécifique.

C’est ici encore cette dernière solution qui a été choisie. Repo a été écarté notamment à cause d’un manque de documentation, et son utilisation remplaçant le fonctionnement de git.

Update : Si vous voulez approfondir la mise en oeuvre de la migration de git vers svn, cet article complet d’Olivier Bazoud répondra à vos dernières questions.

In Action

La commande subtree manque un petit peu de documentation (git subtree sans argument donne le minimum vital, mais git help subtree n’indique pas encore d’entrée…)

Pour fusionner un dépôt dans un répertoire de votre dépôt, la commande à utiliser est :



git subtree add --prefix=<repertoire> <repository> <commit>

git va alors récupérer l’ensemble des commits du dépôt distant et les mettre dans le répertoire que vous aurez indiqué. Le repository est maintenant intégré dans le vôtre.

Pour récupérer les nouveaux commits sur le repository distant, un git pull ne suffira pas : en effet, ce que vous avez récupéré via le git subtree vit maintenant sa vie dans votre répertoire. Si vous voulez réintégrer les dernières modifications, git subtree pull sera votre allié :



git subtree pull --prefix=<repertoire> <repository>

2013-04-04 21.47.29

D’autres commandes sont disponibles :
  • git subtree add : importe le contenu d’un repository dans un sous-répertoire
  • git subtree merge : fusionne un commit dans votre sous-répertoire
  • git subtree pull : récupère le contenu et merge un repository dans votre sous-répertoire
  • git subtree push : effectue un git split, puis git push du sous-répertoire
  • git subtree split : récupère l’ensemble des commits affectant votre sous-répertoire

Tips & Tricks

Migrer de subversion à git n’est pas trivial. Aurez-vous un réel intérêt à passer à git ? Toujours est-il que pour éviter certains écueils, Thomas et Renaud finissent avec quelques conseils :

  • Essayer de migrer un petit projet avant d’essayer de migrer un plus gros projet.
  • Former ses utilisateurs avant la migration, pour qu’ils soient opérationnels dès que les dépôts sont migrés et surtout éviter les mauvaises manipulations par la suite.
  • Avoir des experts git sous la main pour gérer les incidents – et il y aura des incidents.
  • Bloquer les push non fast-forward pour éviter les drames, et ne les autoriser qu’à certaines personnes maîtrisant git.

Rétrospective

Mais chez moi ?

La question d’une migration vers git se pose de plus en plus. La preuve en est : deux sujets sur une migration vers git étaient présents à Devoxx France 2013 !
Le premier – résumé par cette article – plus orienté sur les outils, le second, “git : quand une application complexe saute le pas”, par  François Nollen , plus orienté, quant à lui, sur le contexte un peu plus difficile de migration.
Ces deux présentations montrent qu’une migration est possible, tout en donnant quelques conseils – à suivre ! pour que cela se passe tout en douceurs si vous êtes amené à effectuer ce même genre de “switch”.