From: Thomas Bachem Date: Mon, 28 Sep 2026 14:50:17 GMT Subject: Re: [PATCH v3 0/5] stash: clean up index-mode test merge Message-ID: In-Reply-To: On Mon, Sep 28, 2026 at 3:45 PM Phillip Wood wrote: > Oh, when I was thinking about this over lunch I did wonder if that might > be the culprit. Previously we didn't run "git maintenance --auto" after > a rebase with the 'merge' backend but with that topic we do, and because > we set GIT_COMMITTER_DATE to sometime in 2005, if 'git reflog expire' > gets triggered it will expire the reflog entries that 'git pull > --rebase' relies on. As you suggested in another mail, I assume this That is it. I ran t5520 on 'seen' with and without Ben's series under GIT_TRACE2_EVENT, and the two runs differ in one place: which command's auto maintenance runs "git reflog expire --all". "git pull --rebase" computes the fork point before it fetches, from the reflog of refs/remotes/me/copy, and test 69 needs the entry that test 68's fetch wrote there, copy-orig (f29aa66) to ae98574. With the reflog empty, "merge-base --fork-point" falls back to the ref itself, ae98574 is no ancestor of to-rebase, and pull hands the merge head to rebase as the upstream. That is your "--onto ae98... ae98...", and the four commits from copy-orig up come back, the first of them conflicting with "conflict". > topic has changed something in one of the '--autostash' tests that come > before the failing test triggers which the new behavior. What that > something is I'm not sure; off the top of my head I'd expect the number > of reflog entries in HEAD to be the same but maybe I'm missing > something. Adding It is eight entries fewer, and they come from the failed merges, not from the autostash tests. "git merge" restores a dirty tree with "stash apply --index --quiet", and until Ben's series that spawned "git reset --quiet --refresh", which writes "reset: moving to HEAD" to the reflog. That happens eight times in t5520 before test 68. Auto maintenance expires reflogs once HEAD's reflog holds a hundred entries that the policy would remove, the default of maintenance.reflog-expire.auto, and after the first test_tick that is every entry. Which run crosses the hundred depends on how many entries and maintenance runs came before it. On 'seen' the expiry lands on "git commit -m conflict" in test 68, before the fetch writes the entry. Eight entries fewer move the crossing past that commit, and the maintenance run my topic adds at the end of the rebase in test 68 is the next one: after the fetch, before test 69 reads the reflog. Either change alone leaves it somewhere harmless, and nothing else is going on. The expiry is the usual 90 days applied to entries dated 2005, and the only new thing is one more maintenance run per rebase, the same one "git commit" and "git fetch" run. > git config maintenance.reflog-expire.auto 0 > > to the 'setup' test fixes the test failure, but it would be good to try > and understand why this topic triggers the reflog to be expired in case > there is something nasty happening that we've not thought of. I'd pin the expiry itself instead, as ea7d894f44 (t34xx: don't expire reflogs where it matters, 2026-02-24) did for the rebase tests: git config set gc.reflogExpire never && git config set gc.reflogExpireUnreachable never && That covers a "git gc" as well, which expires reflogs on its own. With it, 'seen' plus Ben's series passes t5520 here and no expiry runs during the script at all. I sent it as a patch on master: FWIW, any script that reads a reflog after a hundred HEAD updates can fall into the same hole. I have not looked further than t5520. Thomas