Mercurial 如何撤销并重新应用变更集

3
我有提交记录A,B,C,D和E。我发现在提交B中发生了非常糟糕的事情,因此我想回滚到A,这次正确地更正了在B之前搞砸的更改,然后自动重新应用C,D和E。
也许您会想知道为什么我不回滚到B并在那里进行修复,然后再合并回E(这是一个好主意吗?)。原因我不太清楚,但与问题发生在一组特殊的Visual Studio文件(应该只通过Visual Studio中的某些GUI屏幕进行编辑)有关,并且不能简单地在出现错误后更正文件...如果我知道更多细节,我会提供的。

如果更改不是非常巨大,我可能只会手动撤销它,并检入新版本F。如果更改很大,你就需要帮我了。我刚开始使用mercurial,所以我也会对答案感兴趣! - DarinH
3个回答

5

只需将您在B中所做的内容回退并将其提交为F。这样,历史记录将保持完整,您的同事也无需知道即可获得更改。

如果B是一个服务发布版,请在那里进行更改,然后将其合并到F中。


4
这可以使用Mercurial Queues(mq)完成。您需要执行以下操作:
  1. 将变更集B到E导入mq
  2. 取消应用变更集C到E
  3. 修复变更集B并刷新补丁
  4. 重新应用C到E
  5. 完成补丁
具体步骤如下:
  1. cd <project>
  2. hg qinit
  3. hg qimport --rev B:E
  4. hg qpop --all
  5. hg qpush <patch name for B>
  6. ...修复您在B中发现的问题
  7. hg qrefresh
  8. hg qpush --all
  9. hg qfinish --applied
这一切都假设B到E没有被推送到任何公共存储库中。如果它们已经被推送,则最好的方法是在新的变更集(F)中解决问题。

这里的想法是实际上改变记录的变更集的历史吗?从我对Mercurial和GIT的理解来看,GIT更容易修改历史记录,而Mercurial也可以做到。但对我来说,似乎我几乎永远不想修改历史变更集,相反,我总是希望以必要的方式获取最新的修复版本,并作为新的变更集提交,适当地进行注释。虽然如此,这样做不被推荐吗?我自己对hg还很陌生... - DarinH
@drventure:我回答中列出的操作将会改变历史记录。在Mercurial中,这通常是不被赞同的,但如果您要更改的变更集从未被推送到远程,则是安全的。一旦变更集被推送到远程,您就不应该尝试更改它们。相反,您应该创建一个新的变更集来反转/修复问题(正如您已经注意到的那样)。 - Tim Henigan
安全地更改尚未分发(推送或拉取)的历史记录是可行的。许多人不赞成更改历史记录,但我个人更喜欢保持历史记录的清洁。如果我弄错了提交,没有必要让我的团队存储库变得混乱。在与他们分享我的提交之前,我可以先修复它。 - bambams
只是为了明确,如果您已经推送了,那么您无法这样做。 - Joshua Goldberg

3

您还可以使用Histedit扩展(而不是MqExtension)。我认为,MqExtension更加强大,但也更加复杂。HisteditExtension有点类似于git rebase --interactive

# Ordinarily it would be something like (I'd normally do -r -5, instead):
hg histedit d0844102a010

您的文本编辑器将打开一个类似于以下内容的文件:

pick d0844102a010 A
pick a9448f0ba534 B
pick b754f9f2513b C
pick 736f7f2363ff D
pick 05bb58f48597 E

# Edit history between d0844102a010 and 05bb58f48597
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  f, fold = use commit, but fold into previous commit
#  d, drop = remove commit from history
#

每一行对应一个提交。第一个词指的是要应用于该提交的命令。默认的“pick”保持提交不变。使用“edit”进行更改(包括提交日志的更改),使用“fold”将其与前一个提交合并,使用“drop”完全删除它。
在您的情况下,您可能只需要将第一行更改为“edit”。
记住,如果您正在“编辑”或存在合并冲突,则必须使用hg histedit --continue而不是hg commit。 :) 如果您遇到冲突,事情看起来不好,您只想取消,则可以使用hg histedit --abort
# Fix up files...
vim foo bar baz

# Finished; apply the changes (and pray for a clean merge ;).
hg histedit --continue

当然,自行编辑历史记录存在风险。我建议在编辑历史记录之前,您应该创建一个源代码树的备份tarball或zip文件,直到您熟悉这些命令为止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接