Interoperabilidad Git con un repositorio Mercurial

195

Yo uso GIT en una Mac. Basta de charla. Tengo las herramientas, tengo la experiencia. Y quiero seguir usándolo. No hay guerras aquí ...

El problema siempre es con la interoperabilidad. La mayoría de la gente usa SVN, lo cual es genial para mí. Git SVN funciona de inmediato y es una solución sencilla. La gente puede continuar felizmente usando SVN y no pierdo mi flujo de trabajo ni mis herramientas.

Ahora ... Algunos chicos vienen con Mercurial. Bien para ellos: tienen sus razones. Pero no puedo encontrar ningún GIT HG listo para usar. No quiero cambiar a HG, pero aún necesito interactuar con su repositorio.

¿Alguno de ustedes sabe una solución simple para esto?

Hugo Sereno Ferreira
fuente
44
hg-git funciona en ambas direcciones.
Derek Mahar
1
La respuesta de @dubiousjim es más útil, completa y más actualizada que las dos principales actuales, que apuntan a repositorios no mantenidos o dan consejos desactualizados. Pero aún más actualizaciones sobre esta pregunta serían muy útiles.
nealmcb

Respuestas:

60

Actualización de junio de 2012. Actualmente parece haber los siguientes métodos para la interoperabilidad de Git / Hg cuando el desarrollador quiere trabajar desde el lado de git:

  1. Instale Mercurial y la extensión hg-git . Puede hacer esto último usando su administrador de paquetes o con easy_install hg-git. Luego, asegúrese de que lo siguiente esté en su ~ / .hgrc:

    [extensions]
    hggit = 
    

    Puede ver algunas referencias que hablan sobre la especificación de la bookmarksextensión aquí también, pero eso se ha incorporado a Mercurial desde la versión 1.8. Aquí hay algunos consejos sobre cómo instalar hg-git en Windows .

    Una vez que tenga hg-git, puede usar comandos más o menos como Abderrahim Kitouni publicado anteriormente . Sin embargo, este método se ha refinado y ajustado desde 2009, y hay un contenedor amigable: git-hg-again . Esto utiliza el directorio de nivel superior como un directorio de trabajo para Mercurial y Git al mismo tiempo. Crea un marcador Mercurial que se mantiene sincronizado con la punta de la defaultrama (sin nombre) en el repositorio de Mercurial, y actualiza una rama Git local desde ese marcador.

  2. git-remote-hg es un contenedor diferente, también basado en lahg-gitextensiónMercurial. Esto además hace uso de losgit-remote-helpersprotocolos (de ahí su nombre). Utiliza el directorio de nivel superior solo para un directorio de trabajo de Git; mantiene su repositorio Mercurial desnudo. También mantiene un segundo repositorio Git desnudo para hacer que la sincronización entre Git y Mercurial sea más segura y más idiomática.

  3. El script git-hg (anteriormente mantenido aquí ) usa un método diferente, basado en hg-fast-exportel proyecto de exportación rápida . Al igual que el método 2, esto también mantiene un repositorio de Mercurial desnudo y un repositorio de Git desnudo adicional.

    Para tirar, esta herramienta ignora los marcadores de Mercurial y en su lugar importa cada rama Mercurial nombrada en una rama Git, y la rama Mercurial predeterminada (sin nombre) en master.

    Algunos comentarios discuten esta herramienta como solo hg-> git, pero afirma haberse fusionado en el soporte de empuje git-> hg el 7 de diciembre de 2011. Sin embargo, como explico en una revisión de estas herramientas , la forma en que esta herramienta intenta implementar El soporte de empuje no parece ser viable.

  4. También hay otro proyecto llamado git-remote-hg . A diferencia de la versión mencionada anteriormente, esta no se basa en hg-git, sino que accede directamente a la API de Mercurial Python. Por el momento, usarlo también requiere una versión parcheada de git. No he probado esto todavía.

  5. Finalmente, Tailor es un proyecto que convierte de forma incremental entre una variedad de VCS diferentes. Parece que el desarrollo de esto no se continuará agresivamente.

