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