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 <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Jan 18, 2014 at 23:48 UTC
e5c223e98b985d9faa274039aefa4391d2da25a6
1 file changed
+12
-1
refs.c
+12
-1
@@ -2081,7 +2081,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
2081
2082
lock->lk = xcalloc(1, sizeof(struct lock_file));
2083
2084
- lflags = LOCK_DIE_ON_ERROR;
2084
+ lflags = 0;
2085
if (flags & REF_NODEREF) {
2086
refname = orig_refname;
2087
lflags |= LOCK_NODEREF;
@@ -2109,6 +2109,17 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
2109
}
2110
2111
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
+ }
2123
return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
2124
2125
error_return: