summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2014-01-18 23:48:54 +0100
committerJunio C Hamano <gitster@pobox.com>2014-01-21 13:46:07 -0800
commitc4c61c763e700d02344490590d6980ee51031a27 (patch)
tree1d3b1b35cdf63ad6f4fa0b48203e45bf805c30a6 /refs.c
parent18d37e860dfb9a98fb93ea7bb517ec3c16f995c4 (diff)
downloadgit-c4c61c763e700d02344490590d6980ee51031a27.tar.gz
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 <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/refs.c b/refs.c
index 5e5a3824b9..2d0faf2326 100644
--- a/refs.c
+++ b/refs.c
@@ -2039,6 +2039,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
int type, lflags;
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
int missing = 0;
+ int attempts_remaining = 3;
lock = xcalloc(1, sizeof(struct ref_lock));
lock->lock_fd = -1;
@@ -2093,7 +2094,15 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
lock->force_write = 1;
- if (safe_create_leading_directories(ref_file)) {
+ retry:
+ switch (safe_create_leading_directories(ref_file)) {
+ case SCLD_OK:
+ break; /* success */
+ case SCLD_VANISHED:
+ if (--attempts_remaining > 0)
+ goto retry;
+ /* fall through */
+ default:
last_errno = errno;
error("unable to create directory for %s", ref_file);
goto error_return;