All of lore.kernel.org
 help / color / mirror / Atom feed
* Introduce "git stash --continue" and "git stash --abort"?
@ 2022-06-02 16:40 Tao Klerks
  2022-06-02 18:30 ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Tao Klerks @ 2022-06-02 16:40 UTC (permalink / raw)
  To: git

Hi folks,

I've spent a little time trying to understand how git stash behaves,
and understanding the differences wrt how a "naive user" (eg me?)
would expect it to.

So far most of the differences are about defaults, eg:
* I would expect "git stash push" (or "git stash") to
"--include-untracked" by default
* I would expect "git stash pop" to include "--index" by default
* I would expect "git checkout" (or at least "git switch") to have an
"--autostash" option like "git rebase" and "git merge" do

There's one "bigger" thing though, that sounds like a whole project:
The behavior of "stash pop" in the case of conflicts is somewhat
traumatizing:

* My worktree is left in a "conflicted" state, and the only way to
"back out" seems to be some sort of "reset" (but good luck figuring
out which one, or how to revert the stash-based changes without
impacting any other uncommitted changes that I had in my worktree)

* If I "forge on", resolve the conflicts, and stage the conflicted
files... my stash stack still contains something that I didn't intend
it to, until/unless I remember to "git stash drop"... which is an
unsafe (non-idempotent / not-easily-reversible) operation...

I would expect that some sort of merge- or rebase-like "--continue or
--abort" facility would make this much easier to understand... but of
course I have no idea how one would go about doing that. I assume the
closest existing pattern would be "git cherry-pick", but I imagine I'm
missing lots of subtleties.

I understand Brian M. Carlson has been working on big changes around
stash export, and Victoria Dye has been working on Sparse Index
support, but I'm not aware of any other major ongoing work from
skimming the mailing list in the past months.

Is this kind of direction one that's been considered before? Are there
reasons why it's a bad idea?

Thanks,
Tao

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

* Re: Introduce "git stash --continue" and "git stash --abort"?
  2022-06-02 16:40 Introduce "git stash --continue" and "git stash --abort"? Tao Klerks
@ 2022-06-02 18:30 ` Junio C Hamano
  2022-06-03  8:29   ` Tao Klerks
  0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2022-06-02 18:30 UTC (permalink / raw)
  To: Tao Klerks; +Cc: git

Tao Klerks <tao@klerks.biz> writes:

> I would expect that some sort of merge- or rebase-like "--continue or
> --abort" facility would make this much easier to understand... but of
> course I have no idea how one would go about doing that. I assume the
> closest existing pattern would be "git cherry-pick", but I imagine I'm
> missing lots of subtleties.
> ...
> Is this kind of direction one that's been considered before? Are there
> reasons why it's a bad idea?

I saw a few exchange on the intended use of "stash" on another
thread in the past days, but I think the reason why the current
set of defaults and behaviour are appropriate for "stash" is related
to it.

