git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* unwanted interaction of git stash and cherry-pick --abort
@ 2025-04-20 13:14 Markus Raab
  2025-04-20 13:37 ` brian m. carlson
  0 siblings, 1 reply; 6+ messages in thread
From: Markus Raab @ 2025-04-20 13:14 UTC (permalink / raw)
  To: git

Dear git maintainers,

What did you do before the bug happened? (Steps to reproduce your issue)

git init-db
git commit --allow-empty # needed for git stash later
echo a > a
echo b > b
git add a b # some arbitrary files with content
git stash
git cherry-pick 170bbe5 # any commit that cannot be applied, e.g. the 
initial commit here
git cherry-pick --abort

What did you expect to happen? (Expected behavior)

That a and b are still there or I am somehow informed that the files a 
and b would get lost.

What happened instead? (Actual behavior)

The files a and b are lost.

What's different between what you expected and what actually happened?

Loss of data.

Anything else you want to add:

Everything fine, only the content of a and b is lost ;(


[System Info]
git version:
git version 2.39.5
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 5.10.0-32-amd64 #1 SMP Debian 5.10.223-1 (2024-08-10) x86_64
compiler info: gnuc: 12.2
libc info: glibc: 2.36
$SHELL (typically, interactive shell): /bin/zsh


[Enabled Hooks]

-- 
Best regards,
Markus Raab


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

* unwanted interaction of git stash and cherry-pick --abort
@ 2025-04-20 13:18 Markus Raab
  0 siblings, 0 replies; 6+ messages in thread
From: Markus Raab @ 2025-04-20 13:18 UTC (permalink / raw)
  To: git

Dear git maintainers,

What did you do before the bug happened? (Steps to reproduce your issue)

git init-db
git commit --allow-empty # needed for git stash later
echo a > a
echo b > b
git add a b # some arbitrary files with content
git stash
git cherry-pick 170bbe5 # any commit that cannot be applied, e.g. the 
initial commit here
git stash pop
git cherry-pick --abort

What did you expect to happen? (Expected behavior)

That a and b are still there or I am somehow informed that the files a 
and b would get lost.

What happened instead? (Actual behavior)

The files a and b are lost.

What's different between what you expected and what actually happened?

Loss of data.

Anything else you want to add:

Everything fine, only the content of a and b is lost ;(


[System Info]
git version:
git version 2.39.5
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 5.10.0-32-amd64 #1 SMP Debian 5.10.223-1 (2024-08-10) x86_64
compiler info: gnuc: 12.2
libc info: glibc: 2.36
$SHELL (typically, interactive shell): /bin/zsh


[Enabled Hooks]

-- 
Best regards,
Markus Raab


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

* Re: unwanted interaction of git stash and cherry-pick --abort
  2025-04-20 13:14 unwanted interaction of git stash and cherry-pick --abort Markus Raab
@ 2025-04-20 13:37 ` brian m. carlson
  2025-04-20 13:48   ` Markus Raab
  0 siblings, 1 reply; 6+ messages in thread
From: brian m. carlson @ 2025-04-20 13:37 UTC (permalink / raw)
  To: Markus Raab; +Cc: git

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

On 2025-04-20 at 13:14:31, Markus Raab wrote:
> Dear git maintainers,
> 
> What did you do before the bug happened? (Steps to reproduce your issue)
> 
> git init-db
> git commit --allow-empty # needed for git stash later
> echo a > a
> echo b > b
> git add a b # some arbitrary files with content
> git stash
> git cherry-pick 170bbe5 # any commit that cannot be applied, e.g. the
> initial commit here
> git cherry-pick --abort

Here's the exact shell script I used to test this case:

----
#!/bin/sh

git init-db --object-format=sha256
git commit --allow-empty -m +
oid=$(git rev-parse HEAD)
echo a > a
echo b > b
git add a b # some arbitrary files with content
git stash
git cherry-pick $oid
git cherry-pick --abort
----

> What did you expect to happen? (Expected behavior)
> 
> That a and b are still there or I am somehow informed that the files a and b
> would get lost.
> 
> What happened instead? (Actual behavior)
> 
> The files a and b are lost.
> 
> What's different between what you expected and what actually happened?
> 
> Loss of data.
> 
> Anything else you want to add:
> 
> Everything fine, only the content of a and b is lost ;(

I don't think these are lost.  Because they were added, they were saved
in the stash with `git stash` and can be recovered from there with `git
stash pop`.  `git cherry-pick` won't have done anything to modify the
stashes and in my test case, I can see `git stash list -p` shows both of
those files.

Is this also the case for you or is your situation maybe a little
different?
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 325 bytes --]

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

* Re: unwanted interaction of git stash and cherry-pick --abort
  2025-04-20 13:37 ` brian m. carlson
