Interoperabilità git con un repository mercuriale


195

Uso GIT su un Mac. È stato detto abbastanza. Ho gli strumenti, ho l'esperienza. E voglio continuare a usarlo. Nessuna guerra qui ...

Il problema è sempre con l'interoperabilità. Molte persone usano SVN, il che è fantastico per me. Git SVN è pronto all'uso ed è una soluzione senza fronzoli. Le persone possono continuare a usare felicemente SVN e io non perdo il mio flusso di lavoro né i miei strumenti.

Ora ... Alcuni ragazzi vengono con Mercurial. Va bene per loro: hanno le loro ragioni. Ma non riesco a trovare nessun GIT HG pronto all'uso. Non voglio passare a HG, ma devo ancora interagire con il loro repository.

Qualcuno di voi ragazzi conosce una soluzione semplice per questo?


4
hg-git funziona in entrambe le direzioni.
Derek Mahar,

1
La risposta di @dubiousjim è più utile, completa e aggiornata rispetto ai primi due attuali, che indicano repository non mantenuti o forniscono consigli obsoleti. Ma ulteriori aggiornamenti su questa domanda sarebbero molto utili.
nealmcb,

Risposte:


60

Aggiornamento da giugno 2012. Attualmente sembrano esserci i seguenti metodi per l'interoperabilità di Git / Hg quando lo sviluppatore vuole lavorare dal lato git:

  1. Installa Mercurial e l' estensione hg-git . Puoi fare quest'ultimo usando il tuo gestore pacchetti o con easy_install hg-git. Quindi assicurati che quanto segue sia nel tuo ~ / .hgrc:

    [extensions]
    hggit = 
    

    Potresti vedere alcuni riferimenti che parlano anche della specifica bookmarksdell'estensione qui, ma che è stato integrato in Mercurial dalla v 1.8. Ecco alcuni suggerimenti sull'installazione di hg-git su Windows .

    Una volta che hai hg-git, puoi usare i comandi più o meno come Abderrahim Kitouni pubblicato sopra . Questo metodo è stato perfezionato e ottimizzato dal 2009, e c'è un wrapper amichevole: git-hg-again . Questo utilizza la directory di livello superiore come directory di lavoro per Mercurial e Git contemporaneamente. Crea un segnalibro Mercurial che mantiene sincronizzato con la punta del defaultramo (senza nome) nel repository Mercurial e aggiorna un ramo Git locale da quel segnalibro.

  2. git-remote-hg è un wrapper diverso, anch'esso basato sull'estensione Mercurialhg-git. Questo fa inoltre uso deigit-remote-helpersprotocolli (da cui il suo nome). Utilizza la directory di livello superiore solo per una directory di lavoro di Git; mantiene nudo il suo repository Mercurial. Mantiene anche un secondo repository Git nudo per rendere la sincronizzazione tra Git e Mercurial più sicura e più idiomaticamente gitlike.

  3. Il git-hg di script (precedentemente mantenuto qui ) utilizza un metodo diverso, sulla base hg-fast-exportdel progetto FAST-export . Come il metodo 2, anche questo mantiene un repository Mercurial nudo e un repository Git nudo aggiuntivo.

    Per il pull, questo strumento ignora i segnalibri Mercurial e importa invece ogni ramo Mercurial con nome in un ramo Git e il ramo Mercurial predefinito (senza nome) in master.

    Alcuni commenti considerano questo strumento solo come hg-> git, ma afferma di essersi unito al supporto push git-> hg il 7 dic 2011. Tuttavia, come spiego in una recensione di questi strumenti , il modo in cui questo strumento tenta di implementare il supporto push non sembra fattibile.

  4. C'è anche un altro progetto chiamato git-remote-hg . A differenza della versione sopra elencata, questa non si basa su hg-git, ma accede direttamente all'API Mercurial Python. Al momento, usarlo richiede anche una versione patchata di git. Non l'ho ancora provato.

  5. Infine, Tailor è un progetto che converte progressivamente tra una varietà di VCS diversi. Sembra che lo sviluppo di questo non sarà continuato in modo aggressivo.

