如何在Mercurial中select一个修订版本?

在Mercurial / TortoiseHg中,给出下面的例子,将修订“G”合并到回购A中,而不用D,E和F(假设G不依赖于D,E或F),最简单的方法是什么。

Repo A: A - B - C Repo B (Clone of A) A - B - C - D - E - F - G 

补丁是最好的select吗?

Tonfa是对的。 你所描述的不是“合并”(或“推”或“拉”); 这是“樱桃采摘”。 推或拉将所有变更集从一个回购站移到另一个回购站中。 一个“合并”需要两个“头”,并将它们合并为一个新的变更集,这是两者的结合。

如果你真的需要移动G,但不可能遵守D,E,F,那么你应该从回购A'hg export'G,然后'hg import'在回购A中。 移植扩展是一个包装导出/导入一些细节,以避免多次移动相同的变更集。

然而 ,使用导入/导出,移植和挑选樱桃的缺点一般在于,如果没有祖先,就不能真正移动G,因为在Mercurial中,变更集的名称是其“hashid”,其中包含其父项的hashid 。 不同的父母(G的新父母应该是C而不是F)意味着不同的hashid,所以它不再是G–这是G的工作,而是一个新的名称变更。

把G作为新的东西,我们称之为G'(Gee prime),对某些用途来说不是什么大不了的事情,但对于其他人来说,这是一个很大的皮塔饼。 当很快的repo B得到一个新的变更集H,并且你想把它移到它的父节点上时,将会从G变成G',它们有不同的哈希值。 这意味着H将移动到H'-100变化集合的下线,并且对于所有的事情你都会有不同的hashid,因为你不能忍受D,E,F的回购A.

如果/当你想把回购A的东西转移到回购B(与之前的移动相反的方向),事情会变得更加糟糕。 如果你试图从A到B做一个简单的“hg push”,你会得到G'(和H'以及后续的后代),这将是你在Repo B中已经有的变更集的重复。

那么,你的select是什么?

  1. 不在乎。 你的数据仍然在那里,你只是以不同的名字进行相同的变更,并且在两个回购之间进行更多的交stream。 这没有错,也许只是有点笨拙,有些人不在乎。
  2. 将D,E和F的全部移到Repo A.如果它们是无害的,可以移动所有的变更集,并避免所有的麻烦。 如果他们不是那么无害的话,你可以把他们移过来,然后做一个“hg撤销”来消除D,E和F在一个新的变更集中的影响。
  3. 先给G一个好的血统。 这是我的意思,因为这条路线已经太晚了(没有编辑历史 )。 在修改G之前,你应该完成的工作是hg update C 如果G不依赖或不需要变更集D,E和F,那么它不应该是他们的孩子。

相反,如果你先更新到C,你将会得到如下的图表:

 A - B - C - D - E - F \ G 

那么,这个问题的整个答案就是hg push -r G ../repoA会干净地移动,保持相同的hashid,而D,E和F不会跟它在一起。

更新:

正如评论中指出的那样。 对于现代的Mercurials来说, hg graft命令是完成这个任务的最佳方式。

关于一般樱桃采摘的标题,我举一个回购工作的例子,因为互联网search引擎可能会把人们带到这里来采摘樱桃。 在一个仓库中工作,它将完成与hg graft

 hg update C hg graft G 

结果是:

  G' / A - B - C - D - E - F - G 

额外的警告:这两个变更集将被视为独立并行提交相同的文件,并可能使您遇到合并冲突,这就是为什么樱桃采摘一般应避免分支pipe理。 例如,如果G是应用于稳定版本分支(书签为1.0.1 )的错误修复,则应该 freeze分支与其合并 ,并且不时将master分支与freeze分支的错误修正合并。