The intended use of "stash" is to clear the deck as quickly as
possible to deal with "emergencies", and its behaviour comes from
the need to support that use case effectively.  Untracked cruft are
often useful even when you do a "quick context switch" (aka "the
boss suddenly appears and asks you to do something different real
quick"), hence "-u" is not the default, for example.  "stash pop"
was the primary way to go back to where you were before the
interruption, and such going back is expected to be done after the
crisis is over when you can be more relaxed, and was expected to be
done _after_ you "reset --hard" and/or "git switch" out of the
crisis mode.  And the natural way to recover from "eh, I moved back
to a different commit---I wanted to go to the commit I was when I
saved the stash" was "reset --hard" that would not lose anything new
(and "stash branch" was later added to make the last one easier to
do), for another example.

Users are better off doing any large scale "I made a mess in the
working tree with mixed changes, and I want to take time to separate
them out" on separate (possibly temporary) branches, instead of
using "stash save" + "stash pop".  Any change that would make it
more cumbersome for the primary intended purpose of "quick save"
would be very much unwelcome, I would have to say.

Thanks.


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

* Re: Introduce "git stash --continue" and "git stash --abort"?
  2022-06-02 18:30 ` Junio C Hamano
@ 2022-06-03  8:29   ` Tao Klerks
  0 siblings, 0 replies; 3+ messages in thread
From: Tao Klerks @ 2022-06-03  8:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Thu, Jun 2, 2022 at 8:30 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Tao Klerks <tao@klerks.biz> writes:
>
> > I would expect that some sort of merge- or rebase-like "--continue or
> > --abort" facility would make this much easier to understand... but of
> > course I have no idea how one would go about doing that. I assume the
> > closest existing pattern would be "git cherry-pick", but I imagine I'm
> > missing lots of subtleties.
> > ...
> > Is this kind of direction one that's been considered before? Are there
> > reasons why it's a bad idea?
>
> I saw a few exchange on the intended use of "stash" on another
> thread in the past days, but I think the reason why the current
> set of defaults and behaviour are appropriate for "stash" is related
> to it.
>
> The intended use of "stash" is to clear the deck as quickly as
> possible to deal with "emergencies", and its behaviour comes from
> the need to support that use case effectively.

Makes sense, with you so far!

> Untracked cruft are
> often useful even when you do a "quick context switch" (aka "the
> boss suddenly appears and asks you to do something different real
> quick"), hence "-u" is not the default, for example.

I don't understand this statement - I would argue the exact opposite
is true in all the day-to-day usage of git that I have come across.

When I have an untracked file in my working tree, it's normally
because I've created a new script, a new java class, or something like
that. It's normally part of what I'm working on - eg I added a file,
and another might well be referencing it.

If I have "untracked cruft" that doesn't logically belong in my
working code / shouldn't be checked in / doesn't affect the
compilability of my project, then I would typically consider this a
bug in my workflow - either there's a pattern missing in my
".gitignore", or I accidentally redirected some command output into a
temp file in my working folder instead of a more sensible place. I
understand a large segment of the *test suite* relies on git's
"untracked files don't get in the way" behavior, but I don't think
that's representative of real-world usage.

Obviously this is a "personal" thing, but it seems to me that git
would benefit from supporting this worldview - *allowing* stash to
default to -u, and similarly allowing "git commit -a" to refer to
untracked files also, which it does not today.

Anyway, sorry, I'm reacting to the perspective and statement about the
role of untracked files in git working trees here, rather than
anything specific about stashes, I guess this is off-topic.

> "stash pop"
> was the primary way to go back to where you were before the
> interruption, and such going back is expected to be done after the
> crisis is over when you can be more relaxed, and was expected to be
> done _after_ you "reset --hard" and/or "git switch" out of the
> crisis mode.

Yep, makes sense - except this perspective is at odds of course with
the stashes being a stack, and with the idea of attempting to export
stashes at all. I understand these are the *primary* usecases, and
those that need to be best-served, absolutely.

> And the natural way to recover from "eh, I moved back
> to a different commit---I wanted to go to the commit I was when I
> saved the stash" was "reset --hard" that would not lose anything new
> (and "stash branch" was later added to make the last one easier to
> do), for another example.

This explains why stash was implemented to behave the way it does,
sure - it made narrow assumptions about the likely context in which a
stash would be popped; my concern with that is that it does not
enforce those assumptions, so its actual usage in the wild might well
differ significantly from those assumptions, and *when* it does, it
can leave your working tree in a messed up state (a mix of staged and
unstaged changes that had nothing to do with the stash, some staged or
unstaged changes successfully "popped" and some stash-popped conflicts
that you cannot easily "undo" without carefully picking apart the
stash-popped bits from the previously present bits).

>
> Users are better off doing any large scale "I made a mess in the
> working tree with mixed changes, and I want to take time to separate
> them out" on separate (possibly temporary) branches, instead of
> using "stash save" + "stash pop".

I agree with this, especially given that stash pop doesn't give you
any opportunity to "partially pop".

In the usecase that I describe (where you "stash pop" into a working
tree that *already* has unrelated staged or unstaged changes), the
intention is not to use stash to help resolve a mess you made - it's
just to "bring back" that stuff you stashed earlier. Stash pop isn't
being used to fix anything - it is accidentally *creating* a problem
if/when the stash pop encounters conflicts. It is this problem that I
believe could be solved with an --abort/--continue model for stash
conflicts.

> Any change that would make it
> more cumbersome for the primary intended purpose of "quick save"
> would be very much unwelcome, I would have to say.

That makes complete sense, I agree!

I believe introducing --abort/--continue on *conflictive*
stash-popping would absolutely not make those intended uses any more
cumbersome - if anything, it would make them much cleaner/smoother
with a simpler, more consistent and safer "exit" from the conflict in
either direction: if the conflict is resolved, "stash --continue" will
drop the stash without risk of dropping anything else you had in the
stash. If you reconsider, "stash --abort" gets you back to where you
were, without having to think about how safe or dangerous the
operation might be.

It might well not be worthwhile, because stash is so hard to use at
the moment that the standing advice I see around is "don't do it -
you're better off learning how to manage branches and commits in a
sufficiently agile fashion that you never worry about stash, and just
create & drop local branches instead". If stash is rarely used, or
only used by people who already know exactly when it works well and
avoid using it in situations where it causes problems, then it might
not be worth investing in. However, if stash is to graduate to a
simple to use and reasonably safe facility, then I would expect this
to make sense from a functional perspective.

On the other hand, I understand that each --abort/--continue
conflict-management flow probably requires/implies another
special/dedicated "working tree state" that tools (eg git-prompt), git
commands, third-party git libraries, and GUI clients need to know
about, so I'm guessing the overhead on something like this is
prohibitive? When was the last time something like this was done?

Thanks,
Tao

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

end of thread, other threads:[~2022-06-03  8:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 16:40 Introduce "git stash --continue" and "git stash --abort"? Tao Klerks
2022-06-02 18:30 ` Junio C Hamano
2022-06-03  8:29   ` Tao Klerks

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.