I primi tre di questi approcci sembravano abbastanza leggeri da convincermi a indagare. Avevo bisogno di modificarli in qualche modo per farli funzionare sul mio setup, e ho visto alcuni modi per ottimizzarli ulteriormente per migliorarli, e poi li ho ulteriormente ottimizzati per farli comportarsi più uno come l'altro in modo da poter valutare più efficacemente. Poi ho pensato che anche altri avrebbero voluto avere queste modifiche, per fare la stessa valutazione. Quindi ho creato un pacchetto sorgente che ti consentirà di installare le mie versioni di uno dei primi tre strumenti. Dovrebbe anche occuparsi dell'installazione dei hg-fast-exportpezzi necessari . (Devi installare hg-gitda solo.)

Ti incoraggio a provarli e a decidere tu stesso cosa funziona meglio. Sarò felice di conoscere casi in cui questi strumenti si rompono. Cercherò di mantenerli sincronizzati con le modifiche a monte e di assicurarmi che gli autori a monte siano consapevoli delle modifiche che ritengo utili.

Come ho accennato in precedenza, nel valutare questi strumenti, sono giunto alla conclusione che git-hgè utilizzabile solo per estrarre da Mercurial, non per spingere.

Di conseguenza, ecco alcuni utili confronti / manuali di traduzione tra Git e Mercurial, in alcuni casi rivolti agli utenti che già conoscono Git:


2
Sto usando il metodo n. 2 da solo, o meglio la mia versione ottimizzata di esso. Nel complesso, questo mi sembra l'approccio più affidabile e flessibile (di quelli che ho provato). Vedi i link alla mia recensione / pacchetto sorgente per i dettagli.
dubiousjim

Sì. Kiln Harmony è eccezionale. Gratuito anche per gli sviluppatori solisti.
Bloke CAD

114

C'è un nuovo git-remote-hg che fornisce supporto nativo:

Supporto bridge in Git per Mercurial e Bazaar

Basta copiare git-remote-hg sul tuo $ PATH, renderlo eseguibile, e basta, senza dipendenze (tranne Mercurial):

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

Dovresti essere in grado di spingere e estrarre da esso come se fosse un repository Git nativo.

Quando si spingono nuovi rami Git, verranno creati i segnalibri Mercurial per loro.

Vedi il wiki di git-remote-hg per maggiori informazioni.


14
Ehi Felipe, non è esattamente vero, hai bisogno di una versione funzionante di Mercurial come dipendenza
Antoine Pelisse,

5
Assicurati di nominarlo esattamente git-remote-hg(cioè nessun .pysuffisso).
schmmd,

3
Funziona anche quando il repository hg è un sottomodulo.
Clayton Stanley,

4
Nota che hai bisogno di python 2. Quindi, se python 3 è l'impostazione predefinita sul tuo sistema (o se non esegui Debian e vuoi essere a prova di futuro) cambia la prima riga in #!/usr/bin/env python2.
Kevin Cox,

4
Si noti che dal git-remote-hg di Mercurial 3.2 di @FelipeC non funziona più ( github.com/felipec/git-remote-hg/issues/27 ), cioè fino a quando il fork che risolve il problema non viene unito (vedere github .com / fingolfin / git-remote-hg )
Cimbali

106

Dovresti essere in grado di usare hg-git .

hg clone <hg repository>

modifica ~/.hgrce aggiungi:

[extensions]
hgext.bookmarks =
hggit =

crea un segnalibro in modo da avere un masterin git:

cd <repository>
hg bookmark -r default master

modifica .hg/hgrcnel repository e aggiungi:

[git]
intree = true

ora puoi creare il repository git:

hg gexport

e puoi usare la directory risultante come un clone git. tirando da mercuriale sarebbe:

hg pull
hg gexport

e spingendo a mercurial:

hg gimport
hg push

(Sì, devi usare hg con questo flusso di lavoro ma il tuo hacking sarà tutto in git)

PS In caso di problemi con questo flusso di lavoro, si prega di presentare un bug.


3
non dimenticare di eseguire prima
easy_install

1
Non esattamente quello che volevo, ma comunque fattibile. Grazie.
Hugo Sereno Ferreira,

