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-export
和 fast-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
试图解决的基本问题是git
和hg
特征之间没有1:1 的映射关系。最大的问题是 git 分支和 hg 未命名分支 和 hg 命名分支 和 hg 书签 之间的阻抗不匹配(所有这些看起来很像分支到git
用户)。一个相关的问题是hg
尝试将原始命名分支名称保存在版本历史记录中,而不是在默认情况下仅将分支名称添加到模板提交消息中的 git。
任何声称在git
和hg
之间创建可互操作桥接的工具都应说明它将如何处理这种阻抗匹配。然后您可以决定所选解决方案是否符合您的需求。
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 并进行大量磁盘访问之间交替。 有没有人测试过由hggit
或hg
导致的性能不佳是否太慢而无法用于一般内核大小的项目?【参考方案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 遥控器。
使用 hg2git
和 git2hg
命令允许将 git commit sha1s 转换为 mercurial 变更集并返回。
更多文档可用on the github page。
【讨论】:
以上是关于Git 与 Mercurial 存储库的互操作性的主要内容,如果未能解决你的问题,请参考以下文章