Los primeros tres de estos enfoques parecían lo suficientemente livianos como para persuadirme de investigar. Necesitaba ajustarlos de alguna manera para que se ejecutaran en mi configuración, y vi algunas formas de ajustarlos aún más para mejorarlos, y luego los ajusté aún más para que se comportaran más entre sí para poder evaluar ellos más efectivamente. Entonces pensé que a otros les gustaría tener estos ajustes también, para hacer la misma evaluación. Así que hice un paquete fuente que le permitirá instalar mis versiones de cualquiera de las tres primeras herramientas. También debe ocuparse de instalar las hg-fast-exportpiezas necesarias . (Necesita instalarlo hg-gitusted mismo).

Te animo a que las pruebes y decidas por ti mismo qué funciona mejor. Estaré encantado de escuchar sobre casos en los que estas herramientas se rompen. Trataré de mantenerlos sincronizados con los cambios ascendentes y para asegurarme de que los autores ascendentes estén al tanto de los ajustes que considero útiles.

Como mencioné anteriormente, al evaluar estas herramientas, llegué a la conclusión de que git-hgsolo se puede usar para sacar de Mercurial, no para empujar.

Relacionado, aquí hay algunas comparaciones útiles / manuales de traducción entre Git y Mercurial, en algunos casos dirigidos a usuarios que ya conocen Git:

dubiousjim
fuente
2
Estoy usando el método # 2 yo mismo, o más bien mi versión modificada. En general, me parece el enfoque más confiable y flexible (de los que probé). Vea los enlaces a mi paquete de revisión / fuente para más detalles.
dubiousjim
Sip. La armonía del horno es increíble. Gratis para desarrolladores en solitario también.
CAD bloke
114

Hay un nuevo git-remote-hg que proporciona soporte nativo:

Soporte de puente en Git para Mercurial y Bazar

Simplemente copie git-remote-hg en su $ PATH, hágalo ejecutable, y eso es todo, sin dependencias (aparte de Mercurial):

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

Debería poder empujar y tirar de él como si fuera un repositorio nativo de Git.

Cuando empuje nuevas ramas de Git, se crearán marcadores Mercurial para ellos.

Vea el wiki de git-remote-hg para más información.

FelipeC
fuente
14
Hola Felipe, eso no es exactamente cierto, necesitas una versión funcional de mercurial como dependencia
Antoine Pelisse
55
Asegúrese de nombrarlo exactamente git-remote-hg(es decir, sin .pysufijo).
schmmd
3
Funciona cuando el repositorio hg también es un submódulo.
Clayton Stanley
44
Tenga en cuenta que necesita Python 2. Por lo tanto, si Python 3 es el valor predeterminado en su sistema (o si no ejecuta Debian y quiere ser una prueba futura) cambie la primera línea a #!/usr/bin/env python2.
Kevin Cox
44
Tenga en cuenta que desde gcur-remote-hg de Mercurial 3.2 @FelipeC ya no funciona ( github.com/felipec/git-remote-hg/issues/27 ), es decir, hasta que la bifurcación que soluciona el problema se fusiona (vea github .com / fingolfin / git-remote-hg )
Cimbali
106

Deberías poder usar hg-git .

hg clone <hg repository>

editar ~/.hgrcy agregar:

[extensions]
hgext.bookmarks =
hggit =

crea un marcador para que tengas un mastergit:

cd <repository>
hg bookmark -r default master

editar .hg/hgrcen el repositorio y agregar:

[git]
intree = true

ahora puedes crear el repositorio git:

hg gexport

y puedes usar el directorio resultante como un clon git. tirar de mercurial sería:

hg pull
hg gexport

y empujando a mercurial:

hg gimport
hg push

(Sí, debe usar hg con este flujo de trabajo, pero su pirateo será todo en git)

PD: si tiene un problema con este flujo de trabajo, presente un error.

