06 décembre 2012

Git et Hg sont dans un bateau...

Depuis que j'ai découvert Git j'ai du mal à m'en passer. Lorsque je suis contraint d'utiliser Subversion je passe par git-svn, ce n'est certes pas idéal mais c'est déjà d'un grand confort.

Pour aider l'équipe Devoxx à adapter leur application sur CloudBees, j'ai du utiliser Mercurial (Hg pour les intimes). Mercurial est très comparable à Git, mais un peu déroutantes pour un Git-iste car les commandes reprennent les même nom mais pour un usage différent (fetch devient pull, pull devient fetch pull, reset devient revert, revert devient backout, etc. Si vous devez faire l'exercice, garder ce tableau sous le coude.

Bref, j'ai eu la flemme d'apprendre Mercurial, ni d'utiliser SourceTree tout en mode graphique parce que... et bien la ligne de commande y'a que ça de vrai, n'est ce pas ?

Il faut savoir qu'il n'existe pas de passerelle officielle hg->git, contrairement à celle qui permet d'utiliser svn. Il existe par contre une passerelle inverse, très mature, qui permet aux utilisateurs de mercurial d'utiliser un repository git: hg-git. La raison de cette absence est apparemment philosophique, si j'ai bien tout suivi ...

Il existe donc pléthore de solution custom pour prendre en charge ce besoin. J'en ai donc testé quelques un pour finalement tomber sur git-remote-hg.

Comme expliqué sur le blog, comparée aux autres solution cette passerelle à l'avantage de se plugger dans les mécanisme de transport de git, et non de chercher à fournir des commands complémentaires du genre "git hg-clone". On travaille donc en pur git, mais avec un repository distant qui utilise le protocole "hg::*".

J'ai donc cloné le repo devoxx, tripatouillé deux trois fichiers de configuration, et voulu pousser tout ça dans bitbucket pour proposer une pull-request. J'ai alors eu un grand moment de solitude :


git-remote-hg fait apparaître les branches mercurial sous l'arborescence "branches", et la branche de développement du projet, équivalente du master git, est donc branches/default. J'ai passé un certain temps à tenter d'attacher mon master à la branche remote origin/branches/default sans succès. Tous les "--set-upstream"n'y ont rien changé. J'ai bien cru que j'allais devoir changer d'outil.

Au final, j'ai crée une branche locale branches/default (les branches git peuvent contenir le caractère '/', le saviez-vous ?) associée à la branche remote origine/branches/default, mergé mon master dedans, et j'ai (enfin) pu pousser tout ça sur bitbucket. Ouf!


Bizarrement, chaque push m'indique la création d'une nouvelle branche remote. Cela fonctionne donc mais l'intégration n'est pas encore parfaite.

Bref, si vous devez vous aussi jongler entre mercurial et git, cette solution semble intéressante, à condition de respecter du 1:1 avec les branches mercurial. Elle permet de synchroniser les repositories sans perte d'information, par exemple pour proposer un miroir Git d'un repo Hg, et vois évite de devoir choisir entre Git et Hg si vous en êtes à ce stade.

Au passage, au cours de mes tentatives j'ai découvert que Perforce venait tenter sa chance sur le territoire Git : http://www.perforce.com/blog/121001/improving-git-experience-everyone. De mon point de vue, question SCM, les jeux sont faits (en attendant le prochain :P)