Interopérabilité Git avec un référentiel Mercurial

195

J'utilise GIT sur un Mac. Assez dit. J'ai les outils, j'ai l'expérience. Et je veux continuer à l'utiliser. Pas de guerres ici ...

Le problème est toujours lié à l'interopérabilité. La plupart des gens utilisent SVN, ce qui est génial pour moi. Git SVN fonctionne immédiatement et est une solution sans fioritures. Les gens peuvent continuer à utiliser SVN avec plaisir et je ne perds pas mon flux de travail ni mes outils.

Maintenant ... Certains gars viennent avec Mercurial. Bien pour eux: ils ont leurs raisons. Mais je ne trouve aucun GIT HG prêt à l'emploi. Je ne veux pas passer à HG, mais j'ai encore besoin d'interopérer avec leur référentiel.

Certains d'entre vous connaissent une solution simple pour cela?

Hugo Sereno Ferreira
la source
4
hg-git fonctionne dans les deux sens.
Derek Mahar
1
La réponse de @dubiousjim est plus utile, complète et plus à jour que les deux premiers, qui pointent vers des référentiels non maintenus ou donnent des conseils obsolètes. Mais encore plus de mises à jour sur cette question seraient très utiles.
nealmcb

Réponses:

60

Mise à jour de juin 2012. Actuellement, il semble y avoir les méthodes suivantes d'interopérabilité Git / Hg lorsque le développeur souhaite travailler du côté git:

  1. Installez Mercurial et l' extension hg-git . Vous pouvez le faire en utilisant votre gestionnaire de paquets ou avec easy_install hg-git. Assurez-vous ensuite que les éléments suivants se trouvent dans votre ~ / .hgrc:

    [extensions]
    hggit = 
    

    Vous pouvez voir quelques références qui parlent de spécifier l' bookmarksextension ici aussi, mais cela a été intégré à Mercurial depuis la v 1.8. Voici quelques conseils sur l'installation de hg-git sous Windows .

    Une fois que vous avez hg-git, vous pouvez utiliser des commandes à peu près comme Abderrahim Kitouni posté ci-dessus . Cette méthode a cependant été affinée et peaufinée depuis 2009, et il existe un wrapper convivial: git-hg-again . Cela utilise le répertoire toplevel comme répertoire de travail pour Mercurial et Git en même temps. Il crée un signet Mercurial qu'il synchronise avec la pointe de la defaultbranche (sans nom) dans le référentiel Mercurial, et il met à jour une branche Git locale à partir de ce signet.

  2. git-remote-hg est un wrapper différent, également basé sur l'hg-gitextensionMercurial. Cela utilise également lesgit-remote-helpersprotocoles (d'où son nom). Il utilise le répertoire toplevel uniquement pour un répertoire de travail Git; il garde son référentiel Mercurial nu. Il maintient également un deuxième référentiel Git nu pour rendre la synchronisation entre Git et Mercurial plus sûre et plus idiomatique.

  3. Le script git-hg (précédemment géré ici ) utilise une méthode différente, basée sur hg-fast-exportle projet d'exportation rapide . Comme la méthode 2, cela conserve également un référentiel Mercurial nu et un référentiel Git nu supplémentaire.

    Pour tirer, cet outil ignore les signets Mercurial et importe à la place chaque branche Mercurial nommée dans une branche Git, et la branche Mercurial par défaut (sans nom) dans master.

    Certains commentaires décrivent cet outil comme étant hg-> git uniquement, mais il prétend avoir fusionné dans git-> hg push support le 7 décembre 2011. Comme je l'explique dans une revue de ces outils , cependant, la façon dont cet outil essaie de mettre en œuvre le support push ne semble pas être réalisable.

  4. Il existe également un autre projet appelé git-remote-hg . Contrairement à la version répertoriée ci-dessus, celle-ci ne repose pas sur hg-git, mais accède directement à l'API Mercurial Python. À l'heure actuelle, son utilisation nécessite également une version corrigée de git. Je n'ai pas encore essayé ça.

  5. Enfin, Tailor est un projet qui convertit progressivement une variété de VCS différents. Il semble que le développement de cela ne sera pas poursuivi de manière agressive.

