I have a file, let's say file.txt I have done git mv file.txt to file1.txt, then I created a new file called file.txt and worked on it. Unfortunately I didn't add that file to git yet. Anyway the problem is that I did git stash, then git stash apply, but the new file.txt disappeared... anyway to get it back?
The problem here is mostly a misunderstanding of what git stash save
does. It saves only changes to tracked files. Untracked files are not saved by git stash
. When you moved file.txt to file1.txt, the new file.txt is an untracked file and will not be saved by git stash
. This isn't a bug, it's just the way that git stash
behaves. It could be that the documentation for git stash
should be more clear about this.
As the documentation for git stash save
states, it will do a git reset --hard
after saving your changes. It was the git reset --hard
that overwrote the new file.txt. One might argue that git reset --hard
should generate a warning if an untracked file will be overwritten, but I still wouldn't call this a bug. It's doing what it's supposed to do.
The important thing to understand here -- and what would have saved you a lot of trouble -- is that git stash save
does not save untracked files (and it probably shouldn't).
git stash
is rolling back and overwriting uncommitted data, there needs to be some sort of notification. –
Costate git stash
and re-applied by git stash apply
. This is simply the wrong expectation. However, as you say, I think it would be reasonable to get a warning (and prompt for confirmation) if an untracked file will be overwritten by git reset --hard
. –
Frasch git status
has to say about the state of the working tree after the original file is moved and the new one is created -- that pretty much says it all. –
Frasch git reset --hard
, not with git stash save
since the former is the one that overwrites the untracked file without warning. –
Frasch git stash
is the user operation that loses the file contents, so it's a bug in git stash
. It overwrites the modified file with the HEAD version with a reset --hard
. Because stash is resetting to a tracked version of the file, it should make sure that it has saved any version that it's overwriting. git stash
should be a safe operation, it's not like reset --hard
which is asking git to throw things away. I don't believe that the observed stash behaviour is acceptable. –
Chrissa git reset --hard
does do that, and it is the reason why git stash save
is overwriting the untracked file. git stash save
doesn't save untracked files. At the point where git stash save
was run in this case, Git considers file.txt an untracked file. So it isn't and shouldn't be saved. The best you can get is a warning that an untracked file will be overwritten. But it's git reset --hard
that needs to be changed if we want to get that behavior. –
Frasch git stash
to save a file, it needs that file to have a blob representation in the repo. The new file.txt was never added to the index, so Git never generated a blob for that file. Since it doesn't have a blob for the file, there is no way that it can save the file in the stash. You're suggesting that Git start tracking a file (by creating a blob for it) that was never explicitly added. That's simply not how it's designed to work. –
Frasch git stash
is supposed to save your local modifications before performing a reset --hard
. Removing a file, then re-adding one with different contents is surely a local change. git stash; git stash apply
should be a no-op (OK, strictly a git reset). Your argument about there not being a blob for it is clearly bogus. If you have unstaged local modifications to files that haven't been removed from the index then git stash
creates new blobs for the changed files. git stash
already performs a git add -u
so why shouldn't it create blobs all files that it removes? –
Chrissa git stash
to save the new "file.txt" you've got to git add
it first. Is that asking too much? –
Frasch git stash
is behaving exactly as advertised. In no case should it wipe modifications. But if it's going to wipe a file that it knows nothing about (an untracked file), then I personally think it would be a good idea for it to issue a warning (much like git checkout
does in the same circumstance). I absolutely disagree that git stash
should save untracked files under any circumstance. –
Frasch git status
would show the new file as "Changed but not updated". But it doesn't. It clearly shows that Git considers this an untracked file. You seem to be arguing that not only is git stash
broken, but git status
is broken as well. –
Frasch git reset --hard
will wipe out untracked files without warning is questionable. –
Frasch git stash
should undo all the changes between HEAD and the current working tree, also resetting the index to HEAD. git stash
followed immediately by git stash apply
should reset the working tree to the state that it was in before the stash. To me, these are key and inevitably lead to the fact that if HEAD contains a file with a particular contents and the working tree version has a different contents then the state of the working tree file must be saved whether or not the index contains that a version of that file or not. –
Chrissa This looks like serious (i.e. data loss) bug in stash. Please report it. Unfortunately, I don't believe that there's any way to get the new file.txt
back.
This bug has now been fixed in git >=1.7.1.1.
for the future, use git stash -u
to stash uncommitted files (http://www.kernel.org/pub/software/scm/git/docs/git-stash.html) You can do this starting from git version 1.7 i believe.
This is post is to simply illustrate the recreation process without getting crammed into a comment. Note: Using Git version 1.7.0.2
To recreate:
~/test $ git init
~/test $ echo "hello" > file.txt
~/test $ git add .
~/test $ git commit -m "init commit"
~/test $ git mv file.txt file1.txt
~/test $ echo "new data" > file.txt
~/test $ git stash
~/test $ git stash apply
~/test $ cat file.txt
cat: file.txt: No such file or directory
~/test $ cat file1.txt
hello
© 2022 - 2024 — McMap. All rights reserved.