Git与Mercurial存储库的互操作性


195

我在Mac上使用GIT。说够了。我有工具,我有经验。而且我想继续使用它。这里没有战争...

问题总是与互操作性有关。大多数人都使用SVN,这对我来说很棒。Git SVN开箱即用,是一种简洁的解决方案。人们可以继续快乐地使用SVN,并且我不会失去工作流程和工具。

现在...有些人和水星一起来。对他们很好:他们有他们的理由。但是我找不到现成的GIT HG。我不想切换到HG,但是我仍然需要与他们的存储库进行互操作。

你们中有人知道一个简单的解决方案吗?


4
hg-git确实可以双向使用。
德里克·马哈尔

1
@dubiousjim的答案比当前的前两个更有用,更全面和最新,后者表示未维护的存储库或提供过时的建议。但是,对此问题进行更多更新将非常有帮助。
nealmcb '02

Answers:


60

从2012年6月开始更新。当开发人员希望从git端进行工作时,目前似乎有以下方法可实现Git / Hg互操作性:

  1. 安装Mercurial和hg-git扩展。您可以使用软件包管理器或通过进行后者easy_install hg-git。然后确保在您的〜/ .hgrc中包含以下内容:

    [extensions]
    hggit = 
    

    您可能还会在bookmarks此处看到一些有关指定扩展名的参考,但这是自v1.8起内置在Mercurial中的。以下是有关在Windows上安装hg-git的一些技巧

    有了hg-git后,就可以使用上面类似的命令Abderrahim Kitouni了。自2009年以来,此方法已经过改进和调整,并且有一个友好的包装器:git-hg-again。它将顶级目录同时用作Mercurial和Git的工作目录。它创建一个Mercurial书签,使其与defaultMercurial存储库中(未命名)分支的尖端保持同步,并从该书签更新本地Git分支。

  2. git-remote-hg是一个不同的包装器,也基于Mercurialhg-git扩展名。此外,这还使用了git-remote-helpers协议(因此得名)。它仅将顶层目录用于Git工作目录;它保持其Mercurial存储库裸露。它还维护了第二个裸Git存储库,以使Git和Mercurial之间的同步更加安全,并且更像gitlike。

  3. 混帐-HG脚本(前身为维护这里)使用不同的方法的基础上,hg-fast-export快速出口项目。与方法2一样,这也保留了一个裸露的Mercurial存储库和一个附加的裸露Git存储库。

    对于拉动,此工具将忽略Mercurial书签,而是将每个命名的Mercurial分支导入Git分支,并将默认的(未命名)Mercurial分支导入master。

    一些评论将该工具仅作为hg-> git进行了讨论,但它声称已于2011年12月7日合并到git-> hg push支持中。不过,正如我在对这些工具的评论中所解释的那样,该工具试图实现的方式推送支持似乎不可行。

  4. 还有另一个名为git-remote-hg的项目。与上面列出的版本不同,该版本不依赖hg-git,而是直接访问Mercurial Python API。目前,使用它还需要git的修补版本。我还没有尝试过。

  5. 最后,Tailor是一个在各种不同的VCS之间进行增量转换的项目。听起来这种发展不会积极地继续下去。

这些方法中的前三种看上去很轻巧,足以说服我进行调查。我需要以某种方式对它们进行调整,以使它们在我的设置上运行,然后我看到了一些调整它们以进一步改进它们的方法,然后我进一步调整了它们以使它们的行为彼此相似,以便我可以进行评估他们更有效。然后,我认为其他人可能也希望进行这些调整,以进行相同的评估。因此,我制作了一个源软件包,使您可以安装前三个工具中任何一个的版本。它还应注意安装所需的hg-fast-export零件。(您需要自行安装hg-git。)

我鼓励您尝试一下,并自己决定最有效的方法。我很高兴听到这些工具损坏的情况。我将尝试使它们与上游更改保持同步,并确保上游作者意识到我认为有用的调整。

如上所述,在评估这些工具时,我得出的结论git-hg是,仅可用于从Mercurial中提取,而不能用于推送。

相关地,以下是一些有用的Git与Mercurial之间的比较/翻译手册,在某些情况下,这些手册是针对已经了解Git的用户的:


2
我自己在使用方法2,或者是我对它进行了调整的版本。总的来说,在我看来,这是最可靠,最灵活的方法。有关详细信息,请参见我的评论/资源包的链接。
dubiousjim 2012年

对。窑和谐很棒。面向开发者免费。
CAD bloke 2013年

114

有一个新的git-remote-hg提供了本机支持:

Git中针对Mercurial和Bazaar的桥梁支持

只需将git-remote-hg复制到$ PATH,使其可执行,就可以了,没有依赖关系(除了Mercurial):

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

您应该能够将其推入并拉出,就像它是本机Git存储库一样。

当您按下新的Git分支时,将为其为其创建Mercurial书签。

有关更多信息,请参见git-remote-hg Wiki


14
嘿菲利普,这是不完全正确,你需要的善变一个工作版本的依赖
安托万斗篷,脑袋挺大

5
确保准确命名git-remote-hg(即没有.py后缀)。
schmmd

3
当hg仓库也是子模块时,也可以使用。
克莱顿·斯坦利

4
请注意,您需要python2。因此,如果python 3是系统上的默认设置(或者如果您不运行Debian并希望成为将来的证明),请将第一行更改为#!/usr/bin/env python2
凯文·考克斯

4
请注意,由于Mercurial 3.2 @FelipeC的git-remote-hg不再起作用(github.com/felipec/git-remote-hg/issues/27),也就是说,直到解决该问题的fork合并(请参见github)的.com /芬国昐/ GIT-远程-HG
CIMBALI

106

您应该可以使用hg-git

hg clone <hg repository>

编辑~/.hgrc并添加:

[extensions]
hgext.bookmarks =
hggit =

创建一个书签,以便您master在git中有一个:

cd <repository>
hg bookmark -r default master

.hg/hgrc在存储库中编辑并添加:

[git]
intree = true

现在您可以创建git存储库:

hg gexport

您可以将生成的目录用作git克隆。从水银中拉出将是:

hg pull
hg gexport

并推向水银:

hg gimport
hg push

(是的,您需要在此工作流程中使用hg,但是您的黑客攻击全都在git中)

PS:如果您对此工作流程有疑问,请提交错误。


3
别忘了先运行easy_install hg-git
Christian Oudard,2009年

1
并不是我想要的,但仍然可行。谢谢。
雨果·塞雷诺·费雷拉

3
仅供参考,在本地hg存储库上运行了一次此过程(并且做错了事)后,我无法使用git克隆生成的存储库。我必须“ hg clone”源hg repo,按照新的hg repo上的步骤操作,然后git clone新的hg repo。
Rocky Burt

1
在尝试发出git status致命命令$ git status时出现错误:此操作必须在工作树中运行这是在hg gexport新克隆的hg存储库中发出了一个之后。如何解决裸存储库? 更新。显然,Rock Burt的建议有效。谢谢
yesudeep

1
@ThaDon我有同样的问题。显然git repo创建为.hg / git。解决方案是“ ln -s .hg / git .git”。
mb14 2011年

15

您可以尝试hg2git,它是python脚本,是快速导出的一部分,可以在http://repo.or.cz/w/fast-export.git中找到它。

您将需要安装Mercurial。


4
这将hg仓库转换为git仓库,非常感谢!
reconbot 2010年

这个脚本对我来说失败了,但是原始脚本hg-fast-export运行良好
Andrei

我认为目前该hg-fast-export脚本调度到hg2git。我还没有找到全部。请注意,这些工具仅允许从Hg-> Git进行操作,而不能相反。
dubiousjim 2012年



6

git-hghttps://github.com/cosmin/git-hg获得了巨大的成功(也需要工作安装hg)。它支持fetch,pull和push,并且对我来说比hg-git(与hggit 类似的功能)更稳定。

有关用法示例,请参见https://github.com/cosmin/git-hg#usage。用户界面与十分相似git-svn

git-hg要求每个克隆的汞回购额外的磁盘空间。该实现使用完整的Mercurial克隆,一个额外的Git裸克隆和实际的Git回购。所需的磁盘空间大约是普通git用法的3倍。多余的副本存储在.git工作目录的目录下(或GIT_DIR照常指向的位置)。