Les trois premières de ces approches semblaient suffisamment légères pour me persuader d'enquêter. J'avais besoin de les modifier de certaines façons pour les faire fonctionner sur ma configuration, et j'ai vu quelques façons de les peaufiner davantage pour les améliorer, puis je les ai encore peaufinées pour les faire se comporter plus comme les autres afin que je puisse évaluer les plus efficacement. Ensuite, j'ai pensé que d'autres pourraient aimer avoir ces ajustements aussi, pour faire la même évaluation. J'ai donc créé un package source qui vous permettra d'installer mes versions de l'un des trois premiers outils. Il devrait également prendre soin d'installer les hg-fast-exportpièces nécessaires . (Vous devez installer hg-gitvous-même.)

Je vous encourage à les essayer et à décider par vous-même de ce qui fonctionne le mieux. Je serai heureux d'entendre parler de cas où ces outils se brisent. J'essaierai de les synchroniser avec les changements en amont et de m'assurer que les auteurs en amont sont conscients des ajustements que je pense utiles.

Comme je l'ai mentionné ci-dessus, lors de l'évaluation de ces outils, je suis arrivé à la conclusion qui git-hgn'est utilisable que pour tirer de Mercurial, pas pour pousser.

De manière similaire, voici quelques comparaisons / manuels de traduction utiles entre Git et Mercurial, dans certains cas destinés aux utilisateurs qui connaissent déjà Git:

dubiousjim
la source
2
J'utilise moi-même la méthode # 2, ou plutôt ma version modifiée de celle-ci. Globalement, cela me semble l'approche la plus fiable et la plus flexible (de celles que j'ai essayées). Voir les liens vers mon package de révision / source pour plus de détails.
dubiousjim
Ouaip. Kiln Harmony est génial. Gratuit aussi pour les développeurs solo.
CAD bloke
114

Il y a un nouveau git-remote-hg qui fournit un support natif:

Prise en charge des ponts dans Git pour Mercurial et Bazaar

Copiez simplement git-remote-hg dans votre $ PATH, rendez-le exécutable, et c'est tout, pas de dépendances (autres que Mercurial):

git clone hg::https://www.mercurial-scm.org/repo/hg/

Vous devriez pouvoir le pousser et le retirer comme s'il s'agissait d'un référentiel Git natif.

Lorsque vous appuyez sur de nouvelles branches Git, des signets Mercurial sont créés pour eux.

Voir le wiki git-remote-hg pour plus d'informations.

FelipeC
la source
14
Hé Felipe, ce n'est pas tout à fait vrai, vous avez besoin d'une version de travail de mercurial comme dépendance
Antoine Pelisse
5
Assurez-vous de le nommer exactement git-remote-hg(c'est-à-dire sans .pysuffixe).
schmmd
3
Fonctionne lorsque le référentiel hg est également un sous-module.
Clayton Stanley
4
Notez que vous avez besoin de python 2. Donc, si python 3 est la valeur par défaut sur votre système (ou si vous n'exécutez pas Debian et que vous voulez être à l'épreuve du temps), changez la première ligne en #!/usr/bin/env python2.
Kevin Cox
4
Notez que depuis gur-remote-hg de Mercurial 3.2 @FelipeC ne fonctionne plus ( github.com/felipec/git-remote-hg/issues/27 ) c'est-à-dire jusqu'à ce que le fork qui résout le problème soit fusionné (voir github .com / fingolfin / git-remote-hg )
Cimbali
106

Vous devriez pouvoir utiliser hg-git .

hg clone <hg repository>

éditez ~/.hgrcet ajoutez:

[extensions]
hgext.bookmarks =
hggit =

créez un signet pour avoir un masterin git:

cd <repository>
hg bookmark -r default master

modifier .hg/hgrcdans le référentiel et ajouter:

[git]
intree = true

vous pouvez maintenant créer le dépôt git:

hg gexport

et vous pouvez utiliser le répertoire résultant comme un clone git. tirer de mercurial serait:

hg pull
hg gexport

et poussant au mercure:

hg gimport
hg push

(Oui, vous devez utiliser hg avec ce workflow mais votre piratage sera tout en git)

PS Si vous avez un problème avec ce flux de travail, veuillez déposer un bogue.

Abderrahim Kitouni
la source
3
n'oubliez pas d'exécuter easy_install hg-git en premier
Christian Oudard
1
Pas exactement ce que je voulais, mais toujours faisable. Merci.
Hugo Sereno Ferreira
3
Juste un info, après avoir exécuté ce processus une fois sur un dépôt hg local (et avoir fait quelque chose de mal), je n'ai pas pu cloner le dépôt résultant à l'aide de git. J'ai dû «cloner hg» le repo hg source, suivre les étapes du nouveau repo hg, puis git cloner le nouveau repo hg.
Rocky Burt
1
J'obtiens ceci lorsque j'essaie d'émettre une git statuscommande $ git status fatal: Cette opération doit être exécutée dans une arborescence de travail C'est après avoir émis un hg gexportdans un référentiel hg fraîchement cloné. Quelle est une solution possible pour contourner les référentiels nus? Mettre à jour . Apparemment, la suggestion de Rock Burt fonctionne. Merci
yesudeep
1
@ThaDon J'ai le même problème. Apparemment, le dépôt git est créé en tant que .hg / git. La solution est de 'ln -s .hg / git .git'.
mb14
15

Vous pouvez essayer hg2git, qui est un script python et fait partie de l'exportation rapide, que vous pouvez trouver sur http://repo.or.cz/w/fast-export.git .

Vous devrez cependant installer mercurial.

sykora
la source
4
Cela a converti un repo hg en repo git, merci beaucoup!
reconbot
Ce script a échoué pour moi, mais l'original hg-fast-exporta bien fonctionné
Andrei
Je pense qu'actuellement le hg-fast-exportscript est expédié vers hg2git. Je n'ai pas tout tracé cependant. Notez que ces outils ne permettent que de passer de Hg-> Git, pas l'inverse.
dubiousjim
9

Étant donné que hg-git est un pont à deux voies, il vous permettra également de pousser les changements de Git vers Mercurial.

Martin Geisler
la source
6

Plugin Hg-Git Mercurial . Je ne l'ai pas essayé moi-même, mais ça vaut peut-être la peine d'être vérifié.

ralphtheninja
la source
7
C'est un plugin qui permet aux utilisateurs mercuriels de pousser et de tirer depuis git repos, et non l'inverse, ce que souhaite l'OP.
sykora
1
@sykora, il peut également être utilisé pour favoriser l'interopérabilité dans le sens inverse. Voir certains des outils que j'énumère dans ma réponse.
dubiousjim
6

J'ai eu un grand succès avec git-hgde https://github.com/cosmin/git-hg (nécessite l' installation de travail hg, aussi). Il prend en charge la récupération, la traction et la poussée et est plus stable pour moi que hg-git(fonctionnalités similaires de hgà git).

Voir https://github.com/cosmin/git-hg#usage pour des exemples d'utilisation. L'interface utilisateur est très similaire à git-svn.

Le git-hgrequiert un espace disque supplémentaire pour chaque dépôt hg cloné. L'implémentation utilise un clone mercurial complet, un clone nu git supplémentaire et le dépôt git réel. L'espace disque requis représente environ 3 fois l'utilisation normale de git only. Les copies supplémentaires sont stockées sous le .gitrépertoire de votre répertoire de travail (ou emplacement indiqué par GIT_DIRcomme d'habitude).

