Migrer un repository SVN vers GIT sous Windows avec SVN2GIT

Dans l’idée de migrer des vieux repos SVN vers GIT, j’ai utilisé par défaut l’outil fournit par GIT pour rapatrier un repo SVN entier en local et le pousser à la fin vers GIT.

Pour rapatrier le repo, c’est assez simple. Pour autant, dans le cas de très gros repo, j’alerte sur le fait que l’outil fournit directement par Git n’est pas fameux, et je donne dans le billet une autre méthode pour migrer, depuis Windows, de très gros et complexes repos.

Récupérer un repo et le pousser vers le master

[sourcecode language=“bash”] cd workspace\svn2git\

git svn clone –stdlayout –authors-file=authors.txt http://my.svn.repo.url/svn/repo_name/ repo_name_php [/sourcecode]

OU, si l’on veut préciser le path de chaque dossier principal (peut être utile si vous n’avez pas un setup propre).

[sourcecode language=“bash”] git svn clone –trunk=/trunk –tags=/tags –branches=/branches –authors-file=authors.txt http://my.svn.repo.url/svn/repo_name/ repo_name_php

Une fois que le rappatriement et la conversion ont été faits :

[sourcecode language=“bash”] cd repo_name_php [/sourcecode] Vous pouvez ensuite, facultativement, re-récupérer (au cas où quelqu’un aurait commité quelque chose sur le repo pendant que vous faisiez votre récupération.

[sourcecode language=“bash”] git svn fetch –authors-file=../authors.txt git svn rebase [/sourcecode]

Puis, à la fin, vous affectez une remote origin à ce repo, puis vous poussez le master (le master sur Git correspond au trunk sur SVN) vers le repo distant. [sourcecode language=“bash”] git remote add origin ssh://git@my_account.bitbucket.com:7999/my_bitbucket_project/git_repo_name.git git push -u origin master [/sourcecode]

Et si vous vous êtes trompé dans l’affectation de l’URL de l’origine, vous pouvez toujours la changer avec la commande suivante : [sourcecode language=“bash”] git remote set-url origin ssh://git@my_account.bitbucket.com:7999/my_bitbucket_project/git_repo_name.git [/sourcecode]

Cas particulier : vous ne voulez récupérer que ce qu’il y a après un certain commit

Disons que vous ne voulez récupérer que ce qui a suivi le commit n°240.

Une fois que vous êtes dans le dossier de votre repo local : [sourcecode language=“bash”] git svn clone -s -r240:HEAD http://my.svn.repo.url/svn/repo_name/ . [/sourcecode]

Après récupération : pousser une branche

[sourcecode language=“bash”] git show-ref cp -Rf .git/refs/remotes/origin/v1 .git/refs/heads/ git push –all origin [/sourcecode]

NB : il peut arriver que vos Remotes n’aient pas été converties en branches. Dans ce cas là, creez un script sh avec ce contenu : [sourcecode language=“bash”] for branch in `git branch -r | grep “branches/” | sed ’s/ branches\///’`; do git branch $branch refs/remotes/$branch done [/sourcecode]

Et exécutez-le depuis la racine de votre dossier de récupération.

Après récupération : pousser les tags

Créez un .sh, que vous nommerez par exemple push_all_tags.sh

Mettre dedans : [sourcecode language=“bash”] for tag in `git branch -r –sort=committerdate | grep “tags/” | sed ’s/.*tags\///’`; do git fetch –tags # must fetch tags before pushing more git tag -a -m “Convert Subversion tag” $tag refs/remotes/origin/tags/$tag git push origin $tag done [/sourcecode]

Mettre le .sh dans le dossier en local du repo Puis exécuter dans un cmd : [sourcecode language=“bash”] workspace\svn2git\repo_namesvnrepo>sh push_all_tags.sh [/sourcecode]

NB : il peut arriver que vos Remotes n’aient pas été converties en tags. Dans ce cas là, creez un script sh avec ce contenu : [sourcecode language=“bash”] for tag in `git branch -r | grep “tags/” | sed ’s/ tags\///’`; do git tag -a -m"Converting SVN tags" $tag refs/remotes/$tag done [/sourcecode]

Et exécutez-le depuis la racine de votre dossier de récupération.

Les différentes erreurs que j’ai pu avoir

J’ai eu plusieurs erreur à la récupération (c’est à dire avant même d’avoir tout récupéré, l’outil ne voulait pas finir la récupération…). Apparemment ces erreurs sont dues à des limitation côté Perl (celui embarqué par l’outil).

[sourcecode language=“bash”] Connection reset by peer: Error running context: Connection reset by peer at /mingw64/share/perl5/site_perl/Git/SVN/Ra.pm line 312. [/sourcecode]

J’ai réglé cette erreur en utilisant Smartgit.

Pareil : [sourcecode language=“bash”] Malformed network data: The XML response contains invalid XML: Malformed XML: no element found at /mingw64/share/perl5/site_perl/Git/SVN/Ra.pm line 312. [/sourcecode]

J’ai résolu également cette erreur en utilisant SmartGit.

Après récupération, j’ai eu aussi l’erreur fatal: Failed to resolve ‘refs/remotes/my_branch_v1.7.3’ as a valid ref.

Encore une fois, l’outil fourni par Git est assez faible, Smartgit n’a eu aucun soucis à la récupération et à la conversion correcte des tags.

Les nouveaux commentaires sont désactivés sur cette version statique du blog.