如何撤销一个提交并将更改重新放回暂存区

8

如何撤销一个提交但将更改保留在暂存区,以便我可以编辑该提交直到满意为止。

以前我熟悉 TFS,在那里撤消操作正好是这样做的。但是在 GIT 中,git revert 似乎会自动提交已撤消的提交,因此没有机会保留更改集中的某些内容。


4
你可以使用命令 git reset --soft,它会取消你的提交并将更改放回暂存区。 - abdullahalali
3个回答

12

试试这个

git reset HEAD^

HEAD^表示前一个提交。


3
请注意,这回答了一个非常不同的问题。这可能是提问者应该问的问题!重置掉一个虚假提交有时是最好的方法。但这并不等同于创建一个新提交来撤消错误的提交。 - torek

5
(make sure that you have a clean working directory)
git revert <commit>
(accept commit message)
git reset HEAD^

这将使您拥有本地更改,如果您接受了所有更改,则可以还原提交,但允许您仅选择几行进行还原。 如果您想将更改放入暂存区,则还可以切换到 git reset HEAD^ --soft 。与其他答案一样,如果您正在处理他人的历史记录,则最好还原完整的提交。不过,当我重新定位并修复自己的更改时,我经常使用此撤销+重置

4

你可以使用git revert -n。但我建议你不要这样做。最好单独创建一个提交来实现想要的更改。

原因很简单,一个提交是一个快照,但它代表了一个变化。为了找到从快照到变更的连接,Git将提交与其直接上级进行比较。

例如文件A之前有10行,现在有11行,在旧版本的文件A和新版本的文件A之间进行比较(可能)会显示有人添加了一行。差异会说:“为了将旧提交更改为新提交,请向文件A中添加此一行。”如果之前文件B有20行,现在只有19行,则差异将说:“为了将旧提交更改为新提交,请从文件B中删除此一行。”

简单的提交撤销会显示相同的更改,但是顺序相反:从文件A中删除此一行,并在文件B中添加此一行。

如果你的意思是,在第三次提交中仅向文件A中添加一行,则你将拥有一个正确的单个提交,该提交将显示“向文件A中添加此一行”。

如果你相反地进行非提交撤销,然后再把这一行放回去,你将不得不将两个单独的提交-错误的提交和更正的撤销-添加在一起,才能看到实际意图。这并不是错误的,但意味着后来的人要查看发生了什么,以及在类似情况下可能需要做些什么时,必须付出更多努力。

比较一下以下说明:

  1. “做X;等等,不要做X。做Y。”
  2. “做X。然后在撤销X的同时,执行Z。”

哪个会使未来的你更喜欢看到呢?

(请注意,你可以通过执行以下操作构建提交Y

git cherry-pick -n X

其中X是您还原的那个版本。这样,您就可以获得所有更改,但可以开始撤消它们。

另请注意,git revert -ngit cherry-pick -n将所有内容放入暂存区域-也就是说,它们对所有更新的文件执行git add。 实际上没有问题,但如果您不喜欢它,您可以运行git reset取消暂存。


如果最初的意图是保留原始提交和撤销的提交,那么这是一个非常有效的论点。然而,我认为OP建议彻底消除原始提交(X),在这种情况下,其他人只会看到Y。 - Michael Sorens
还应该说一句:删除提交也会带来自己的风险! :-) - Michael Sorens
@MichaelSorens:是的 - 虽然如果您从未将提交发送到任何地方(例如,如果它是私有的,并且您从未运行过git push),则是安全的。如果提交是最近的提交,则这也是git reset HEAD~1或等效项的用途。 - torek

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