Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git stash issue

Tags:

git

git-stash

I have an issue in git stash.

Say for example I have 3 files say a.txt,b.txt & c.txt in the repo and the directory is clean.

Now I'm modifying 2 files among them : a.txt and b.txt.

Now I havent completed my changes in thw two files so I am stashing them by the foll command:

$ git stash save "First Stash"

No if I do a $ git stash list, I get

stash@{0}: On master: First Stash

No if I modify the third text file c.txt and stash that as well as shown:

$ git stash save "Second Stash"

No finally if I do a $git stash list I'm getting the foll result,

stash@{0}: On master: Second stash
stash@{1}: On master: First Stash

The stash number and the messages are mixed up here.What's going on here? Now if i pop the stash@{0} I get the first stash contents but the message reversed here which is displaying as Second stash but should have been First Stash.

This is my work flow

admin:stud:/demo/stash_demo> ls
a.txt  b.txt
admin:stud:/demo/stash_demo> echo Hello World >> a.txt
admin:stud:/demo/stash_demo> git stash save "First"
Saved working directory and index state On master: First
HEAD is now at cff03c6 Initail Commit
admin:stud:/demo/stash_demo> echo Hello World >> b.txt
admin:stud:/demo/stash_demo> git stash save "Second"
Saved working directory and index state On master: Second
HEAD is now at cff03c6 Initail Commit

These are my available stashes:

admin:stud:/demo/stash_demo> git stash list
stash@{0}: On master: Second
stash@{1}: On master: First

Now I''ll be trying to apply the stash@{1} which is the first stash and should apply the file a.txt

admin:stud:/demo/stash_demo> git stash apply `stash@{1}`
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   b.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

As seen above I get the most recent changes applied.

And if i try without the ticks `` then it gives me the foll error.

admin:stud:/demo/stash_demo> git stash apply stash@{1}
fatal: ambiguous argument 'stash@1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
like image 586
david.colais Avatar asked Jan 29 '13 12:01

david.colais


2 Answers

Git's stash is (by default) a LIFO storage.

By using git stash apply or git stash pop you will always get the last stashed patch (which can be also referenced using stash@{0}, 0 is the index inside the stash). Stashing a new patch will place it on top of other stashed patches, thus increasing their indices by one (stash@{0} will become stash@{1}).

That said, if you want to apply or pop a patch other than the last one stashed, you need pass its ref to the command:

$ git stash apply stash@{1}
like image 76
Koraktor Avatar answered Oct 18 '22 06:10

Koraktor


they are not mixed up!

Stashing stores the "commits" (not the correct word here, I know) in a Stack:

http://en.wikipedia.org/wiki/Stack_(abstract_data_type)

so the operation pop always gets you the last thing you put in there.

This behaviour is by design

edit: if you need to flip something around, then pop each item in the stack(stash) individually - do a real commit - and interactive rebase or whatever ..

edit/edit: do a

git stash pop 

then commit your changes (regardless of whether this commit is usefull or not)

then do a git stash pop again, commit again

now you can reorder or delete single commits - take a look here: http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html or search for interactive rebasing (again .. the next time do a branch this concept is much more powerfull then stashing)

like image 26
Stephan Avatar answered Oct 18 '22 07:10

Stephan