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

Tom*_*ard 69 mercurial tortoisehg cherry-pick

在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
Run Code Online (Sandbox Code Playgroud)

补丁是最好的选择吗?

Ry4*_*ase 77

Tonfa是对的.你所描述的不是'合并'(或'推'或'拉'); 这是'挑选'.推或拉将所有变更集从一个仓库移动到另一个仓库中但尚未在该仓库中.'merge'需要两个'head'并将它们合并到一个新的变更集中,这是两者的组合.

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

但是,一般来说使用导入/导出,移植和挑选的缺点是,如果没有它的祖先,你就无法真正移动G,因为在Mercurial中,变更集的名称是其'hashid',其中包含其父项的哈希值.不同的父母(G的新父母将是C而不是F)意味着不同的哈希,所以它不再是G - 这是G的工作,但是名称是新的变更集.

将G作为新事物移动,我们称之为G'(Gee prime),对某些用途来说并不是什么大不了的事,但对于其他用途来说,这是一个很大的皮塔饼.当很快回购B获得一个新的变更集H时,你希望将它移动到它的父变量将从G变为G',它们具有不同的哈希值.这意味着H将移动为H' - 100变换集,你将拥有不同的哈希值,因为你不能忍受在回购A中有D,E,F.

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

那你的选择是什么?

  1. 不在乎. 您的数据仍然存在,您最终会使用不同名称的相同变更集,并在两个存储库之间的未来交换中开展更多工作.这没有错,也许有点笨拙,有些人不在乎.
  2. 将所有D,E和F移动到Repo A. 如果它们无害,可以移动所有变更集并避免所有麻烦.如果它们不是那么无害,你可以移动它们然后做一个'hg backout'来消除D,E和F在新变化集H中的影响.
  3. 给予G更好的亲子关系. 这对我来说是值得一提的,因为走这条路是为时已晚(没有编辑历史记录).在处理变更集G之前你应该做些什么hg update C.如果G不依赖或要求变更集D,E和F那么它不应该是他们的孩子.

如果你首先更新到C,你将有一个这样的图形:

A - B - C - D - E - F
          \
            G
Run Code Online (Sandbox Code Playgroud)

然后,这个问题的整个答案就是hg push -r G ../repoA,G会干净利落地移动,保持相同的哈希值,D,E和F不会随之而来.

更新:

正如评论中指出的那样.使用现代Mercurials,hg graft命令是执行此操作的完美方式.

  • 我想要注意的是,自Mercurial 2.0以来,应尽可能使用移植而不是移植,因为它使用内部合并机制而不是拒绝冲突.另见http://stackoverflow.com/a/8010738/67988. (7认同)
  • 使用rebase是"编辑历史"的一种形式.它确实改变了hashids,如果你还没有将它们推向世界是非常酷的.如果你这样做了,那么每个人都会看到相同的变更集两次等等. (4认同)
  • 语气说"樱桃采摘不应该是你正常工作流程的一部分".在你的例子中,你正在修正一个错误("在错误的分支上"),所以一定是樱桃挑选.但是,那些构建复杂工作流程的人,其中计划是"然后我们挑选从默认版本到稳定版本分支的错误修复程序"正在以艰难的方式做事,并且将使他们未来的合并变得更加困难.在它告诉你如何做之前,答案中指出"你问的怎么做通常是一个坏主意"是有价值的. (3认同)
  • 实际上,我猜`rebase`扩展会起作用. (2认同)
  • 我是唯一一个认为这个答案的语气是暗示挑选樱桃是永远不应该做的事情的人吗?如果您在错误的分支上进行了 2 次提交并且需要将这些提交移过来,您应该怎么做?樱桃采摘正是为此而设计的。这并没有错。 (2认同)

Iod*_*nas 43

参考标题,它总体上讲述了樱桃采摘,我给出了在一个回购中工作的例子,因为互联网搜索引擎可能会将人们带到这里进行樱桃采摘.在一个存储库中工作,它将完成hg graft:

hg update C
hg graft G
Run Code Online (Sandbox Code Playgroud)

结果是:

            G'
          / 
A - B - C - D - E - F - G
Run Code Online (Sandbox Code Playgroud)

额外警告:两个变更集将被视为对相同文件的独立并行提交,并可能使您遇到合并冲突,这就是为什么应该避免对分支管理进行分析.例如,如果G是应用到一个稳定的版本分支书签作为一个bug修复1.0.1,你倒是应该合并freeze与它的分支,不时合并master与分支freeze的分支的错误修正.