Skip to content

Commit 14e8711

Browse files
committed
Merge pull request #3646 from sunzhuoshi/main
Fix append failure issue under remote directories #2753
2 parents 829e797 + e04ab53 commit 14e8711

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

Documentation/config.txt

+2
Original file line numberDiff line numberDiff line change
@@ -537,4 +537,6 @@ include::config/versionsort.txt[]
537537

538538
include::config/web.txt[]
539539

540+
include::config/windows.txt[]
541+
540542
include::config/worktree.txt[]

Documentation/config/windows.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
windows.appendAtomically::
2+
By default, append atomic API is used on windows. But it works only with
3+
local disk files, if you're working on a network file system, you should
4+
set it false to turn it off.

compat/mingw.c

+30-2
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ static int is_local_named_pipe_path(const char *filename)
745745

746746
int mingw_open (const char *filename, int oflags, ...)
747747
{
748+
static int append_atomically = -1;
748749
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
749750
va_list args;
750751
unsigned mode;
@@ -761,7 +762,16 @@ int mingw_open (const char *filename, int oflags, ...)
761762
return -1;
762763
}
763764

764-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
765+
/*
766+
* Only set append_atomically to default value(1) when repo is initialized
767+
* and fail to get config value
768+
*/
769+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
770+
git_config_get_bool("windows.appendatomically", &append_atomically))
771+
append_atomically = 1;
772+
773+
if (append_atomically && (oflags & O_APPEND) &&
774+
!is_local_named_pipe_path(filename))
765775
open_fn = mingw_open_append;
766776
else
767777
open_fn = _wopen;
@@ -910,8 +920,26 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
910920
HANDLE h = (HANDLE) _get_osfhandle(fd);
911921
if (GetFileType(h) == FILE_TYPE_PIPE)
912922
errno = EPIPE;
913-
else
923+
else {
924+
wchar_t path[MAX_LONG_PATH];
925+
DWORD ret = GetFinalPathNameByHandleW(h, path,
926+
ARRAY_SIZE(path), 0);
927+
UINT drive_type = ret > 0 && ret < ARRAY_SIZE(path) ?
928+
GetDriveTypeW(path) : DRIVE_UNKNOWN;
929+
930+
/*
931+
* The default atomic append causes such an error on
932+
* network file systems, in such a case, it should be
933+
* turned off via config.
934+
*
935+
* `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
936+
*/
937+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
938+
warning("invalid write operation detected; you may try:\n"
939+
"\n\tgit config windows.appendAtomically false");
940+
914941
errno = EINVAL;
942+
}
915943
}
916944

917945
return result;

0 commit comments

Comments
 (0)