Discussion:
[bug] [UX] `stash save --untracked` produces a stash that *looks* empty
Alberto Scotto
2014-10-05 17:28:45 UTC
Permalink
Hi all,

I've just found that:
- given you have an empty staging area
- and you have only untracked files in your working dir
- when you do `git stash --untracked`
- then `git stash show` gives you an empty output => stash looks empty

My first thought was "oh god, my files are lost!"
Second thought: "Jeez I found a bug in git! cool!"
Then I found that actually `git stash apply` restores the apparently lost
files
So I think it's a UX issue.
It cost me a few lost files already, as I thought "an empty stash? uhm..
can't remember what/when I stashed.. whatever.. let's just delete it and
clean up a little bit this mess of stashes".


Here are the reproducible steps:

1. create new fresh git repo in $REPO_DIR
2. create a couple of files/dirs and commit
3. edit src/MyClass.java and commit
4. create dir src/new-dir with one file inside
5. edit file.txt and stage it
6. stash => stashes staged changes; only untracked files are left
7. stash -u => stashes untracked changes => working dir is clean
8. stash list
9. git stash show -p => empty output
10. git stash apply (restore stashed untracked files)


I made a bash script that runs through those steps.
Please check it out.
https://gist.github.com/alb-i986/a4002f1ac50ce355278e

Envs:

- Mac OSX 10.9.5
- Darwin 13.4.0 Darwin Kernel Version 13.4.0: Sun Aug 17 19:50:11 PDT
2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64
- git version 1.9.3 (Apple Git-50)
- GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
- Ubuntu precise <-
https://github.com/alb-i986/vagrantfiles/tree/master/basic
- Linux precise64 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51
UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
- git version 1.7.9.5
- GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)


Thank you


Alberto Scotto
http://alb-i986.me
Tanay Abhra
2014-10-08 09:20:14 UTC
Permalink
Post by Alberto Scotto
Hi all,
- given you have an empty staging area
- and you have only untracked files in your working dir
- when you do `git stash --untracked`
- then `git stash show` gives you an empty output => stash looks empty
My first thought was "oh god, my files are lost!"
Second thought: "Jeez I found a bug in git! cool!"
Then I found that actually `git stash apply` restores the apparently lost
files
So I think it's a UX issue.
It cost me a few lost files already, as I thought "an empty stash? uhm..
can't remember what/when I stashed.. whatever.. let's just delete it and
clean up a little bit this mess of stashes".
1. create new fresh git repo in $REPO_DIR
2. create a couple of files/dirs and commit
3. edit src/MyClass.java and commit
4. create dir src/new-dir with one file inside
5. edit file.txt and stage it
6. stash => stashes staged changes; only untracked files are left
7. stash -u => stashes untracked changes => working dir is clean
8. stash list
9. git stash show -p => empty output
10. git stash apply (restore stashed untracked files)
Hi,

I think problem lies with show_stash() which just shows the
diff between working tree and the base tree, it ignores the
untracked files. A quick and dirty fix can be to just show
the diff between the untracked files and a NULL commit.
Here's the patch, it works all right but can be implemented
much better. I will try to find a better approach tomorrow.

diff --git a/git-stash.sh b/git-stash.sh
index d4cf818..7088584 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -304,6 +304,8 @@ show_stash () {
assert_stash_like "$@"

git diff ${FLAGS:---stat} $b_commit $w_commit
+ empty_tree=$(git hash-object -t tree /dev/null)
+ git diff ${FLAGS:---stat} ${empty_tree} $u_commit
}

#

Cheers,
Tanay
Jeff King
2014-10-09 02:51:12 UTC
Permalink
Post by Tanay Abhra
I think problem lies with show_stash() which just shows the
diff between working tree and the base tree, it ignores the
untracked files. A quick and dirty fix can be to just show
the diff between the untracked files and a NULL commit.
Here's the patch, it works all right but can be implemented
much better. I will try to find a better approach tomorrow.
You may want to read through another recent attempt at the same thing
here:

http://thread.gmane.org/gmane.comp.version-control.git/254420

It ended with us just making "git stash list" behave like "git stash
show" (and show only the working tree); that ended up as 288c67c (stash:
default listing to working-tree diff, 2014-08-06).

Which isn't to say there isn't room for more improvement. But you may
find the backstory and pitfalls helpful (and I think Junio explicitly
said he prefers the current behavior in that thread).

-Peff

Loading...