Skip to content

Commit 1ebeed2

Browse files
committed
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 c6da52e + 5dd28c1 commit 1ebeed2

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
@@ -2651,7 +2651,7 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
26512651
int mingw_rename(const char *pold, const char *pnew)
26522652
{
26532653
static int supports_file_rename_info_ex = 1;
2654-
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle;
2654+
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle, attrsold;
26552655
int tries = 0;
26562656
wchar_t wpold[MAX_LONG_PATH], wpnew[MAX_LONG_PATH];
26572657
int wpnew_len;
@@ -2739,11 +2739,24 @@ int mingw_rename(const char *pold, const char *pnew)
27392739
gle = GetLastError();
27402740
}
27412741

2742-
if (gle == ERROR_ACCESS_DENIED && is_inside_windows_container()) {
2743-
/* Fall back to copy to destination & remove source */
2744-
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
2745-
return 0;
2746-
gle = GetLastError();
2742+
if (gle == ERROR_ACCESS_DENIED) {
2743+
if (is_inside_windows_container()) {
2744+
/* Fall back to copy to destination & remove source */
2745+
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
2746+
return 0;
2747+
gle = GetLastError();
2748+
} else if ((attrsold = GetFileAttributesW(wpold)) & FILE_ATTRIBUTE_READONLY) {
2749+
/* if file is read-only, change and retry */
2750+
SetFileAttributesW(wpold, attrsold & ~FILE_ATTRIBUTE_READONLY);
2751+
if (MoveFileExW(wpold, wpnew,
2752+
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
2753+
SetFileAttributesW(wpnew, attrsold);
2754+
return 0;
2755+
}
2756+
gle = GetLastError();
2757+
/* revert attribute change on failure */
2758+
SetFileAttributesW(wpold, attrsold);
2759+
}
27472760
}
27482761

27492762
/* revert file attributes on failure */

0 commit comments

Comments
 (0)