Subject: [RFC] stash: let the stash stack live in a configurable ref

Vladimir Sitnikov <[email protected]>
Newsgroups org.kernel.vger.git
Message-ID <CAB=Je-GRbyonmkW4qXCuMRQhWcAZE8zc_Xp32hwC1i61bNnjaw@mail.gmail.com>
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

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.