Windows's rename() is based on the MoveFile() API, which fails if the destination exists. Here we work around the problem by using MoveFileEx(). Furthermore, the posixly correct error is returned if the destination is a directory. The implementation is still slightly incomplete, however, because of the missing error code translation: We assume that the failure is due to permissions. Signed-off-by: Johannes Sixt <johannes.sixt@xxxxxxxxxx> --- compat/mingw.c | 25 +++++++++++++++++++++++++ git-compat-util.h | 3 +++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 0c1d0e4..733ef87 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -60,6 +60,31 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) return result; } +#undef rename +int mingw_rename(const char *pold, const char *pnew) +{ + /* + * Try native rename() first to get errno right. + * It is based on MoveFile(), which cannot overwrite existing files. + */ + if (!rename(pold, pnew)) + return 0; + if (errno != EEXIST) + return -1; + if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING)) + return 0; + /* TODO: translate more errors */ + if (GetLastError() == ERROR_ACCESS_DENIED) { + DWORD attrs = GetFileAttributes(pnew); + if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { + errno = EISDIR; + return -1; + } + } + errno = EACCES; + return -1; +} + struct passwd *getpwuid(int uid) { static char user_name[100]; diff --git a/git-compat-util.h b/git-compat-util.h index 06ac2c1..f44a287 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -592,6 +592,9 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out); int mingw_open (const char *filename, int oflags, ...); #define open mingw_open +int mingw_rename(const char*, const char*); +#define rename mingw_rename + #endif /* __MINGW32__ */ #endif -- 1.5.4.1.126.ge5a7d - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html