From 6bec6be1b7d1b30e28ee350e98824403ba7962fa Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sat, 14 Jan 2017 21:10:37 +0100 Subject: [PATCH] Update libgit2 to 0.25.1 Signed-off-by: Sven Strickroth --- ext/libgit2 | 2 +- ...06-Deduplicate-code-Use-p_open-in-p_creat.patch | 33 ++++++ ...eFile-with-FILE_SHARE_DELETE-for-O_RDONLY.patch | 42 ------- ...it2-0007-Use-CreateFile-instead-of-_wopen.patch | 132 +++++++++++++++++++++ ...nfigure-default-file-share-mode-for-openi.patch | 129 ++++++++++++++++++++ src/Changelog.txt | 2 +- src/TGitCache/TGITCache.cpp | 3 +- 7 files changed, 298 insertions(+), 45 deletions(-) create mode 100644 ext/libgit2-0006-Deduplicate-code-Use-p_open-in-p_creat.patch delete mode 100644 ext/libgit2-0006-Use-CreateFile-with-FILE_SHARE_DELETE-for-O_RDONLY.patch create mode 100644 ext/libgit2-0007-Use-CreateFile-instead-of-_wopen.patch create mode 100644 ext/libgit2-0008-Allow-to-configure-default-file-share-mode-for-openi.patch diff --git a/ext/libgit2 b/ext/libgit2 index 5afd0f9b7..a6d833a29 160000 --- a/ext/libgit2 +++ b/ext/libgit2 @@ -1 +1 @@ -Subproject commit 5afd0f9b7b39ecab4b9334f678bdc2631990c945 +Subproject commit a6d833a29e100cae66d5144367e9102d093d4dbd diff --git a/ext/libgit2-0006-Deduplicate-code-Use-p_open-in-p_creat.patch b/ext/libgit2-0006-Deduplicate-code-Use-p_open-in-p_creat.patch new file mode 100644 index 000000000..26ab74f8a --- /dev/null +++ b/ext/libgit2-0006-Deduplicate-code-Use-p_open-in-p_creat.patch @@ -0,0 +1,33 @@ +From 86aa2578d8a1b8a8af8bb4589a28160c1b1b9fa6 Mon Sep 17 00:00:00 2001 +From: Sven Strickroth +Date: Sat, 14 Jan 2017 17:15:50 +0100 +Subject: [PATCH 1/4] Deduplicate code: Use p_open in p_creat + +Signed-off-by: Sven Strickroth +--- + src/win32/posix_w32.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c +index fea634b00..8c1aa7840 100644 +--- a/src/win32/posix_w32.c ++++ b/src/win32/posix_w32.c +@@ -301,14 +301,7 @@ int p_open(const char *path, int flags, ...) + + int p_creat(const char *path, mode_t mode) + { +- git_win32_path buf; +- +- if (git_win32_path_from_utf8(buf, path) < 0) +- return -1; +- +- return _wopen(buf, +- _O_WRONLY | _O_CREAT | _O_TRUNC | STANDARD_OPEN_FLAGS, +- mode & WIN32_MODE_MASK); ++ return p_open(path, _O_WRONLY | _O_CREAT | _O_TRUNC, mode); + } + + int p_getcwd(char *buffer_out, size_t size) +-- +2.11.0.windows.1 + diff --git a/ext/libgit2-0006-Use-CreateFile-with-FILE_SHARE_DELETE-for-O_RDONLY.patch b/ext/libgit2-0006-Use-CreateFile-with-FILE_SHARE_DELETE-for-O_RDONLY.patch deleted file mode 100644 index f534fa861..000000000 --- a/ext/libgit2-0006-Use-CreateFile-with-FILE_SHARE_DELETE-for-O_RDONLY.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 57dce6dd6fb6b1279dd73d14962ab04612cf316f Mon Sep 17 00:00:00 2001 -From: Sven Strickroth -Date: Sun, 8 Jan 2017 01:18:08 +0100 -Subject: [PATCH] Use CreateFile with FILE_SHARE_DELETE for O_RDONLY - -This prevents FILE_SHARED_VIOLATIONS when used in tools such as -TortoiseGit TGitCache, because the file is not locked. - -Signed-off-by: Sven Strickroth ---- - src/win32/posix_w32.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c -index fea634b00..9839b24cf 100644 ---- a/src/win32/posix_w32.c -+++ b/src/win32/posix_w32.c -@@ -295,6 +295,21 @@ int p_open(const char *path, int flags, ...) - mode = (mode_t)va_arg(arg_list, int); - va_end(arg_list); - } -+ else if (flags == O_RDONLY) { -+ // use CreateFile here, so that we can request FILE_SHARE_DELETE -+ HANDLE handle; -+ -+ SECURITY_ATTRIBUTES security_attributes; -+ security_attributes.nLength = sizeof(security_attributes); -+ security_attributes.lpSecurityDescriptor = NULL; -+ security_attributes.bInheritHandle = FALSE; -+ -+ handle = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); -+ if (handle == INVALID_HANDLE_VALUE) -+ return -1; -+ -+ return _open_osfhandle((intptr_t)handle, 0); -+ } - - return _wopen(buf, flags | STANDARD_OPEN_FLAGS, mode & WIN32_MODE_MASK); - } --- -2.11.0.windows.1 - diff --git a/ext/libgit2-0007-Use-CreateFile-instead-of-_wopen.patch b/ext/libgit2-0007-Use-CreateFile-instead-of-_wopen.patch new file mode 100644 index 000000000..84d646394 --- /dev/null +++ b/ext/libgit2-0007-Use-CreateFile-instead-of-_wopen.patch @@ -0,0 +1,132 @@ +From 5dcf147039be35b2e2443e3917c5ab0c3c2b3eb0 Mon Sep 17 00:00:00 2001 +From: Sven Strickroth +Date: Sat, 14 Jan 2017 18:20:59 +0100 +Subject: [PATCH 2/4] Use CreateFile instead of _wopen + +Signed-off-by: Sven Strickroth +--- + src/win32/posix_w32.c | 89 ++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 78 insertions(+), 11 deletions(-) + +diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c +index 8c1aa7840..a20ae9b2f 100644 +--- a/src/win32/posix_w32.c ++++ b/src/win32/posix_w32.c +@@ -26,15 +26,6 @@ + #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) + #endif + +-/* Options which we always provide to _wopen. +- * +- * _O_BINARY - Raw access; no translation of CR or LF characters +- * _O_NOINHERIT - Do not mark the created handle as inheritable by child processes. +- * The Windows default is 'not inheritable', but the CRT's default (following +- * POSIX convention) is 'inheritable'. We have no desire for our handles to be +- * inheritable on Windows, so specify the flag to get default behavior back. */ +-#define STANDARD_OPEN_FLAGS (_O_BINARY | _O_NOINHERIT) +- + /* Allowable mode bits on Win32. Using mode bits that are not supported on + * Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it + * so we simply remove them. +@@ -283,20 +274,96 @@ int p_symlink(const char *old, const char *new) + int p_open(const char *path, int flags, ...) + { + git_win32_path buf; +- mode_t mode = 0; ++ HANDLE handle; ++ DWORD desired_access; ++ DWORD creation_disposition; ++ DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL; ++ int osfhandle_flags = 0; + + if (git_win32_path_from_utf8(buf, path) < 0) + return -1; + + if (flags & O_CREAT) { + va_list arg_list; ++ mode_t mode = 0; + + va_start(arg_list, flags); + mode = (mode_t)va_arg(arg_list, int); + va_end(arg_list); ++ ++ if (!(mode & _S_IWRITE)) ++ flags_and_attributes = FILE_ATTRIBUTE_READONLY; ++ } ++ ++ /* we only support _O_BINARY and set this by default */ ++ if (flags & (_O_TEXT | _O_WTEXT | _O_U16TEXT | _O_U8TEXT)) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ /* currently unsupported */ ++ if (flags & (_O_SEQUENTIAL | _O_RANDOM | _O_TEMPORARY | _O_SHORT_LIVED)) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR | _O_APPEND)) { ++ case _O_RDONLY: ++ desired_access = GENERIC_READ; ++ osfhandle_flags = _O_RDONLY; ++ break; ++ case _O_WRONLY | _O_APPEND: ++ osfhandle_flags = _O_APPEND; ++ case _O_WRONLY: ++ desired_access = GENERIC_WRITE; ++ break; ++ case _O_RDWR | _O_APPEND: ++ osfhandle_flags = _O_APPEND; ++ case _O_RDWR: ++ desired_access = GENERIC_READ | GENERIC_WRITE; ++ break; ++ default: ++ /* invalid or unsupported flag (combination) */ ++ errno = EINVAL; ++ return -1; ++ } ++ ++ switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { ++ case 0: ++ creation_disposition = OPEN_EXISTING; ++ break; ++ ++ case _O_CREAT: ++ creation_disposition = OPEN_ALWAYS; ++ break; ++ ++ case _O_CREAT | _O_TRUNC: ++ creation_disposition = CREATE_ALWAYS; ++ break; ++ ++ case _O_CREAT | _O_EXCL: ++ case _O_CREAT | _O_TRUNC | _O_EXCL: ++ creation_disposition = CREATE_NEW; ++ break; ++ ++ case _O_TRUNC: ++ creation_disposition = TRUNCATE_EXISTING; ++ break; ++ ++ default: ++ /* _O_EXCL required O_CREAT to be set, IIRC this is no error in MSVC implementaton */ ++ errno = EINVAL; ++ return -1; ++ } ++ ++ handle = CreateFileW(buf, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, creation_disposition, flags_and_attributes, 0); ++ if (handle == INVALID_HANDLE_VALUE) ++ { ++ _dosmaperr(GetLastError()); ++ return -1; + } + +- return _wopen(buf, flags | STANDARD_OPEN_FLAGS, mode & WIN32_MODE_MASK); ++ return _open_osfhandle((intptr_t)handle, osfhandle_flags); + } + + int p_creat(const char *path, mode_t mode) +-- +2.11.0.windows.1 + diff --git a/ext/libgit2-0008-Allow-to-configure-default-file-share-mode-for-openi.patch b/ext/libgit2-0008-Allow-to-configure-default-file-share-mode-for-openi.patch new file mode 100644 index 000000000..f9817ff30 --- /dev/null +++ b/ext/libgit2-0008-Allow-to-configure-default-file-share-mode-for-openi.patch @@ -0,0 +1,129 @@ +From 005d051ce8dc252c7b0cac70b7f72e96cda57134 Mon Sep 17 00:00:00 2001 +From: Sven Strickroth +Date: Sat, 14 Jan 2017 18:39:32 +0100 +Subject: [PATCH 4/4] Allow to configure default file share mode for opening + files + +This can prevent FILE_SHARED_VIOLATIONS when used in tools such as TortoiseGit TGitCache and FILE_SHARE_DELETE, because files can be opened w/o being locked any more. + +Signed-off-by: Sven Strickroth +--- + CHANGELOG.md | 4 ++++ + include/git2/common.h | 12 ++++++++++++ + src/settings.c | 18 ++++++++++++++++++ + src/win32/posix.h | 2 ++ + src/win32/posix_w32.c | 4 +++- + 5 files changed, 39 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG.md b/CHANGELOG.md +index 6137efd71..060d8f7e3 100644 +--- a/CHANGELOG.md ++++ b/CHANGELOG.md +@@ -52,6 +52,10 @@ v0.25 + + ### API additions + ++* You can now set the default share modes on Windows for opening files using ++ `GIT_OPT_SET_WINDOWS_SHAREMODE` option with `git_libgit2_opts()`. ++ It is the counterpart to `GIT_OPT_GET_WINDOWS_SHAREMODE`. ++ + * You can now get the user-agent used by libgit2 using the + `GIT_OPT_GET_USER_AGENT` option with `git_libgit2_opts()`. + It is the counterpart to `GIT_OPT_SET_USER_AGENT`. +diff --git a/include/git2/common.h b/include/git2/common.h +index 99c99812b..f7ba89a33 100644 +--- a/include/git2/common.h ++++ b/include/git2/common.h +@@ -177,6 +177,8 @@ typedef enum { + GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, + GIT_OPT_SET_SSL_CIPHERS, + GIT_OPT_GET_USER_AGENT, ++ GIT_OPT_GET_WINDOWS_SHAREMODE, ++ GIT_OPT_SET_WINDOWS_SHAREMODE, + } git_libgit2_opt_t; + + /** +@@ -281,6 +283,16 @@ typedef enum { + * > - `user_agent` is the value that will be delivered as the + * > User-Agent header on HTTP requests. + * ++ * * opts(GIT_OPT_SET_WINDOWS_SHAREMODE, DWORD value) ++ * ++ * > Set the default share modes on Windows for opening files. ++ * > This can be used to add FILE_SHARE_DELETE. ++ * > The Windows default is: FILE_SHARE_READ | FILE_SHARE_WRITE. ++ * ++ * * opts(GIT_OPT_GET_WINDOWS_SHAREMODE, DWORD *value) ++ * ++ * > Get the default share modes on Windows for opening files. ++ * + * * opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled) + * + * > Enable strict input validation when creating new objects +diff --git a/src/settings.c b/src/settings.c +index 980233d88..3fa4bae8b 100644 +--- a/src/settings.c ++++ b/src/settings.c +@@ -217,6 +217,24 @@ int git_libgit2_opts(int key, ...) + } + break; + ++ case GIT_OPT_GET_WINDOWS_SHAREMODE: ++#ifdef GIT_WIN32 ++ *(va_arg(ap, DWORD *)) = git_posix_w32__windows_sharemode; ++#else ++ giterr_set(GITERR_INVALID, "cannot set windows share mode on non Windows builds"); ++ error = -1; ++#endif ++ break; ++ ++ case GIT_OPT_SET_WINDOWS_SHAREMODE: ++#ifdef GIT_WIN32 ++ git_posix_w32__windows_sharemode = (va_arg(ap, DWORD) & (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)); ++#else ++ giterr_set(GITERR_INVALID, "cannot set windows share mode on non Windows builds"); ++ error = -1; ++#endif ++ break; ++ + default: + giterr_set(GITERR_INVALID, "invalid option key"); + error = -1; +diff --git a/src/win32/posix.h b/src/win32/posix.h +index 73705fb2b..89d543b73 100644 +--- a/src/win32/posix.h ++++ b/src/win32/posix.h +@@ -14,6 +14,8 @@ + #include "utf-conv.h" + #include "dir.h" + ++extern DWORD git_posix_w32__windows_sharemode; ++ + typedef SOCKET GIT_SOCKET; + + #define p_lseek(f,n,w) _lseeki64(f, n, w) +diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c +index a20ae9b2f..3f4fa7d25 100644 +--- a/src/win32/posix_w32.c ++++ b/src/win32/posix_w32.c +@@ -18,6 +18,8 @@ + #include + #include + ++DWORD git_posix_w32__windows_sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE; ++ + #ifndef FILE_NAME_NORMALIZED + # define FILE_NAME_NORMALIZED 0 + #endif +@@ -356,7 +358,7 @@ int p_open(const char *path, int flags, ...) + return -1; + } + +- handle = CreateFileW(buf, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, creation_disposition, flags_and_attributes, 0); ++ handle = CreateFileW(buf, desired_access, git_posix_w32__windows_sharemode, NULL, creation_disposition, flags_and_attributes, 0); + if (handle == INVALID_HANDLE_VALUE) + { + _dosmaperr(GetLastError()); +-- +2.11.0.windows.1 + diff --git a/src/Changelog.txt b/src/Changelog.txt index b544969f0..a2394a885 100644 --- a/src/Changelog.txt +++ b/src/Changelog.txt @@ -20,7 +20,7 @@ Released: unreleased * Fixed issue #2865: Clickable URLs in TortoiseGit output window * Fixed issue #2154: Copy to clipboard function in show log window doesn't include annotated tag or notes messages * Fixed issue #1668: Allow submodules to be removed ("Delete" is now available for submodules) - * Update libgit2 to 0.25 + * Update libgit2 to 0.25.1 * Fixed issue #2863: Increase text box size limit for command progress dialog and make it configurable * Fixed issue #2274 and issue #2750 : Add advanced option for controlling which date/time is used for squashed commits (setting: SquashDate) 1: Use date of last commit, 2: Use current date, 0: Use time of first commit into which others are squashed (default) diff --git a/src/TGitCache/TGITCache.cpp b/src/TGitCache/TGITCache.cpp index df614a727..a1ea5f85d 100644 --- a/src/TGitCache/TGITCache.cpp +++ b/src/TGitCache/TGITCache.cpp @@ -1,7 +1,7 @@ // TortoiseGit - a Windows shell extension for easy version control // External Cache Copyright (C) 2005 - 2006,2010 - Will Dean, Stefan Kueng -// Copyright (C) 2008-2014, 2016 - TortoiseGit +// Copyright (C) 2008-2014, 2016-2017 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -184,6 +184,7 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR lp { SetDllDirectory(L""); git_libgit2_init(); + git_libgit2_opts(GIT_OPT_SET_WINDOWS_SHAREMODE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE); HandleCommandLine(lpCmdLine); CAutoGeneralHandle hReloadProtection = ::CreateMutex(nullptr, FALSE, GetCacheMutexName()); -- 2.11.4.GIT