我经常遇到一个用例,在这个用例中我确定了一个承诺的变更集中的一个小错误,因此恢复变更集不是一个选项。
我查看了similar questions和the Mercurial docs for graft以及general advice on backporting changes,但这个“简单”用例未被涵盖,或者它被归入DVCS变基/克隆的复杂泥潭中/出口/进口对于看似微不足道的操作而言,其滥用程度远远超过它的价值。
简而言之,在由
组成的存储库中A -> B -> C -> D -> E
需要在变更集B中的一个文件中修复一行错误,该文件包含对多个文件的大量更改。有没有办法在不恢复/修复/重新应用所有B的情况下执行此操作?能够做到
... -> B -> B' -> C -> ...
会解决这个问题。
请注意,我对于变基的概念没有任何背景,所以除非你愿意用勺子喂它,否则它不会有多大帮助。我的需求通常很简单;我主要在单用户模式下使用Mecurial作为RCS或SVN的高级形式,通常仅使用提交,分支和合并(绝对不使用推送,拉取,导入,导出,重新定位或其他“分布式”功能)。是的,我知道我可能排除了解决这个问题的很多选择,但我的重点是修复我的代码,而不是理解我从未使用的Mercurial功能的细粒度行为(对不起,只是在这里诚实。)
如果这是不可能的,请告诉我,这样我就可以将我的修复提交为F,并提交更改集B到E的提交消息。
答案 0 :(得分:3)
如果您已将更改推送给其他用户,我建议您简单地提交为F.
如果还没有,请记住C,D,......的变更集ID也会改变。因此,提交哈希将变为C',D',...
我开始注意到新的'hg evolve'功能非常适合你所要求的。
首先,一个小小的警告:进化是(我相信)现在仍然是实验性的。一定要备份!然而,evolve似乎最适合这个。
首先关注setup instructions。
然后,您可以执行以下步骤:
hg update -r B
hg commit --amend
现在,您将收到有关不稳定变更集的警告(所有变更集都是B的后代)。hg evolve --all
。这将修改C,D,......以正确地基于B'。答案 1 :(得分:3)
“转储”和显而易见的方式:
hg up B
hg commit
hg up E
hg merge
(可能解决冲突)即你将你的修复作为B的孩子(在当前分支中获得匿名分支和额外的头部变更集F)并将F合并到E(作为G变更集),这将F变为主线。您可以跳过更新到E:在匿名分支没有多大意义的情况下合并的方向
答案 2 :(得分:0)
我的经验是git,而不是mercurial,所以我可能没有得到正确的命令。 你想要做的是,是的,有时被称为" rebase"在DVCS-land中,但我来自不同的版本控制,呃,年份,所以我不认为它是" rebase"。我只是将其视为"重写历史"。它只有几个命令。
勺子喂,嗯?这架飞机......
我认为你的命令将会是这样的:
hg up B
...进行修复并在B之上提交变更集:您的更改树将如下所示:
A -> B -> C -> D -> E
\
-> FIX <--- you are here
好的,现在是重写历史部分。您希望将更改历史记录导致E
,并将其重写为基于A->B->FIX
而非A->B
。
hg up E
(因为这是您有兴趣重写的代码行)hg rebase --dest FIX
B
是一个共同的祖先,所以它将进行后续更改并按顺序应用它们。那就是它。在此之后,您的历史记录将如下所示(根据要求):
A -> B -> FIX -> C' -> D' -> E'
我将它们写成C'
等,因为了解这些点的来源与以前不同很重要:具体来说,它们会反映FIX
的合并。变更集C, D, E
对代码所做的更改应与C', D', E'
中的更改相同,除非与修补程序存在某些冲突或其他重叠,在这种情况下您可能需要手动与应用程序进行交互。
例如,受修复影响的代码的重构可能意味着确保更改修复也得到正确的重构。如果版本控制系统无法跟踪文件之间的代码,它甚至可能意味着本练习的另一个实例。
重要,也许:如果其他人一直在跟踪您的回购邮件中的更改,并且已经撤消了原始更改集,那么通过执行此操作您已经将他们的一些历史记录带走了,这可能是真的让他们搞砸了,这就是为什么你会看到人们大喊大叫,把他们的网上发型拉下来&#34; rebase&#34;。