'What's the difference between git stash apply and git stash apply --index?

Whenever I run git stash apply and git stash apply --index after having done git stash -a I get the same result even though my WIP directory has staged changes, unstaged (but tracked changes) and untracked files.

Is this normal? Shouldn't git stash apply not return the index?

git


Solution 1:[1]

Using git stash apply the changes to your files were reapplied, but the file(s) you staged before wouldn't be re-staged.

If you want to do that, you could add the --index option to tell the command to try to reapply the staged changes.

Solution 2:[2]

While git stage apply --index should restore the index in addition of applying a stashed change, its behavior has changed with Git 2.36 (Q2 2022).

It does not output as much as before.

"git stash"(man) does not allow subcommands it internally runs as its implementation detail, except for "git reset"(man), to emit messages; now "git reset" part has also been squelched.

See commit 5891c76 (24 Mar 2022) by Junio C Hamano (gitster).
See commit 7cff676, commit 2efc9b8, commit 45bf762 (23 Mar 2022), and commit 4b8b0f6, commit d492abb, commit 9396251, commit fd56fba, commit e86ec71 (15 Mar 2022) by Victoria Dye (vdye).
(Merged by Junio C Hamano -- gitster -- in commit 6d51217, 30 Mar 2022)

stash: make internal resets quiet and refresh index

Helped-by: Junio C Hamano
Signed-off-by: Victoria Dye

Add the options '-q' and '--refresh' to the 'git reset'(man) executed in 'reset_head()', and '--refresh' to the 'git reset -q'(man) executed in 'do_push_stash(...)'.

'stash' is implemented such that git commands invoked as part of it (e.g., 'clean', 'read-tree', 'reset', etc.) have their informational output silenced.

However, the 'reset' in 'reset_head()' is not called with '-q', leading to the potential for a misleading printout from 'git stash apply --index'(man) if the stash included a removed file:

Unstaged changes after reset: D      <deleted file>  

Not only is this confusing in its own right (since, after the reset, 'git stash'(man) execution would stage the deletion in the index), it would be printed even when the stash was applied with the '-q' option.

As a result, the messaging is removed entirely by calling 'git status'(man) with '-q'.

Additionally, because the default behavior of 'git reset -q' is to skip refreshing the index, but later operations in 'git stash' subcommands expect a non-stale index, enable '--refresh' as well.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Clijsters
Solution 2 VonC