@ 2025-04-20 13:48   ` Markus Raab
  2025-04-20 21:05     ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Markus Raab @ 2025-04-20 13:48 UTC (permalink / raw)
  To: brian m. carlson, git

Dear Brian,

Thanks for the quick reply.

Unfortunately, I forgot an essential line in my first e-mail, thus I've 
resent my e-mail shortly later again.

To "fix" your shell script (make the files get lost), git stash pop 
should be inserted before the last line:

----
#!/bin/sh

git init-db --object-format=sha256
git commit --allow-empty -m +
oid=$(git rev-parse HEAD)
echo a > a
echo b > b
git add a b # some arbitrary files with content
git stash
git cherry-pick $oid
git stash pop
git cherry-pick --abort
----

So it is basically about unexpected adding of files, that got discarded 
via a "git cherry-pick --abort".

Btw. the files can be recovered via

----
#!/usr/bin/env bash

headcommit="$(git log --format=format:%H)"
headcommitobject=".git/objects/${headcommit:0:2}/${headcommit:2}"
mkdir recovering_lost_files
find .git/objects/ -type f -daystart -ctime 0|while read -r path
do
     obj="${path#.git/objects/}"
     obj="${obj/\/}"
     git cat-file -p $obj > recovering_lost_files/$obj
done
----

best regards,
Markus


Am 20.04.25 um 15:37 schrieb brian m. carlson:
> On 2025-04-20 at 13:14:31, Markus Raab wrote:
>> Dear git maintainers,
>>
>> What did you do before the bug happened? (Steps to reproduce your issue)
>>
>> git init-db
>> git commit --allow-empty # needed for git stash later
>> echo a > a
>> echo b > b
>> git add a b # some arbitrary files with content
>> git stash
>> git cherry-pick 170bbe5 # any commit that cannot be applied, e.g. the
>> initial commit here
>> git cherry-pick --abort
> 
> Here's the exact shell script I used to test this case:
> 
> ----
> #!/bin/sh
> 
> git init-db --object-format=sha256
> git commit --allow-empty -m +
> oid=$(git rev-parse HEAD)
> echo a > a
> echo b > b
> git add a b # some arbitrary files with content
> git stash
> git cherry-pick $oid
> git cherry-pick --abort
> ----
> 
>> What did you expect to happen? (Expected behavior)
>>
>> That a and b are still there or I am somehow informed that the files a and b
>> would get lost.
>>
>> What happened instead? (Actual behavior)
>>
>> The files a and b are lost.
>>
>> What's different between what you expected and what actually happened?
>>
>> Loss of data.
>>
>> Anything else you want to add:
>>
>> Everything fine, only the content of a and b is lost ;(
> 
> I don't think these are lost.  Because they were added, they were saved
> in the stash with `git stash` and can be recovered from there with `git
> stash pop`.  `git cherry-pick` won't have done anything to modify the
> stashes and in my test case, I can see `git stash list -p` shows both of
> those files.
> 
> Is this also the case for you or is your situation maybe a little
> different?


-- 
Best regards,
Markus Raab

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

* Re: unwanted interaction of git stash and cherry-pick --abort
  2025-04-20 13:48   ` Markus Raab
