Interoperabilidade Git com um repositório Mercurial

195

Eu uso o GIT em um Mac. Disse o suficiente. Eu tenho as ferramentas, tenho a experiência. E eu quero continuar a usá-lo. Não há guerras aqui ...

O problema está sempre com a interoperabilidade. A maioria das pessoas usa SVN, o que é ótimo para mim. O Git SVN funciona imediatamente e é uma solução sem frescuras. As pessoas podem continuar felizes usando o SVN e eu não perco meu fluxo de trabalho e nem minhas ferramentas.

Agora ... Alguns caras vêm com o Mercurial. Tudo bem para eles: eles têm suas razões. Mas não consigo encontrar nenhum GIT HG pronto para uso. Não quero mudar para o HG, mas ainda preciso interoperar com o repositório.

Algum de vocês conhece uma solução simples para isso?

Hugo Sereno Ferreira
fonte
4
O hg-git funciona nas duas direções.
Derek Mahar
1
A resposta de @dubiousjim é mais útil, abrangente e mais atualizada do que as duas principais atuais, que apontam para acordos não mantidos ou fornecem conselhos desatualizados. Porém, mais atualizações sobre essa questão seriam muito úteis.
Nealmcb

Respostas:

60

Atualização de junho de 2012. Atualmente, parece haver os seguintes métodos para a interoperabilidade do Git / Hg quando o desenvolvedor deseja trabalhar do lado do git:

  1. Instale o Mercurial e a extensão hg-git . Você pode fazer o último usando o gerenciador de pacotes ou com easy_install hg-git. Em seguida, verifique se o seguinte está em seu ~ / .hgrc:

    [extensions]
    hggit = 
    

    Você pode ver algumas referências que falam sobre a especificação da bookmarksextensão aqui também, mas que foram incorporadas ao Mercurial desde a v 1.8. Aqui estão algumas dicas sobre a instalação do hg-git no Windows .

    Depois de ter o hg-git, você pode usar comandos mais ou menos como o Abderrahim Kitouni postado acima . Esse método foi aprimorado e aprimorado desde 2009, e existe um empacotador amigável: git-hg-again . Isso usa o diretório de nível superior como um diretório de trabalho para o Mercurial e o Git ao mesmo tempo. Ele cria um marcador Mercurial que mantém sincronizado com a ponta da defaultramificação (sem nome) no repositório Mercurial e atualiza uma ramificação Git local a partir desse marcador.

  2. O git-remote-hg é um wrapper diferente, também baseado nahg-gitextensãoMercurial. Além disso, faz uso dogit-remote-helpers protocolos (daí o nome). Ele usa o diretório de nível superior apenas para um diretório de trabalho do Git; mantém seu repositório Mercurial vazio. Ele também mantém um segundo repositório simples do Git para tornar a sincronização entre o Git e o Mercurial mais segura e mais semelhante ao git do idioma.

  3. O git-hg roteiro (anteriormente mantido aqui ) utiliza um método diferente, com base hg-fast-exportna partir do projeto de fast-exportação . Como o método 2, isso também mantém um repositório Mercurial vazio e um repositório Git vazio adicional.

    Para puxar, essa ferramenta ignora os favoritos do Mercurial e, em vez disso, importa todos os ramos do Mercurial nomeados para um ramo do Git, e o ramo do Mercurial padrão (sem nome) para o mestre.

    Alguns comentários discutem essa ferramenta como sendo apenas hg-> git, mas afirma ter se fundido no suporte a git-> hg push em 7 de dezembro de 2011. Porém, como explico em uma revisão dessas ferramentas , o modo como essa ferramenta tenta implementar O suporte por push não parece viável.

  4. Há também outro projeto chamado git-remote-hg . Diferente da versão listada acima, esta não depende do hg-git, mas acessa diretamente a API Mercurial Python. No momento, usá-lo também requer uma versão corrigida do git. Ainda não tentei isso.

  5. Finalmente, o Tailor é um projeto que converte incrementalmente entre uma variedade de VCSs diferentes. Parece que o desenvolvimento disso não será agressivamente continuado.

