{"thread":{"id":"66209","subject":"Subject: [RFC] stash: let the stash stack live in a configurable ref","startedAt":"2026-08-23T14:19:25Z","lastAt":"2026-08-26T10:08:58Z","messageCount":8,"participants":["Vladimir Sitnikov","Kristoffer Haugsbakk","Phillip Wood","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"551074","messageId":"CAB=Je-GRbyonmkW4qXCuMRQhWcAZE8zc_Xp32hwC1i61bNnjaw@mail.gmail.com","threadId":"66209","inReplyTo":null,"subject":"Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Vladimir Sitnikov","fromEmail":"sitnikov.vladimir@gmail.com","sentAt":"2026-08-23T14:19:11Z","receivedAt":"2026-08-23T14:19:25Z","isPatch":false,"body":"Hi,\n\nrefs/stash is shared by the main checkout and every linked worktree, so\ntwo worktrees push onto and pop from the same stack.  With git 2.52.0:\n\n    git init wt-a && cd wt-a\n    git commit --allow-empty -m base\n    git worktree add ../wt-b -b b\n\n    echo A >file-a && git add file-a\n    git stash push -m \"worktree A: half-finished refactor\"\n\n    cd ../wt-b\n    echo B >file-b && git add file-b\n    git stash push -m \"worktree B: unrelated fix\"\n    git stash pop      # worktree B's own entry, as expected\n    git stash pop      # worktree A's entry, applied here\n\nAfter the second pop, wt-b holds both file-a and file-b, and wt-a has an\nempty stash and a clean tree.  Nothing warned about it, and the entry is\ngone from the stack, so wt-a has no way to find out where its changes\nwent.\n\nThis is documented behavior: git-worktree(1) lists refs/bisect,\nrefs/worktree and refs/rewritten as the per-worktree exceptions, and\nrefs/stash is not among them.  For a human who drives one worktree at a\ntime it is mostly harmless, and sharing is occasionally useful - stash\nin one worktree, apply in another, as a way to move work across\ncheckouts.\n\nWhat changed is who runs these commands.  Running one coding agent per\nworktree, against one repository, has become a common setup, and the\nagents stash and pop on their own schedule.  The failure above then\nturns into silent data movement between unrelated sessions.  The same\nreport has already been filed against at least two such tools:\n\n    https://github.com/github/copilot-cli/issues/1725\n    https://github.com/stablyai/orca/issues/13695\n\nI would like to propose a configuration knob rather than a new concept,\nbecause most of the machinery is already in the tree:\n\n  - refs/worktree/* is per-worktree, so a private stack has somewhere\n    to live;\n  - `git stash export --to-ref` and `git stash import` already read and\n    write a stash stack under an arbitrary ref;\n  - extensions.worktreeConfig and `git config --worktree` already give\n    a worktree its own configuration.\n\nThe missing piece is telling stash itself which ref to use.  Say\nstash.ref, defaulting to refs/stash, honored by push, save, list,\nshow, pop, apply, drop, branch and clear.  A worktree that wants\nisolation then asks for it once:\n\n    git config extensions.worktreeConfig true\n    git config --worktree stash.ref refs/worktree/stash\n\nNothing changes for anyone who does not set it, and the tools that\nmanage worktrees for agents can set it when they create a worktree.\n\nAlternatives I considered and rejected:\n\n  - Making the stash per-worktree unconditionally.  It breaks the\n    stash-here-apply-there workflow, and it moves existing entries out\n    from under scripts.  If that is the destination, it belongs in\n    Documentation/BreakingChanges.adoc for Git 3.0, with a warning\n    released first - but it does not have to block a knob today.\n\n  - Named stashes.  A name that survives a push by another process is\n    what a ref already is, so this would grow a second naming scheme\n    over the one branches and tags already use, plus commands to list\n    and delete those names.\n\n  - Leaving it to tooling.  It works - `git stash create` writes a\n    stash commit without touching any ref, so a wrapper can store it\n    under refs/worktree/<name> and apply it later - but every tool\n    reimplements it, and the failure mode for anyone who does not is\n    silent.\n\nPoints I am not sure about, and where I would like guidance before\nwriting a patch:\n\n  - Whether stash.ref is the right name, and whether it should be\n    restricted to refs/ (rejecting a value that is not a ref name).\n\n  - Whether `git stash list` should be able to show the other stacks -\n    a worktree's entries becoming invisible to the main checkout is the\n    cost of the knob, and `git stash list --all` over\n    worktrees/*/refs/worktree/stash might be a reasonable answer.\n\n  - Reachability.  fsck and reflog expiry learned to iterate\n    per-worktree refs, and I would like a second opinion on whether\n    stash entries under refs/worktree/* are safe from gc in the same\n    way refs/stash entries are.\n\nIf the direction sounds reasonable, I am happy to write the patch.\n\nThanks,\nVladimir Sitnikov\n"},{"id":"551081","messageId":"4a9dd6d8-f5ff-4579-82a6-01ea2f1474f0@app.fastmail.com","threadId":"66209","inReplyTo":"CAB=Je-GRbyonmkW4qXCuMRQhWcAZE8zc_Xp32hwC1i61bNnjaw@mail.gmail.com","subject":"Re: Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-08-23T15:54:45Z","receivedAt":"2026-08-23T15:55:10Z","isPatch":false,"body":"On Sun, Aug 23, 2026, at 16:19, Vladimir Sitnikov wrote:\n> refs/stash is shared by the main checkout and every linked worktree, so\n> two worktrees push onto and pop from the same stack.  With git 2.52.0:\n>\n>     git init wt-a && cd wt-a\n>     git commit --allow-empty -m base\n>     git worktree add ../wt-b -b b\n>\n>     echo A >file-a && git add file-a\n>     git stash push -m \"worktree A: half-finished refactor\"\n>\n>     cd ../wt-b\n>     echo B >file-b && git add file-b\n>     git stash push -m \"worktree B: unrelated fix\"\n>     git stash pop      # worktree B's own entry, as expected\n>     git stash pop      # worktree A's entry, applied here\n>\n> After the second pop, wt-b holds both file-a and file-b, and wt-a has an\n> empty stash and a clean tree.  Nothing warned about it, and the entry is\n> gone from the stack, so wt-a has no way to find out where its changes\n> went.\n>\n> This is documented behavior: git-worktree(1) lists refs/bisect,\n> refs/worktree and refs/rewritten as the per-worktree exceptions, and\n> refs/stash is not among them.\n\nYes. Both the existing behavior and per-worktree stashes are useful in\nthe abstract:\n\n• I sometimes make changes in the wrong worktree and then just push\n  there and pop in the correct one. So it has practical uses. But it\n  doesn’t feel like it jives with modern Git (Git 2015, when worktrees\n  came). It does not feel elegant.\n• Pushing and popping in isolation also makes sense and surely has just\n  as many practical uses for people who both use worktrees and the stash\n  compared to someone who only uses the stash.\n\nIf not for hysterical raisins, I think per-worktree would make sense as\nthe default. But with history in mind a configuration option makes the\nmost sense.\n\n> For a human who drives one worktree at a\n> time it is mostly harmless, and sharing is occasionally useful - stash\n> in one worktree, apply in another, as a way to move work across\n> checkouts.\n\nI see the narrative crescendo in the first clause.\n\nI don’t see how it is mostly harmless. Yes, it is useful, but it could\nalso be confusing because it IMO isn’t consistent with (again IMO)\nmodern Git with worktrees. So people might only get confused while using\nGit all manually, stalling the current session and sending them to ask\nSO/LLM; there is no massively parallel cluster of Git sessions going off\nthe rails as one automated entity creates a merge conflict that somehow\ncascades and wastes many dollars.\n\nBut the bar for introducing configuration options for porcelain commands\nfor can’t-break-default has always been, my my knowledge, those lone\nmanual sessions that merely get stalled and leads to confusion in the\nperson operator. So this could be worth implementing just based on\nthat. (And it benefiting other cases is also great.)\n\n>\n> What changed is who runs these commands.\n\nThe reveal.\n\n> Running one coding agent per\n> worktree, against one repository, has become a common setup, and the\n> agents stash and pop on their own schedule.  The failure above then\n> turns into silent data movement between unrelated sessions.  The same\n> report has already been filed against at least two such tools:\n>\n>     https://github.com/github/copilot-cli/issues/1725\n>     https://github.com/stablyai/orca/issues/13695\n\nTo my uninformed, not-using-agents mind, what agents do with the tool\nseems like the least concerning thing. They can be non-deterministically\ninstructed to not use the stash.\n\nThe stash has already been optional, something that you can achieve with\nthe other porcelain commands. So any code-changing entity can adapt to\nnot being allowed to use the stash.\n\nAnd for determinism you can give them a git(1) wrapper that bans\ngit-stash(1).\n\n>\n> I would like to propose a configuration knob rather than a new concept,\n> because most of the machinery is already in the tree:\n>\n>   - refs/worktree/* is per-worktree, so a private stack has somewhere\n>     to live;\n>   - `git stash export --to-ref` and `git stash import` already read and\n>     write a stash stack under an arbitrary ref;\n>   - extensions.worktreeConfig and `git config --worktree` already give\n>     a worktree its own configuration.\n>\n> The missing piece is telling stash itself which ref to use.  Say\n> stash.ref, defaulting to refs/stash, honored by push, save, list,\n> show, pop, apply, drop, branch and clear.  A worktree that wants\n> isolation then asks for it once:\n>\n>     git config extensions.worktreeConfig true\n>     git config --worktree stash.ref refs/worktree/stash\n\nOpting in to `refs/worktree/stash` makes sense.\n\n>[snip]\n>   - Reachability.  fsck and reflog expiry learned to iterate\n>     per-worktree refs, and I would like a second opinion on whether\n>     stash entries under refs/worktree/* are safe from gc in the same\n>     way refs/stash entries are.\n\nSee gitdatamodel(7).\n\n    Git may delete objects that aren’t \"reachable\" from any reference or\n    reflog.\n\nAny particular ref namespace is not special with regards to\nreachability and GC.\n\n>[snip]\n"},{"id":"551114","messageId":"91feddb6-0d1b-42af-9942-307b98aa747d@gmail.com","threadId":"66209","inReplyTo":"CAB=Je-GRbyonmkW4qXCuMRQhWcAZE8zc_Xp32hwC1i61bNnjaw@mail.gmail.com","subject":"Re: Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-24T09:13:37Z","receivedAt":"2026-08-24T09:13:44Z","isPatch":false,"body":"Hi Vladimir\n\nOn 23/08/2026 15:19, Vladimir Sitnikov wrote:\n> Hi,\n> \n> refs/stash is shared by the main checkout and every linked worktree, so\n> two worktrees push onto and pop from the same stack.  With git 2.52.0:\n> \n>      git init wt-a && cd wt-a\n>      git commit --allow-empty -m base\n>      git worktree add ../wt-b -b b\n> \n>      echo A >file-a && git add file-a\n>      git stash push -m \"worktree A: half-finished refactor\"\n> \n>      cd ../wt-b\n>      echo B >file-b && git add file-b\n>      git stash push -m \"worktree B: unrelated fix\"\n>      git stash pop      # worktree B's own entry, as expected\n>      git stash pop      # worktree A's entry, applied here\n\nWhen I'm not trying to move changes between branches I associate a stash \nwith the branch that's checked out when it is created, not the worktree \nwhere that the branch happens to be checked out. We already record the \nbranch name when creating the stash so perhaps we should add an option \nto pop the last stash that was created on the current branch. Assuming \nagents are working on a branch rather than a detached HEAD that would \nstop them from treading on each others toes and it would mean it is \nstill easy to move stashed changes between branches/worktrees when \nneeded. It also makes it easy to retrieve a stash for the current branch \nthat was created when the branch was checked out in a different \nworktree. If an agent really needs a private stash it can use \"git stash \ncreate\" and record the oid of the stash under \"refs/worktree/\".\n\nOn a related note I've been meaning to add an option to specify an \nalternative branch name when creating a stash, so that \"git checkout -m\" \nand \"git rebase --autostash <upstream> <branch>\" can record the branch \nthat we're switching to, rather than the one that's currently checked \nout when creating stashes.\n\nThanks\n\nPhillip\n\n> After the second pop, wt-b holds both file-a and file-b, and wt-a has an\n> empty stash and a clean tree.  Nothing warned about it, and the entry is\n> gone from the stack, so wt-a has no way to find out where its changes\n> went.\n> \n> This is documented behavior: git-worktree(1) lists refs/bisect,\n> refs/worktree and refs/rewritten as the per-worktree exceptions, and\n> refs/stash is not among them.  For a human who drives one worktree at a\n> time it is mostly harmless, and sharing is occasionally useful - stash\n> in one worktree, apply in another, as a way to move work across\n> checkouts.\n> \n> What changed is who runs these commands.  Running one coding agent per\n> worktree, against one repository, has become a common setup, and the\n> agents stash and pop on their own schedule.  The failure above then\n> turns into silent data movement between unrelated sessions.  The same\n> report has already been filed against at least two such tools:\n> \n>      https://github.com/github/copilot-cli/issues/1725\n>      https://github.com/stablyai/orca/issues/13695\n> \n> I would like to propose a configuration knob rather than a new concept,\n> because most of the machinery is already in the tree:\n> \n>    - refs/worktree/* is per-worktree, so a private stack has somewhere\n>      to live;\n>    - `git stash export --to-ref` and `git stash import` already read and\n>      write a stash stack under an arbitrary ref;\n>    - extensions.worktreeConfig and `git config --worktree` already give\n>      a worktree its own configuration.\n> \n> The missing piece is telling stash itself which ref to use.  Say\n> stash.ref, defaulting to refs/stash, honored by push, save, list,\n> show, pop, apply, drop, branch and clear.  A worktree that wants\n> isolation then asks for it once:\n> \n>      git config extensions.worktreeConfig true\n>      git config --worktree stash.ref refs/worktree/stash\n> \n> Nothing changes for anyone who does not set it, and the tools that\n> manage worktrees for agents can set it when they create a worktree.\n> \n> Alternatives I considered and rejected:\n> \n>    - Making the stash per-worktree unconditionally.  It breaks the\n>      stash-here-apply-there workflow, and it moves existing entries out\n>      from under scripts.  If that is the destination, it belongs in\n>      Documentation/BreakingChanges.adoc for Git 3.0, with a warning\n>      released first - but it does not have to block a knob today.\n> \n>    - Named stashes.  A name that survives a push by another process is\n>      what a ref already is, so this would grow a second naming scheme\n>      over the one branches and tags already use, plus commands to list\n>      and delete those names.\n> \n>    - Leaving it to tooling.  It works - `git stash create` writes a\n>      stash commit without touching any ref, so a wrapper can store it\n>      under refs/worktree/<name> and apply it later - but every tool\n>      reimplements it, and the failure mode for anyone who does not is\n>      silent.\n> \n> Points I am not sure about, and where I would like guidance before\n> writing a patch:\n> \n>    - Whether stash.ref is the right name, and whether it should be\n>      restricted to refs/ (rejecting a value that is not a ref name).\n> \n>    - Whether `git stash list` should be able to show the other stacks -\n>      a worktree's entries becoming invisible to the main checkout is the\n>      cost of the knob, and `git stash list --all` over\n>      worktrees/*/refs/worktree/stash might be a reasonable answer.\n> \n>    - Reachability.  fsck and reflog expiry learned to iterate\n>      per-worktree refs, and I would like a second opinion on whether\n>      stash entries under refs/worktree/* are safe from gc in the same\n>      way refs/stash entries are.\n> \n> If the direction sounds reasonable, I am happy to write the patch.\n> \n> Thanks,\n> Vladimir Sitnikov\n> \n\n"},{"id":"551135","messageId":"xmqqfr03sgyu.fsf@gitster.g","threadId":"66209","inReplyTo":"91feddb6-0d1b-42af-9942-307b98aa747d@gmail.com","subject":"Re: Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-24T14:58:33Z","receivedAt":"2026-08-24T14:58:36Z","isPatch":false,"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> On a related note I've been meaning to add an option to specify an \n> alternative branch name when creating a stash, so that \"git checkout -m\" \n> and \"git rebase --autostash <upstream> <branch>\" can record the branch \n> that we're switching to, rather than the one that's currently checked \n> out when creating stashes.\n\nInteresting.  I think we have seen ideas floated to allow per-branch\nand per-worktree stashes in the past.  I am not sure how much we\nshould rely on the stash message, though.  The more heavily we rely\non it, the more restricted the end-user messages supplied via the\n'-m' option would become.  If we were to officially support\nper-branch stashes, we may have to adopt a more structured format\n(which could be something simple like \"at the end of the message\nafter the last ':' is the name of the branch the stash entry\ntargets\", alongside a tweak to the '-m' option to always append\n': target-branch' after whatever the user gives as the message).\n"},{"id":"551193","messageId":"e3e7d23c-ad66-42de-b959-f9f2fae8d16b@gmail.com","threadId":"66209","inReplyTo":"xmqqfr03sgyu.fsf@gitster.g","subject":"Re: Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-25T14:43:52Z","receivedAt":"2026-08-25T14:44:03Z","isPatch":false,"body":"On 24/08/2026 15:58, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> \n>> On a related note I've been meaning to add an option to specify an\n>> alternative branch name when creating a stash, so that \"git checkout -m\"\n>> and \"git rebase --autostash <upstream> <branch>\" can record the branch\n>> that we're switching to, rather than the one that's currently checked\n>> out when creating stashes.\n> \n> Interesting.  I think we have seen ideas floated to allow per-branch\n> and per-worktree stashes in the past.  I am not sure how much we\n> should rely on the stash message, though.  The more heavily we rely\n> on it, the more restricted the end-user messages supplied via the\n> '-m' option would become.  If we were to officially support\n> per-branch stashes, we may have to adopt a more structured format\n> (which could be something simple like \"at the end of the message\n> after the last ':' is the name of the branch the stash entry\n> targets\", alongside a tweak to the '-m' option to always append\n> ': target-branch' after whatever the user gives as the message).\n\nWe add the branch name to the beginning of the user-supplied message in \ncreate_stash(). If the user supplies the message then we prepend \"On \n$branch: \", if the user does not supply a message we use \"WIP on $branch \n...\" so I think we already have simple structured messages.\n\nThanks\n\nPhillip\n\n\n"},{"id":"551201","messageId":"xmqqecfmm76c.fsf@gitster.g","threadId":"66209","inReplyTo":"e3e7d23c-ad66-42de-b959-f9f2fae8d16b@gmail.com","subject":"Re: Subject: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-25T17:38:51Z","receivedAt":"2026-08-25T17:38:54Z","isPatch":false,"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> We add the branch name to the beginning of the user-supplied message in \n> create_stash(). If the user supplies the message then we prepend \"On \n> $branch: \", if the user does not supply a message we use \"WIP on $branch \n> ...\" so I think we already have simple structured messages.\n\nMakes sense.\n"},{"id":"551215","messageId":"CAB=Je-GVyfrP=3kW6hRh8aVnzkKg_6yKZW2LCV=Z1XB=T7KxFg@mail.gmail.com","threadId":"66209","inReplyTo":"xmqqecfmm76c.fsf@gitster.g","subject":"Re: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Vladimir Sitnikov","fromEmail":"sitnikov.vladimir@gmail.com","sentAt":"2026-08-25T18:24:03Z","receivedAt":"2026-08-25T18:24:17Z","isPatch":false,"body":"Kristoffer Haugsbakk writes:\n\n> To my uninformed, not-using-agents mind, what agents do with the tool\n> seems like the least concerning thing. They can be non-deterministically\n> instructed to not use the stash.\n[...]\n> And for determinism you can give them a git(1) wrapper that bans\n> git-stash(1).\n\nA wrapper that bans git-stash(1) misses it, because a command that never\nmentions the stash still writes to refs/stash:\n\n    git rebase topic --autostash\n    Created autostash: 637ca99\n    Applying autostash resulted in conflicts.\n    Your changes are safe in the stash.\n    You can run \"git stash pop\" or \"git stash drop\" at any time.\n\nThe entry sits in refs/stash afterwards, where every worktree sees it.\nrebase.autoStash lives in the shared .git/config, so one worktree can\nturn this on for all of them, and the flag then never appears in any\ncommand line to ban.\n\nHaving a stash subcommand and forbidding it to execute is fishy.\nAgents might miss the instructions and they might still attempt calling stash.\n\nYour point about the bar for a configuration option is well taken, and\nso is the one about the framing.  The single confused session justifies\nthe option on its own; the agents changed how often it happens, not\nwhether it is worth fixing.\n\nPhillip Wood writes:\n\n> When I'm not trying to move changes between branches I associate a stash\n> with the branch that's checked out when it is created, not the worktree\n> where that the branch happens to be checked out.  We already record the\n> branch name when creating the stash so perhaps we should add an option\n> to pop the last stash that was created on the current branch.\n\nThat covers more of my case than I expected.  Git refuses to check the\nsame branch out in two worktrees, so a per-branch filter separates every\nworktree that sits on a branch, and the entries stay visible to\n`git stash list`, which a private ref gives up.\n\nThe gap is a detached HEAD:\n\n    git checkout --detach\n    echo v2 >f && git stash push -m \"my own text\"\n    git stash list\n    stash@{0}: On (no branch): my own text\n\nEvery detached worktree records the same \"(no branch)\", so a per-branch\nfilter groups them together rather than separating them.  That is not a\ncorner case for the tools I have in mind: one repository here has 436\nlinked worktrees, 23 of them on a detached HEAD, because a worktree\ncreated to look at someone else's commit has no branch to be on.\n\n> If an agent really needs a private stash it can use \"git stash create\"\n> and record the oid of the stash under \"refs/worktree/\".\n\nThat is what I do today, and it works.  It is also what every tool has\nto reimplement, and the ones that skip it produce the failure I opened\nwith.\n\nThe two ideas may well be one knob.  If the scope of the stack were\nconfigurable (the shared ref, the current branch, or a per-worktree\nref), then \"pop what this branch stashed\" and \"pop what this worktree\nstashed\" become two values rather than two features, and a detached\nworktree can choose the one that still separates it.\n\nI am happy to write the patch for whichever direction you prefer, or to\ntest yours.\n\nThanks,\nVladimir Sitnikov\n"},{"id":"551271","messageId":"4c7734f5-2ef4-4bb0-9397-a97cd67a3bd4@gmail.com","threadId":"66209","inReplyTo":"CAB=Je-GVyfrP=3kW6hRh8aVnzkKg_6yKZW2LCV=Z1XB=T7KxFg@mail.gmail.com","subject":"Re: [RFC] stash: let the stash stack live in a configurable ref","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-08-26T10:08:55Z","receivedAt":"2026-08-26T10:08:58Z","isPatch":false,"body":"Hi Vladimir\n\nOn 25/08/2026 19:24, Vladimir Sitnikov wrote:\n> Kristoffer Haugsbakk writes:\n> \n>> To my uninformed, not-using-agents mind, what agents do with the tool\n>> seems like the least concerning thing. They can be non-deterministically\n>> instructed to not use the stash.\n> [...]\n>> And for determinism you can give them a git(1) wrapper that bans\n>> git-stash(1).\n> \n> A wrapper that bans git-stash(1) misses it, because a command that never\n> mentions the stash still writes to refs/stash:\n> \n>      git rebase topic --autostash\n>      Created autostash: 637ca99\n>      Applying autostash resulted in conflicts.\n>      Your changes are safe in the stash.\n>      You can run \"git stash pop\" or \"git stash drop\" at any time.\n> \n> The entry sits in refs/stash afterwards, where every worktree sees it.\n> rebase.autoStash lives in the shared .git/config, so one worktree can\n> turn this on for all of them, and the flag then never appears in any\n> command line to ban.\n> \n> Having a stash subcommand and forbidding it to execute is fishy.\n> Agents might miss the instructions and they might still attempt calling stash.\n\nRight, your wrapper would need to be a bit more complicated. It would \nneed to pass \"-c rebase.autoStash=false -c merge.autoStash=false -c \npull.autoStash=false\", disallow command-lines containing --autostash and \nprobably set GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true to enforce that.\n\n> Your point about the bar for a configuration option is well taken, and\n> so is the one about the framing.  The single confused session justifies\n> the option on its own; the agents changed how often it happens, not\n> whether it is worth fixing.\n> \n> Phillip Wood writes:\n> \n>> When I'm not trying to move changes between branches I associate a stash\n>> with the branch that's checked out when it is created, not the worktree\n>> where that the branch happens to be checked out.  We already record the\n>> branch name when creating the stash so perhaps we should add an option\n>> to pop the last stash that was created on the current branch.\n> \n> That covers more of my case than I expected.  Git refuses to check the\n> same branch out in two worktrees, so a per-branch filter separates every\n> worktree that sits on a branch, and the entries stay visible to\n> `git stash list`, which a private ref gives up.\n> \n> The gap is a detached HEAD:\n> \n>      git checkout --detach\n>      echo v2 >f && git stash push -m \"my own text\"\n>      git stash list\n>      stash@{0}: On (no branch): my own text\n> \n> Every detached worktree records the same \"(no branch)\", so a per-branch\n> filter groups them together rather than separating them.  That is not a\n> corner case for the tools I have in mind: one repository here has 436\n> linked worktrees, 23 of them on a detached HEAD, because a worktree\n> created to look at someone else's commit has no branch to be on.\n\nWhen we create a stash entry its first parent is HEAD. So I think you \ncan find the last stash that was created in the current worktree by \nusing HEAD's reflog and the first parents of the stashes. You want to \nfind the most recent stash entry stash@{M} where\n\n     object-id(HEAD@{N}) == object-id(refs/stash@{M}^1) &&\n     reflog-date(HEAD@{N}) <= commit-date(refs/stash@{M}) &&\n     commit-date(refs/stash@{M}) <= reflog-date{HEAD@{N-1})\n\nthat will give you the stash whose first parent is the same commit as \nHEAD in the current worktree when the stash was created.\n\n>> If an agent really needs a private stash it can use \"git stash create\"\n>> and record the oid of the stash under \"refs/worktree/\".\n> \n> That is what I do today, and it works.  It is also what every tool has\n> to reimplement, and the ones that skip it produce the failure I opened\n> with.\n> \n> The two ideas may well be one knob.  If the scope of the stack were\n> configurable (the shared ref, the current branch, or a per-worktree\n> ref), then \"pop what this branch stashed\" and \"pop what this worktree\n> stashed\" become two values rather than two features, and a detached\n> worktree can choose the one that still separates it.\n> \n> I am happy to write the patch for whichever direction you prefer, or to\n> test yours.\n\nMy preference would be to add options to \"git stash pop\" to pop the most \nrecent stash created on the current branch, or the most recent stash \ncreated in the current worktree. That keeps the convenience of the \nglobal store for moving changes between different branches/worktrees \nwhile making it easy to pop the stash that you intended. It would be \nnice to have options to filter the output of \"git stash list\" by branch \nor worktree as well but that could be added separately.\n\nI'd be interested to hear what others think\n\nThanks\n\nPhillip\n\n"}]}