Skip to content

Commit c4c61c7

Browse files
mhaggergitster
authored andcommitted
lock_ref_sha1_basic(): on SCLD_VANISHED, retry
If safe_create_leading_directories() fails because a file along the path unexpectedly vanished, try again (up to 3 times). This can occur if another process is deleting directories at the same time as we are trying to make them. For example, "git pack-refs --all" tries to delete the loose refs and any empty directories that are left behind. If a pack-refs process is running, then it might delete a directory that we need to put a new loose reference in. If safe_create_leading_directories() thinks this might have happened, then take its advice and try again (maximum three attempts). Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 18d37e8 commit c4c61c7

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

refs.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
20392039
int type, lflags;
20402040
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
20412041
int missing = 0;
2042+
int attempts_remaining = 3;
20422043

20432044
lock = xcalloc(1, sizeof(struct ref_lock));
20442045
lock->lock_fd = -1;
@@ -2093,7 +2094,15 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
20932094
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
20942095
lock->force_write = 1;
20952096

2096-
if (safe_create_leading_directories(ref_file)) {
2097+
retry:
2098+
switch (safe_create_leading_directories(ref_file)) {
2099+
case SCLD_OK:
2100+
break; /* success */
2101+
case SCLD_VANISHED:
2102+
if (--attempts_remaining > 0)
2103+
goto retry;
2104+
/* fall through */
2105+
default:
20972106
last_errno = errno;
20982107
error("unable to create directory for %s", ref_file);
20992108
goto error_return;

0 commit comments

Comments
 (0)