Mercurial:如何撤消上次未推送的提交?

Mercurial: how to undo last unpushed commit?

我不小心提交了我的本地存储库。更具体地说,当我打算一次提交一个文件时,我一次提交了对许多文件的更改。

如何撤消此提交并将我的工作副本恢复到提交之前的状态,以便我可以做我应该做的事情?

自提交以来我没有推或拉过任何东西。


您可能会怀疑这是重复的,所以我将解释为什么以下问题不同,或者不回答我的问题:

Mercurial undo last commit

对此的回答指出您可以使用 hg commit --amend 执行此操作,但没有解释 如何 或给出执行此操作的示例。 mercurail 帮助也没有为我拼出来。

How do you "rollback" last commit on Mercurial?

说明要使用 hg rollback。此命令显然已被弃用,无论如何我都尝试使用它,但我收到消息:没有可用的回滚信息。遗憾的是这不起作用,因为这将是实现我想要的东西的一种非常直观的方式。

好的,我想我找到了答案,就是启用 strip 扩展,并使用以下命令:

hg strip -r -1 --keep

这会从存储库中删除最后一个修订版(-r -1 位),--keep 选项意味着不会对工作副本进行任何更改。因此,您最终得到了一个与提交之前完全一样的工作副本,并且存储库中没有最后一次提交。

我不是 mercurial 专家,所以使用风险自负。

根据来自 this question 的信息:

hg strip --keep --rev .
--keep: do not modify working directory during strip
--rev .(点表示最后一次提交。阅读 sid0 关于后代的回答)


对于更熟悉 git 语言的人,您正在寻找 git reset --mixed HEAD^

hard 这会丢弃您的更改,使您的工作 "disappear"(我认为这不是一个选项)

soft 会撤消提交,但会保留之前提交的文件索引(即跟踪)

mixed 保留您更改的文件,但告诉索引撤消提交。在 git 中说话:git st 会说 Changes not staged for commit


另见 git-reset docs , Difference git reset soft/mixed, git/hg Command equivalence table

在这种情况下,我会做的是创建一个新分支,其中包含我想要的更改,然后再考虑删除错误的更改集。所以在这种情况下,我需要在做出错误提交之前返回到修订版,重新进行更改,然后进行多次提交,每个文件一次提交。

一步一步:

1) 回到错误提交之前。

% cd <top of repo>
% hg log -l 5
<identify the last good revision>
% hg update -r <last good revision number>

2) 重新进行更改:我会得到一个描述我想要的更改的补丁,并将其应用于树。 (我假设提示当前指向我们开始的地方)

% hg diff -r .:tip | patch -p1
patching file a/b/c/d
patching file a/b/e/f

3) 进行新的提交:我们现在回到了您进行要拆分的提交之前的状态。执行 hg status 并查看修改后的文件,确保一切如您所愿。此时,您可以通过在命令行上命名文件来一个一个地提交文件,或者使用 recordcrecord 之类的扩展名以交互方式 select 它们。

% hg commit a/b/c/d
% hg commit a/b/e/f

...或...

% hg crecord
<select files in UI>
% hg crecord
<select files in UI>

你最终会得到一个如下所示的回购协议:

o----o----B
      \
       \
        --o----o----o----T

其中 B 是旧的错误提交,T 是回购的新提示。如果你想让那个分支关闭,这样它就不会出现在日志/等中,你可以...

% hg update -r <revision B>
% hg commit --close_branch
% hg update -r tip

如果你想完全去除它,你可以剥离它。

% hg strip -r <revision B>

无论哪种方式,您的日志看起来都不会发生任何事情。

评论和详细说明@crobar 的 post 因为字符数不够。

在执行本地提交(无推送)然后 运行 hg strip -r -1 --keep 时,它会删除您之前的提交并保留您等待提交的文件列表。基本上这是一个完整的撤销。

如果我在没有 --keep 的情况下使用 hg strip -r -1,它仍然会删除您之前的提交但是当我尝试列出要提交的文件时它找不到更改所以我不会建议这样做。

如果我提交然后执行推送(到远程)然后执行 hg strip -r -1 --keep,它完全按照它应该做的但是当你执行另一个提交然后推送时,它会创建另一个分支。

I.E. 

o----o----Branch (local)
      \
       \
        --o----o----o----Branch (with previous push)

我的source/reference:测试这些场景