Subject: Re: [PATCH] checkout: add --autostash option for branch switching

From: Junio C Hamano <[email-masked]>
Date: Thu, 12 Mar 2026 07:40:29 -0700

"Harald Nordgren via GitGitGadget" <[email-masked]> writes:

> From: Harald Nordgren <[email-masked]>
>
> When switching branches, local modifications in the working tree can
> prevent the checkout from succeeding.  While "git rebase" and "git
> merge" already support --autostash to handle this case automatically,
> "git checkout" and "git switch" require users to manually stash and
> unstash their changes.
>
> Teach "git checkout" and "git switch" to accept --autostash and
> --no-autostash options that automatically create a temporary stash
> entry before the branch switch begins and apply it after the switch
> completes.  If the stash application results in conflicts, the stash
> entry is saved to the stash list so the user can resolve them later.
>
> Also add a checkout.autoStash configuration option that enables this
> behavior by default, which can be overridden with --no-autostash on
> the command line.

Unconditionally always stash when checkout happens?  This feature as
implemented does not have to be a separate feature.  It can be done
by end-users as a short-cut for "stash" followed by "checkout" via
alias or custom command.

Perhaps doing it this way would make it more worth doing?

 - At the beginning of branch switching, ask a new helper function
   that takes the branch we are switching to as an argument this
   question:

   Do any paths that are different between the current branch and
   the branch we are switching to have local (i.e., either in the
   index or in the working tree) change [Yes/No]?

 - When the answer is "yes", save the local changes to a new stash
   entry, and clear the local changes from the index and from the
   working tree.  If not, do not bother with stash at all.

 - Switch to other branch the usual way.  This will never conflict.

 - If we created a stash entry earlier, try to unstash it.  It may
   conflict or it may not.  

   - If it does not conflict, then we are done.  We drop that stash
     entry, and tell nothing about the stash to the user, as there
     is nothing they can do to the now-consumed stash.

   - If it does conflict, tell the user that the original change is
     in the stash, and can be used to recover if you botch the
     conflict resolution, and also tell the user that they need to
     drop the stash entry once they are done with the change that
     caused this current conflict.

Essentially, the new "autostaash only when needed" would become a
much better reimplementation of the "-m" option.  From the point of
view of a user who is used to "checkout -m", the basic workflow
would be the same, only with vast improvement.

 - It may not conflict and merge cleanly, in which case they do not
   have to do anything.  This is the same as status quo.

 - It may conflict and they find it too involved to resolve right at
   the moment, in which case they now have a choiceto say "git reset
   --hard", essentially declaring "I prioritize working on this new
   branch; I'll deal with the work in progress I started on the
   previous branch later", and then later they can "git stash pop"
   to deal with it.

   Which is a vast improvement over the current "-m" that gives you
   only one chance to resolve it right.

 - It may conflict and they may be able to resolve cleanly, in which
   case they have to remember that they need to do an extra thing
   (i.e., drop the stash we created just in case) but that may not
   be too bad a tradeoff.

If we can sell it as an improved implementation of "-m", we probably
can lose some code that the current "-m" implementation uses to do
its merge; we'd be instead using the "unstash" code paths.

And the new helper function to detect if switching from one commit
to another commit would never conflict can later be used to enhance
"git rebase" as well---we could call it N times to rebase a branch
with N commits and if all steps are clear, we do not have to insist
that there is no local changes like we do currently.

Hmm?