用简单的英语,“git reset”有什么作用?

时间:2010-03-27 16:44:40

标签: git reset

我看到interesting posts解释了关于git reset的微妙之处。

不幸的是,我读的越多,我就越不能完全理解它。我来自SVN背景,Git是一个全新的范例。我很容易变得善变,但Git更具技术性。

我认为git reset接近hg revert,但似乎存在差异。

那么git reset究竟做了什么?请提供以下详细说明:

  • 选项--hard--soft--merge;
  • 您与HEAD使用的奇怪记法,例如HEAD^HEAD~1;
  • 具体用例和工作流程;
  • 对工作副本的影响,HEAD以及您的全球压力水平。

7 个答案:

答案 0 :(得分:934)

答案 1 :(得分:77)

请记住,git你有:

  • HEAD指针,告诉您正在进行的提交
  • 工作树,表示系统中文件的状态
  • 临时区域(也称为索引),它“分阶段”更改,以便以后可以一起提交
  

请提供以下详细说明:

     

--hard--soft--merge;

按危险程度递增:

  • --soft移动HEAD,但不会触及暂存区域或工作树。
  • --mixed移动HEAD并更新暂存区域,但不更新工作树。
  • --merge移动HEAD,重置暂存区域,并尝试将工作树中的所有更改移动到新的工作树中。
  • --hard移动HEAD 将您的暂存区和工作树调整为新HEAD,丢弃所有内容。
  

具体用例和工作流程;

  • 当您想要转移到另一个提交并修补内容而不“丢失您的位置”时,请使用--soft。你需要这个很少见。

-

# git reset --soft example
touch foo                            // Add a file, make some changes.
git add foo                          // 
git commit -m "bad commit message"   // Commit... D'oh, that was a mistake!
git reset --soft HEAD^               // Go back one commit and fix things.
git commit -m "good commit"          // There, now it's right.

-

  • 当您想要查看另一次提交时的内容时,请使用--mixed(这是默认设置),但您不想丢失已有的任何更改。

    < / LI>
  • 当您想要移动到新位置时使用--merge,但将已有的更改合并到工作树中。

  • 使用--hard清除所有内容,并在新提交时开始新的目标。

答案 2 :(得分:35)

博客Reset Demystified中的帖子Pro Gitgit resetgit checkout上提供了非常简单的简明解释。

在该帖子顶部的所有有用的讨论之后,作者将规则简化为以下简单的三个步骤:

  

基本上就是这样。 reset命令以特定顺序覆盖这三棵树,当你告诉它时停止。

     
      
  1. 移动HEAD指向的任何分支(如果--soft
  2. ,则停止   
  3. 然后,让索引看起来像那样(除非--hard
  4. 停在这里   
  5. 然后,让工作目录看起来像那样
  6.         

    还有--merge--keep选项,但我宁愿现在更简单 - 这将是另一篇文章。

答案 3 :(得分:24)

当您提交git内容时,首先必须暂存(添加到索引)您的更改。这意味着在git认为它们是提交的一部分之前,你必须git添加你想要包含在这个提交中的所有文件。让我们先来看看git repo的图像: enter image description here

所以,现在很简单。我们必须在工作目录中工作,创建文件,目录和所有。这些更改是未跟踪的更改。要跟踪它们,我们需要使用 git add 命令将它们添加到git索引。一旦将它们添加到git索引中。如果我们想将它推送到git存储库,我们现在可以提交这些更改。

但突然我们知道我们提交了一个额外的文件,我们在索引中添加了不需要推入git存储库。这意味着我们不希望索引中的该文件。 现在的问题是如何从git索引中删除该文件,因为我们使用 git add 将它们放入索引中,使用 git rm 是合乎逻辑的?错误! git rm 只会删除该文件并将删除添加到索引中。那么现在该怎么做:

使用: -

  

git reset

清除索引,保持工作目录不变。 (只是取消暂停一切)。

它可以与多个选项一起使用。 git reset有三个主要选项: - hard, - soft和--mixed 。重置时,这些会影响除HEAD指针之外的重置。

首先, - 硬重置所有内容。您当前的目录将完全像您一直关注该分支一样。工作目录和索引将更改为该提交。这是我经常使用的版本。 git reset --hard 类似 svn revert

接下来,完全相反的 -soft 不会重置工作树和索引。它只移动HEAD指针。这使您的当前状态的任何更改都与您在目录中切换到的提交不同,并且“暂存”以进行提交。如果您在本地进行提交但尚未将提交推送到git服务器,则可以重置为先前的提交,并重新发送一个良好的提交消息。

最后, - mixed 重置索引,但不重置工作树。所以这些变化仍然存在,但是“未分级”并且需要git add'ed或 git commit -a 。我们有时会使用这个,如果我们使用git commit -a提交的更多,我们可以使用git reset -mixed返回提交,添加我们想要提交的内容并提交它们。

git revert和git reset之间的区别 : -


简单来说, git reset &#34;修复 - 未公开错误&#34; git revert 的命令命令&#34;修复提交错误&#34;

这意味着如果我们在某些更改中犯了一些错误并提交并将其推送到git repo,那么 git revert 就是解决方案。如果我们在推送/提交之前已经识别出相同的错误,我们可以使用 git reset 来解决问题。

我希望它可以帮助你摆脱困惑。

答案 4 :(得分:6)

TL; DR

  

git reset重置Staging到最后一次提交。使用--hard还可以将工作目录中的文件重置为上次提交。

LONGER VERSION

但这显然是简单化的,因此许多相当冗长的答案。在撤消更改的上下文中,我更有意义地阅读git reset。例如。看到这个:

  

如果git revert是一种撤消更改的“安全”方式,你可以想到git   重置为危险方法。当您使用git reset撤消时(和   任何引用或reflog都不再引用提交,有   无法检索原始副本 - 它是永久撤消。必须小心   使用此工具时,因为它是唯一可能丢失工作的Git命令之一。

来自https://www.atlassian.com/git/tutorials/undoing-changes/git-reset

和这个

  

在提交级别,重置是一种将分支的提示移动到另一个提交的方法。这可以用于从当前分支中删除提交。

来自https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/commit-level-operations

答案 5 :(得分:2)

请注意,这是一个简化的解释,旨在帮助您了解这一复杂功能。

对于想要在每个命令之后可视化项目状态的视觉学习者可能会有所帮助:


对于使用打开颜色的终端的用户 (git config --global color.ui auto):

git reset --soft A你会看到B和C的东西是绿色的(上演并准备提交)

git reset --mixed A(或git reset A)你会看到B和C的东西是红色的(未分期并准备上演(绿色)然后提交)

git reset --hard A你将不再在任何地方看到B和C的变化(就像它们从未存在过一样)


或者对于使用“Tower”或“SourceTree”等GUI程序的人

git reset --soft A你会在'staged files'区域看到B和C的东西准备提交

git reset --mixed A(或git reset A)您将在“未暂存文件”区域看到B和C的内容,可以将其移至暂存状态然后提交

git reset --hard A你将不再在任何地方看到B和C的变化(就像它们从未存在过一样)

答案 6 :(得分:1)

结帐将头部指向特定提交。

Reset将分支指向特定的提交。 (分支是指向提交的指针。)

顺便说一句,如果您的头没有指向分支也指向的提交,则您的头是分离的。 (结果是错误的。请参阅注释。 。)