Subject: Re: stashing only unstaged changes?

From: Junio C Hamano <[email-masked]>
Date: Fri, 24 Jun 2022 12:47:01 -0700

Ævar Arnfjörð Bjarmason <[email-masked]> writes:

> No, it does work when you stage chunks in the same file, I tested this
> by modifying the top & bottom of our README.md.

This is primarily because of the three-way merge magic.  If you
consider what "git stash pop" does after "git stash push -k"
followed by a "git commit", you can compare the difference between
recorded HEAD and recorded working tree (which is replayed on top of
the result of the "git commit" step) and what is in the working tree
after "git commit".  We do replay both the changes already committed
(and is already in the working tree) and leftover ones (removed from
the working tree when "push -k" was run), and the former is *often*
resolved cleanly as "both sides (meaning: the "stash" and the human
user who did "git commit") made the same change", while the latter
is resolved cleanly because only the "stash" side.

Here, *often* is a key phrase.  If you did a tricky "add -p" that
edited the patch, such a three-way merge may not resolve itself
cleanly.

In addition, if you did something after the "git commit", the former
may get conflicts because what the "working tree" side did may not
match what was in "stash", hence "both sides made the same change"
no longer applies.

The story is very similar when the testing after "git stash push -k"
turned out to be unsuccessful and the user decides not to commit.
"git reset --hard HEAD && git stash pop" is how you would go back to
the state before "git stash push -k" in such a case, but if you edit
between these two operations, you can make "both sides did the same
change" rule not to apply any more.