Abderrahim Kitouni
fuente
3
no olvide ejecutar easy_install hg-git primero
Christian Oudard
1
No es exactamente lo que quería, pero aún es factible. Gracias.
Hugo Sereno Ferreira
3
Solo para su información, después de ejecutar este proceso una vez en un repositorio local de hg (y hacer algo mal) no pude clonar el repositorio resultante usando git. Tuve que "clonar hg" el repositorio hg de origen, seguir los pasos del nuevo repositorio hg y luego clonar el nuevo repositorio hg.
Rocky Burt
1
Obtengo esto cuando intento emitir un git statuscomando $ git status fatal: esta operación debe ejecutarse en un árbol de trabajo Esto es después de haber emitido un hg gexporten un repositorio hg recién clonado. ¿Qué es un posible trabajo para moverse por los repositorios desnudos? Actualización . Aparentemente, la sugerencia de Rock Burt funciona. Gracias
yesudeep
1
@ThaDon Tengo el mismo problema. Aparentemente, el repositorio de git se crea como .hg / git. La solución es 'ln -s .hg / git .git'.
mb14
15

Puede probar hg2git, que es un script de Python y es parte de la exportación rápida, que puede encontrar en http://repo.or.cz/w/fast-export.git .

Sin embargo, deberá tener instalado mercurial.

sykora
fuente
44
Esto convirtió un repositorio hg en un repositorio git, ¡muchas gracias!
Reconbot
Este guión falló para mí, pero el original hg-fast-exportfuncionó bien
Andrei
Creo que actualmente el hg-fast-exportscript se envía a hg2git. Sin embargo, no lo he rastreado todo. Tenga en cuenta que estas herramientas solo permiten pasar de Hg-> Git, no al revés.
dubiousjim
9

Dado que hg-git es un puente de dos vías, también le permitirá empujar conjuntos de cambios de Git a Mercurial.

Martin Geisler
fuente
6

Complemento Mercurial Hg-Git . No lo he intentado yo mismo, pero podría valer la pena echarle un vistazo.

ralphtheninja
fuente
77
Este es un complemento que permite a los usuarios mercuriales empujar y tirar de los repositorios de git, no al revés, que es lo que quiere el OP.
sykora
1
@sykora, también se puede utilizar para impulsar la interoperabilidad desde la dirección inversa. Vea algunas de las herramientas que enumero en mi respuesta.
dubiousjim
6

He tenido un gran éxito con los git-hgde https://github.com/cosmin/git-hg (requiere trabajar instalación de hg, también). Es compatible con fetch, pull and push y es más estable para mí que hg-git(características similares de hggit).

Consulte https://github.com/cosmin/git-hg#usage para ver ejemplos de uso. La interfaz de usuario es muy similar a git-svn.

El git-hgrequiere espacio en disco adicional para cada uno de recompra hg clonado. La implementación utiliza clon mercurial completo, un clon desnudo git adicional y el repositorio git real. El espacio en disco requerido es aproximadamente 3 veces el uso normal de solo git. Las copias adicionales se almacenan debajo del .gitdirectorio de su directorio de trabajo (o ubicación señalada GIT_DIRcomo de costumbre).

Aviso: El problema básico que git-hgintenta resolver es que no hay una correlación 1: 1 entre las características gity hg. El mayor problema es la falta de concordancia entre las ramas Git y ramas sin nombre hg y ramas hg llamado y marcadores hg (todos aquellos parecen mucho a las ramas de gitlos usuarios). Un problema relacionado es que hgintenta guardar el nombre original de la rama con nombre en el historial de versiones en lugar de git, donde el nombre de la rama solo se agrega al mensaje de confirmación de plantilla de forma predeterminada.

Cualquier herramienta que pretenda crear un puente interoperable entre gity hgdebería explicar cómo va a lidiar con este partido de impedancia. Luego puede decidir si la solución seleccionada se ajusta a sus necesidades.

La solución que git-hgutiliza es descartar todos los marcadores hg y convertir ramas con nombre en ramas git. Además, establece la rama maestra git en la rama hg sin nombre predeterminada.

