Skip to content

Commit c38e4c7

Browse files
committed
Merge branch 'optionally-dont-append-atomically-on-windows'
Fix append failure issue under remote directories #2753 Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 990b30e + a966265 commit c38e4c7

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

Documentation/config.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,4 +556,6 @@ include::config/versionsort.txt[]
556556

557557
include::config/web.txt[]
558558

559+
include::config/windows.txt[]
560+
559561
include::config/worktree.txt[]

Documentation/config/windows.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
windows.appendAtomically::
2+
By default, append atomic API is used on windows. But it works only with
3+
local disk files, if you're working on a network file system, you should
4+
set it false to turn it off.

compat/mingw.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "gettext.h"
2222
#define SECURITY_WIN32
2323
#include <sspi.h>
24+
#include "../repository.h"
2425

2526
#define HCAST(type, handle) ((type)(intptr_t)handle)
2627

@@ -614,6 +615,7 @@ static int is_local_named_pipe_path(const char *filename)
614615

615616
int mingw_open (const char *filename, int oflags, ...)
616617
{
618+
static int append_atomically = -1;
617619
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
618620
va_list args;
619621
unsigned mode;
@@ -630,7 +632,16 @@ int mingw_open (const char *filename, int oflags, ...)
630632
return -1;
631633
}
632634

633-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
635+
/*
636+
* Only set append_atomically to default value(1) when repo is initialized
637+
* and fail to get config value
638+
*/
639+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
640+
git_config_get_bool("windows.appendatomically", &append_atomically))
641+
append_atomically = 1;
642+
643+
if (append_atomically && (oflags & O_APPEND) &&
644+
!is_local_named_pipe_path(filename))
634645
open_fn = mingw_open_append;
635646
else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT)))
636647
open_fn = mingw_open_existing;
@@ -781,9 +792,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
781792

782793
/* check if fd is a pipe */
783794
HANDLE h = (HANDLE) _get_osfhandle(fd);
784-
if (GetFileType(h) != FILE_TYPE_PIPE)
795+
if (GetFileType(h) != FILE_TYPE_PIPE) {
796+
if (orig == EINVAL) {
797+
wchar_t path[MAX_PATH];
798+
DWORD ret = GetFinalPathNameByHandleW(h, path,
799+
ARRAY_SIZE(path), 0);
800+
UINT drive_type = ret > 0 && ret < ARRAY_SIZE(path) ?
801+
GetDriveTypeW(path) : DRIVE_UNKNOWN;
802+
803+
/*
804+
* The default atomic append causes such an error on
805+
* network file systems, in such a case, it should be
806+
* turned off via config.
807+
*
808+
* `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
809+
*/
810+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
811+
warning("invalid write operation detected; you may try:\n"
812+
"\n\tgit config windows.appendAtomically false");
813+
}
814+
785815
errno = orig;
786-
else if (orig == EINVAL)
816+
} else if (orig == EINVAL)
787817
errno = EPIPE;
788818
else {
789819
DWORD buf_size;

0 commit comments

Comments
 (0)