合并两个不相关的Mercurial存储库后,如何调整历史记录?

合并两个不相关的Mercurial存储库后,如何调整历史记录?,mercurial,merge,repository,Mercurial,Merge,Repository,根据给出的建议,我刚刚合并了两个存储库。因为两个存储库完全不相关,所以我使用 hg convert --filemap fm rep1a rep1b hg convert --filemap fm rep2a rep2b 将存储库1中的文件移动到子目录a,将存储库2中的文件移动到子目录b。现在两个存储库中都没有冲突的文件,所以我将它们合并在一起 结果是一个具有合并修订版的存储库,该修订版有两个父版本,一个包含存储库1的历史记录,另一个包含存储库2的历史记录。很好 mb--ma--2f--2e-

根据给出的建议,我刚刚合并了两个存储库。因为两个存储库完全不相关,所以我使用

hg convert --filemap fm rep1a rep1b
hg convert --filemap fm rep2a rep2b
将存储库1中的文件移动到子目录a,将存储库2中的文件移动到子目录b。现在两个存储库中都没有冲突的文件,所以我将它们合并在一起

结果是一个具有合并修订版的存储库,该修订版有两个父版本,一个包含存储库1的历史记录,另一个包含存储库2的历史记录。很好

mb--ma--2f--2e--2d--2c--2b--2a
      \
       -------------------------1e--1d--1c--1b--1a     
现在我真正想要的是一个历史,其中补丁是按时间排序的。这没问题,我使用了hg convert--datesort src dst,一切看起来都正常:

mb--ma--2f------2e--2d------2c--2b--2a
      \
       -----1e----------1d--------------1c--1b--1a     
我现在想要的最后一件事是合并所有补丁,以便它们具有线性依赖关系图,从而有效地消除合并修订版'ma'。我认为解决办法是重新确定一些修订的基础,但我不了解哪些修订需要重新确定基础。我做了一些实验,但似乎没有任何效果。一次尝试产生了如下奇怪的问题:

use (c)hanged version or (d)elete?
我该怎么做最后一步

编辑:我部分解决了这个问题。由于rebase似乎把事情搞砸了(或者我没有完全理解问题所在),一种不同的方法似乎效果更好(正如Lasse所建议的):重写历史

我所做的是使用hg convert with filemap将存储库再次拆分为原来的两部分,直到合并修订版。然后我用汞移植将一个存储库移植到另一个存储库中。瞧,线性历史

2f--2e--2d--2c--2b--2a--1e--1d--1c--1b--1a
在这之后,我将合并后所做的变更集移植到了上面。结果:备份的实际工作副本与两个历史时间线没有差异。到目前为止,一切都很好

mb--2f--2e--2d--2c--2b--2a--1e--1d--1c--1b--1a
现在修订没有按时间排序,这将是理想的,因此我尝试了hg convert--datesort repository.src repository.sorted,但结果仍然是变更集的顺序与上面显示的相同。如果有人知道怎么做的话,我可以手工把它们分类

编辑2:我终于解决了这个问题,创建了一个新的存储库

mkdir repository_c
cd repository_c
hg init .
我使用
hg-transplant
,以正确的顺序拉入所有补丁:

hg transplant --source ../src 0:53
hg transplant --source ../src 70
hg transplant --source ../src 54:55
hg transplant --source ../src 71:79
hg transplant --source ../src 55:60
...

这样就完成了任务,历史是线性的,补丁按正确的顺序排序。因为没有冲突的补丁,而且head修订版与原始存储库相同,有两条时间线,所以我很高兴。我确实使用MQ扩展为所有修订创建了一个补丁文件列表,并手动控制它们,但从我所能看出,历史记录是完美的。

合并不相关的历史记录并不奏效,因为每个变更集都是某个状态下项目的快照。如果您只是简单地拉-f或使用convert进行嫁接,您将得到一个显然不相关的历史被嫁接在一起的存储库。你不会得到一个整洁的历史记录,它显示嫁接的历史记录在你想要的时候被添加到主项目中。相反,您将得到一组只包含来自项目a的文件的提交,以及一组只包含来自项目B的文件的提交。简而言之,这是因为“事情实际上并没有以这种方式发生”。将历史图拼接在一起不会修复这些变更集的内容

因此,唯一可用的答案是在项目A的提交中,在项目A的目录名称空间的正确部分,一次实际重放项目B的历史记录。这可以通过HgExport+import“手工”完成,也可以通过HgConvert--filemap和移植或重设基础的某种组合来完成


我已经调整了你提到的维基页面,不赞成“建议”。一般来说,我不建议尝试做这种事情,因为“事实上并不是这样”。最好在一次提交中拉入项目B的整个历史记录,并在提交消息中有一个指向其真实历史记录的指针。

我认为获得一个线性历史记录的唯一方法是一次一步手动重新应用一行开发,但我要问你这个问题。你为什么要这么做?现在的时间线有什么问题?我看到当前修订历史有三个问题:a)将来如果一家新的风投被强加给我,这可能会导致问题b)我认为我无法将这种历史转换为颠覆,我可能在不久的将来不得不这样做(尽管我还没有尝试过)c)逻辑上,所有更改都是一条开发线的一部分,因为两个存储库并不是完全不相交的,但这太多的信息无法解释我的原始问题。两条原始开发线是在同一个文件上工作,还是完全不相交?而且,这个问题和你的评论似乎不一致。您在评论中说,这是两个并非完全不相交的存储库中的一条开发线,但您的问题是“两个存储库完全不相关”。存储库不相关,因为它们不共享代码或公共历史,但它们在某种意义上是语义相关的,因为它们都包含可以组合的代码示例部分,比如Qt示例代码。它们在相同的文件上工作吗?是的,你是对的!但在这种情况下,这对我来说是必要的,移植解决了我的问题。我必须指出,自从我提出问题以来,我已经更多地使用了mercurial,我是它的忠实粉丝。例如,我非常喜欢补丁队列扩展。是的,我知道,修补历史记录是不好的,但是如果你单独处理某件事情,如果你可以修复发生错误的地方,并且不需要额外的提交,那就很方便了。我不太喜欢50%的提交都是简单的“flying_pig.c中的固定打字错误”:)