2121#include "gettext.h"
2222#define SECURITY_WIN32
2323#include <sspi.h>
24+ #include "../repository.h"
2425
2526#define HCAST (type , handle ) ((type)(intptr_t)handle)
2627
@@ -614,6 +615,7 @@ static int is_local_named_pipe_path(const char *filename)
614615
615616int mingw_open (const char * filename , int oflags , ...)
616617{
618+ static int append_atomically = -1 ;
617619 typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
618620 va_list args ;
619621 unsigned mode ;
@@ -630,7 +632,16 @@ int mingw_open (const char *filename, int oflags, ...)
630632 return -1 ;
631633 }
632634
633- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
635+ /*
636+ * Only set append_atomically to default value(1) when repo is initialized
637+ * and fail to get config value
638+ */
639+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
640+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
641+ append_atomically = 1 ;
642+
643+ if (append_atomically && (oflags & O_APPEND ) &&
644+ !is_local_named_pipe_path (filename ))
634645 open_fn = mingw_open_append ;
635646 else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT )))
636647 open_fn = mingw_open_existing ;
@@ -781,9 +792,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
781792
782793 /* check if fd is a pipe */
783794 HANDLE h = (HANDLE ) _get_osfhandle (fd );
784- if (GetFileType (h ) != FILE_TYPE_PIPE )
795+ if (GetFileType (h ) != FILE_TYPE_PIPE ) {
796+ if (orig == EINVAL ) {
797+ wchar_t path [MAX_PATH ];
798+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
799+ ARRAY_SIZE (path ), 0 );
800+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
801+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
802+
803+ /*
804+ * The default atomic append causes such an error on
805+ * network file systems, in such a case, it should be
806+ * turned off via config.
807+ *
808+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
809+ */
810+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
811+ warning ("invalid write operation detected; you may try:\n"
812+ "\n\tgit config windows.appendAtomically false" );
813+ }
814+
785815 errno = orig ;
786- else if (orig == EINVAL )
816+ } else if (orig == EINVAL )
787817 errno = EPIPE ;
788818 else {
789819 DWORD buf_size ;
0 commit comments