3
Solo un problema, dopo aver eseguito questo processo una volta su un repository hg locale (e aver fatto qualcosa di sbagliato) non sono stato in grado di clonare il repository risultante usando git. Ho dovuto "clonare hg" il repository hg di origine, seguire i passaggi sul nuovo repository hg e quindi clonare git sul nuovo repository hg.
Rocky Burt,

1
Ottengo questo quando provo ad emettere un git statuscomando $ git status fatale: questa operazione deve essere eseguita in un albero di lavoro Questo è dopo che ho emesso un hg gexportrepository hg appena clonato. Qual è una possibile soluzione per aggirare i repository nudi? Aggiornamento . Apparentemente, il suggerimento di Rock Burt funziona. Grazie
sìudeep, il

1
@ThaDon Ho lo stesso problema. Apparentemente il repository git viene creato come .hg / git. La soluzione è "ln -s .hg / git .git".
mb14

15

Puoi provare hg2git, che è lo script Python e fa parte dell'esportazione rapida, che puoi trovare su http://repo.or.cz/w/fast-export.git .

Tuttavia, dovrai installare mercurial.


4
Questo ha convertito un repository hg in un repository git, grazie mille!
Riconnettere il

Questa sceneggiatura non è riuscita per me, ma l'originale ha hg-fast-exportfunzionato bene
Andrei,

Penso che attualmente lo hg-fast-exportscript venga spedito a hg2git. Non ho rintracciato tutto però. Si noti che questi strumenti consentono solo di andare da Hg-> Git, non il contrario.
dubiousjim,

9

Poiché hg-git è un bridge a due vie, ti consentirà anche di spostare i changeset da Git a Mercurial.


6

Plugin mercuriale Hg-Git . Non l'ho provato da solo, ma potrebbe valere la pena verificarlo.


7
Questo è un plugin che consente agli utenti mercuriali di spingere e tirare dai repository git, non viceversa, che è ciò che l'OP vuole.
Sykora,

1
@sykora, può essere utilizzato anche per guidare l'interoperabilità dalla direzione opposta. Vedi alcuni degli strumenti che elenco nella mia risposta.
dubiousjim,

6

Ho avuto un grande successo con git-hgda https://github.com/cosmin/git-hg (richiede anche l'installazione funzionante di hg). Supporta il recupero, il pull e il push ed è più stabile per me rispetto a hg-git(funzionalità simili dahg a git).

Consulta https://github.com/cosmin/git-hg#usage per esempi di utilizzo. L'interfaccia utente è molto simile agit-svn .

Lo git-hgrichiede più spazio su disco per ogni repo hg clonati. L'implementazione utilizza un clone completo, un clone bare git extra e l'effettivo repository git. Lo spazio su disco richiesto è circa 3 volte il normale utilizzo di git. Le copie extra sono archiviate sotto la .gitdirectory della directory di lavoro (o posizione indicata daGIT_DIR come al solito).

Avviso: il problema di base che git-hgtenta di risolvere è che non esiste un mapping 1: 1 tra gite hgfunzionalità. Il problema maggiore è la mancata corrispondenza dell'impedenza tra i rami git e i rami hg senza nome e i rami con nome hg e i segnalibri hg (tutti sembrano molto simili ai rami per gli gitutenti). Un problema correlato è quellohg tenta di salvare il nome del ramo con nome originale nella cronologia delle versioni invece di git in cui il nome del ramo viene aggiunto al messaggio di commit del modello per impostazione predefinita.

Qualsiasi strumento che afferma di creare un ponte interoperabile tra gite hgdovrebbe spiegare come gestirà questa corrispondenza di impedenza.Puoi quindi decidere se la soluzione selezionata soddisfa le tue esigenze.

La soluzione che git-hgutilizza è scartare tutti i segnalibri hg e convertire i rami con nome in rami git. Inoltre imposta il ramo master git sul ramo hg predefinito senza nome.


Sembra che git-hgsia praticabile solo per estrarre da Hg, non per spingere (vedi la spiegazione a cui mi collego nella mia risposta). Hai trovato il modo di usarlo con successo in entrambe le direzioni? Per quanto riguarda lo spazio extra, tutte le tecniche con cui ho familiarità riguardano il dir di lavoro + una copia di git db / metadata + una copia di hg db / metadata. L'aggiunta di una seconda copia di git db / metadata comporta un maggiore utilizzo del disco, sì, ma in termini comparativi non è così male come potrebbe sembrare.
dubiousjim,

