Skip to content

Commit 042d0ec

Browse files
dschoGit for Windows Build Agent
authored and
Git for Windows Build Agent
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 eebb366 + 13d657d commit 042d0ec

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

Documentation/config.adoc

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

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

563+
include::config/windows.adoc[]
564+
563565
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
@@ -17,6 +17,7 @@
1717
#include "../trace2.h"
1818
#include "../symlinks.h"
1919
#include "../wrapper.h"
20+
#include "../repository.h"
2021
#include "dir.h"
2122
#include "gettext.h"
2223
#define SECURITY_WIN32
@@ -620,6 +621,7 @@ static int is_local_named_pipe_path(const char *filename)
620621

621622
int mingw_open (const char *filename, int oflags, ...)
622623
{
624+
static int append_atomically = -1;
623625
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
624626
va_list args;
625627
unsigned mode;
@@ -638,7 +640,16 @@ int mingw_open (const char *filename, int oflags, ...)
638640
return -1;
639641
}
640642

641-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
643+
/*
644+
* Only set append_atomically to default value(1) when repo is initialized
645+
* and fail to get config value
646+
*/
647+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
648+
git_config_get_bool("windows.appendatomically", &append_atomically))
649+
append_atomically = 1;
650+
651+
if (append_atomically && (oflags & O_APPEND) &&
652+
!is_local_named_pipe_path(filename))
642653
open_fn = mingw_open_append;
643654
else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT)))
644655
open_fn = mingw_open_existing;
@@ -804,9 +815,28 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
804815

805816
/* check if fd is a pipe */
806817
HANDLE h = (HANDLE) _get_osfhandle(fd);
807-
if (GetFileType(h) != FILE_TYPE_PIPE)
818+
if (GetFileType(h) != FILE_TYPE_PIPE) {
819+
if (orig == EINVAL) {
820+
wchar_t path[MAX_PATH];
821+
DWORD ret = GetFinalPathNameByHandleW(h, path,
822+
ARRAY_SIZE(path), 0);
823+
UINT drive_type = ret > 0 && ret < ARRAY_SIZE(path) ?
824+
GetDriveTypeW(path) : DRIVE_UNKNOWN;
825+
826+
/*
827+
* The default atomic append causes such an error on
828+
* network file systems, in such a case, it should be
829+
* turned off via config.
830+
*
831+
* `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
832+
*/
833+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
834+
warning("invalid write operation detected; you may try:\n"
835+
"\n\tgit config windows.appendAtomically false");
836+
}
837+
808838
errno = orig;
809-
else if (orig == EINVAL)
839+
} else if (orig == EINVAL)
810840
errno = EPIPE;
811841
else {
812842
DWORD buf_size;

0 commit comments

Comments
 (0)