Skip to content

Commit a49ea55

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 0a21cc7 + 2cbb28f commit a49ea55

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
@@ -2579,7 +2579,7 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
25792579
#undef rename
25802580
int mingw_rename(const char *pold, const char *pnew)
25812581
{
2582-
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle;
2582+
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle, attrsold;
25832583
int tries = 0;
25842584
wchar_t wpold[MAX_LONG_PATH], wpnew[MAX_LONG_PATH];
25852585
if (xutftowcs_long_path(wpold, pold) < 0 ||
@@ -2592,11 +2592,24 @@ int mingw_rename(const char *pold, const char *pnew)
25922592
return 0;
25932593
gle = GetLastError();
25942594

2595-
if (gle == ERROR_ACCESS_DENIED && is_inside_windows_container()) {
2596-
/* Fall back to copy to destination & remove source */
2597-
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
2598-
return 0;
2599-
gle = GetLastError();
2595+
if (gle == ERROR_ACCESS_DENIED) {
2596+
if (is_inside_windows_container()) {
2597+
/* Fall back to copy to destination & remove source */
2598+
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
2599+
return 0;
2600+
gle = GetLastError();
2601+
} else if ((attrsold = GetFileAttributesW(wpold)) & FILE_ATTRIBUTE_READONLY) {
2602+
/* if file is read-only, change and retry */
2603+
SetFileAttributesW(wpold, attrsold & ~FILE_ATTRIBUTE_READONLY);
2604+
if (MoveFileExW(wpold, wpnew,
2605+
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
2606+
SetFileAttributesW(wpnew, attrsold);
2607+
return 0;
2608+
}
2609+
gle = GetLastError();
2610+
/* revert attribute change on failure */
2611+
SetFileAttributesW(wpold, attrsold);
2612+
}
26002613
}
26012614

26022615
/* revert file attributes on failure */

0 commit comments

Comments
 (0)