14

Suppose the current commit is A, and then I create a new commit B, and then I make some changes in the working tree directory. Now I run git stash push. What does git stash push stash? Is it only the changes that I have made in the working tree directory since B was created, or also the changes that I made into commit B since A?

If I then checkout commit A, and run git stash pop, will that apply the changes that I made to the working directory after creating commit B, or also the changes that I made into commit B since A?

Does git stash push stash the changes to the last committed state (i.e. the differences between the current working tree directory and the last committed state), or stash just the current state?

1
  • 2
    Was the question about the differences (or lack thereof) between git stash and git stash push? Because although the title made me think that also for some reason, reading the body of the question revealed a whole different topic. Am I missing something, guys? Commented Jan 22, 2019 at 23:12

3 Answers 3

15

According to the documentation:

Save your local modifications to a new stash entry and roll them back to HEAD (in the working tree and in the index). The part is optional and gives the description along with the stashed state.

For quickly making a snapshot, you can omit "push".

In other words, git stash push is the same as git stash.

Also in the documentation, git stash save has been deprecated in favor of git stash push.


When you run git stash, you stash any changes that haven't been committed, reverting your branch back to the latest commit. If you change branches and run git stash pop, Git will then apply your changes to the new branch.

However, git stash pop can fail if the two branches are out of sync. For example, the file FOO has been pushed to branch A, and git stash stashes a change to that file. Branch B doesn't contain FOO, so git stash pop will fail to apply your stash onto branch B.

Sign up to request clarification or add additional context in comments.

Comments

3

As per the Git documentation, git stash push is the same as git stash:

Calling git stash without any arguments is equivalent to git stash push. A stash is by default listed as "WIP on branchname …​", but you can give a more descriptive message on the command line when you create one.

Therefore this will stash all the new changes you have made from your last commit.

git stash pop does the same as git stash apply only that it removes this stashed state from the stash list, so this is the inverse operation of git stash push.

All in all, this means that everything that has already been committed to your branch will not be considered by default by stash operations, and only the new changes you have made since that commit.

Comments

1

To answer the different parts :

What does git stash push stash? Is it only the changes that I have made in the working tree directory since B was created, or also the changes that I made into commit B since A?

Yes, only the changes made since B was created are stashed.

If I then checkout commit A, and run git stash pop, will that apply the changes that I made to the working directory after creating commit B, or also the changes that I made into commit B since A?

You'll apply the changes made since B was created on top of the state where your files were at point A (commits are snapshots of your whole repo)

Does git stash push stash the changes to the last committed state (i.e. the differences between the current working tree directory and the last committed state), or stash just the current state?

(The following part of my answer is inaccurate. See torek's comment below.) Only the changes between commit B and state of your repo at the moment of git stash will be stashed, not a whole snapshot of the repo (which, if you wanted that, would just be a proper commit.)

4 Comments

Actually, git stash makes two commits, which are perfectly ordinary commits in almost every way. One commit is the result of writing out the current index, and hence is an ordinary commit in every way. The second commit is the result of git adding the work-tree files to a temporary index; its only difference from an ordinary commit is that it has both the current commit and the index commit as its (two) parents, fooling other parts of Git into treating it as a merge commit. The refs/stash reference then points to this second commit. (If you use -a or -u, you get a third commit.)
@torek Thanks. (1) "The second commit is the result of git adding the work-tree files to a temporary index", does this second commit contain all the whole work-tree files, or just the difference between the work tree and HEAD commit? (2) Does that explain why "Only the changes between commit B and state of your repo at the moment of git stash will be stashed, not a whole snapshot of the repo", and how?
@Tim: All commits contain whole files. That's the nature of a commit: it saves some metadata, including a tree object that retains mode/filename/hash-ID entries. The hash ID for each entry is computed from the stored file data. (You could, conceivably, make a file out of diff-listings and save that as a file inside a commit, but that's not what git stash does.) The claim that "only the changes are saved" is quite wrong: Git converts the saved files to changes, by comparing them to some other saved file, when needed.
@torek I knew that logic for the commits themselves, but I see that my understanding of stash entries was quite off ^^ I stand torrected!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.