Skip to content

Commit e5c223e

Browse files
mhaggergitster
authored andcommitted
lock_ref_sha1_basic(): if locking fails with ENOENT, retry
If hold_lock_file_for_update() fails with errno==ENOENT, it might be because somebody else (for example, a pack-refs process) has just deleted one of the lockfile's ancestor directories. So if this condition is detected, try again (up to 3 times). Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c4c61c7 commit e5c223e

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

refs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
20812081

20822082
lock->lk = xcalloc(1, sizeof(struct lock_file));
20832083

2084-
lflags = LOCK_DIE_ON_ERROR;
2084+
lflags = 0;
20852085
if (flags & REF_NODEREF) {
20862086
refname = orig_refname;
20872087
lflags |= LOCK_NODEREF;
@@ -2109,6 +2109,17 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
21092109
}
21102110

21112111
lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
2112+
if (lock->lock_fd < 0) {
2113+
if (errno == ENOENT && --attempts_remaining > 0)
2114+
/*
2115+
* Maybe somebody just deleted one of the
2116+
* directories leading to ref_file. Try
2117+
* again:
2118+
*/
2119+
goto retry;
2120+
else
2121+
unable_to_lock_index_die(ref_file, errno);
2122+
}
21122123
return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
21132124

21142125
error_return:

0 commit comments

Comments
 (0)