【问题标题】:How to adjust history after merge of two unrelated Mercurial repositories?合并两个不相关的 Mercurial 存储库后如何调整历史记录?
【发布时间】:2011-07-31 13:33:25
【问题描述】:

我刚刚按照here 的建议合并了两个存储库。由于两个存储库完全不相关,因此我使用了

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 和 filemap,直到合并修订。然后我使用 hg 移植将一个存储库移植到另一个存储库。瞧,线性历史!

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
...

这完成了工作,历史是线性的,并且补丁以正确的顺序排序。由于没有冲突的补丁,并且头部修订版与原始存储库相同,有两个时间线,我很高兴。我确实使用 MQ 扩展为所有修订创建了一个补丁文件列表并手动控制它们,但据我所知,历史是完美的。

【问题讨论】:

  • 我认为获得一个线性历史的唯一方法是一次一步地手动重新应用一条开发线,但让我问你这个问题。为什么需要这样做?现在的时间表有什么问题?
  • 我看到当前修订历史记录存在三个问题:a) 将来如果强制我使用新的 vcs,这可能会导致问题 b) 我认为我无法转换这种历史记录颠覆,我可能在不久的将来必须这样做(虽然我还没有尝试过)c)从逻辑上讲,所有更改都是一条开发线的一部分,因为两个存储库并不是完全不相交的,但那是太多的信息解释我原来的问题。
  • 最初的两条开发线是在同一个文件上工作,还是完全不相交?此外,问题和您的评论似乎不同意。您在评论中说这是两个不完全不相交的存储库中的一条开发线,但是您的问题是“两个存储库完全不相关”。
  • 存储库是不相关的,因为它们不共享代码或共同历史,但它们在某种意义上是语义相关的,因为它们都包含可以组合的代码示例部分,例如 Qt 示例代码。
  • 他们在处理相同的文件吗?

标签: mercurial merge repository


【解决方案1】:

合并不相关的历史记录效果不佳,因为每个变更集都是项目在某个状态下的快照。如果您只是简单地拉动 -f 或使用 convert 移植,您将获得一个将明显不相关的历史移植在一起的存储库。您不会得到一个漂亮整洁的历史记录,显示嫁接的历史记录被添加到主项目中,一次提交就像您想要的那样。相反,您将获得一堆仅来自项目 A 的文件的提交,以及一堆仅来自项目 B 的文件的提交。简而言之,这是因为“事情实际上并没有那样发生”。将历史图表拼接在一起不会修复这些变更集的内容。

因此,唯一可用的答案是在项目 A 中实际重放项目 B 的历史,一次提交一次,并且在 A 的目录命名空间的右侧。这可以通过 hg export + import 或 hg convert --filemap 和移植或 rebase 的某种组合“手动”完成。

我已调整您提到的 wiki 页面以弃用该“建议”。一般来说,我根本不建议尝试做这种事情,因为“它实际上并没有那样发生”。最好在一次提交中提取项目 B 的整个历史记录,并在提交消息中指向其真实历史记录。

【讨论】:

  • 是的,你是对的!但在这种情况下,这对我的目的是必要的,移植解决了我的问题。我必须注意,自从我提出问题以来,我使用 mercurial 的次数更多,而且我是它的忠实粉丝。例如,我非常喜欢补丁队列扩展。是的,我知道,修补历史记录很糟糕,但是如果您单独处理某些事情,那么如果您可以修复它发生的错字,并且不需要额外的提交,那么它会很方便。如果 50% 的提交都是简单的 `flying_pig.c 中的固定错字',我不太喜欢 :-)
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 2019-01-24
  • 2012-10-14
相关资源
最近更新 更多