@dubiousjim Le mie esigenze sono state soddisfatte con un pull / fetch funzionante e in realtà non ho mai testato la spinta. Mi fidavo della documentazione, ma dopo aver controllato le tue spiegazioni ora credo che git-hgnon sia adatto a spingere. Ho modificato la mia risposta per chiarire che pushnon è abbastanza stabile.
Mikko Rantalainen,

Peccato, ho pensato che potesse esserci un modo per usare la spinta con successo che non vedevo.
dubiousjim,

1
+1 per evidenziare la mancata corrispondenza dell'impedenza e cosa cercare
matt wilkie,

3

Ho provato Hggit. Funziona per me, dal momento che devo affrontare il lavoro di git'ers e hg'ers. Soprattutto per le recensioni è fantastico.

Un piccolo problema / avvertimento su questo argomento:

Ho provato a clonare un repository del kernel Linux stabile con hg. Questi repository sono mantenuti in git e in genere contengono un gran numero di file.

E 'stato molto lento Mi ci sono voluti 2 giorni per clonare e aggiornare completamente una copia funzionante.


Sembra che stia migliorando --- il mio checkout è in corso da circa sei ore e sostiene che ce ne saranno solo altri nove ...
David Dato

Me lo riprendo. Ora è in esecuzione da circa 25 ore e sostiene ancora che mancano solo altri nove. Due giorni, hai detto?
David Dato

1
L'ho sperimentato - il mio primo tentativo non ha funzionato affatto - presumo che fosse un bug, ma non l'ho mai analizzato ulteriormente, al mio secondo tentativo - con un hg-git aggiornato ci sono volute quasi 50 ore per completare sul mio Mac Book Pro (2,66 GHz, 8 GB di RAM)
Wizz,

39 ore adesso, quindi solo 11 per andare! Quad core AMD Phenom. Si sta facendo progressi, che è il motivo per cui sto lasciando correre (l'estensione della barra di progresso hg è un must-have). Si alterna tra il pegging di una CPU e il non utilizzo di alcuna CPU e l'accesso a disco.
David Dato

Qualcuno ha testato se le scarse prestazioni causate hggito sono hgtroppo lente per essere utilizzabili con progetti di dimensioni del kernel in generale?
Mikko Rantalainen il

1

Ho provato di nuovo Git-Hg di Cosmin e Git -Hg di abourget sia su hg repo di Mutt , sembra che il secondo rispetti bene l'ordine di fusione, che il primo sia un po 'casuale. Puoi vedere dagli screenshot qui sotto.

Un grafico cronologico di unione di mutt importato da gmin-hg di cosmin :

inserisci qui la descrizione dell'immagine

Un grafico cronologico di unione di mutt importato da gurg-hg-again di abourget :

inserisci qui la descrizione dell'immagine

Il grafico cronologico attuall tracciato da hgk sul repository hg di mutt:

inserisci qui la descrizione dell'immagine

Come puoi vedere da quanto sopra, il secondo grafico di git-hg-again di abourget è molto vicino al grafico hgk originale e in realtà riflette il vero flusso di lavoro del mutt.

Uno svantaggio di git-hg-again che ho riscontrato è che non aggiunge un telecomando 'hg', piuttosto importa tutti i suoi riferimenti come tag locali, git-hg ha un meraviglioso telecomando 'hg' che rappresenta il repository hg a monte.


1
Mi sembra che le differenze tra le versioni di cosmin e abourget siano nell'ordine dei genitori che si uniscono. Un buon strumento di visualizzazione della cronologia (ad es. gitk) Dovrebbe essere in grado di rendere identiche entrambe le storie. L'unica cosa ovviamente mancante è il ramo hg/stablenella versione di abourget. Immagino sia la cosa tra rami con nome, rami senza nome e segnalibri in Mercurial.
Mikko Rantalainen,

0

La sincronizzazione bidirezionale di hg-git (e git-git, hg-hg) è anche possibile con il servizio Git-hg Mirror . Usa hg-git (tra gli altri) dietro le quinte e il suo codice è anche open source.


Disclaimer : vengo dalla società dietro di esso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.