Commit f34408a7b440489e474f5a5f8d90167b7d8195e9

Vicent Marti 2014-04-04T14:23:07

Merge pull request #2211 from Yogu/retry-renaming-config Retry committing locked files on error

diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 18f717b..6f29318 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -467,10 +467,31 @@ int p_rename(const char *from, const char *to)
 {
 	git_win32_path wfrom;
 	git_win32_path wto;
+	int rename_tries;
+	int rename_succeeded;
+	int error;
 
 	git_win32_path_from_c(wfrom, from);
 	git_win32_path_from_c(wto, to);
-	return MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
+	
+	/* wait up to 50ms if file is locked by another thread or process */
+	rename_tries = 0;
+	rename_succeeded = 0;
+	while (rename_tries < 10) {
+		if (MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) {
+			rename_succeeded = 1;
+			break;
+		}
+		
+		error = GetLastError();
+		if (error == ERROR_SHARING_VIOLATION || error == ERROR_ACCESS_DENIED) {
+			Sleep(5);
+			rename_tries++;
+		} else
+			break;
+	}
+	
+	return rename_succeeded ? 0 : -1;
 }
 
 int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)