@ 2025-04-20 21:05     ` Junio C Hamano
  2025-04-21  5:38       ` Markus Raab
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2025-04-20 21:05 UTC (permalink / raw)
  To: Markus Raab; +Cc: brian m. carlson, git

Markus Raab <mailinglists@markus-raab.org> writes:

> Dear Brian,
>
> Thanks for the quick reply.
>
> Unfortunately, I forgot an essential line in my first e-mail, thus
> I've resent my e-mail shortly later again.
>
> To "fix" your shell script (make the files get lost), git stash pop
> should be inserted before the last line:
>
> ----
> #!/bin/sh
>
> git init-db --object-format=sha256
> git commit --allow-empty -m +
> oid=$(git rev-parse HEAD)
> echo a > a
> echo b > b
> git add a b # some arbitrary files with content
> git stash
> git cherry-pick $oid
> git stash pop
> git cherry-pick --abort
> ----

So, this is not limited to stash at all.

When you start "cherry-pick", which cannot complete without your
help (most often, this happens when the cherry-picked change
conflicts with what you have in the current commit), the command
stops and gives control back.

At that point, it is up to you to do anything to bring your index
into a shape that you desire the "cherry-picked" commit to have.
You'd do so by editing working tree files (often with conflicts),
creating new files, removing unneeded files, etc., and then updating
your index with these changes, and then "cherry-pick --continue" to
conclude.

Or, after mucking your working tree and index to "correct" the
stalled "cherry-pick", you may decide that it is not a good idea to
cherry-pick the commit after all.  You say "cherry-pick --abort" and
you expect your index to be clean relative to HEAD, and working tree
files also adjusted for it.  You may have edited existing working
tree files, created new files, or removed files that you thought
unneeded, before deciding that it is not a good idea to perform this
cherry-pick.  And the way to ask Git to revert all of these changes
you made to your index and your working tree file, and get you out
of the "cherry-picking" state, is to run "cherry-pick --abort".

Instead of doing "git stash pop" there, you could have added
arbitrary files with content, or edited working tree files, or
any other changes manually, and "cherry-pick --abort" would have
removed such changes to your index and your working tree files, just
the same way.

So there is nothing unexpected.

There is another aspect in this story.

"git stash pop" will remove the stash entry after updating your
index and your working tree files, and unless you save them away
elsewhere, if you make further changes to these files, there is no
easy way to get that exact change you took out of the stash entry
back.

And this is not limited to "cherry-pick --abort".

You can edit these files manually (totally outside of Git), remove
them, or ask Git to give you a clean slate with "git reset --hard".

So one lesson we can learn from this episode is

    Never use "git stash pop" WHEN IT IS POSSIBLE YOU MAY LATER
    CHANGE YOUR MIND.  "pop" applies and then drops the stash entry,
    so what you will have in your index and working tree will become
    the ONLY copy of the change you previously stashed.

If you are in doubt, use "git stash apply" instead.  The stash entry
will stay, so when you decide to get rid of the change you pulled
out of the stash entry into the working tree, you can safely do so
with "reset --hard" and nothing is lost.

Of course, you need to remember at some point to drop the entry you
no longer need with "git stash drop" if you take that approach.

HTH.

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

* Re: unwanted interaction of git stash and cherry-pick --abort
  2025-04-20 21:05     ` Junio C Hamano
@ 2025-04-21  5:38       ` Markus Raab
  0 siblings, 0 replies; 6+ messages in thread
From: Markus Raab @ 2025-04-21  5:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: brian m. carlson, git

Dear maintainers,

