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

git reset --soft seems to change index

通读 Mark Dominus's article and Scott Chanon's article 我假设 git reset abcd --soft 不会影响索引,但是,下面显示它会影响。

重置前

c1.txtc2.txtc3.txt 在 repo 中,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

我以为会发生什么

从斯科特的文章中,他说:

The first thing reset will do is move what HEAD points to.... If you add the flag --soft, this is the only thing it will do. With --soft, reset will simply stop there.

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

c3.txt 似乎已与 c4.txt 一起移入索引。

引自 git 文档:

Does not touch the index file or the working tree at all (but resets the head to , just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

这意味着您的提交将被删除,但仅限于 "Changes to be committed"。所以你必须再次 运行 git reset <file> 才能完全删除它们。对于未来的提交,您可能需要 --mixed 模式 (git reset --mixed 231a)。文档:

Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.

基本的误解似乎是关于索引 是什么 。索引不是一组差异,它是一组文件。 git status 显示的不是索引,而是最后一次提交与索引之间的差异。

git reset --soft 之前,索引包含文件 c1.txtc2.txtc3.txtc4.txt。所以在你的 git reset --soft 之后,索引仍然包含那些相同的文件。 git status 会以不同的方式报告,但这不是因为索引发生了变化,而是因为提交发生了变化。