Skip to content

Commit a5a7c4c

Browse files
sunzhuoshidscho
authored andcommitted
Add config option windows.appendAtomically
Atomic append on windows is only supported on local disk files, and it may cause errors in other situations, e.g. network file system. If that is the case, this config option should be used to turn atomic append off. Co-Authored-By: Johannes Schindelin <[email protected]> Signed-off-by: 孙卓识 <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 235fe17 commit a5a7c4c

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
@@ -558,4 +558,6 @@ include::config/versionsort.adoc[]
558558

559559
include::config/web.adoc[]
560560

561+
include::config/windows.adoc[]
562+
561563
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"
@@ -621,6 +622,7 @@ static int is_local_named_pipe_path(const char *filename)
621622

622623
int mingw_open (const char *filename, int oflags, ...)
623624
{
625+
static int append_atomically = -1;
624626
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
625627
va_list args;
626628
unsigned mode;
@@ -639,7 +641,16 @@ int mingw_open (const char *filename, int oflags, ...)
639641
return -1;
640642
}
641643

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

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

0 commit comments

Comments
 (0)