我正在使用Mercurial本地项目(这是唯一的回购,没有推/拉到/从其他任何地方)。

到目前为止,它有一个线性的历史。然而,我现在意识到我正在做的事情是一个糟糕的方法,我想回到我开始之前的版本,并以不同的方式实现它。

我对Mercurial中的分支/ revert / update -C命令有点困惑。基本上,我想要恢复到版本38(目前是45),并让我的下一次提交有38作为父,并从那里继续。我不在乎修订版39-45是否会永远消失,或者最终在他们自己的分支中陷入死胡同。

我需要哪个命令/一组命令?


hg update [-r REV]

如果稍后提交,您将有效地创建一个新分支。然后您可以继续只在这个分支上工作,或者最终将现有的分支合并到它中。


下面是关于这些命令的小抄:

hg update changes your working copy parent revision and also changes the file content to match this new parent revision. This means that new commits will carry on from the revision you update to. hg revert changes the file content only and leaves the working copy parent revision alone. You typically use hg revert when you decide that you don't want to keep the uncommited changes you've made to a file in your working copy. hg branch starts a new named branch. Think of a named branch as a label you assign to the changesets. So if you do hg branch red, then the following changesets will be marked as belonging on the "red" branch. This can be a nice way to organize changesets, especially when different people work on different branches and you later want to see where a changeset originated from. But you don't want to use it in your situation.

如果你使用hg update—rev 38,那么变更集39-45将会成为一个死胡同——我们称之为一个悬垂的头。当你推送时,你会得到一个警告,因为你将在你推送的存储库中创建“多个头部”。警告是存在的,因为它是一种不礼貌的留下这样的头,因为他们表明有人需要做合并。但在你的情况下,你可以继续hg push -force,因为你真的想让它挂着。

如果你还没有将修订39-45推送到其他地方,那么你可以将它们保密。这很简单:hg克隆-rev 38 foo foo-38你会得到一个新的本地克隆,只包含到修订38。您可以继续在foo-38中工作,并推动您创建的新(好的)更改集。你仍然会有旧的(坏的)修订在你的foo克隆。(你可以随心所欲地重命名克隆,例如,foo为foo-bad, foo-38为foo。)

最后,你也可以使用hg revert—all—rev 38然后提交。这将创建一个修订版46,看起来与修订版38相同。然后,您将继续从第46版开始学习。这不会像hg更新那样在历史中创建一个分叉,但另一方面,你不会收到关于有多个头的抱怨。如果我和其他人合作,他们已经根据45版做出了自己的工作,我会使用hg回复。否则,hg update更加显式。


我刚刚遇到了一个需要将一个文件恢复到以前版本的情况,就在我完成提交和推送之后。指定这些修订的简写语法没有包含在其他答案中,因此下面的命令可以做到这一点

hg revert path/to/file -r-2

-2将恢复到上次提交之前的版本,使用-1只会恢复当前未提交的更改。


在使用hg update -r REV后,答案中不清楚如何提交更改,以便您可以推送。

如果您只是在更新后尝试提交,Mercurial不会认为有任何更改。

我必须首先对任何文件进行更改(比如在README中),这样Mercurial就能识别我做了新的更改,然后我就可以提交了。

这就产生了前面提到的两个头像。

为了在按压前摆脱另一个头部,我随后执行了No-Op Merges步骤来补救这种情况。

那时我就能推了。


恕我直言,hg strip -r 39更适合这种情况。

它需要启用mq扩展,并具有与Martin Geisler推荐的“克隆回购方法”相同的限制: 如果变更集以某种方式发布,它(可能)会在某个时间点返回到您的回购,因为您只更改了本地回购。


上面的答案是最有用的,我学到了很多。然而,对于我的需求,简洁的回答是:

hg revert --all --rev ${1}

hg commit -m "Restoring branch ${1} as default"

其中${1}是修订的编号或分支的名称。这两行实际上是bash脚本的一部分,但是如果您想手动执行,它们本身就可以很好地工作。

如果您需要为发布分支添加一个热修复,但需要从默认值构建(直到我们获得正确的CI工具并能够从分支构建,然后再去掉发布分支),这是非常有用的。


我会安装Tortoise Hg (Mercurial的免费GUI)并使用它。然后,你只需右键单击你可能想要返回的版本——所有的提交消息都在你眼前——然后“恢复所有文件”。使在文件集的版本之间向后和向前滚动变得直观和容易,如果您希望确定问题第一次出现的时间,这可能非常有用。