20
20
#include "gettext.h"
21
21
#define SECURITY_WIN32
22
22
#include <sspi.h>
23
+ #include "../repository.h"
23
24
24
25
#define HCAST (type , handle ) ((type)(intptr_t)handle)
25
26
@@ -613,6 +614,7 @@ static int is_local_named_pipe_path(const char *filename)
613
614
614
615
int mingw_open (const char * filename , int oflags , ...)
615
616
{
617
+ static int append_atomically = -1 ;
616
618
typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
617
619
va_list args ;
618
620
unsigned mode ;
@@ -629,7 +631,16 @@ int mingw_open (const char *filename, int oflags, ...)
629
631
return -1 ;
630
632
}
631
633
632
- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
634
+ /*
635
+ * Only set append_atomically to default value(1) when repo is initialized
636
+ * and fail to get config value
637
+ */
638
+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
639
+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
640
+ append_atomically = 1 ;
641
+
642
+ if (append_atomically && (oflags & O_APPEND ) &&
643
+ !is_local_named_pipe_path (filename ))
633
644
open_fn = mingw_open_append ;
634
645
else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT )))
635
646
open_fn = mingw_open_existing ;
@@ -780,9 +791,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
780
791
781
792
/* check if fd is a pipe */
782
793
HANDLE h = (HANDLE ) _get_osfhandle (fd );
783
- if (GetFileType (h ) != FILE_TYPE_PIPE )
794
+ if (GetFileType (h ) != FILE_TYPE_PIPE ) {
795
+ if (orig == EINVAL ) {
796
+ wchar_t path [MAX_PATH ];
797
+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
798
+ ARRAY_SIZE (path ), 0 );
799
+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
800
+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
801
+
802
+ /*
803
+ * The default atomic append causes such an error on
804
+ * network file systems, in such a case, it should be
805
+ * turned off via config.
806
+ *
807
+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
808
+ */
809
+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
810
+ warning ("invalid write operation detected; you may try:\n"
811
+ "\n\tgit config windows.appendAtomically false" );
812
+ }
813
+
784
814
errno = orig ;
785
- else if (orig == EINVAL )
815
+ } else if (orig == EINVAL )
786
816
errno = EPIPE ;
787
817
else {
788
818
DWORD buf_size ;
0 commit comments