git reset --soft似乎会改变索引

3

阅读了Mark Dominus的文章Scott Chanon的文章后,我认为git reset abcd --soft不会影响索引,但是下面的内容表明它确实会。

重置之前

仓库中有c1.txtc2.txtc3.txt,索引中有c4.txt。所有文件都在工作目录中:

历史记录:

$ git log --oneline --decorate
b91d91b (HEAD, master) C3
231a5df C2
7e7b2d7 C1

索引:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   c4.txt

工作目录:

$ ls
c1.txt  c2.txt  c3.txt  c4.txt

重置到C2提交

$ git reset 231a --soft

$ git log --oneline --decorate
231a5df (HEAD, master) C2
7e7b2d7 C1

索引已更改

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   c3.txt
        new file:   c4.txt


$ ls
c1.txt  c2.txt  c3.txt  c4.txt

我原本认为会发生什么

从Scott的文章中,他说:

reset将要做的第一件事情是移动HEAD指向的内容...如果你添加了--soft标志,那么这是它唯一要做的事情。使用--soft,reset将只停留在这里。

所以,我认为索引(我希望我已经理解了在git status输出中显示的内容)不会改变,也就是说,它仍然包含c4.txt。但上面的输出显示它实际上包含c3.txtc4.txt

看起来,c3.txt已经与c4.txt一起移动到索引中。


1
然而,以下内容表明它并没有这样做。不,它没有,坦白地说,我很难理解为什么你认为它会这样做。你能详细解释一下吗?(请记住,索引不变意味着如果它等于旧的提交树,并且旧的提交树和新的提交树不同,则索引不能等于新的提交树。) - user743382
我猜这是我没有理解的东西,我会在问题中添加更多信息。 - BanksySan
你应该提供所有的Git命令,以使重现变得非常简单。 - barlop
2个回答

5
基本误解似乎在于对索引的理解。索引不是一组差异,而是一组文件。"git status"显示的不是索引,而是最后一次提交和索引之间的差异。
在你执行"git reset --soft"之前,索引包含文件"c1.txt"、"c2.txt"、"c3.txt"和"c4.txt"。因此,在执行了"git reset --soft"之后,索引仍然包含同样的文件。"git status"将会报告不同的信息,但这并不是索引改变了,而是提交改变了。

1
好的,所以,在提交后立即的那个点上,索引等于先前的提交。因此,向后移动,git status将报告索引中有新文件,这些文件不在先前的提交中。 - BanksySan
是的,对于仅添加文件的提交,这就是实际结果。 - user743382
那就是缺失的环节。现在有意义了。 - BanksySan
哪个命令显示索引呢?假设我执行了提交,我一直以为这会清除索引,因为 git status -s 显示它已清除,但是也许索引并没有被清除,只是索引中没有与提交中相同的文件。所以,也许提交会清除索引,但是哪个命令可以显示出来呢?看起来 git status -s 不能。 - barlop
1
@barlop git ls-files 显示索引中包含哪些文件。 - user743382

1

来自Git文档的引用:

此操作不会对索引文件或工作树产生任何影响(但是像所有模式一样将重置头)。这意味着所有更改的文件都会被标记为“Changes to be committed”,就像git status所显示的那样。

这意味着您的提交将被删除,但仅限于“Changes to be committed”。因此,您需要再次运行git reset <file>以完全删除它们。对于未来的提交,您可能希望使用--mixed模式(git reset --mixed 231a)。文档如下:

重置索引,但不重置工作树(即保留更改的文件,但不标记为提交),并报告未更新的内容。这是默认操作。


谢谢,我只是想了解--soft--mixed--hard的作用。我预期的行为与我理解的不太一样。 - BanksySan
1
请记住,索引只是一个以路径名为索引的内容列表。当您使用 git add 命令时,将添加的内容放入存储库中,git 会更新索引以表示现在这就是您已经拥有的与该路径相关的内容。当前提交(也称为 HEAD)是一个小文件,其中包含分支 ID 或提交 ID 的引用。git reset --soft 命令更改该 ID,但不更改其他任何内容。git reset --mixed 命令更改 ID 并从新提交中重新加载索引,因此现在的差异在于您的工作树和索引内容之间(自然也包括头提交)。 - jthill

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