'git reset --hard HEAD〜1'和'git reset --soft HEAD〜1'有什么区别?


Answers:


176

git reset确实知道五种“模式”:软,混合,硬,合并和保留。我将从头三个开始,因为这是您通常会遇到的模式。之后,您会发现一点好处,所以请继续关注。

柔软的

使用时,git reset --soft HEAD~1您将从当前分支中删除最后的提交,但是文件更改将保留在您的工作树中。更改也将保留在索引上,因此,在后面加上git commit将会创建一个提交,该提交的更改与之前“删除”的提交完全相同。

混合的

这是默认模式,与软模式非常相似。当“删除”与git reset HEAD~1您的提交时,所做的更改仍将保留在工作树中,但不保留在索引中。因此,如果您要“重做”提交,则必须在提交git add之前添加更改()。

使用时,除了上一次提交中引入的更改之外,git reset --hard HEAD~1您还将丢失所有未提交的更改。所做的更改不会保留在您的工作树中,因此执行git status命令将告诉您存储库中没有任何更改。

小心踩一下。如果您不小心删除了从未被跟踪的未提交更改git(说:已提交或至少已添加到索引),则无法使用恢复它们git

奖金

保持

git reset --keep HEAD~1是一个有趣而有用的。它仅重置当前 HEAD提交和给定提交之间不同的文件。如果这些文件中的任何一个有未提交的更改,它将中止重置。基本上,它是的更安全版本hard

当您进行了很多更改并希望切换到另一个分支而不丢失这些更改时,例如当您开始在错误的分支上工作时,此模式特别有用。


您可以在git reset文档中阅读有关此内容的更多信息。

注意:
在执行git reset删除提交操作时,提交操作并没有真正丢失,只是没有引用指向该提交文件或其任何子项。您仍然可以git reset通过找到它的SHA-1密钥来恢复被“删除”的提交,例如,使用诸如这样的命令git reflog


1
我不同意这3个是我们通常应该使用的。它们是第一个可用的3种,因此人们会更多地谈论这3种,但是--hard几乎从来都不是正确的事,因为--keep它更安全,并且适用于大多数--hard工作环境。训练手指的使用--keep可能会为您节省一天的时间
Matthieu Moy 2015年

我并没有建议我们应该使用它们,只是这些是大多数时候都会遇到的命令。随意编辑您认为合适的答案。
2015年

要添加更多详细信息,请在git reset --soft HEAD〜1之后,使用git commit --reuse-message = HEAD @ {1}重用具有保留的旧索引的最后一次提交,如下所示stackoverflow.com/a/ 25930432/2883282
吞噬了

3
@MatthieuMoy,晚了三年,但我在上添加了一节keep。;)
Sascha Wolf

如何撤消上一次提交?请帮忙。如果我使用git reset --soft HEAD〜1,则会收到:致命的:模糊参数'HEAD〜1':未知修订或路径不在工作树中。使用'-'将路径与修订版本分开,例如:'git <command> [<revision> ...]-[<file> ...]'
elvis

6

Git重置有5种主要模式:软,混合,合并,硬,保持。它们之间的区别是更改或不更改头,阶段(索引),工作目录

Git reset --hard将更改头,索引和工作目录。
Git reset --soft只会改变头。不变索引,工作目录。

因此,换句话说,如果您要撤消提交,则--soft应该足够好。但是之后,您仍然可以从索引和工作目录中的错误提交中进行更改。您可以修改文件,修复文件,将它们添加到索引并再次提交。

使用--hard,您就可以在项目中获得完全的成功。好像上一次提交没有任何更改。如果您确定这是您想要的,请继续前进。但是一旦执行此操作,您将完全丢失上一次提交。(注意:仍有一些方法可以恢复丢失的提交)。


5

这篇有用的文章以图形方式显示了reset命令的说明。

https://git-scm.com/docs/git-reset

Reset --hard可能非常危险,因为它会在不检查的情况下覆盖您的工作副本,因此,如果您根本没有提交文件,则文件将消失。

至于源代码树,我没有办法撤消提交。无论如何,它很可能会在掩护下使用reset


+1以获取官方文档的链接。我还要提到git reset --help,这(在我看来)很好地解释了五种模式,或者至少解释了OP所要求的两种模式。
ThanksForAllTheFish

1
链接断开。可能这是当前版本:git-scm.com/docs/git-reset
Kiki Jewell

1

这是使用git reset --hardgit reset --soft之间的主要区别

--soft

完全不触摸索引文件或工作树(而是将头重置为,就像所有模式一样)。就像git status那样,这会将所有更改的文件保留为“要提交的更改”。

--hard

重置索引和工作树。由于对工作树中跟踪文件的任何更改,都将被丢弃。


1
这就是我想要的。简洁准确。
卡西姆
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.