Skip to content

pr-2214/thomasbachem/rerere-gc-lock-v3

tagged this 04 Sep 15:51
From: Thomas Bachem <mail@thomasbachem.com>

A "git rerere gc" holds MERGE_RR.lock for as long as pruning rr-cache
takes, and since 2.54 the auto maintenance after every commit runs
one whenever rr-cache has an entry. The commit a rebase spawns for a
resolved pick starts it too, and the sequencer's repo_rerere() at the
next conflict wants the lock a few milliseconds later. Both take it
with LOCK_DIE_ON_ERROR, so whichever comes second dies. When it is
the rebase, the index is written but the state for "git rebase
--continue" is not, and every later continue refuses with "you have
staged changes".

The gc needs the lock, since a rerere that has just created its
directory looks like the empty ones it prunes. So wait for it
instead, rerere.lockTimeout milliseconds, 1000 by default with the
semantics of core.packedRefsTimeout, then warn and go on without
rerere: a lost recording or replay is nothing next to a rebase that
cannot continue. The gc itself never waits, and "git rerere", "git
rerere forget" and "git rerere clear" wait but then die, since the
state behind the lock is all they are for. The clearing "am" and
"rebase" do on --abort, --skip and --quit goes on without it, and
leaves the entries for the gc.

Assisted-by: Claude Fable 5.1
Signed-off-by: Thomas Bachem <mail@thomasbachem.com>

Submitted-As: https://lore.kernel.org/git/pull.2214.v3.git.1788537081930.gitgitgadget@gmail.com
In-Reply-To: https://lore.kernel.org/git/pull.2214.git.1788337897490.gitgitgadget@gmail.com
In-Reply-To: https://lore.kernel.org/git/pull.2214.v2.git.1788507876543.gitgitgadget@gmail.com
Assets 2
Loading