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


70

在Mercurial / TortoiseHg中,给出以下示例,最简单的方法是在不采用D,E和F的情况下将修订“ G”合并到存储库A中(假设G不依赖于D,E或F)。

Repo A: A - B - C

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

补丁是最好的选择吗?


36
它不是合并,而是真正的挑剔,为此,最好的工具是移植。但是补丁也可以。
09年

9
tonfa,您应该发表评论答案。您永远是对的,没有人能投票赞成您。
Ry4an Brase 09年

5
@ Ry4n我有时没有时间,如果可以帮助下一个人回答问题,我不介意接受投票:)
tonfa

Answers:


78

通法是对的。您所描述的不是“合并”(或“推”或“拉”);这是“采摘樱桃”。推或拉将所有变更集从一个存储库移动到该存储库中尚未存在的另一个变更集。一个“合并”需要两个“头”,然后将它们合并成一个新的变更集,这是两者的结合。

如果您确实需要移动G,但又不能忍受D,E,F,则应该从回购A中“ hg导出” G,然后在回购A中“ hg导入”它。Transplant扩展名是一个包装具有一些优点的导出/导入,有助于避免多次移动相同的变更集。

但是,一般而言,使用导入/导出,移植和挑选樱桃的缺点是,没有G的祖先,您无法真正移过G,因为在Mercurial中,变更集的名称是其“哈希”,其中包括其父母的哈希值。 。不同的父代(G的新父代将是C而不是F)意味着不同的hashid,所以它不再是G了-它是G的工作,而是一个新的名称变更集。

将G作为新的东西移动,我们称其为G'(Gee素数),对于某些用途而言并没有什么大不了的,但是对于其他用途而言,这却是一个大问题。很快,回购B获得了一个新的变更集H,而您想将其移到其母集上,则将其从G更改为G',这具有不同的哈希值。这意味着H将以H'的形式移动-向下移动100个变更集,并且所有内容将具有不同的hashid,因为您无法忍受回购A中的D,E,F。

如果/当您想将物料从Repo A移至Repo B(与您之前的举动相反)时,事情将会变得更加混乱。如果您尝试从A到B进行简单的'hg push'操作,您将得到G'(和H',以及其后代),它们将与您在存储库B中已有的变更集重复。

那您有什么选择呢?

  1. 不在乎 您的数据仍然在那里,您最终将得到具有不同名称的相同变更集,并且需要做更多工作来处理两个存储库之间的将来交换。没错,也许只是笨拙,有些人不在乎。
  2. 将所有D,E和F移至存储库A。 如果变更集无害,则可以将所有变更集移至存储区,并避免所有麻烦。如果它们不是那么无害,则可以将其移开,然后执行“ hg退出”操作以撤消新变更集H中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,G会干净利落地移动,保持其相同的哈希值,而D,E和F则不会。

更新:

正如评论中指出的那样。对于现代Mercurial,hg graft命令是执行此操作的理想方法。


4
使用rebase是“编辑历史记录”的一种形式。它的确改变了哈希值,如果您还没有将它们推向世界,那将非常酷。如果你这样做了,然后大家将看到相同的变更两次,等等
Ry4an Brase

7
我想指出,自Mercurial 2.0起,应尽可能使用嫁接代替移植,因为它使用内部合并机制而不是拒绝冲突。另请参阅stackoverflow.com/a/8010738/67988
Helgi

我是唯一认为这一答案的意思是挑樱桃的人不应该这样做的人吗?如果在错误的分支上进行了2次提交,并且需要将这些提交移到另一端,应该怎么办。采摘樱桃正是为此而设计的。没错
杰森·麦卡雷尔

3
语气是“樱桃采摘不应该是您正常工作流程的一部分”。在您的示例中,您正在解决一个错误(“在错误的分支上”),因此请务必选择。但是在计划为“然后我们从默认漏洞到稳定版本分支中挑选错误修复程序”的情况下构建复杂工作流的人们正在艰难地做事,并且会使他们的未来更加艰难。答案中有一个价值,指出“您要问怎么做通常是个坏主意”,然后才告诉您如何做。
Ry4an Brase 2014年

在那里,您应该从存储库A中“ hg导出” G-@ Ry4anBrase是从存储库B中指的?
crazyGuy

43

提到标题,它通常涉及到樱桃采摘,我举一个在一个仓库中工作的例子,因为互联网搜索引擎可能会带人们来这里进行樱桃采摘。在一个存储库中工作,可以使用hg graft

hg update C
hg graft G

结果是:

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

额外警告:这两个变更集将被视为对同一文件的独立并行提交,并且可能使您遇到合并冲突,因此,对于分支机构管理,通常应避免选择樱桃。例如,如果G将某个错误修复应用到以标记为的稳定版本分支上1.0.1,则您应该与其合并freeze分支,并且不时将master分支与该freeze分支的错误修复合并。


除了“ hg嫁接G”带来了D,E和F的许多更改。导出补丁,导入补丁的工作与人们期望嫁接的工作一样。
LovesTha

C上的“ hg嫁接G”会创建一个新的头部/分支。您为什么认为它可以给D ... G分支带来任何变化?
Iodnas

因为我已经尝试了好几次,但确实如此。我真的希望不要,但确实如此。
LovesTha
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.