The claim that git reset --soft
leaves the index/staging-area unmodified is correct.
Note that git diff
always compares two things. Which two things does it compare? The answer is a bit complicated for the fully general form of git diff
, but you are using git diff --cached
, and it compares the two things noted in the git diff
documentation`:
git diff [--options] --cached [<commit>
] [--] [<path> ...
]
This form is to view the changes you staged for the next commit relative to the named <commit>
. Typically you would want comparison with the latest commit, so if you do not give <commit>
, it defaults to HEAD
. [snip]
Thus, the two things being compared are HEAD
and the index.
Aside: the documentation is misleading
The above implies that the index stores changes, which is not true! The index / staging area is simply what would be in the next commit if you made that commit right now. Hence, after making a commit, the index and the current commit are identical—at least, they represent the same work-tree (the index omits significant parts of a commit, namely author and committer name+email+date, parent pointers, and commit message—or to put it a little more briefly, the index has only a work tree, and it's in an unusual form, more suited for being an index/cache than for being a commit).
Back to git reset
and git diff --cached
git reset --soft
modifies HEAD
. It does not modify the index. You first compare HEAD
against the index and see no output. Then you change HEAD
. Now you compare the changed HEAD
against the index, and see output.
What changed to cause the changed output? Well, HEAD
changed.
You can see the same thing by omitting the git reset --soft
step and providing a specific commit:
git diff --cached HEAD~
This will compare commit HEAD~
against the index, and show you the same output.