如何在Mercurial中执行git reset --hard HEAD命令?

82

我是一名使用Git的用户,现在想尝试使用Mercurial。

这是发生的事情:我想要恢复一个变更集,于是我执行了hg backout。这产生了一个新的分支,所以hg告诉我要合并(回到“默认状态”)。在合并后,它告诉我仍然需要提交。然后我注意到在解决合并中的冲突时犯了一个错误,于是我想要将所有东西恢复到hg backout之前的状态,也就是说,我希望这个未提交的合并被删除。在Git中,这个未提交的内容位于索引中,我只需要使用git reset --hard HEAD来清除它,但据我所读,Mercurial中不存在索引。那么我该如何恢复到之前的状态呢?


可能是重复的问题:如何在Hg中摆脱一些变更集? - binki
5个回答

101
如果您尚未提交更改,而且似乎您还没有这样做,您可以使用hg update --clean撤消所有合并工作。

然而,在更新的Mercurial版本中,有一个方便的命令可以重新合并单个文件:hg resolve path/to/file.ext。来自hg help resolve

The available actions are: ...

 4) discard your current attempt(s) at resolving conflicts and
重新开始合并:使用“hg resolve file...”(或“-a”用于所有未解决的文件)。

抱歉,我还有点困惑:我运行了 hg up -C,但是“撤销”的提交仍然在我的分支的顶部。我以为这是使用 backout 创建的“幽灵分支”,但是运行 hg branch 返回 default,所以我实际上是在主分支上? - agentofuser
5
你可以在同一个分支上有两个头,这就是你现在的情况。它们都叫做“default”。在Mercurial中,这是非常正常的一种情况。使用“hg heads”命令可以查看和理解这种情况。当你运行“hg backout”命令时,“被撤销的改动将作为新的变更集进行提交”,这样就会创建一个新的变更集,如果不付出艰苦努力,它将无法消失。所以现在你在名为“default”的分支上有两个头。在执行“hg merge”(并提交)之后,你将回到名为“default”的分支上只有一个头。 - Ry4an Brase

26
这是近义词:

hg update --clean

这条命令会更新并清理工作目录。

6
是的...有时候当你移动文件(从一个目录到另一个目录)然后决定放弃所有更改时,这不会像git reset --hard那样起作用。Ergo-mercurial很愚蠢。 - iLemming

14

从git中,命令:

git reset --hard     # reset to last commit    
git clean -df        # delete untracked files

等于

hg update --clean    # reset to last commit  
hg purge             # delete untracked files

8
尽管这段代码片段可能解决了问题,但是附加一些解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您提供代码建议的原因。 - Kyll
git reset --hard 不会删除未被追踪的文件。 - Ruslan
对我不起作用。hg update --clean 18:8e139889ff02 显示“更新了2个文件”,但是当我查看日志时,它仍然停留在原地。更新:话虽如此,它确实将文件重置为修订版。尽管如此,这只是 git reset --hard 行为的一半。 - Hi-Angel

13

Hg手册中的GitConcepts页面解释了如何在Mercurial中执行许多git用户熟悉的操作。

Mercurial没有任何内置的git reset --hard行为。然而,strip扩展提供了一个strip命令来实现这一功能。要使用它,请先在您的~/.hgrc文件中启用strip

[extensions]
strip =

注意:此扩展在Mercurial 2.8中新推出。早期版本提供了mq扩展中的strip命令。

现在,您可以运行诸如 hg strip 或甚至hg help strip之类的命令。要删除一个变更集及其所有子级,请将该变更集指定为hg strip的参数。例如,要删除您刚刚提交的最后一次提交(在您使用导致hg rollback报告不再有任何事务要回滚的命令后),可以删除tip修订版。每次运行此命令时,将删除另一个修订版。请注意,hg strip的操作应被视为不可逆转;不熟悉的用户在使用前应备份其存储库。

$ hg strip tip
例如,使用 revsets 语法,我表明当运行 hg heads 时显示多个分支的提交是不必要的,并希望移除这些提交。如果您在下面的表达式中指定了一个特定的修订版本而不是 tip,那么当前分支中任何不是您选择的修订版本的祖先的提交都将被删除。当我执行 git reset --hard HEAD 命令时,这似乎最接近我想要的行为。
$ hg strip "branch(tip) and not(ancestors(tip)::tip)"

2
Mercurial 2.8及以上版本具有“strip”扩展,以防止仅显式使用“hg strip”命令。使用“mq”还会添加各种其他补丁管理命令。 - davidjb
在TortoiseHg 4.7及以上版本中,可以通过文件>设置>扩展来启用此功能,然后勾选strip,并重新启动TortoiseHg。然后选择查看>显示控制台,以获取命令行输入,例如hg strip --keep -r 50。 - Assad Ebrahim
条带工作得很好,但在我的情况下,我没有~/.hgrc文件,所以请将其添加到mercurial.ini文件中。 - Rossi Alex

1

在mercurial中,我期望找到一个替代git reset --hard的方法:

hg strip --keep -r . # --keep optional
hg update --clean    # reset to last commit

如果您需要的话:

hg purge

hg purge 将无条件删除所有未被跟踪的文件,包括那些在 hg update --clean 之前未被跟踪的文件。而 git reset --hard 仅影响已暂存的文件。 - Jason R. Coombs

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