2020#include "gettext.h"
2121#define SECURITY_WIN32
2222#include <sspi.h>
23+ #include "../repository.h"
2324
2425#define HCAST (type , handle ) ((type)(intptr_t)handle)
2526
@@ -549,6 +550,7 @@ static int is_local_named_pipe_path(const char *filename)
549550
550551int mingw_open (const char * filename , int oflags , ...)
551552{
553+ static int append_atomically = -1 ;
552554 typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
553555 va_list args ;
554556 unsigned mode ;
@@ -565,7 +567,16 @@ int mingw_open (const char *filename, int oflags, ...)
565567 return -1 ;
566568 }
567569
568- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
570+ /*
571+ * Only set append_atomically to default value(1) when repo is initialized
572+ * and fail to get config value
573+ */
574+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
575+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
576+ append_atomically = 1 ;
577+
578+ if (append_atomically && (oflags & O_APPEND ) &&
579+ !is_local_named_pipe_path (filename ))
569580 open_fn = mingw_open_append ;
570581 else
571582 open_fn = _wopen ;
@@ -714,9 +725,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
714725
715726 /* check if fd is a pipe */
716727 HANDLE h = (HANDLE ) _get_osfhandle (fd );
717- if (GetFileType (h ) != FILE_TYPE_PIPE )
728+ if (GetFileType (h ) != FILE_TYPE_PIPE ) {
729+ if (orig == EINVAL ) {
730+ wchar_t path [MAX_PATH ];
731+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
732+ ARRAY_SIZE (path ), 0 );
733+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
734+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
735+
736+ /*
737+ * The default atomic append causes such an error on
738+ * network file systems, in such a case, it should be
739+ * turned off via config.
740+ *
741+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
742+ */
743+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
744+ warning ("invalid write operation detected; you may try:\n"
745+ "\n\tgit config windows.appendAtomically false" );
746+ }
747+
718748 errno = orig ;
719- else if (orig == EINVAL )
749+ } else if (orig == EINVAL )
720750 errno = EPIPE ;
721751 else {
722752 DWORD buf_size ;
0 commit comments