Git 与 Mercurial 存储库的互操作性

Posted

技术标签:

【中文标题】Git 与 Mercurial 存储库的互操作性【英文标题】:Git interoperability with a Mercurial Repository 【发布时间】:2010-10-27 09:00:13 【问题描述】:

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

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

现在...有些人和 Mercurial 一起来了。对他们来说很好:他们有他们的理由。但我找不到任何开箱即用的 GIT HG。我不想切换到 HG,但我仍然需要与他们的存储库互操作。

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

【问题讨论】:

hg-git 确实可以双向工作。 @dubiousjim 的答案比当前的前两个更有用、更全面、更最新,它们指向未维护的存储库或提供过时的建议。但是关于这个问题的更多更新将非常有帮助。 【参考方案1】:

有一个新的 git-remote-hg 提供原生支持:

Bridge support in Git for Mercurial and Bazaar

只需将git-remote-hg 复制到您的$PATH 中,使其可执行,就是这样,没有依赖项(Mercurial 除外):

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

您应该能够像本地 Git 存储库一样对其进行推送和拉取。

当您推送新的 Git 分支时,将为它们创建 Mercurial 书签。

请参阅git-remote-hg wiki 了解更多信息。

【讨论】:

嘿 Felipe,这并不完全正确,您需要一个工作版本的 mercurial 作为依赖项 确保您将其准确命名为git-remote-hg(即没有.py 后缀)。 当 hg 存储库也是子模块时也可以使用。 请注意,您需要 python 2。因此,如果 python 3 是您系统上的默认设置(或者如果您不运行 Debian 并希望成为未来的证明),请将第一行更改为 #!/usr/bin/env python2 请注意,由于 Mercurial 3.2 @FelipeC 的 git-remote-hg 不再工作(github.com/felipec/git-remote-hg/issues/27),也就是说,直到合并解决问题的分支(请参阅github.com/fingolfin/git-remote-hg) 【参考方案2】:

你应该可以使用hg-git。

hg clone <hg repository>

编辑~/.hgrc 并添加:

[extensions]
hgext.bookmarks =
hggit =

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

cd <repository>
hg bookmark -r default master

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

[git]
intree = true

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

hg gexport

您可以将生成的目录用作 git clone。从 mercurial 中提取将是:

hg pull
hg gexport

并推送到 mercurial :

hg gimport
hg push

(是的,您需要在此工作流程中使用 hg,但您的黑客操作将全部在 git 中)

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

【讨论】:

别忘了先运行easy_install hg-git 不完全是我想要的,但仍然可行。谢谢。 仅供参考,在本地 hg repo 上运行一次此过程后(并且做错了什么),我无法使用 git 克隆生成的 repo。我必须“hg clone”源 hg repo,按照新 hg repo 上的步骤操作,然后 git clone the new hg repo。 我在尝试发出git status 命令时收到此消息 $ git status fatal: 此操作必须在工作树中运行 这是在我在新克隆的 hg 中发出hg gexport 之后存储库。绕过裸存储库的可行方法是什么? 更新。显然,Rock Burt 的建议奏效了。谢谢 @ThaDon 我也有同样的问题。显然 git repo 被创建为 .hg/git。解决方案是'ln -s .hg/git .git'。【参考方案3】:

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

    安装 Mercurial 和 hg-git extension。您可以使用包管理器或easy_install hg-git 执行后者。然后确保您的 ~/.hgrc 中有以下内容:

    [extensions]
    hggit = 
    

您也可能会看到一些提及在此处指定 bookmarks 扩展名的参考资料,但自 1.8 版起,Mercurial 已内置此扩展名。这里是some tips about installing hg-git on Windows。

一旦你有了 hg-git,你就可以使用类似Abderrahim Kitouni posted above 的命令了。自 2009 年以来,此方法一直是 refined and tweaked,并且有一个友好的包装器:git-hg-again。这同时使用***目录作为 Mercurial 和 Git 的工作目录。它创建一个 Mercurial 书签,它与 Mercurial 存储库中的 default(未命名)分支的尖端保持同步,并从该书签更新本地 Git 分支。

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

    git-hg 脚​​本(以前维护的 here)使用不同的方法,基于 hg-fast-exportfast-export project。与方法 2 一样,这也保留了一个裸 Mercurial 存储库和一个额外的裸 Git 存储库。

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