As três primeiras dessas abordagens pareciam leves o suficiente para me convencer a investigar. Eu precisava ajustá-los de algumas maneiras para fazê-los funcionar na minha configuração, e vi algumas maneiras de ajustá-los ainda mais para melhorá-los, e então os ajustei ainda mais para fazê-los se comportar mais como se, para que eu pudesse avaliar eles de forma mais eficaz. Então pensei que outras pessoas também gostariam de ter esses ajustes, para fazer a mesma avaliação. Então, eu criei um pacote de origem que permitirá que você instale minhas versões de qualquer uma das três primeiras ferramentas. Também deve cuidar da instalação das hg-fast-exportpeças necessárias . (Você precisa instalarhg-git por conta própria.)

Convido você a experimentá-los e decidir por si mesmo o que funciona melhor. Ficarei feliz em ouvir casos em que essas ferramentas quebram. Vou tentar mantê-los em sincronia com as alterações anteriores e garantir que os autores anteriores estejam cientes dos ajustes que considero úteis.

Como mencionei acima, ao avaliar essas ferramentas, cheguei à conclusão de que git-hgsó é útil extrair do Mercurial, não empurrar.

De maneira semelhante, aqui estão algumas comparações úteis / manuais de tradução entre o Git e o Mercurial, em alguns casos direcionados a usuários que já conhecem o Git:

dubiousjim
fonte
2
Eu mesmo estou usando o método 2, ou melhor, minha versão aprimorada. No geral, isso me parece a abordagem mais confiável e flexível (das que eu tentei). Veja os links para meu pacote de revisão / fonte para obter detalhes.
dubiousjim
Sim. Kiln Harmony é incrível. Grátis para desenvolvedores solo também.
Bloke CAD
114

Há um novo git-remote-hg que fornece suporte nativo:

Suporte de ponte no Git para Mercurial e Bazaar

Apenas copie o git-remote-hg para o seu $ PATH, torne-o executável e é isso, sem dependências (além do Mercurial):

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

Você deve poder empurrar e puxar dele como se fosse um repositório Git nativo.

Quando você pressiona novos ramos Git, os indicadores do Mercurial serão criados para eles.

Veja o wiki do git-remote-hg para mais informações.

FelipeC
fonte
14
Hey Felipe, isso não é exatamente verdade, você precisa de uma versão de trabalho do mercurial como uma dependência
Antoine Pelisse
5
Certifique-se de nomeá-lo exatamente git-remote-hg(ou seja, sem .pysufixo).
23913 schmmd
3
Funciona quando o repositório hg também é um submódulo.
Clayton Stanley
4
Note que você precisa do python 2. Portanto, se o python 3 é o padrão no seu sistema (ou se você não executa o Debian e deseja ser à prova de futuro), mude a primeira linha para #!/usr/bin/env python2.
Kevin Cox
4
Observe que, como o git-remote-hg do Mercurial 3.2 @FelipeC não funciona mais ( github.com/felipec/git-remote-hg/issues/27 ), ou seja, até que o fork que resolve o problema seja mesclado (consulte o github .com / fingolfin / git-remote-hg )
Cimbali 4/15
106

Você deve poder usar o hg-git .

hg clone <hg repository>

edite ~/.hgrce adicione:

[extensions]
hgext.bookmarks =
hggit =

crie um marcador para ter um masterno git:

cd <repository>
hg bookmark -r default master

edite .hg/hgrcno repositório e adicione:

[git]
intree = true

agora você pode criar o repositório git:

hg gexport

e você pode usar o diretório resultante como um clone do git. puxar de mercurial seria:

hg pull
hg gexport

e empurrando para mercurial:

hg gimport
hg push

(Sim, você precisa usar o hg com esse fluxo de trabalho, mas seus hackers estarão todos no git)

PS Se você tiver um problema com este fluxo de trabalho, registre um bug.