注意:git-hg尝试解决的基本问题是githg功能之间没有1:1映射。最大的问题是git分支和hg未命名分支hg命名分支hg书签之间的阻抗不匹配(所有这些看起来都像是git用户的分支)。一个相关的问题是,hg尝试将原始命名的分支名称保存在版本历史记录中,而git则默认情况下仅将分支名称添加到模板提交消息中。

任何工具,要求建立可互操作之间的桥梁git,并hg应说明它是如何去应对这种阻抗匹配。然后,您可以决定所选解决方案是否符合您的需求。

使用的解决方案git-hg是丢弃所有hg书签,并将命名的分支转换为git分支。另外,它将git master分支设置为默认的未命名hg分支。


看来git-hg仅适用于从汞中拉出,而不适用于推入(请参见我在答案中链接的说明)。您是否找到了可以在两个方向上成功使用它的方法?至于额外的空间,我所熟悉的所有技术都涉及工作目录+一份git db / metadata副本+一份hg db / metadata副本。是的,添加第二个git db / metadata副本确实会占用更多磁盘空间,但是相对而言,它并没有看上去那么糟糕。
dubiousjim 2012年

@dubiousjim我的需求已通过有效的拉取/获取来满足,但我从未真正测试过推送。我信任该文档,但是在检查了您的解释之后,我现在认为git-hg不适合推送。我修改了我的答案,以使其更清楚地表明push其不够稳定。
Mikko Rantalainen'7

太糟糕了,我认为可能有某种我没有看到的成功使用推的方法。
dubiousjim

1
+1用于突出显示阻抗不匹配以及寻找的内容
马特·威尔基

3

尝试过hggit。为我工作,因为我必须应付git'ers和hg'ers的工作。特别是对于评论,这很棒。

关于该主题的次要问题/警告:

我试图用hg克隆一个稳定的linux内核存储库。这些存储库都保存在git中,并且通常其中包含大量文件。

非常慢。我花了2天的时间来完全克隆更新工作副本。


情况似乎越来越好---我的结帐已经运行了大约六个小时,它声称只剩下九个了……
大卫鉴于

我收回之前说过的话。它已经运行了大约25个小时,并且仍然声称只剩下9个了。两天,你说?
大卫

1
我经历了-我的第一次尝试根本没有用-我认为这是一个错误,但是在第二次尝试中再也没有进行任何分析-更新后的hg-git在Mac Book上花费了将近50个小时才能完成专业版(2.66GHz,8 Gig RAM)
Wizz,2012年

现在39个小时,所以只有11个小时了!四核AMD Phenom。它正在取得进展,这就是为什么我要让它运行(hg进度条扩展是必须的)。在固定一个CPU和完全不使用CPU以及进行大量磁盘访问之间交替进行。
大卫

有没有人测试过由内核大小的项目引起的性能下降hggithg速度太慢而无法正常使用?
Mikko Rantalainen 2012年

1

我已经在mutt的hg repo再次尝试了cosmin的git-hgabourget的git-hg-a,似乎后面的人很好地遵守了合并的顺序,前者有点随机。您可以从下面的屏幕截图中看到。

cosmin的git-hg导入的Mutt的合并历史记录图:

在此处输入图片说明

abourget的git-hg-again再次导入的mutt的合并历史记录图:

在此处输入图片说明

hgk在mutt的hg存储库上绘制的实际历史记录图:

在此处输入图片说明

从上面可以看到,abourget的git-hg-again的第二张图非常接近原始的hgk图,并且实际上反映了mutt的实际工作流程。

我发现git-hg-again的一个缺点是它没有添加'hg'远程,而是将其所有引用导入为本地标签,git-hg有一个很棒的'hg'远程代表上游hg存储库。


1
在我看来,cosmin和abourget的版本之间的差异是合并提交中父级的​​顺序。良好的历史记录可视化工具(例如gitk)应该能够相同地呈现两个历史记录。唯一明显缺失的是hg/stableabourget版本中的分支。我猜这是Mercurial中命名分支,未修改分支和书签之间的问题。
Mikko Rantalainen 2014年

0

使用服务Git-hg Mirror也可以进行双向hg-git(和git-git,hg-hg)同步。它在后台使用了hg-git(除其他外),其代码也是开源的。


免责声明:我来自背后的公司。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.