Mikko Rantalainen
fuente
Parece que git-hgsolo es viable para tirar de Hg, no para empujar (ver la explicación a la que enlazo en mi respuesta). ¿Has encontrado alguna manera de usarlo con éxito en ambas direcciones? En cuanto al espacio extra, todas las técnicas con las que estoy familiarizado implican trabajar dir + una copia de git db / metadata + una copia de hg db / metadata. Agregar una segunda copia de git db / metadata implica más uso del disco, sí, pero en términos comparativos no es tan malo como parece.
dubiousjim
@dubiousjim Mis necesidades se cumplieron con un pull / fetch funcional y nunca probé el push. Estaba confiando en la documentación, pero después de revisar sus explicaciones, ahora creo que git-hgno es adecuado para presionar. Modifiqué mi respuesta para dejar más claro que pushno es lo suficientemente estable.
Mikko Rantalainen
Lástima, pensé que podría haber alguna forma de usar push con éxito que no estaba viendo.
dubiousjim
1
+1 para resaltar la falta de coincidencia de impedancia y qué buscar
matt wilkie
3

He intentado hggit. Funciona para mí, ya que tengo que hacer frente al trabajo de git'ers y hg'ers. Especialmente para las reseñas, esto es genial.

Un pequeño problema / advertencia sobre ese tema:

He intentado clonar un repositorio estable de kernel de Linux con hg. Estos repositorios se mantienen en git y generalmente tienen una gran cantidad de archivos.

Fue muy lento Me tomó 2 días clonar y actualizar completamente una copia de trabajo.

Wizz
fuente
Parece que está mejorando --- mi proceso de pago ha estado funcionando durante aproximadamente seis horas, y afirma que solo quedan nueve más ...
David Dado
Tomare eso de vuelta. Ahora ha estado funcionando durante aproximadamente 25 horas, y aún afirma que solo quedan nueve más. ¿Dos días, dijiste?
David dado
1
Experimenté eso: mi primer intento no funcionó en absoluto, supongo que fue un error, pero nunca lo analicé más, en mi segundo intento, con un hg-git actualizado, me llevó casi 50 horas completarlo en mi Mac Book Pro (2.66GHz, 8 Gig RAM)
Wizz
¡39 horas ahora, así que solo quedan 11! Quad core AMD Phenom. Se está haciendo un progreso, que es por eso que estoy dejándolo funcionar (la extensión de la barra de progreso hg es un must-have). Alterna entre vincular una CPU y no usar ninguna CPU y hacer mucho acceso al disco.
David dado
¿Alguien ha probado si el bajo rendimiento causado por hggito es hgdemasiado lento para ser utilizable con proyectos de tamaño de núcleo en general?
Mikko Rantalainen
1

He tratado git-hg de Cosmin y de abourget git-hg-nuevo tanto en repo hg de Mutt , parece que los aspectos posteriores del orden de una fusión bien, el primero es un poco aleatorio. Puedes ver las capturas de pantalla a continuación.

Un gráfico de historial de fusión de mutt importado por git-hg de cosmin :

ingrese la descripción de la imagen aquí

Un gráfico de historia de fusión de mutt importado por gour-hg-again de abourget :

ingrese la descripción de la imagen aquí

El gráfico de la historia actual trazado por hgk en el repositorio hg de mutt:

ingrese la descripción de la imagen aquí

Como puede ver en lo anterior, la segunda gráfica de gour-hg-again de abourget está muy cerca de la gráfica hgk original y en realidad refleja el flujo de trabajo real del mutt.

Un inconveniente de git-hg-again que encontré es que no agrega un control remoto 'hg', sino que importa todas sus referencias como etiquetas locales, git-hg tiene un maravilloso control remoto 'hg' que representa el repositorio hg ascendente.

weynhamz
fuente
1
Me parece que las diferencias entre las versiones de cosmin y abourget son del orden de los padres en los compromisos de fusión. Una buena herramienta de visualización de historial (p gitk. Ej. ) Debería poder representar ambos historiales de forma idéntica. La única cosa que obviamente falta es la rama hg/stableen la versión de abourget. Supongo que es lo que hay entre ramas con nombre, ramas sin nombre y marcadores en Mercurial.
Mikko Rantalainen
0

La sincronización bidireccional hg-git (y git-git, hg-hg) también es posible con el servicio Git-hg Mirror . Utiliza hg-git (entre otros) detrás de escena y su código también es de código abierto.


Descargo de responsabilidad : soy de la compañía detrás de esto.

Piedone
fuente