Abderrahim Kitouni
fonte
3
não se esqueça de executar easy_install hg-git primeira
Christian Oudard
1
Não é exatamente o que eu queria, mas ainda é possível. Obrigado.
Hugo Sereno Ferreira
3
Apenas um fyi, depois de executar esse processo uma vez em um repositório local de hg (e fazer algo errado), não consegui clonar o repositório resultante usando o git. Eu tive que "hg clone" o repositório hg de origem, siga as etapas no novo repositório hg e, em seguida, git clone o novo repositório hg.
Rocky Burt
1
Eu recebo isso ao tentar emitir um git statuscomando $ git status fatal: Esta operação deve ser executada em uma árvore de trabalho Isso ocorre depois de emitir um hg gexportem um repositório hg recentemente clonado. O que é um possível trabalho para contornar repositórios vazios? Update . Aparentemente, a sugestão de Rock Burt funciona. Obrigado
yesudeep
1
@ ThaDon Eu tenho o mesmo problema. Aparentemente, o repositório git é criado como .hg / git. A solução é 'ln -s .hg / git .git'.
MB14
15

Você pode tentar hg2git, que é um script python e faz parte da exportação rápida, que pode ser encontrada em http://repo.or.cz/w/fast-export.git .

Você precisará ter o mercurial instalado.

sykora
fonte
4
Isso converteu um repositório hg em um repositório git, muito obrigado!
reconbota
Este script falhou para mim, mas o original hg-fast-exportfuncionou bem #
Andrei
Eu acho que atualmente o hg-fast-exportscript é enviado para hg2git. Eu não rastreei tudo embora. Observe que essas ferramentas permitem apenas passar de Hg-> Git, não o contrário.
dubiousjim
9

Como o hg-git é uma ponte de duas vias, ele também permitirá que você transfira conjuntos de alterações do Git para o Mercurial.

Martin Geisler
fonte
6

Plug-in Mercurial Hg-Git . Ainda não tentei, mas pode valer a pena conferir.

ralphtheninja
fonte
7
Este é um plug-in que permite aos usuários mercuriais empurrar e puxar dos repositórios git, e não o contrário, que é o que o OP deseja.
21909 sykora
1
@ sykora, também pode ser usado para conduzir a interoperabilidade na direção inversa. Veja algumas das ferramentas que listo na minha resposta.
dubiousjim
6

Eu tenho tido grande sucesso com git-hga partir https://github.com/cosmin/git-hg (requer o trabalho de instalação de hg, também). Ele suporta buscar, puxar e empurrar e é mais estável para mim do que hg-git(recursos semelhantes do hggit).

Consulte https://github.com/cosmin/git-hg#usage para obter exemplos de uso. A interface do usuário é muito parecida com git-svn.

Isso git-hgrequer espaço em disco extra para cada repositório hg clonado. A implementação usa o clone completo do mercurial, um clone extra do git bare e o repositório real do git. O espaço em disco necessário é aproximadamente três vezes o uso normal apenas do git. As cópias extras são armazenadas abaixo do .gitdiretório do seu diretório de trabalho (ou local indicado GIT_DIRcomo de costume).

Aviso: O problema básico que git-hgtenta resolver é que não há mapeamento 1: 1 entre gite hgrecursos. O maior problema é a incompatibilidade de impedância entre os ramos git e ramos sem nome hg e hg chamado ramos e bookmarks hg (todos aqueles parecem muito com ramos para gitusuários). Um problema relacionado é que hgtenta salvar o nome da ramificação nomeada original no histórico da versão, em oposição ao git, em que o nome da ramificação é adicionado apenas à mensagem de confirmação do modelo por padrão.

Qualquer ferramenta que pretenda criar uma ponte interoperável entre gite hgdeve explicar como vai lidar com essa correspondência de impedância. Você pode decidir se a solução selecionada atende às suas necessidades.

A solução git-hgusada é descartar todos os indicadores hg e converter ramificações nomeadas em ramificações git. Além disso, define o ramo mestre do git como padrão do ramo hg sem nome.

