如何使用hg-git将现有的Mercurial和git存储库关联起来?

18

这是一个相当深奥的问题,所以我在此明确一下:我不是在谈论从svn转换到git、git转换到mercurial或mercurial转换到git。我谈的是利用“跨系统”插件的复杂情况,这些插件允许Mercurial与git和SVN在某种程度上进行相互操作。

我使用hg-subversion插件来“跟踪”代码库中的upstream SVN repository on code.google.com。由于这个插件,Mercurial认为代码库是“相关的”,并且能够拉取自从我上次拉取代码库以来发生的更改。这使我能够维护自己的私有Mercurial代码库,包括私有变更集、分支、标签等,但是定期同步并合并与upstream SVN repo发生的更改。

upstream repo已干净地从SVN转移到了git。当我说“干净”,我的意思是他们携带了整个提交树,或者至少是我关心的默认/主分支的部分。

现在我面临的情况是,我有一个Mercurial代码库,它与已废弃的SVN代码库最后一次提交保持同步,我想开始从新的upstream git代码库拉取更改,从svn代码库转移到github后的第一个更改开始。

我可以使用很棒的hg-git插件从这个代码库拉取更改,但是由于当前代码库没有被认为与git upstream repo“相关”,它将拉取所有更改,包括那些已经存在于我的代码库中的镜像变更集。

所以我想要的是关于如何让Mercurial代码库通过hg-git将自己视为与upstream git代码库相关,并考虑来自git代码库的所有适当提交,在维护变更集平衡的目的下将其视为“已经拉取”的建议。

我看到内部hg-git似乎使用一个名为.git/git-mapfile的文件,我推测这个文件将upstream git和本地Mercurial代码库之间的变更集进行了映射。这可能是一个线索。

什么是最简单的方法将我的本地Mercurial存储库设置为基本上表现得像从上游git存储库开始克隆,但保留所有已添加的不相关的变更集?
(注:我宁愿不要使用全新的克隆,然后应用我的私有更改,因为我想为自己的构建/调试目的维护该存储库的历史完整性。)

2
如果我能指导您如何保留完整历史记录的更改,您愿意创建一个新的代码库吗?如果可以的话,神奇的答案将是有关使用hg-git的简短教程(确保顺便使用durin42的分支),以及hg convert中很少使用的splicemap - Benjamin Pollack
新建一个代码库会失去什么?只是每个变更集的特定UUID标签吗?假设我为它们保留标签名称,这应该是可以接受的。当我从svn转换到hg时,我实际上已经在某种程度上涉足了hg convert的splicemap。 - danielpunkass
是的,那就是你要放弃的一切。 - Benjamin Pollack
很好。我想知道如何简洁地将这个一般性的方法写成回答,或者它是否需要互动并且在特定的代码库上进行详细说明?如果能够澄清这个方法,我相信其他人也会受益! - danielpunkass
@BenjaminPollack的建议是我能想到的唯一符合要求的事情,即不在存储库中拥有所有额外的更改集。 - StayOnTarget
3个回答

5

我以前用git做过类似的事情。在git->git的情况下,我能够执行git-merge --strategy=ours命令,这基本上让我的当前存储库相信正在合并的所有内容都是无操作。

你需要做的是创建一个代表已经合并到你的树中的所有上游内容的分支,然后执行一个无操作样式的合并到你的树中,然后开始使用“真正的”合并来拉取更改。

来自这个网站:

https://www.mercurial-scm.org/wiki/TipsAndTricks#Keep_.22My.22_or_.22Their.22_files_when_doing_a_merge

我看到像下面这样的命令可能能帮助您合并上游存储库并忽略所有上游内容: $ hg --config ui.merge=internal:local merge #保留我的文件
这样可以让您将下游与上游重新同步。

太好了,Ben。谢谢!快速的谷歌搜索表明还有其他一些策略。我认为你的建议总结了一个有趣的限制:“我只关心从这一点开始的历史记录,但想要跟踪他们从这一点开始的历史记录。” - danielpunkass
我猜这可能反映了我对分布式版本控制系统操作的不完全理解,但是如果我不想将变更集拉入存储库,我该如何执行“保留我的文件”合并操作呢?至少在Mercurial中,似乎在合并之前必须拉取变更集,而这里的一个目标是避免在存储库中拥有所有那些冗余的变更集。 - danielpunkass
我没有看到解决重复变更集问题的立即方法。 - Ben Goodwyn

2

我会使用Hg-git克隆新的上游存储库,然后尝试使用Convert扩展将旧本地存储库中的所有更改拼接到新存储库中。实际上,我可能会将本地的Hg-git存储库克隆到本机Mercurial存储库中,并从上游Git存储库进行两步拉取。


这将完全符合 OP 的要求,并且可能会产生最干净的最终结果。它看起来就像跟踪 HG 存储库始终在跟随父 git 存储库一样。 - StayOnTarget

1
如果没有现成的解决方案,我想可以编写一个脚本,将您的更改打补丁并提交到一个基于git-clone的新存储库中。您只需要协调hg-git-fromsvn和hg-svn之间的svn版本,并在新存储库上复制您已完成的更新/打补丁/提交/合并序列。
对于任何愿意尝试的人来说,这是一个有趣的项目。 :)

这肯定会产生“最纯净”的结果,隐藏了任何“移植”点的证据。如果Ben的建议使得“获取所有变更集并运行”变得容易,那么我可能不会太担心纯度问题 :) - danielpunkass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接