17
17
#include "../trace2.h"
18
18
#include "../symlinks.h"
19
19
#include "../wrapper.h"
20
+ #include "../repository.h"
20
21
#include "dir.h"
21
22
#include "gettext.h"
22
23
#define SECURITY_WIN32
@@ -620,6 +621,7 @@ static int is_local_named_pipe_path(const char *filename)
620
621
621
622
int mingw_open (const char * filename , int oflags , ...)
622
623
{
624
+ static int append_atomically = -1 ;
623
625
typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
624
626
va_list args ;
625
627
unsigned mode ;
@@ -638,7 +640,16 @@ int mingw_open (const char *filename, int oflags, ...)
638
640
return -1 ;
639
641
}
640
642
641
- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
643
+ /*
644
+ * Only set append_atomically to default value(1) when repo is initialized
645
+ * and fail to get config value
646
+ */
647
+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
648
+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
649
+ append_atomically = 1 ;
650
+
651
+ if (append_atomically && (oflags & O_APPEND ) &&
652
+ !is_local_named_pipe_path (filename ))
642
653
open_fn = mingw_open_append ;
643
654
else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT )))
644
655
open_fn = mingw_open_existing ;
@@ -804,9 +815,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
804
815
805
816
/* check if fd is a pipe */
806
817
HANDLE h = (HANDLE ) _get_osfhandle (fd );
807
- if (GetFileType (h ) != FILE_TYPE_PIPE )
818
+ if (GetFileType (h ) != FILE_TYPE_PIPE ) {
819
+ if (orig == EINVAL ) {
820
+ wchar_t path [MAX_PATH ];
821
+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
822
+ ARRAY_SIZE (path ), 0 );
823
+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
824
+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
825
+
826
+ /*
827
+ * The default atomic append causes such an error on
828
+ * network file systems, in such a case, it should be
829
+ * turned off via config.
830
+ *
831
+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
832
+ */
833
+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
834
+ warning ("invalid write operation detected; you may try:\n"
835
+ "\n\tgit config windows.appendAtomically false" );
836
+ }
837
+
808
838
errno = orig ;
809
- else if (orig == EINVAL )
839
+ } else if (orig == EINVAL )
810
840
errno = EPIPE ;
811
841
else {
812
842
DWORD buf_size ;
0 commit comments