Skip to content

Commit 194c5f1

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 <johannes.schindelin@gmx.de>
2 parents aaa1ec9 + d7974eb commit 194c5f1

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

compat/mingw.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,7 +2864,7 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
28642864
int mingw_rename(const char *pold, const char *pnew)
28652865
{
28662866
static int supports_file_rename_info_ex = 1;
2867-
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle;
2867+
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle, attrsold;
28682868
int tries = 0;
28692869
wchar_t wpold[MAX_LONG_PATH], wpnew[MAX_LONG_PATH];
28702870
int wpnew_len;
@@ -2956,11 +2956,24 @@ int mingw_rename(const char *pold, const char *pnew)
29562956
gle = GetLastError();
29572957
}
29582958

2959-
if (gle == ERROR_ACCESS_DENIED && is_inside_windows_container()) {
2960-
/* Fall back to copy to destination & remove source */
2961-
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold, 1))
2962-
return 0;
2963-
gle = GetLastError();
2959+
if (gle == ERROR_ACCESS_DENIED) {
2960+
if (is_inside_windows_container()) {
2961+
/* Fall back to copy to destination & remove source */
2962+
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold, 1))
2963+
return 0;
2964+
gle = GetLastError();
2965+
} else if ((attrsold = GetFileAttributesW(wpold)) & FILE_ATTRIBUTE_READONLY) {
2966+
/* if file is read-only, change and retry */
2967+
SetFileAttributesW(wpold, attrsold & ~FILE_ATTRIBUTE_READONLY);
2968+
if (MoveFileExW(wpold, wpnew,
2969+
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
2970+
SetFileAttributesW(wpnew, attrsold);
2971+
return 0;
2972+
}
2973+
gle = GetLastError();
2974+
/* revert attribute change on failure */
2975+
SetFileAttributesW(wpold, attrsold);
2976+
}
29642977
}
29652978

29662979
/* revert file attributes on failure */

0 commit comments

Comments
 (0)