我看过一些有趣的帖子,解释git重置的微妙之处。
不幸的是,我读得越多,就越觉得我并没有完全理解它。我有SVN的背景,Git是一个全新的范例。我很容易得到mercurial,但是Git的技术含量更高。
我认为git重置接近hg恢复,但似乎有区别。
git重置到底是做什么的?请详细说明:
选项——硬、软和合并; 你对HEAD使用的奇怪符号,如HEAD^和HEAD~1; 具体的用例和工作流程; 对工作副本、HEAD和整体压力水平的影响。
我看过一些有趣的帖子,解释git重置的微妙之处。
不幸的是,我读得越多,就越觉得我并没有完全理解它。我有SVN的背景,Git是一个全新的范例。我很容易得到mercurial,但是Git的技术含量更高。
我认为git重置接近hg恢复,但似乎有区别。
git重置到底是做什么的?请详细说明:
选项——硬、软和合并; 你对HEAD使用的奇怪符号,如HEAD^和HEAD~1; 具体的用例和工作流程; 对工作副本、HEAD和整体压力水平的影响。
当前回答
当你向git提交一些东西时,你首先必须stage(添加到索引中)你的更改。这意味着在git认为这些文件是提交的一部分之前,你必须在git中添加所有你想要包含在这个提交中的文件。让我们先看一下git回购的图像:
现在很简单了。我们必须工作在工作目录,创建文件,目录和所有。这些更改是未跟踪的更改。为了跟踪它们,我们需要使用git add命令将它们添加到git索引中。一旦它们被添加到git索引。我们现在可以提交这些更改,如果我们想把它推到git存储库。
但在提交时,我们突然意识到,我们在索引中添加的一个额外文件不需要推入git存储库。这意味着我们不希望这个文件出现在索引中。 现在的问题是如何从git索引中删除该文件,因为我们使用git添加把它们放在索引中,使用git rm是合乎逻辑的?错了!Git rm将简单地删除文件并将删除添加到索引中。那么现在该怎么做呢:
使用:
去重置
它清除你的索引,保持你的工作目录不变。(简单地取消所有内容)。
它可以使用与它的数量选项。 git重置有三个主要选项:——hard,——soft和——mixed。除了重置时的HEAD指针外,这些还会影响get重置的内容。
首先,硬重置一切。如果您一直在跟踪该分支,那么当前目录将完全相同。工作目录和索引将更改为该提交。这是我最常用的版本。Git重置——很难像SVN恢复。
接下来,完全相反的-soft不会重置工作树或索引。它只移动HEAD指针。这将使您的当前状态与您要切换到的目录中的提交不同,并且“阶段性”提交。如果你在本地进行了一次提交,但还没有将提交推到git服务器,你可以重置到上一次提交,并使用一个好的提交消息重新进行一次提交。
最后,——mixed重置索引,但不重置工作树。所以这些更改仍然存在,但是是“非分期的”,需要git add 'ed或git commit -a。我们有时会使用这个,如果我们提交了比git commit -a更多的东西,我们可以用git reset -mixed返回提交,添加我们想要提交的东西,然后只提交那些。
git revert和git reset的区别:-
简单来说,git reset是一个“修复未提交的错误”的命令,git revert是一个“修复已提交的错误”的命令。
这意味着如果我们在某些更改中犯了一些错误,并提交了相同的更改并将其推给了git repo,那么git revert就是解决方案。如果我们在推送/提交之前发现了同样的错误,我们可以使用git reset来修复这个问题。
我希望它能帮助你摆脱困惑。
其他回答
博客Pro Git中的Reset Demystified给出了一个关于Git重置和Git checkout的非常简单的解释。
在那篇文章的顶部进行了有益的讨论之后,作者将这些规则简化为以下简单的三步:
基本上就是这样。reset命令以特定顺序覆盖这三棵树,当您命令它停止时停止。 移动HEAD指向的分支(如果—软) 然后,让索引看起来像这样(停止在这里,除非——很难) 然后,让工作目录看起来像这样 还有“合并”和“保留”选项,但我现在宁愿让事情简单一些——这将是另一篇文章。
我不总是做git重置,但当我这样做时,我看到这个:
* 444668f (HEAD -> main) C
|
* c3739b7 B
|
* 207e8a1 A
|
* 38fab46 Initial commit
git reset --hard 207e8
* 207e8a1 (HEAD -> main) A
|
* 38fab46 Initial commit
To retrieve the changes, use --soft instead
HEAD移到A (main也是,因为HEAD指向main)。git reset不会“重置”B和C。你仍然可以使用git log的——reflog选项看到B和C:
git log --graph --oneline --all --reflog
警告
在你做git重置之前,
如果你有非阶段性的变化: 如果用力,就会被丢弃 使用——mixed(默认),它将与阶段性更改混合,检索到的更改将提交更改 如果你有阶段性的变化: 如果用力,就会被丢弃 使用——mixed,它将与非阶段更改和检索到的提交更改混合 使用——soft,它将与检索到的提交更改混合在一起
要摆脱它们,你可以使用git stash,但我更喜欢只创建一个新分支,并为那里的阶段性和非阶段性更改创建一个单独的提交。然后使用git rebase + git重置当我需要他们回来。
记住在git中你有:
HEAD指针,它告诉你你在做什么提交 工作树,它表示系统上文件的状态 暂存区(也称为索引),它“暂存”更改,以便稍后可以一起提交
请详细说明: ——硬,——软,——融合;
按危险程度递增:
-轻轻移动头部,但不触及集结区或工作树。 mixed移动HEAD并更新暂存区,但不更新工作树。 ——merge移动HEAD,重置暂存区域,并尝试将工作树中的所有更改移动到新的工作树中。 -hard移动HEAD,调整你的集结区和工作树到新的HEAD,扔掉所有东西。
具体的用例和工作流;
当你想要转移到另一个地方,修补事情而不“失去你的位置”时,使用-软。你很少需要这个。
--
# 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(这是默认值)。 使用—合并当你想移动到一个新的点,但合并你已经有到工作树的变化。 使用——在新的提交时很难清除所有内容并重新开始。
请注意,这是一个简化的解释,旨在作为寻求理解这个复杂功能的第一步。
对于那些想要在这些命令之后可视化他们的项目状态的视觉学习者来说,这可能是有帮助的:
适用于开启彩色终端机的用户 (git配置——global color。ui汽车):
git重置-软A,你会看到B和C的东西在绿色(分期和准备提交)
git重置-混合A(或git重置A),你会看到B和C的东西在红色(未分期和准备分期(绿色),然后提交)
git重置-硬A,你将不再看到B和C的变化在任何地方(将好像他们从来没有存在过)
或者对于那些使用像“塔”或“SourceTree”这样的GUI程序的人
git重置——软A,你会看到B和C的东西在“阶段性文件”区域准备提交
git reset—混合A(或git reset A),你会看到B和C的东西在“unstaging files”区域准备移动到staging,然后提交
git重置-硬A,你将不再看到B和C的变化在任何地方(将好像他们从来没有存在过)
当你向git提交一些东西时,你首先必须stage(添加到索引中)你的更改。这意味着在git认为这些文件是提交的一部分之前,你必须在git中添加所有你想要包含在这个提交中的文件。让我们先看一下git回购的图像:
现在很简单了。我们必须工作在工作目录,创建文件,目录和所有。这些更改是未跟踪的更改。为了跟踪它们,我们需要使用git add命令将它们添加到git索引中。一旦它们被添加到git索引。我们现在可以提交这些更改,如果我们想把它推到git存储库。
但在提交时,我们突然意识到,我们在索引中添加的一个额外文件不需要推入git存储库。这意味着我们不希望这个文件出现在索引中。 现在的问题是如何从git索引中删除该文件,因为我们使用git添加把它们放在索引中,使用git rm是合乎逻辑的?错了!Git rm将简单地删除文件并将删除添加到索引中。那么现在该怎么做呢:
使用:
去重置
它清除你的索引,保持你的工作目录不变。(简单地取消所有内容)。
它可以使用与它的数量选项。 git重置有三个主要选项:——hard,——soft和——mixed。除了重置时的HEAD指针外,这些还会影响get重置的内容。
首先,硬重置一切。如果您一直在跟踪该分支,那么当前目录将完全相同。工作目录和索引将更改为该提交。这是我最常用的版本。Git重置——很难像SVN恢复。
接下来,完全相反的-soft不会重置工作树或索引。它只移动HEAD指针。这将使您的当前状态与您要切换到的目录中的提交不同,并且“阶段性”提交。如果你在本地进行了一次提交,但还没有将提交推到git服务器,你可以重置到上一次提交,并使用一个好的提交消息重新进行一次提交。
最后,——mixed重置索引,但不重置工作树。所以这些更改仍然存在,但是是“非分期的”,需要git add 'ed或git commit -a。我们有时会使用这个,如果我们提交了比git commit -a更多的东西,我们可以用git reset -mixed返回提交,添加我们想要提交的东西,然后只提交那些。
git revert和git reset的区别:-
简单来说,git reset是一个“修复未提交的错误”的命令,git revert是一个“修复已提交的错误”的命令。
这意味着如果我们在某些更改中犯了一些错误,并提交了相同的更改并将其推给了git repo,那么git revert就是解决方案。如果我们在推送/提交之前发现了同样的错误,我们可以使用git reset来修复这个问题。
我希望它能帮助你摆脱困惑。