Depuis que j’ai compris que Git c’est facile, je suis de plus en plus enclin à l’utiliser couramment.
De plus, j’apprécie vraiment le service et les facilités proposés par GitHub comme son interface de consultation, la gestion des issues, le zip automatique des tags.
Mais j’ai aussi un historique de développement sous SVN, avec plein de petits projets développés et versionnés sur mon serveur SVN accouplé à une interface TRAC.
C’est donc au cas par cas que je migre chacun de ces petits projets sous Git, ce qui me permet tout à la fois de passer à Git, d’améliorer grandement mon confort de consultation par l’interface web, et de faciliter les contributions externes.
Nous allons voir deux cas pratiques de migration, en commençant par un projet simple sans branche, puis en essayant d’importer un projet avec ses branches et ses tags.
Un cas simple
Pour l’exemple, on va ici créer un projet GitHub pour le plugin SPIP Crayons, actuellement versionné sur [l’espace SVN partagé de la communauté SPIP appelé SPIP-Zone, dans le dossier _plugins_/crayons
1. Importer de SVN vers Git
On va utiliser pour importer la fonction git svn
.
La syntaxe est simple. Pour importer le Repository SVN svn://zone.spip.org/spip-zone
vers un repertoire local gitzone
versionné sous Git, on utiliserait la syntaxe
Ici, on ne veut pas importer tout le dépot, mais seulement un sous répertoire. On précise donc le chemin complet. On s’abstient aussi de préciser le nom du dossier local, qui sera automatiquement celui du dernier dossier du chemin :
Voila, on a maintenant un dossier Git [1] :
On retrouve bien tout l’historique des commits. On voit aussi que Git a conservé les auteurs des commits SVN, ici identifiés par leurs emails. Mais on aimerait évidemment que les auteurs GitHub soient reconnus pour faciliter la navigation et l’utilisation de l’interface, et respecter au mieux les crédits de chacun.
2. Réattribuer les auteurs
Pour cela il suffit de définir la correspondance entre les auteurs des commits SVN et les auteurs nommés, dans un fichier que l’on indiquera avec l’option --authors-file
. Comme il faut fournir la correspondance pour tous les auteurs, commençons par générer un template à partir des logs SVN. On adapte la contribution à notre cas où les auteurs sont déjà des adresses mails, pour en extraire la première partie :
Il reste a copier ce template dans un fichier nommé authors
, et de corriger les auteurs dont le compte GitHub n’est pas bon (c’est souvent le même pseudo que dans l’adresse mail, mais pas toujours).
Supprimons notre premier import, et recommençons avec la correspondance des auteurs :
Regardons le résultat :
On a bien cette fois les auteurs des commits qui apparaissent sous leur vrai nom.
3. Nettoyer les messages de commit
En revanche on voit que les logs de commit ont été complétés par une référence au repository SVN d’origine, avec mention du commit SVN. C’est souvent très bien, mais c’est parfois gênant quand le repository d’origine est privé et que vous voulez éviter de le divulguer.
Pour cela, on peut ré-écrire tous les messages de commit grâce à la fonction filter-branch
de Git. Attention, ré-écrire les messages de commit va modifier aussi les hash de tous les commits ; Git va donc ré-écrire tout l’historique. Cela est faisable dans un cas comme ici où notre dépôt n’a pas encore été publié ou partagé, mais dès que nous l’aurons poussé, ce type d’opération n’est plus envisageable (sauf à accepter de casser tous les historiques et des autres utilisateurs).
Ré-écrivons donc nos messages avec un sed
bien senti :
et vérifions :
Voilà, on a retrouvé nos messages de commits originaux (mais perdu le lien avec les commits SVN).
5. Pousser fort
Il ne reste plus qu’à créer un dépôt GitHub, de le relier à notre dépôt local, et de tout envoyer :
Et c’est gagné !
Un dépôt avec branches et tags
Cette fois nous allons faire un peu plus compliqué : importons dans Git un dépôt qui contient des branches et tags, en récupérant évidemment tout cela sous Git.
Pour l’exemple, on choisit ici le plugin SPIP Corbeille, versionné lui aussi sur l’espace SVN partagé de la communauté SPIP appelé SPIP-Zone
1. Référencer les auteurs
On commence par créer le fichier d’auteurs avec notre commande magique, que l’on copie dans un fichier cette fois nommé authors2
:
2. Importer
Puis on importe en utilisant les options --trunk
, --branches
, --tags
de git svn
. Notre dossier corbeille est organisé depuis peu en 3 sous-dossiers trunk/
, branches/
et tags/
, nous les indiquons donc comme tel :
C’est cette fois un peu plus long car l’analyse du dépôt SVN est plus compliquée. Une fois fini, regardons ce que git-svn nous a importé :
Notre historique ne semble contenir qu’un commit. En fait c’est ici parce que le dernier commit SVN a été une opération de déplacement fichier à fichier pour créer le dossier trunk/
, et Git a eu du mal à reconstituer l’historique.
On peut afficher tout l’historique :
On voit alors le graphe complet des branches du dépôt.
3. Référencer les branches importées
Listons les branches importées :
On voit que git-svn
a importé toutes les branches et tags sous forme de branches distantes, y compris a différentes périodes correspondant en général à des opérations de copie ou déplacement. Aucun tag n’a été créé.
Il suffit donc de recréer les branches et tags correctement à partir des branches distantes référencées ici. Pour vérifier le contenu d’une branche, on la checkout :
Puis on la créé localement :
Faisons de même pour la seconde branche et son tag :
4. Pousser encore
Il ne reste qu’à pousser tout cela :
Conclusion
Dans notre dernier cas, la reprise de l’historique n’est pas une franche réussite. La faute en incombe à la dernière opération de réorganisation du repository SVN :
Pour créer une organisation en 3 sous-dossiers trunk/
, branches/
et tags/
, on a créé le sous dossier trunk et on y a déplacé les fichiers un à un. Cela est à éviter, car pour l’import, les fichiers « apparaissent » dans trunk/
. Il est préférable de déplacer le dossier complet sous SVN pour faciliter une migration ultérieure sous Git.
Hormis ce soucis, l’import de SVN vers Git à l’aide de la commande git svn
permet donc de migrer assez facilement, qui plus est en découpant un gros dépôt SVN en de multiples petits dépôts Git.
Vos commentaires
# Le 7 avril 2012 à 13:06, par Gitstack En réponse à : Migrer un projet SVN vers GIT
Bonjour,
Merci pour ce tutoriel fort utile et il est vrai que la commande git svn simplifie le travail. Elle est donc intéressante.
Sinon, je suis assez d’accord pour dire que Git est assez simple à gérer et utiliser et j’ai l’impression que de plus en plus de projets s’y mettent. On verra à la longue mais l’outil prend de l’ampleur.
# Le 25 septembre 2012 à 16:31, par Greg En réponse à : Migrer un projet SVN vers GIT
Merci pour ce tuto.
Par contre, je trouve un peu fastidieux de refaire les tag a la main.
Dans mon cas, les tags sont représenté par un nouveau commit.
J’ai donc fait un petit script pour retagguer :
https://gist.github.com/3782266
# Le 6 juin 2013 à 13:25, par ponsfrilus En réponse à : Migrer un projet SVN vers GIT
Sauf erreur, l’option —no-metadata lors du git svn clone évite les ids des commits svn.
# Le 2 janvier 2014 à 12:50, par Ismail SEBBANE En réponse à : Migrer un projet SVN vers GIT
Bonjour,
Après avoir exécuter la commande svn git clone d’un repo SVN , j’ai ce message d’erreur aprés quelques minutes :
RA layer request failed : REPORT of ’/repositories/GALEC-SCANER-DEV/ !svn/vcc/default’ : Could not read chunk delimiter : connection was closed by server (http://repository.neoxia.net) at /usr/local/git/lib/perl5/site_perl/Git/SVN/Ra.pm line 282
Quelqu’un a déja rencontré ce problème ? avez vous des solutions ?
MERCI
# Le 2 janvier 2014 à 17:14, par Ismail SEBBANE En réponse à : Migrer un projet SVN vers GIT
J’ai trouvé la solution a mon problème , l’erreur viens quand on a un gros repo avec des fichiers volumineux, git svn clone n’arrive pas jusqu’au bout !
La dernière révision récupéré avant l’erreur étais r480.
sachant que mon repo a 600 révisions (svn log) donc j’ai joué les commandes suivantes :
git svn clone -r1:400 http://url-repo
git svn fetch -r400:500
git svn fetch -r500:600
git svn rebase
Je ne sais pas si c’est la meilleur solution mais ça marchais pour moi :)
MERCI
# Le 2 janvier 2014 à 17:28, par Ismail SEBBANE En réponse à : Migrer un projet SVN vers GIT
Pour info, c’est ce site qui m’a aidé a résoudre mon problème :
http://randomallsorts.blogspot.fr/2011/10/using-git-svn-with-large-repository.html
# Le 1er juillet 2015 à 10:00, par BELTRAMI En réponse à : Migrer un projet SVN vers GIT
Pour ceux qui seraient sur Windows ;)
# Le 2 novembre 2017 à 10:09, par Mims En réponse à : Migrer un projet SVN vers GIT
Simple et bien expliqué :)
Merci !
Vos commentaires
Suivre les commentaires : |