0

我经常遇到一个用例,在该用例中,我在事后很久才发现已提交的变更集中的一个小错误,因此恢复变更集不是一种选择。

我查看了类似的问题Mercurial 文档中的移植关于反向移植更改的一般建议,但要么没有涵盖这个“简单”用例,要么它被包含在 DVCS 变基/克隆/导出/导入的复杂泥潭中对于看似微不足道的操作,滥用远远超过它的价值。

简而言之,在一个由

A -> B -> C -> D -> E

在变更集 B 中的一个文件中存在一个需要修复的单行错误,其中包含对多个文件的许多更改。有没有办法在不恢复/修复/重新应用所有 B 的情况下做到这一点?只是能够做

... -> B -> B' -> C -> ...

会解决这个问题。

请注意,我对变基概念的上下文为零,所以除非你愿意用勺子喂给我,否则它不会有太大帮助。我的需求通常很简单;我基本上在单用户模式下使用 Mecurial 作为 RCS 或 SVN 的高级形式,通常只使用提交、分支和合并(绝对没有推送、拉取、导入、导出、变基或其他“分布式”功能)。是的,我知道我可能会排除很多解决这个问题的选择,但我的重点是修复我的代码,而不是理解我从不使用的 Mercurial 功能的细粒度行为(对不起,在这里说实话。)

如果这是不可能的,请让我知道,这样我就可以将我的修复提交为 F,并提交更改集 B 到 E 已损坏的提交消息。

4

3 回答 3

3

如果您已经将更改推送给其他用户,我建议您只需提交为 F。

如果还没有,请记住 C、D、... 的变更集 ID 也会发生变化。所以提交哈希将变为 C', D', ...

我开始注意到新的“hg Evolution”功能非常适合您的要求。

首先,一个小警告:进化(我相信)现在仍然是实验性的。一定要有备份!然而,进化似乎真的是最适合这个的。

首先按照设置说明进行操作。

然后,您可以执行以下步骤:

  1. 更新到 B:hg update -r B
  2. 做出改变。
  3. 提交修改后的变更集:hg commit --amend 您现在将收到关于不稳定变更集(所有 B 的后代的变更集)的警告。
  4. 运行hg evolve --all。这将修改 C, D, ... 以正确基于 B'。
于 2014-09-03T06:34:25.893 回答
3

“转储”和明显的方式:

  • hg up B
  • 使固定
  • hg commit
  • hg up E
  • hg merge(可能解决冲突)

即,您将修复作为 B 的子项提交(在当前分支中获取匿名分支和附加头 - 变更集 F)并将 F 合并到 E(作为 G 变更集),这会将 F 更改带入主线。您可以跳过对 E 的更新:在匿名分支的情况下合并方向没有多大意义

于 2014-09-04T00:28:25.293 回答
0

我的经验是使用 git,而不是 mercurial,因此我可能无法完全正确地获取命令。你想要做的是,是的,有时在 DVCS 领域被称为“rebase”,但我来自不同的版本控制,呃,复古,所以我不认为它是“rebase”。我只是认为它是“改写历史”。这只是几个命令。

勺子喂,嗯?飞机来了...

我认为你的命令会是这样的:

  1. 启用rebase 扩展(似乎它带有 hg 但未启用?)
  2. hg up B
    • 对 B 进行修复:您将针对 B 中的代码进行修复
    • 希望我有正确的命令?这实际上应该将您的工作目录设置为在源上运行,就像它在 B 点一样。
  3. ...进行修复并在 B 之上提交变更集:您的变更树将如下所示:

    A -> B -> C -> D -> E  
          \
           -> FIX  <--- you are here
    

    好的,现在是重写历史部分。您想要获取导致的更改历史记录E,并重写它们,就好像它们是基于A->B->FIX而不是基于A->B

  4. hg up E(因为这是您有兴趣重写的代码行)
  5. hg rebase --dest FIX
    • hg 足够聪明,知道这B是一个共同的祖先,因此它将进行后续更改并按顺序应用它们。

而已。在此之后,您的历史记录将如下所示(根据要求):

A -> B -> FIX -> C' -> D' -> E'

我将它们写为C'etc,因为重要的是要了解这些点的源将与以前不同:具体来说,它们将反映FIX. 变更集对代码所做的更改C, D, E应该与 中所做的相同C', D', E',除非与修复存在冲突或其他重叠,在这种情况下,您可能必须手动与更改的应用程序交互。

例如,重构受修复影响的代码可能意味着确保更改修复也得到正确重构。如果版本控制系统无法跟踪文件之间的代码,它甚至可能意味着此练习的另一个实例。

可能很重要:如果其他人一直在跟踪您的存储库中的更改,并且已经提取了原始更改集,那么通过这样做,您已经带走了他们的一些历史记录,这可能真的把他们搞砸了,这就是为什么您看到人们尖叫的原因并将他们的在线头发拉出来关于“rebase”。

于 2014-09-03T06:58:05.277 回答