]> git.ipfire.org Git - thirdparty/git.git/commit
config: retry acquiring config.lock, configurable via core.configLockTimeout
authorJörg Thalheim <joerg@thalheim.io>
Sun, 17 May 2026 13:21:11 +0000 (15:21 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 18 May 2026 00:30:29 +0000 (09:30 +0900)
commitdf67d73ca3268eec5c924d6fe9d2c050ce23f3b1
tree825a5dba16a1fdeaca3c9e650f74286f458f5897
parent94f057755b7941b321fd11fec1b2e3ca5313a4e0
config: retry acquiring config.lock, configurable via core.configLockTimeout

Concurrent config writers race for the ".lock" file, which is taken
with open(O_EXCL) and no retry, so the losers fail right away with
"could not lock config file".

This shows up with parallel "git worktree add -b" against the same
repository: each one writes a couple of branch.* keys and the losers
fail at random. Worse, "git worktree add" doesn't propagate that
failure to its exit code, so the tracking config is silently dropped.
(The swallowed error is a separate bug.)

Retry instead of giving up on the first EEXIST. The lock is only held
while rewriting a small file, so the loser only has to wait out the
other writers. Same approach as 4ff0f01cb7 (refs: retry acquiring
reference locks for 100ms, 2017-08-21).

On the semantics: the on-disk config is read only after the lock is
taken, so writers touching different keys can't lose each other's
change. Writers touching the same key still get last-writer-wins, but
that is already the case today and would need a compare-and-swap config
API to fix. The retry only turns hard failures into successes.

Default to 1000ms, like core.packedRefsTimeout: same shape of problem,
one shared file everyone serializes through. A larger timeout only
costs anything when a stale lock is left behind by a crash, which is
rare; a smaller one fails spuriously on slow filesystems (NTFS has
been seen needing more than 100ms). Make it configurable as
core.configLockTimeout. There is no chicken-and-egg problem: we read
the config before we lock it.

microsoft/git carries a similar patch (core.configWriteLockTimeoutMS,
default off) for Scalar's tests. Defaulting to non-zero here because
the worktree case fails silently.

Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/core.adoc
config.c
t/t1300-config.sh
t/t3200-branch.sh
t/t5505-remote.sh