tags:

views:

50

answers:

1

Ok, so i have run into this a few times and it's really annoying. Scenario:

modify a file say a.txt (add say two lines)
stash it
stash apply
git reset
remove the two lines added to a.txt because you want to commit and push these partial  changes
git add a.txt
git commit the above, and push the changes (push irrelevant for this discussion)
git reset --hard
now do git stash apply

Now, a.txt is the same version as was committed, it should be the version that i stashed. Thus i have now lost my changes to a.txt. If i go back one commit, ie. git co head~1 and apply my stash it still doesn't work.

A fix would be much appreciated.

Thanks.

Okay, so i tried extensively with a script to reproduce this, trying many variations of merge commits etc and could not get reproduce it. Unfortunately it's very difficult in a script for me to reproduce the complexity of the source tree i was working on when this happened. The one other caviat i'm thinking of now is that i had multiple stashes based on different versions of the same branch, with some files pushed, some files committed locally that were in those stashes. My commands only ever applied the last stash as described earlier, but during this whole process, i lost 2 stashes, they just disappeared when executing git stash list. So i maybe this somehow also affects the outcome. If anybody runs into anything similar please update this thread. If anybody is interested in taking my testing further, i can post my script (completely self contained, creates the repository and everything). In the mean time i will continue using git and the next time it happens maybe i get a better idea of what happened.

Also this happened at work, hence why i can't supply original code, but i will take a look at the gitk results again and post my findings as that might help.

Thanks for all the help!

Ok, so looking at gitk shows that my stash is based on an index (which i think is normal), then that index is based off of a commit, that seems to only exist in the stash (this does not make sense. Ie. the save has the commit message i gave it when i committed it to my private branch, but somehow, my private branch does not have that commit as part of the gitk path.

+1  A: 

Okay, I just followed your sequence of instructions, and what I get is:

$ # Update a.txt
$ git stash
$ git stash apply
$ git reset
$ git add a.txt
$ git commit -m "Updated a.txt"

The git stash apply re-applies the changes you made to a.txt that you just saved in the stash.

The git reset clears the index, but leaves the working directory alone.

The git add and git commit save the changes to a.txt that you meant to stash for later use.

But, besides for possibly misunderstanding what you are doing, it looks like you may benefit from git add --patch. That allows you to add individual changes to a file, without adding all of the changes in that file.

Jonathan
that is not the workflow i described. I made some experimental changes to file a.txt, then i stashed them, then i reverted some of the stashed experimental changes so i could commit the file and push it. a.txt is not the only file stashed, there are many others.
Coder
shoot i just realized my text was formatted as a paragraph, making it hard to read, my apologies. I have updated the problem description to be more clear.
Coder
thanks for the suggestion, but again, that's not what i'm doing. I have a lot of experimental changes, including adding 2 lines in a.txt. I stash these changes on my private branch, then i reapply the changes, but only add a.txt to be committed, however, i don't want to commit a.txt as is because it will break the master branch, so i revert 1 of the two lines i added to it (both of which are in my stash), then i commit and push it. However i want to continue developing my functionality, so i want both lines restored to a.txt when i apply the stash, but nothing is restored to a.txt.
Coder
I haven't used git add --patch, i'm not sure if that's flexible enough for what i need, but to me the above scenario should work. I think of git stash as zipping up all my modified files somewhere, resetting then when i'm done overwriting my local changes with the zip file. However git stash also does merges which is nice, but i would never expect to LOSE my changes that are in the stash or not be able to get at them at all.
Coder
Could you please update your question with an actual list of commands that will produce this behavior? I'm having difficulty doing it myself.
Jonathan
did you try after after i updated the description of the problem? I will try to reproduce it again. I'm using msysgit on windows if that helps
Coder
I have tried reproducing it again and have had no luck. This time git merged the file and gave me the old conflict ==== signs in the file. This is extremely strange as these are the steps i took. It might be related to having new files in my stash that have never been committed before, or working off of a private branch which is liked to another branch in the public repo, or more complicated changes in a.txt. I simplified the steps above, but the problem happened on netbeans project files NB 6.9 (committed into Git). What i added was a new test and src path to the project which i reverted.
Coder
Thanks for trying, i will hopefully update as i run into this problem again as this was not the first time. Oh, i also did a rebase before or after the stash (actually i'm almost 100% that it was after) as i did not want to have modified files while doing the rebase, not sure if it would have worked if i did. The rebase was from my private branch onto the local public branch, and my private branch had a merge commit as well. I'm thinking this likely has something to do with it. I noticed that as i commit things, i lose whole stashes. Ie. i had stash${0}-5 and after some commits i ....
Coder
lost 2 stashes, at index 1 and 3 or something like that, so i don't know how git tracks stashes and commits, but this also concerned me.
Coder
A few pointers: 1) `git stash` does not save untracked files. So if you had not yet committed `a.txt` and you did a `git stash`, the file would remain unchanged and would not be stashed. 2) Rebasing should not affect the stash; otherwise you could not do `git stash; git rebase; git stash apply` to temporarily save your working directory changes while you update to the latest code. Hopefully you won't run into the same problem again, it sounds very frustrating.
Jonathan
It is very frustrating, thanks for the suggestions, however one important correction to what you just said. Git does stash uncommitted files as long as they are added to the index. Which is what i did. I am 100% sure that the file that had the problem was in the index. I had no untracked files.
Coder