Skip to content

Commit ea51c6d

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 e1fef0b + ec5a686 commit ea51c6d

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

Documentation/config.txt

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

546546
include::config/web.txt[]
547547

548+
include::config/windows.txt[]
549+
548550
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: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ static int is_local_named_pipe_path(const char *filename)
538538

539539
int mingw_open (const char *filename, int oflags, ...)
540540
{
541+
static int append_atomically = -1;
541542
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
542543
va_list args;
543544
unsigned mode;
@@ -554,7 +555,16 @@ int mingw_open (const char *filename, int oflags, ...)
554555
return -1;
555556
}
556557

557-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
558+
/*
559+
* Only set append_atomically to default value(1) when repo is initialized
560+
* and fail to get config value
561+
*/
562+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
563+
git_config_get_bool("windows.appendatomically", &append_atomically))
564+
append_atomically = 1;
565+
566+
if (append_atomically && (oflags & O_APPEND) &&
567+
!is_local_named_pipe_path(filename))
558568
open_fn = mingw_open_append;
559569
else
560570
open_fn = _wopen;
@@ -703,8 +713,26 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
703713
HANDLE h = (HANDLE) _get_osfhandle(fd);
704714
if (GetFileType(h) == FILE_TYPE_PIPE)
705715
errno = EPIPE;
706-
else
716+
else {
717+
wchar_t path[MAX_LONG_PATH];
718+
DWORD ret = GetFinalPathNameByHandleW(h, path,
719+
ARRAY_SIZE(path), 0);
720+
UINT drive_type = ret > 0 && ret < ARRAY_SIZE(path) ?
721+
GetDriveTypeW(path) : DRIVE_UNKNOWN;
722+
723+
/*
724+
* The default atomic append causes such an error on
725+
* network file systems, in such a case, it should be
726+
* turned off via config.
727+
*
728+
* `drive_type` of UNC path: DRIVE_NO_ROOT_DIR
729+
*/
730+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
731+
warning("invalid write operation detected; you may try:\n"
732+
"\n\tgit config windows.appendAtomically false");
733+
707734
errno = EINVAL;
735+
}
708736
}
709737

710738
return result;

0 commit comments

Comments
 (0)