Am 20.04.25 um 23:05 schrieb Junio C Hamano:
> Markus Raab <mailinglists@markus-raab.org> writes:
>> To "fix" your shell script (make the files get lost), git stash pop
>> should be inserted before the last line:
>>
>> ----
>> #!/bin/sh
>>
>> git init-db --object-format=sha256
>> git commit --allow-empty -m +
>> oid=$(git rev-parse HEAD)
>> echo a > a
>> echo b > b
>> git add a b # some arbitrary files with content
>> git stash
>> git cherry-pick $oid
>> git stash pop
>> git cherry-pick --abort
>> ----
> 
> So, this is not limited to stash at all.

Yes, it is just how I ran into it. It is neither limited to stash nor 
cherry-pick --abort.

> When you start "cherry-pick", which cannot complete without your
> help (most often, this happens when the cherry-picked change
> conflicts with what you have in the current commit), the command
> stops and gives control back.

This is fine and expected.

> At that point, it is up to you to do anything to bring your index
> into a shape that you desire the "cherry-picked" commit to have.
> You'd do so by editing working tree files (often with conflicts),
> creating new files, removing unneeded files, etc., and then updating
> your index with these changes, and then "cherry-pick --continue" to
> conclude.
> 
> Or, after mucking your working tree and index to "correct" the
> stalled "cherry-pick", you may decide that it is not a good idea to
> cherry-pick the commit after all.  You say "cherry-pick --abort" and
> you expect your index to be clean relative to HEAD, and working tree
> files also adjusted for it. 

What I additionally would have hoped for (hence this bug report) was 
some way to undo the "cherry-pick --abort". A "help for undoing" would 
actually be helpful for many other operations, too.

Actually, I later on found how to undo it, so you might also consider to 
do nothing here.

But if you want to become even more user friendly, you could also 
consider to print a message which would help the user to recover the 
state/files which might have been lost accidentally.

E.g. "git rebase" could print which sha256 was the HEAD before rebase 
and "cherry-pick --abort" could print how to recover the added files 
that were reset etc.

Or an alternative approach would be some "git recover-recent-files", 
"git recover-recent-commits" etc. commands so that the user does not 
have to fiddle manually in .git/objects. Similar to the "go back in 
time" feature in vim (which I rarely use, though).

> Instead of doing "git stash pop" there, you could have added
> arbitrary files with content, or edited working tree files, or
> any other changes manually, and "cherry-pick --abort" would have
> removed such changes to your index and your working tree files, just
> the same way.

Yes, it is the same and I agree the main problem was in the front of the 
keyboard. But things like this happen ;)

> "git stash pop" will remove the stash entry after updating your
> index and your working tree files, and unless you save them away
> elsewhere, if you make further changes to these files, there is no
> easy way to get that exact change you took out of the stash entry
> back.

Yes, so you could take my story as hint to improve the "undo-ability" of 
git in such scenarios.

> So one lesson we can learn from this episode is
> 
>      Never use "git stash pop" WHEN IT IS POSSIBLE YOU MAY LATER
>      CHANGE YOUR MIND.  "pop" applies and then drops the stash entry,
>      so what you will have in your index and working tree will become
>      the ONLY copy of the change you previously stashed.

Yeah, thanks to clearly state it.

> Of course, you need to remember at some point to drop the entry you
> no longer need with "git stash drop" if you take that approach.

Exactly, also a failed "git stash pop" won't get removed, so there 
easily accumulate "forgotten" things in git stashes. But much better to 
have a bit less tidiness then lost files after "git gc". So I think the 
behavior of "git stash pop" itself actually has good "undo-ability".

-- 
Best regards,
Markus Raab

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

end of thread, other threads:[~2025-04-21  5:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-20 13:14 unwanted interaction of git stash and cherry-pick --abort Markus Raab
2025-04-20 13:37 ` brian m. carlson
2025-04-20 13:48   ` Markus Raab
2025-04-20 21:05     ` Junio C Hamano
2025-04-21  5:38       ` Markus Raab
  -- strict thread matches above, loose matches on Subject: below --
2025-04-20 13:18 Markus Raab

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 NNTP newsgroup(s).