Skip to content

Commit e4a0cd8

Browse files
dschoGit for Windows Build Agent
authored andcommitted
Merge branch 'optionally-dont-append-atomically-on-windows'
Fix append failure issue under remote directories git-for-windows#2753 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2 parents 52be839 + 0319277 commit e4a0cd8

3 files changed

Lines changed: 39 additions & 3 deletions

File tree

Documentation/config.adoc

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

562562
include::config/web.adoc[]
563563

564+
include::config/windows.adoc[]
565+
564566
include::config/worktree.adoc[]

Documentation/config/windows.adoc

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
@@ -8,6 +8,7 @@
88
#include "dir.h"
99
#include "environment.h"
1010
#include "gettext.h"
11+
#include "repository.h"
1112
#include "run-command.h"
1213
#include "strbuf.h"
1314
#include "symlinks.h"
@@ -766,6 +767,7 @@ static int is_local_named_pipe_path(const char *filename)
766767

767768
int mingw_open (const char *filename, int oflags, ...)
768769
{
770+
static int append_atomically = -1;
769771
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
770772
va_list args;
771773
unsigned mode;
@@ -785,7 +787,16 @@ int mingw_open (const char *filename, int oflags, ...)
785787
return -1;
786788
}
787789

788-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
790+
/*
791+
* Only set append_atomically to default value(1) when repo is initialized
792+
* and fail to get config value
793+
*/
794+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
795+
repo_config_get_bool(the_repository, "windows.appendatomically", &append_atomically))
796+
append_atomically = 1;
797+
798+
if (append_atomically && (oflags & O_APPEND) &&
799+
!is_local_named_pipe_path(filename))
789800
open_fn = mingw_open_append;
790801
else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT)))
791802
open_fn = mingw_open_existing;
@@ -964,9 +975,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
964975

965976
/* check if fd is a pipe */
966977
HANDLE h = (HANDLE) _get_osfhandle(fd);
967-
if (GetFileType(h) != FILE_TYPE_PIPE)
978+
if (GetFileType(h) != FILE_TYPE_PIPE) {
979+
if (orig == EINVAL) {
980+
wchar_t path[MAX_PATH];
981+
DWORD ret = GetFinalPathNameByHandleW(h, path,
982+
ARRAY_SIZE(path), 0);
983+
UINT drive_type = ret > 0 && ret < ARRAY_SIZE(path) ?
984+
GetDriveTypeW(path) : DRIVE_UNKNOWN;
985+
986+
/*
987+
* The default atomic append causes such an error on
988+
* network file systems, in such a case, it should be
989+
* turned off via config.
990+
*
991+
* `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
992+
*/
993+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
994+
warning("invalid write operation detected; you may try:\n"
995+
"\n\tgit config windows.appendAtomically false");
996+
}
997+
968998
errno = orig;
969-
else if (orig == EINVAL)
999+
} else if (orig == EINVAL)
9701000
errno = EPIPE;
9711001
else {
9721002
DWORD buf_size;

0 commit comments

Comments
 (0)