Salut !

Comme promis à de nombreuses reprises, j'ai repris la conversion de
mercurial vers git.

j'avais déjà fait un premier essai en 2013 qui se trouve là:
https://github.com/dotclear/dotclear

Voici quels étaient mes buts:

* ne pas péter le dépôt git existant qui a quelques forks.
* permettre les imports itératifs (pour mettre à jour facilement).
* que ce soit répétable par n'importe qui.
* qu'on retrouve toutes les branches.


Voici pour commencer quelques informations importantes sur git pour bien
comprendre la suite. Je simplifie un peu donc si certains lecteurs sont
bien versés dans git, ne m'en veuillez pas.

* format des auteurs: Mercurial n'a pas de contrainte même s'il recommande
le format "Auteur <email>". En revanche git force ce format.

* référence d'un commit (ça va être plus long)
Dans git, un commit est identifié de manière unique par son "commit hash",
une suite de chiffres hexadécimaux. Ce qu'il faut savoir, c'est que ce
"commit hash" est réellement un "hash" issu de différentes informations,
notamment: son ou ses parent(s) (le(s) commit(s) sur lequel ce nouveau
commit est basé), son contenu (y compris l'auteur donc).

En pratique, pour nous, ça signifie que si l'une de ces informations
change, le hash change... ainsi que tous ses "enfants", puisque,
rappelez-vous, leurs "hashes" respectifs sont basés sur le "hash" de leur
parent. Bref.

Quelle est l'implication, me dites-vous ? Simple: si d'autres personnes ont
basé des changements sur un commit hash qui change... les changements
doivent être "portés" vers le nouveau. Et si on ne connait pas si bien que
ça git, c'est un peu pénible pour trouver les bonnes commandes (notamment
les bons hashes de base, etc, je rentre pas dans les détails).

* les merges: c'est tout simplement un commit avec 2 parents. (papa ou
maman, on s'en fout).


Voici les différents moyens pour convertir de hg vers git:

* le plus simple: github permet de convertir depuis un dépôt mercurial.
J'ai vérifié: ça marche bien depuis le dépôt sur bitbucket. En revanche je
ne crois pas que ce soit répétable.
Par ailleurs le dépôt obtenu a des différences par rapport au dépôt
existant (la première différence est un commit de "Frank" converti en
"Frank <Frank@localhost>" par github et "Frank <devnull@localhost>" par mon
outil précédent. Et donc... et oui, des hashes différents à partir de ce
commit.

* fast-export: https://github.com/frej/fast-export/
C'est de loin le plus rapide. Il existe aussi des outils un peu plus
simples d'utilisation qui l'utilisent (je crois que c'est Kevin qui en
avait partagé un récemment). Je suis à peu près sûr que c'est celui que
j'avais utilisé en 2013.

Guide sommaire d'utilisation:

hg clone https://hg.dotclear.org/dotclear dotclear-hg
mkdir dotclear-git && cd gotclear-git && git init
hg-fast-export.sh -r ../dotclear-hg --force

Le problème est qu'en faisant cette manip j'obtiens encore des hashes
différents à partir d'un commit de merge... il semble que l'ancienne
version de fast-export que j'avais utilisée n'avait pas utilisé le même
ordre pour les parents, et que ça suffise pour changer les hashes. À noter
que l'ordre utilisé par la version courante de l'outil ressemble plus à ce
qu'on ferait "à la main", donc a ma préférence.

Il utilise des fichiers de mapping qu'il ajoute dans le répertoire .git (et
qui ne sont donc pas commités... et que j'ai donc perdus depuis mon essai
de 2013 ;) ).

* hg-git: http://hg-git.github.io/
Assez lent, et je n'ai pas réussi à récupérer toutes les branches. Mais je
n'ai pas insisté énormément encore.
Il consiste à "pusher" et "fetcher" directement dans git depuis un dépôt
mercurial. Ça semble marcher tant localement que à distance. Et semble
prévu pour fonctionner de manière itérative.

* git-remote-hg: https://github.com/felipec/git-remote-hg
Non encore essayé. C'est le pendant du précédent: il permet de "pusher" et
"fetcher" directement dans hg depuis git. Il a un mode de compatibilité
avec l'outil précédent également. Il est prévu pour fonctionner de manière
itérative.
Je crois (non vérifié) qu'il fonctionne avec un dépôt local caché (si le
dépôt spécifié est distant).

* Outils de Mozilla:
https://wiki.mozilla.org/ReleaseEngineering/VCSSync/HowTo
Assez complexe car historiquement Mozilla a plusieurs dépôts distants pour
ses différentes branches (c'était ainsi que fonctionnaient les anciennes
versions de Mercurial). Et du coup l'outil doit prendre ça en compte alors
que nous on s'en fout.
Pas encore essayé. Mais il a l'avantage non négligeable d'être maintenu et
utilisé en production tous les jours.


Voilà en gros où j'en suis. J'ai pas mal poussé l'outil "fast-export" déjà,
j'aimerais bien pousser mieux les autres avant de décider de l'outil, pour
les raisons de permanence du "hash" dont j'ai parlé plus haut.


NOTE: si on décide de tout passer sur git une bonne fois pour toutes, et
abandonner mercurial une bonne fois pour toutes, le problème devient
immensément plus simple.

On pourrait alors utiliser l'outil de github pour convertir, puis
l'importer sur bitbucket et/ou https://git.framasoft.org/. Une fois qu'on a
du git partout c'est trivial de synchroniser des dépôts ensemble (et
d'ailleurs celui de framasoft a un outil pour le faire automatiquement).
Voir
http://framablog.org/2015/03/13/google-code-ferme-ses-portes-nous-on-les-ouvre/
pour le dépôt de framasoft.

Si on est prêt à le faire, ce serait la solution que je préconiserais par
simplicité + utiliser le dépôt de framasoft parce qu'on aime bien ce qu'ils
font, et c'est du libre.

Avoir une présence sur github me semble nécessaire car c'est là que tout se
passe aujourd'hui, mais on ne pourrait n'y avoir qu'une présence en miroir.

Bon dimanche !
-- 
Julien
-- 
Dev mailing list - [email protected] - http://ml.dotclear.org/listinfo/dev

Répondre à