Re: [BUG] stash.index=true leaves a redundant stash entry after an autostash fast-forward
flat view
From: Eli Barzilay <hidden>
Date: 2026-09-16 19:57:51
[Note from the peanut gallery since I can't spend time diving into the code -- that's result of collecting dead autostashes is the only thorn in my joy of discovering `stash.index` + `rebase.autoStash`. So while I can't spend time in the code, I'll be happy to try patches or whatever if it helps...] On Wed, Sep 16, 2026 at 10:30 AM Ben Knoble [off-list ref] wrote:
Hi Phillip,quoted
Le 16 sept. 2026 à 09:35, Phillip Wood [off-list ref] a écrit : Hi Benquoted
On 15/09/2026 22:16, D. Ben Knoble wrote: I'm experimenting with something that swaps that out for a call to reset_working_tree(), but I don't think I've gotten it quite right for this bug yet (let alone run other test cases that might be affected by this change).It looks like stash has its own unpack_trees() wrapper, so I think the simplest fix is to replace reset_head() with reset_tree(&c_tree, 0, 1); Taking a step back, this code applies the stashed index changes into the current index, writes the result to a tree and then resets the index to HEAD. We could avoid touching the index at all if we used merge_incore_nonrecursive() to cherry pick the index changes instead. That way we'd get a proper three-way merge and avoid spawning subprocesses for "git diff-tree", "git apply --cached", and "git reset". We're already using merge_ort_nonrecursive() to merge the working tree changes in that function so we have nearly everything we need already set up to merge the index changes as well. Essentially, when merging the index, we just need to call merge_incore_nonrecursive() instead of merge_ort_nonrecursive() and use info->i_tree instead of info->w_tree.Wow, I wish I’d had this info this morning! I spent a couple hours trying to understand this flow and still don’t have it in my head :) Thanks for the pointers. With the way I batch my side project time, it’ll be tomorrow before I get to trying to make and test patches for this, but I’ excited now. I may try to summarize my own notes (= questions about the existing code) and send those out later today, though, since I’d love to make my understanding line up with yours!quoted
quoted
BTW, it's really weird to me that the reset manual doesn't mention all these "extra" cleanups reset does via remove_merge_branch_state()!Agreed, I think it comes from "git foo --abort" calling "git reset (--merge|--hard)" though that doesn't really explain why a mixed reset also removes the branch state.Yeah, that abort bit makes sense. I wonder if we should have had a better side-channel for communicating that, but I’m a bit too afraid to touch that for now ;)quoted
Thanks PhillipThank *you*!
--
((x=>x(x))(x=>x(x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!