git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* git stash ; git stash pop unstages all staged changes
@ 2018-01-30 10:05 Martin Häcker
  2018-01-30 19:57 ` Igor Djordjevic
  0 siblings, 1 reply; 2+ messages in thread
From: Martin Häcker @ 2018-01-30 10:05 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 2994 bytes --]

Hi there,

I just lost quite some work, because `git stash; git stash pop` doesn’t seem to understand the concept of the index correctly.

To reproduce:

— snip —
dwt@crest ~/Desktop % mkdir test
dwt@crest ~/Desktop % cd test
dwt@crest ~/Desktop/test % git init
Initialized empty Git repository in /Users/dwt/Desktop/test/.git/
dwt@crest ~/Desktop/test (git)-[master] % touch foo
dwt@crest ~/Desktop/test (git)-[master] % git add foo
dwt@crest ~/Desktop/test (git)-[master] % git commit -m "initial commit"
[master (root-commit) 893b428] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
dwt@crest ~/Desktop/test (git)-[master] % echo "bar" >> foo
dwt@crest ~/Desktop/test (git)-[master] % git status
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:   foo

no changes added to commit (use "git add" and/or "git commit -a")
dwt@crest ~/Desktop/test (git)-[master] % git add foo
dwt@crest ~/Desktop/test (git)-[master] % git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   foo

dwt@crest ~/Desktop/test (git)-[master] % echo "baz" >> foo
dwt@crest ~/Desktop/test (git)-[master] % git diff
diff --git a/foo b/foo
index 5716ca5..e2994c5 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
 bar
+baz
dwt@crest ~/Desktop/test (git)-[master] % git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   foo

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:   foo

dwt@crest ~/Desktop/test (git)-[master] % git stash
Saved working directory and index state WIP on master: 893b428 initial commit
dwt@crest ~/Desktop/test (git)-[master] % git status
On branch master
nothing to commit, working tree clean
dwt@crest ~/Desktop/test (git)-[master] % git stash pop
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:   foo

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (7a8d892120c0a231a529222dabeec1fd3594f514)
dwt@crest ~/Desktop/test (git)-[master] % git diff
diff --git a/foo b/foo
index e69de29..e2994c5 100644
--- a/foo
+++ b/foo
@@ -0,0 +1,2 @@
+bar
+baz

— snap —

What git stash does get right is that it does remove everything that is stashed from the current state of the repo, but what it doesn’t get right is restoring that state fatefully in `git stash pop`.

As a user, I would expect that `git stash pop` undoes the change that `git stash` inflicted.

Best Regards,
Martin Häcker

[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 235 bytes --]

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: git stash ; git stash pop unstages all staged changes
  2018-01-30 10:05 git stash ; git stash pop unstages all staged changes Martin Häcker
@ 2018-01-30 19:57 ` Igor Djordjevic
  0 siblings, 0 replies; 2+ messages in thread
From: Igor Djordjevic @ 2018-01-30 19:57 UTC (permalink / raw)
  To: Martin Häcker; +Cc: git

Hi Marten,

On 30/01/2018 11:05, Martin Häcker wrote:
> 
> I just lost quite some work, because `git stash; git stash pop` 
> doesn’t seem to understand the concept of the index correctly.

I`m afraid it actually seems you`re not fully understanding how `git 
stash pop` works - but the good news is none of your work is lost, as 
long as you have the stash sha1 (or you can find/restore it through 
`git fsck`).

> What git stash does get right is that it does remove everything that 
> is stashed from the current state of the repo, but what it doesn’t 
> get right is restoring that state fatefully in `git stash pop`.

According `git stash pop`[1] documentation, this is as expected, but 
I see the confusing part:

  Remove a single stashed state from the stash list and apply it on top 
  of the current working tree state, i.e., do the inverse operation of 
  `git stash push`. The working directory must match the index.

It clearly says that stash is applied "on top of the current _working 
tree_ state" (so _not_ index), but then it says "i.e., do the inverse 
operation of `git stash push`", which is not exactly true (in regards 
to index handling, no options provided explicitly).

Later below, it notes what to do to restore index as well:

  If the `--index` option is used, then tries to reinstate not only the 
  working tree’s changes, but also the index’s ones. However, this can 
  fail, when you have conflicts (which are stored in the index, where 
  you therefore can no longer apply the changes as they were originally).

> As a user, I would expect that `git stash pop` undoes the change that 
> `git stash` inflicted.

This seems as a fair expectation, especially when documentation 
itself states that `git stash pop` is reverse operation of `git stash 
push`...

As to why `git stash pop` behaves like this, I would leave to someone 
more informed to answer, what I myself managed to dig out so far is that 
it seems `--index` was originally discussed to be a default indeed, 
with `--skip-index` to turn it off if needed, see "[PATCH] Teach 
git-stash to "apply --index""[2] (2007-07-02, Johannes Schindelin) 
(note that `git stash pop` is essentially `git stash apply && git 
stash drop`).

For the reference, here are some similar topics:
 - "[BUG] git stash doesn't use --index as default"[3] (2013-10-11, James)
 - "Asymmetric default behavior of git stash"[4] (2013-08-27, Uwe Storbeck)
 - "Newbie question: Is it possible to undo a stash?"[5] (2008-05-14, Iván V.)

Finally, here`s your demo script, just modified to use `git stash 
pop --index` instead, yielding desired results:

  mkdir test
  cd test
  git init
  touch foo
  git add foo
  git commit -m "initial commit"
  echo "bar" >> foo
  git status
  git add foo
  git status
  echo "baz" >> foo
  git diff
  git status
  git stash
  git status
  git stash pop --index
  git diff


Regards, Buga

[1] https://git-scm.com/docs/git-stash#git-stash-pop--index-q--quietltstashgt
[2] https://public-inbox.org/git/Pine.LNX.4.64.0707021213350.4438@racer.site/T/#u
[3] https://public-inbox.org/git/1381467430.4130.38.camel@freed.purpleidea.com/T/#u
[4] https://public-inbox.org/git/20130827132210.GA14266@ibr.ch/T/#u
[5] https://public-inbox.org/git/509f40850805141256gce6ac1brf5ced6436f81dae8@mail.gmail.com/T/#u

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-01-30 19:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-30 10:05 git stash ; git stash pop unstages all staged changes Martin Häcker
2018-01-30 19:57 ` Igor Djordjevic

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).