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
@@ -545,6 +546,7 @@ static int is_local_named_pipe_path(const char *filename)
545
546
546
547
int mingw_open (const char * filename , int oflags , ...)
547
548
{
549
+ static int append_atomically = -1 ;
548
550
typedef int (* open_fn_t )(wchar_t const * wfilename , int oflags , ...);
549
551
va_list args ;
550
552
unsigned mode ;
@@ -561,7 +563,16 @@ int mingw_open (const char *filename, int oflags, ...)
561
563
return -1 ;
562
564
}
563
565
564
- if ((oflags & O_APPEND ) && !is_local_named_pipe_path (filename ))
566
+ /*
567
+ * Only set append_atomically to default value(1) when repo is initialized
568
+ * and fail to get config value
569
+ */
570
+ if (append_atomically < 0 && the_repository && the_repository -> commondir &&
571
+ git_config_get_bool ("windows.appendatomically" , & append_atomically ))
572
+ append_atomically = 1 ;
573
+
574
+ if (append_atomically && (oflags & O_APPEND ) &&
575
+ !is_local_named_pipe_path (filename ))
565
576
open_fn = mingw_open_append ;
566
577
else
567
578
open_fn = _wopen ;
@@ -710,8 +721,26 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
710
721
HANDLE h = (HANDLE ) _get_osfhandle (fd );
711
722
if (GetFileType (h ) == FILE_TYPE_PIPE )
712
723
errno = EPIPE ;
713
- else
724
+ else {
725
+ wchar_t path [MAX_PATH ];
726
+ DWORD ret = GetFinalPathNameByHandleW (h , path ,
727
+ ARRAY_SIZE (path ), 0 );
728
+ UINT drive_type = ret > 0 && ret < ARRAY_SIZE (path ) ?
729
+ GetDriveTypeW (path ) : DRIVE_UNKNOWN ;
730
+
731
+ /*
732
+ * The default atomic append causes such an error on
733
+ * network file systems, in such a case, it should be
734
+ * turned off via config.
735
+ *
736
+ * `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
737
+ */
738
+ if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type )
739
+ warning ("invalid write operation detected; you may try:\n"
740
+ "\n\tgit config windows.appendAtomically false" );
741
+
714
742
errno = EINVAL ;
743
+ }
715
744
}
716
745
717
746
return result ;
0 commit comments