Skip to content

Commit 08692d4

Browse files
sunzhuoshidscho
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. Signed-off-by: 孙卓识 <[email protected]> Co-Authored-By: Johannes Schindelin <[email protected]>
1 parent 9b2e006 commit 08692d4

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

Documentation/config.txt

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

501501
include::config/web.txt[]
502502

503+
include::config/windows.txt[]
504+
503505
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: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ static int is_local_named_pipe_path(const char *filename)
743743

744744
int mingw_open (const char *filename, int oflags, ...)
745745
{
746+
static int append_atomically = -1;
746747
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
747748
va_list args;
748749
unsigned mode;
@@ -759,7 +760,16 @@ int mingw_open (const char *filename, int oflags, ...)
759760
return -1;
760761
}
761762

762-
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
763+
/*
764+
* Only set append_atomically to default value(1) when repo is initialized
765+
* and fail to get config value
766+
*/
767+
if (append_atomically < 0 && the_repository && the_repository->commondir &&
768+
git_config_get_bool("windows.appendatomically", &append_atomically))
769+
append_atomically = 1;
770+
771+
if (append_atomically && (oflags & O_APPEND) &&
772+
!is_local_named_pipe_path(filename))
763773
open_fn = mingw_open_append;
764774
else
765775
open_fn = _wopen;
@@ -908,8 +918,24 @@ ssize_t mingw_write(int fd, const void *buf, size_t len)
908918
HANDLE h = (HANDLE) _get_osfhandle(fd);
909919
if (GetFileType(h) == FILE_TYPE_PIPE)
910920
errno = EPIPE;
911-
else
921+
else {
922+
wchar_t path[MAX_LONG_PATH];
923+
912924
errno = EINVAL;
925+
/*
926+
* default atomic append causes such error on network file system,
927+
* in such case, it should be turned off via config.
928+
*/
929+
DWORD ret = GetFinalPathNameByHandleW(h, path,
930+
ARRAY_SIZE(path), 0);
931+
if (ret > 0 && ret < ARRAY_SIZE(path)) {
932+
UINT drive_type = GetDriveTypeW(path);
933+
/* drive type of UNC path: DRIVE_NO_ROOT_DIR */
934+
if (DRIVE_NO_ROOT_DIR == drive_type || DRIVE_REMOTE == drive_type)
935+
warning("invalid write operation detected, "
936+
"you may try to set config windows.appendAtomically to 0.");
937+
}
938+
}
913939
}
914940

915941
return result;

0 commit comments

Comments
 (0)