Skip to content

Commit 9b3fdb0

Browse files
dschoGit for Windows Build Agent
authored andcommitted
mingw: try resetting the read-only bit if rename fails (#4527)
With this patch, Git for Windows works as intended on mounted APFS volumes (where renaming read-only files would fail). Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 9abf4c7 + 12017a8 commit 9b3fdb0

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

compat/mingw.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,7 +2703,7 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
27032703
int mingw_rename(const char *pold, const char *pnew)
27042704
{
27052705
static int supports_file_rename_info_ex = 1;
2706-
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle;
2706+
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle, attrsold;
27072707
int tries = 0;
27082708
wchar_t wpold[MAX_LONG_PATH], wpnew[MAX_LONG_PATH];
27092709
int wpnew_len;
@@ -2795,11 +2795,24 @@ int mingw_rename(const char *pold, const char *pnew)
27952795
gle = GetLastError();
27962796
}
27972797

2798-
if (gle == ERROR_ACCESS_DENIED && is_inside_windows_container()) {
2799-
/* Fall back to copy to destination & remove source */
2800-
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
2801-
return 0;
2802-
gle = GetLastError();
2798+
if (gle == ERROR_ACCESS_DENIED) {
2799+
if (is_inside_windows_container()) {
2800+
/* Fall back to copy to destination & remove source */
2801+
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold, 1))
2802+
return 0;
2803+
gle = GetLastError();
2804+
} else if ((attrsold = GetFileAttributesW(wpold)) & FILE_ATTRIBUTE_READONLY) {
2805+
/* if file is read-only, change and retry */
2806+
SetFileAttributesW(wpold, attrsold & ~FILE_ATTRIBUTE_READONLY);
2807+
if (MoveFileExW(wpold, wpnew,
2808+
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
2809+
SetFileAttributesW(wpnew, attrsold);
2810+
return 0;
2811+
}
2812+
gle = GetLastError();
2813+
/* revert attribute change on failure */
2814+
SetFileAttributesW(wpold, attrsold);
2815+
}
28032816
}
28042817

28052818
/* revert file attributes on failure */

0 commit comments

Comments
 (0)