Remarque: Le problème de base qui git-hgtente de résoudre est qu'il n'y a pas de mappage 1: 1 entre les entités gitet hg. Le plus gros problème est le décalage d'impédance entre les branches git et les branches hg sans nom et les branches nommées hg et les signets hg (tous ceux-ci ressemblent beaucoup à des branches pour les gitutilisateurs). Un problème connexe est celui qui hgessaie d'enregistrer le nom de la branche nommée d'origine dans l'historique des versions, par opposition à git où le nom de la branche n'est ajouté qu'au message de validation du modèle par défaut.

Tout outil qui prétend créer un pont interopérable entre gitet hgdevrait expliquer comment il va gérer cette correspondance d'impédance. Vous pouvez alors décider si la solution sélectionnée correspond à vos besoins.

La solution qui git-hgconsiste à supprimer tous les signets hg et à convertir les branches nommées en branches git. De plus, il définit la branche git master sur la branche hg sans nom par défaut.

Mikko Rantalainen
la source
Il semble que ce git-hgne soit viable que pour tirer du Hg, pas pour pousser (voir l'explication à laquelle je renvoie dans ma réponse). Avez-vous trouvé un moyen de l'utiliser avec succès dans les deux sens? En ce qui concerne l'espace supplémentaire, toutes les techniques que je connais impliquent de travailler dir + une copie de git db / metadata + une copie de hg db / metadata. Ajouter une deuxième copie de la base de données / métadonnées git implique une utilisation plus importante du disque, oui, mais en comparaison, ce n'est pas aussi mauvais que cela puisse paraître.
dubiousjim
@dubiousjim Mes besoins étaient satisfaits avec un pull / fetch de travail et je n'ai jamais vraiment testé le push. Je faisais confiance à la documentation mais après avoir vérifié vos explications, je crois maintenant que cela git-hgne convient pas pour pousser. J'ai modifié ma réponse pour que ce soit plus clair qui pushn'est pas assez stable.
Mikko Rantalainen
Dommage, je pensais qu'il pourrait y avoir un moyen d'utiliser avec succès push que je ne voyais pas.
dubiousjim
1
+1 pour avoir mis en évidence le décalage d'impédance et ce qu'il faut rechercher
Matt Wilkie
3

J'ai essayé hggit. Fonctionne pour moi, car je dois faire face au travail des git'ers et des hg'ers. Surtout pour les avis, c'est super.

Un problème / avertissement mineur à ce sujet:

J'ai essayé de cloner un référentiel de noyau Linux stable avec hg. Ces référentiels sont maintenus dans git et contiennent généralement un grand nombre de fichiers.

C'était très lent. Il m'a fallu 2 jours pour cloner entièrement et mettre à jour une copie de travail.

Wizz
la source
Il semble que ça s'améliore --- ma caisse fonctionne depuis environ six heures, et elle prétend qu'il n'y en a plus que neuf ...
David Given,
Je reprends ça. Il fonctionne maintenant depuis environ 25 heures, et il prétend toujours qu'il ne reste plus que neuf heures . Deux jours, tu as dit?
David Given
1
J'ai vécu cela - Mon premier essai n'a pas fonctionné du tout - je suppose que c'était un bug, mais je n'ai jamais analysé cela plus loin, lors de mon deuxième essai - avec un hg-git mis à jour, il a fallu près de 50 heures pour terminer sur mon Mac Book Pro (2,66 GHz, 8 Go de RAM)
Wizz
39 heures maintenant, il ne reste plus que 11 heures! Quad core AMD Phenom. Il est fait des progrès, ce qui est la raison pour laquelle je laisse courir (l'extension de barre de progression hg est un must-have). C'est alterner entre le rattachement d'un processeur et l'utilisation d'aucun processeur et faire beaucoup d'accès au disque.
David Given
Quelqu'un a-t-il testé si les mauvaises performances causées par hggitou sont hgtrop lentes pour être utilisables avec des projets de taille noyau en général?
Mikko Rantalainen
1

J'ai essayé à nouveau git-hg de cosmin et git-hg-d'abourget sur le repo hg de mutt , il semble que le dernier respecte bien l'ordre de fusion, le premier est un peu aléatoire. Vous pouvez le voir sur les captures d'écran ci-dessous.

Un graphique d'historique de fusion de mutt importé par git-hg de cosmin :

entrez la description de l'image ici

Un graphique d'historique de fusion de mutt importé par git-hg-again d' abourget :

entrez la description de l'image ici

Le graphique historique actuall tracé par hgk sur le référentiel hg de mutt:

entrez la description de l'image ici

Comme vous pouvez le voir ci-dessus, le deuxième graphique de git-hg-again d' abourget est très proche du graphique hgk d'origine et reflète en fait le flux de travail réel du mutt.

Un inconvénient de git-hg-again que j'ai trouvé est qu'il n'ajoute pas de télécommande `` hg '', importe plutôt toutes ses références sous forme de balises locales, git-hg a une merveilleuse télécommande `` hg '' qui représente le dépôt hg en amont.

weynhamz
la source
1
Il me semble que les différences entre les versions par cosmin et abourget sont de l'ordre des parents dans les merge commits. Un bon outil de visualisation de l'histoire (par exemple gitk) devrait être capable de rendre les deux histoires de manière identique. La seule chose qui manque visiblement est la branche hg/stabledans la version par abourget. Je suppose que c'est la chose entre les branches nommées, les branches non nommées et les signets dans Mercurial.
Mikko Rantalainen
0

La synchronisation bidirectionnelle hg-git (et git-git, hg-hg) est également possible avec le service Git-hg Mirror . Il utilise hg-git (entre autres) dans les coulisses et son code est également open source.


Avis de non - responsabilité : je suis de la société derrière elle.

Piedone
la source