18
18
#include "gettext.h"
19
19
#define SECURITY_WIN32
20
20
#include <sspi.h>
21
+ #include "../repository.h"
21
22
22
23
#define HCAST (type , handle ) ((type)(intptr_t)handle)
23
24
@@ -547,6 +548,7 @@ static int is_local_named_pipe_path(const char *filename)
547
548
548
549
int mingw_open (const char * filename , int oflags , ...)
549
550
{
551
+ static int append_atomically = -1 ;
550
552
typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
551
553
va_list args ;
552
554
unsigned mode ;
@@ -563,7 +565,16 @@ int mingw_open (const char *filename, int oflags, ...)
563
565
return -1 ;
564
566
}
565
567
566
- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
568
+ /*
569
+ * Only set append_atomically to default value(1) when repo is initialized
570
+ * and fail to get config value
571
+ */
572
+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
573
+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
574
+ append_atomically = 1 ;
575
+
576
+ if (append_atomically && (oflags & O_APPEND ) &&
577
+ !is_local_named_pipe_path (filename ))
567
578
open_fn = mingw_open_append ;
568
579
else
569
580
open_fn = _wopen ;
@@ -712,9 +723,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
712
723
713
724
/* check if fd is a pipe */
714
725
HANDLE h = (HANDLE ) _get_osfhandle (fd );
715
- if (GetFileType (h ) != FILE_TYPE_PIPE )
726
+ if (GetFileType (h ) != FILE_TYPE_PIPE ) {
727
+ if (orig == EINVAL ) {
728
+ wchar_t path [MAX_PATH ];
729
+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
730
+ ARRAY_SIZE (path ), 0 );
731
+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
732
+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
733
+
734
+ /*
735
+ * The default atomic append causes such an error on
736
+ * network file systems, in such a case, it should be
737
+ * turned off via config.
738
+ *
739
+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
740
+ */
741
+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
742
+ warning ("invalid write operation detected; you may try:\n"
743
+ "\n\tgit config windows.appendAtomically false" );
744
+ }
745
+
716
746
errno = orig ;
717
- else if (orig == EINVAL )
747
+ } else if (orig == EINVAL )
718
748
errno = EPIPE ;
719
749
else {
720
750
DWORD buf_size ;
0 commit comments