aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2014-01-18 23:48:55 +0100
committerJunio C Hamano <gitster@pobox.com>2014-01-21 13:46:30 -0800
commite5c223e98b985d9faa274039aefa4391d2da25a6 (patch)
tree30c86f94026bed250aa888d6b81ea414cba9fcfb
parentc4c61c763e700d02344490590d6980ee51031a27 (diff)
downloadgit-e5c223e98b985d9faa274039aefa4391d2da25a6.tar.gz
git-e5c223e98b985d9faa274039aefa4391d2da25a6.tar.xz
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>
-rw-r--r--refs.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/refs.c b/refs.c
index 2d0faf232..a09bbb768 100644
--- a/refs.c
+++ b/refs.c
@@ -2081,7 +2081,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
lock->lk = xcalloc(1, sizeof(struct lock_file));
- lflags = LOCK_DIE_ON_ERROR;
+ lflags = 0;
if (flags & REF_NODEREF) {
refname = orig_refname;
lflags |= LOCK_NODEREF;
@@ -2109,6 +2109,17 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
}
lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
+ if (lock->lock_fd < 0) {
+ if (errno == ENOENT && --attempts_remaining > 0)
+ /*
+ * Maybe somebody just deleted one of the
+ * directories leading to ref_file. Try
+ * again:
+ */
+ goto retry;
+ else
+ unable_to_lock_index_die(ref_file, errno);
+ }
return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
error_return: