Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does 'git stash apply' stage my changes?

Tags:

I make a change and then I git stash and then I git stash apply

My question is

  1. why after I git stash apply, my change becomes 'staged'? i.e. I won't see anything if I do git diff, I only see my difference if I do git diff --cached?

  2. Is there anyway to 'unstage' my changes staged by git stash apply command?

  3. Is there any git command basically let me to 'make a backup of my change, reset it to the HEAD and the copy my backup back'? I thought git stash and then git stash apply is that command, but some how it 'staged' all my changes? Is there any equivalent which let me git stash apply without the staged my changes part?

like image 379
n179911 Avatar asked Aug 06 '09 04:08

n179911


People also ask

Does git stash apply stage changes?

The answer to this issue is the git stash command. Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time (even on a different branch).

Do you need to stage before stash?

If you stash your files you should "unstash" to recover them. Now, if those are new files, yes, you should stage them first.

How do you stash changes not including anything in the staging area?

Git doesn't have a command that stashes only your unstaged changes. Git does, however, let you specify which files you want to stash. If you only want to stash specific changes in those files, add the --patch option. The --include-untracked option lets you stash untracked files.

How do you stash all staged changes?

Stage all your files that you need to stash. Run git stash --keep-index . This command will create a stash with ALL of your changes (staged and unstaged), but will leave the staged changes in your working directory (still in state staged). Now your "good stash" has ONLY staged files.


2 Answers

If you find that your changes are unexpectedly staged, do:

git reset HEAD 

I usually only see this if there is a conflict when applying the stashed changes. You will want to check to see whether this is the case before doing the git reset.

The git stash command is the most appropriate command for your use case. I use it all the time for exactly this purpose.

like image 129
Greg Hewgill Avatar answered Oct 26 '22 07:10

Greg Hewgill


Why does git stash apply stage my changes?

Anything that will affect your working tree (like a git checkout -- afile) will first affect your index.

the index is the middle-man for moving things from your work-tree to the object-store AND for moving things from the object-store to your work-tree.

The index is also used by git stash apply for recording merge conflicts, as the index has stage-n entries. See git merge:

For conflicting paths, the index file records up to three versions:

  • stage 1 stores the version from the common ancestor,
  • stage 2 from HEAD, and
  • stage 3 from MERGE_HEAD (you can inspect the stages with git ls-files -u).

In the history of the evolution of git stash --apply, two interesting events are to be noted: In April 2011 (Git 1.7.5.1, commit e0e2a9c), stash dropped the dirty worktree check on apply.

Before we apply a stash, we make sure there are no changes in the worktree that are not in the index. This check dates back to the original git-stash.sh, and is presumably intended to prevent changes in the working tree from being accidentally lost during the merge.

However, this check has two problems:

  1. It is overly restrictive. If my stash changes only file "foo", but "bar" is dirty in the working tree, it will prevent us from applying the stash.

  2. It is redundant. We don't touch the working tree at all until we actually call merge-recursive.
    But it has its own (much more accurate) checks to avoid losing working tree data, and will abort the merge with a nicer message telling us which paths were problems.

So we can simply drop the check entirely.

Using the index to manage the merge done by a git stash apply lead to another bug, detected in April 2015, Git 2.4.2, commit ed178ef:

stash: require a clean index to apply

If you have staged contents in your index and run "stash apply", we may hit a conflict and put new entries into the index.
Recovering to your original state is difficult at that point, because tools like "git reset --keep" will blow away anything staged.
We can make this safer by refusing to apply when there are staged changes.

like image 28
VonC Avatar answered Oct 26 '22 05:10

VonC