一些评论将此工具讨论为仅 hg->git,但它声称已在 2011 年 12 月 7 日合并到 git->hg 推送支持中。不过,正如我在 a review of these tools 中解释的那样,此工具尝试的方式实现推送支持似乎不可行。

    还有another project called git-remote-hg。与上面列出的版本不同,这个版本不依赖 hg-git,而是直接访问 Mercurial Python API。目前,使用它还需要一个修补版本的 git。我还没试过。

    最后,Tailor 是一个在各种不同 VCS 之间进行增量转换的项目。听起来这方面的开发不会继续积极进行。

前三种方法看起来很轻巧,足以说服我进行调查。我需要以某种方式调整它们以使它们在我的设置上运行,我看到了一些进一步调整它们以改进它们的方法,然后我进一步调整它们以使它们的行为更像彼此,以便我可以评估他们更有效。然后我认为其他人可能也希望进行这些调整,以进行相同的评估。所以我有made a source package,这将使您能够安装我的前三个工具中的任何一个版本。它还应该负责安装所需的hg-fast-export 件。 (需要自己安装hg-git。)

我鼓励您尝试一下,然后自己决定最有效的方法。我很高兴听到这些工具损坏的案例。我会尽量让它们与上游更改保持同步,并确保上游作者了解我认为有用的调整。

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

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

Mercurial for Git users Git and Mercurial - Compare and Contrast What is the difference between Mercurial and Git Mercurial and Git: a technical comparison Git hg rosetta stone Homebrew Coding: Mercurial Francisoud's Blog: Git vs Mercurial (hg) Git vs Mercurial

【讨论】:

我自己使用方法#2,或者更确切地说是我的调整版本。总的来说,在我看来,这是最可靠和最灵活的方法(在我尝试过的方法中)。有关详细信息,请参阅我的评论/源包的链接。 是的。窑和谐真棒。独立开发者也免费。【参考方案4】:

你可以试试hg2git,这是一个python脚本,是fast-export的一部分,你可以在http://repo.or.cz/w/fast-export.git找到。

不过,您需要安装 mercurial。

【讨论】:

这将 hg repo 转换为 git repo,非常感谢! 这个脚本对我来说失败了,但原来的 hg-fast-export 工作正常 我认为目前hg-fast-export 脚本发送到hg2git。不过,我还没有追查到这一切。请注意,这些工具只允许从 Hg->Git 开始,而不是相反。【参考方案5】:

由于 hg-git 是一个双向桥,它还允许您将变更集从 Git 推送到 Mercurial。

【讨论】:

【参考方案6】:

Hg-Git Mercurial Plugin。自己没有尝试过,但可能值得一试。

【讨论】:

这是一个插件,允许 mercurial 用户从 git repos 推送和拉取,而不是相反,这正是 OP 想要的。 @sykora,它也可以用来从相反的方向推动互操作性。请参阅我在回答中列出的一些工具。【参考方案7】:

我在https://github.com/cosmin/git-hg 的git-hg 上取得了巨大成功(也需要hg 的有效安装)。它支持 fetch、pull 和 push 并且对我来说比 hg-git 更稳定(从 hg 到 git 的类似功能)。

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

git-hg 需要为每个克隆的 hg 存储库提供额外的磁盘空间。该实现使用完整的 mercurial 克隆、一个额外的 git 裸克隆和实际的 git repo。所需的磁盘空间大约是普通 git 使用量的 3 倍。额外的副本存储在工作目录的.git 目录下(或像往常一样由GIT_DIR 指向的位置)。

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

任何声称在githg 之间创建可互操作桥接的工具都应说明它将如何处理这种阻抗匹配。然后您可以决定所选解决方案是否符合您的需求。

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

【讨论】:

看起来git-hg 仅适用于从 Hg 中拉出,而不适用于推送(请参阅我在答案中链接到的解释)。您是否找到了在两个方向上成功使用它的方法?至于额外空间,我熟悉的所有技术都涉及工作目录 + 一份 git db/metadata + 一份 hg db/metadata。添加 git db/metadata 的第二个副本确实涉及更多的磁盘使用,是的,但相对而言它并不像看起来那么糟糕。 @dubiousjim 我的需求已经被有效的 pull/fetch 满足了,但我从未真正测试过 push。我相信文档,但在检查了您的解释后,我现在认为 git-hg 不适合推送。我修改了我的答案,以更清楚地说明push 不够稳定。 太糟糕了,我认为可能有一些我没有看到的成功使用推送的方法。 +1 用于突出显示阻抗不匹配以及要查找的内容【参考方案8】:

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

关于该主题的小问题/警告:

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

速度很慢。我花了 2 天时间完全克隆更新工作副本。

【讨论】:

它似乎在变好 --- 我的结账已经运行了大约六个小时,它声称只剩下九个小时了...... 我收回了。它现在已经运行了大约 25 个小时,它仍然声称只有另外 9 个小时可以运行。你说两天? 我经历过 - 我的第一次尝试根本不起作用 - 我认为这是一些错误,但在我第二次尝试时从未进一步分析过 - 使用更新的 hg-git 几乎花了在我的 Mac Book Pro(2.66GHz,8 Gig RAM)上完成 50 小时 现在 39 小时,所以只剩 11 小时了!四核 AMD Phenom。它正在取得进展,这就是我让它运行的原因(hg 进度条扩展是必备的)。它在固定一个 CPU 和根本不使用 CPU 并进行大量磁盘访问之间交替。 有没有人测试过由hggithg 导致的性能不佳是否太慢而无法用于一般内核大小的项目?【参考方案9】:

我在mutt's hg repo上都试过cosmin's git-hg和abourget's git-hg-again,看来后者很好地尊重了合并的顺序,前者有点随机。您可以从下面的屏幕截图中看到。

cosmin's git-hg导入的mutt合并历史图:

abourget's git-hg-again导入的mutt合并历史图:

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

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

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

【讨论】:

在我看来,cosmin 和 abourget 版本之间的差异是合并提交中父级的​​顺序。一个好的历史可视化工具(例如gitk)应该能够以相同的方式呈现两个历史。唯一明显缺失的是 abourget 版本中的分支hg/stable。我猜这是 Mercurial 中命名分支、未命名分支和书签之间的关系。【参考方案10】:

使用Git-hg Mirror 服务也可以实现双向 hg-git(和 git-git、hg-hg)同步。它在幕后使用 hg-git(以及其他),其代码也是开源的。


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

【讨论】:

【参考方案11】:

2021 年的最新答案似乎是 git cinnabar,例如用于火狐浏览器。

此页面上建议的其他脚本要么未维护,要么需要过时的软件才能运行(通常是 python 2.7)。相比之下,cinnabar 与 python 3.5+ 一起工作,并且至少维护到写作之日。

安装 cinnabar 后,您可以通过前缀 hg:: 直接克隆 mercurial 存储库:

git clone hg::https://hg.mozilla.org/mozilla-unified

或添加或设置遥控器

git remote set-url origin hg::https://hg.mozilla.org/mozilla-unified
git fetch origin

您可以推送到 mercurial 遥控器。

使用 hg2gitgit2hg 命令允许将 git commit sha1s 转换为 mercurial 变更集并返回。 更多文档可用on the github page。

【讨论】:

以上是关于Git 与 Mercurial 存储库的互操作性的主要内容,如果未能解决你的问题,请参考以下文章

[转]Go与C语言的互操作

PWA 与 Android 应用程序/服务的互操作性?

Kotlin的互操作——Kotlin与Java互相调用

使用与 C# 的互操作,Excel 保存更改的原始文件。如何否定这一点?

JavaScript与C#的互操作示例

为 GCS 与 Terraform 启用“互操作”访问?