Mikko Rantalainen
fonte
Parece que git-hgsó é viável extrair do Hg, não empurrar (veja a explicação para a qual vinculo na minha resposta). Você encontrou alguma maneira de usá-lo com êxito nas duas direções? Quanto ao espaço extra, todas as técnicas com as quais estou familiarizado envolvem o trabalho dir + uma cópia do git db / metadata + uma cópia do hg db / metadata. Adicionar uma segunda cópia dos git db / metadata envolve mais uso de disco, sim, mas comparativamente falando, não é tão ruim quanto pode parecer.
dubiousjim
@dubiousjim Minhas necessidades foram preenchidas com um pull / fetch de trabalho e eu nunca testei o push. Eu estava confiando na documentação, mas depois de verificar suas explicações, agora acredito que git-hgnão é adequado para envio. Modifiquei minha resposta para deixar mais claro que pushnão é suficientemente estável.
Mikko Rantalainen
Que pena, eu pensei que poderia haver alguma maneira de usar o push com sucesso que eu não estava vendo.
precisa saber é o seguinte
1
+1 para destacar a diferença de impedância e o que procurar
Matt Wilkie
3

Já tentei hggit. Funciona para mim, já que eu tenho que lidar com o trabalho de pessoas e animais. Especialmente para comentários, isso é ótimo.

Um pequeno problema / aviso sobre esse tópico:

Eu tentei clonar um repositório estável de kernel Linux com hg. Esses repositórios são mantidos no git e normalmente possuem um grande número de arquivos.

Foi muito lento. Demorei 2 dias para clonar completamente e atualizar uma cópia de trabalho.

Wizz
fonte
Parece estar ficando melhor --- meu check-out foi executado por cerca de seis horas, e alega que só há outros nove para ir ...
David Dada
Retiro o que eu disse. Ele já está em funcionamento há cerca de 25 horas e ainda afirma que há apenas mais nove pela frente. Você disse dois dias?
David Data
1
Eu experimentei isso - minha primeira tentativa não funcionou - presumo que tenha sido um bug, mas nunca analisei mais sobre isso, na minha segunda tentativa - com um hg-git atualizado que levou quase 50 horas para ser concluído no meu Mac Book Pro (2,66 GHz, 8 GB de RAM)
Wizz
39 horas agora, então só faltam 11! AMD Phenom de quatro núcleos. Ele está progredindo, e é por isso que eu o deixo rodar (a extensão da barra de progresso hg é um item obrigatório). É alternar entre vincular uma CPU e não usar nenhuma CPU e fazer muito acesso ao disco.
David Data
Alguém já testou se o baixo desempenho causado por hggitou é hgmuito lento para ser utilizável em projetos de tamanho de kernel em geral?
Mikko Rantalainen
1

Eu tentei git-hg de cosmin e de abourget git-hg-again tanto no repo hg de vira-lata , parece que os aspectos mais tarde a ordem de uma fusão bem, o primeiro é um pouco aleatório. Você pode ver nas imagens abaixo.

Um gráfico de histórico de mesclagem de mutt importado pelo git-hg da cosmin :

insira a descrição da imagem aqui

Um gráfico de histórico de mesclagem de mutt importado pelo git-hg-again da abourget :

insira a descrição da imagem aqui

O gráfico de histórico atual plotado por hgk no repositório hg do mutt:

insira a descrição da imagem aqui

Como você pode ver acima, o segundo gráfico de abourget's git-hg-again está muito próximo do gráfico hgk original e reflete o fluxo de trabalho real do mutt.

Uma desvantagem do git-hg-again que eu descobri é que ele não adiciona um controle remoto 'hg', mas importa todos os seus refs como tags locais, o git-hg possui um controle remoto maravilhoso 'hg' que representa o repositório hg upstream.

weynhamz
fonte
1
Parece-me que as diferenças entre as versões cosmin e abourget estão na ordem dos pais nos commits de mesclagem. Uma boa ferramenta de visualização de histórico (por exemplo gitk) deve ser capaz de renderizar os dois históricos de forma idêntica. Obviamente, a única coisa que falta é o ramo hg/stablena versão abourget. Eu acho que é a coisa entre ramificações nomeadas, ramificações não nomeadas e marcadores no Mercurial.
Mikko Rantalainen
0

A sincronização bidirecional hg-git (e git-git, hg-hg) também é possível com o serviço Git-hg Mirror . Ele usa hg-git (entre outros) nos bastidores e seu código também é de código aberto.


Disclaimer : Eu sou da empresa por trás disso.

Piedone
fonte