All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Vladimir Sitnikov <sitnikov.vladimir@gmail.com>, git@vger.kernel.org
Cc: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>
Subject: Re: Subject: [RFC] stash: let the stash stack live in a configurable ref
Date: Mon, 24 Aug 2026 10:13:37 +0100	[thread overview]
Message-ID: <91feddb6-0d1b-42af-9942-307b98aa747d@gmail.com> (raw)
In-Reply-To: <CAB=Je-GRbyonmkW4qXCuMRQhWcAZE8zc_Xp32hwC1i61bNnjaw@mail.gmail.com>

Hi Vladimir

On 23/08/2026 15:19, Vladimir Sitnikov wrote:
> Hi,
> 
> refs/stash is shared by the main checkout and every linked worktree, so
> two worktrees push onto and pop from the same stack.  With git 2.52.0:
> 
>      git init wt-a && cd wt-a
>      git commit --allow-empty -m base
>      git worktree add ../wt-b -b b
> 
>      echo A >file-a && git add file-a
>      git stash push -m "worktree A: half-finished refactor"
> 
>      cd ../wt-b
>      echo B >file-b && git add file-b
>      git stash push -m "worktree B: unrelated fix"
>      git stash pop      # worktree B's own entry, as expected
>      git stash pop      # worktree A's entry, applied here

When I'm not trying to move changes between branches I associate a stash 
with the branch that's checked out when it is created, not the worktree 
where that the branch happens to be checked out. We already record the 
branch name when creating the stash so perhaps we should add an option 
to pop the last stash that was created on the current branch. Assuming 
agents are working on a branch rather than a detached HEAD that would 
stop them from treading on each others toes and it would mean it is 
still easy to move stashed changes between branches/worktrees when 
needed. It also makes it easy to retrieve a stash for the current branch 
that was created when the branch was checked out in a different 
worktree. If an agent really needs a private stash it can use "git stash 
create" and record the oid of the stash under "refs/worktree/".

On a related note I've been meaning to add an option to specify an 
alternative branch name when creating a stash, so that "git checkout -m" 
and "git rebase --autostash <upstream> <branch>" can record the branch 
that we're switching to, rather than the one that's currently checked 
out when creating stashes.

Thanks

Phillip

> After the second pop, wt-b holds both file-a and file-b, and wt-a has an
> empty stash and a clean tree.  Nothing warned about it, and the entry is
> gone from the stack, so wt-a has no way to find out where its changes
> went.
> 
> This is documented behavior: git-worktree(1) lists refs/bisect,
> refs/worktree and refs/rewritten as the per-worktree exceptions, and
> refs/stash is not among them.  For a human who drives one worktree at a
> time it is mostly harmless, and sharing is occasionally useful - stash
> in one worktree, apply in another, as a way to move work across
> checkouts.
> 
> What changed is who runs these commands.  Running one coding agent per
> worktree, against one repository, has become a common setup, and the
> agents stash and pop on their own schedule.  The failure above then
> turns into silent data movement between unrelated sessions.  The same
> report has already been filed against at least two such tools:
> 
>      https://github.com/github/copilot-cli/issues/1725
>      https://github.com/stablyai/orca/issues/13695
> 
> I would like to propose a configuration knob rather than a new concept,
> because most of the machinery is already in the tree:
> 
>    - refs/worktree/* is per-worktree, so a private stack has somewhere
>      to live;
>    - `git stash export --to-ref` and `git stash import` already read and
>      write a stash stack under an arbitrary ref;
>    - extensions.worktreeConfig and `git config --worktree` already give
>      a worktree its own configuration.
> 
> The missing piece is telling stash itself which ref to use.  Say
> stash.ref, defaulting to refs/stash, honored by push, save, list,
> show, pop, apply, drop, branch and clear.  A worktree that wants
> isolation then asks for it once:
> 
>      git config extensions.worktreeConfig true
>      git config --worktree stash.ref refs/worktree/stash
> 
> Nothing changes for anyone who does not set it, and the tools that
> manage worktrees for agents can set it when they create a worktree.
> 
> Alternatives I considered and rejected:
> 
>    - Making the stash per-worktree unconditionally.  It breaks the
>      stash-here-apply-there workflow, and it moves existing entries out
>      from under scripts.  If that is the destination, it belongs in
>      Documentation/BreakingChanges.adoc for Git 3.0, with a warning
>      released first - but it does not have to block a knob today.
> 
>    - Named stashes.  A name that survives a push by another process is
>      what a ref already is, so this would grow a second naming scheme
>      over the one branches and tags already use, plus commands to list
>      and delete those names.
> 
>    - Leaving it to tooling.  It works - `git stash create` writes a
>      stash commit without touching any ref, so a wrapper can store it
>      under refs/worktree/<name> and apply it later - but every tool
>      reimplements it, and the failure mode for anyone who does not is
>      silent.
> 
> Points I am not sure about, and where I would like guidance before
> writing a patch:
> 
>    - Whether stash.ref is the right name, and whether it should be
>      restricted to refs/ (rejecting a value that is not a ref name).
> 
>    - Whether `git stash list` should be able to show the other stacks -
>      a worktree's entries becoming invisible to the main checkout is the
>      cost of the knob, and `git stash list --all` over
>      worktrees/*/refs/worktree/stash might be a reasonable answer.
> 
>    - Reachability.  fsck and reflog expiry learned to iterate
>      per-worktree refs, and I would like a second opinion on whether
>      stash entries under refs/worktree/* are safe from gc in the same
>      way refs/stash entries are.
> 
> If the direction sounds reasonable, I am happy to write the patch.
> 
> Thanks,
> Vladimir Sitnikov
> 


  parent reply	other threads:[~2026-08-24  9:13 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-23 14:19 Subject: [RFC] stash: let the stash stack live in a configurable ref Vladimir Sitnikov
2026-08-23 15:54 ` Kristoffer Haugsbakk
2026-08-24  9:13 ` Phillip Wood [this message]
2026-08-24 14:58   ` Junio C Hamano
2026-08-25 14:43     ` Phillip Wood
2026-08-25 17:38       ` Junio C Hamano
2026-08-25 18:24         ` Vladimir Sitnikov
2026-08-26 10:08           ` Phillip Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=91feddb6-0d1b-42af-9942-307b98aa747d@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=sitnikov.vladimir@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.