{"thread":{"id":"63899","subject":"[PATCH 0/4] mingw: rename and open fixes","startedAt":"2025-08-03T21:25:20Z","lastAt":"2025-08-04T08:54:57Z","messageCount":7,"participants":["Johannes Schindelin via GitGitGadget","Matthias Aßhauer via GitGitGadget","Junio C Hamano","Oswald Buddenhagen"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"523356","messageId":"pull.1948.git.1754256318.gitgitgadget@gmail.com","threadId":"63899","inReplyTo":null,"subject":"[PATCH 0/4] mingw: rename and open fixes","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-03T21:25:14Z","receivedAt":"2025-08-03T21:25:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The recent change of mingw_rename() to use POSIX semantics had quite a bit\nof fall-out, breaking in pre-Windows 11 setups that use ReFS, and in a\ndifferent way on Windows Server 2016.\n\nWhile at it, this patch series also upstreams two related patches that\nmatured in Git for Windows for long enough already.\n\nJohannes Schindelin (3):\n  mingw: drop Windows 7-specific work-around\n  mingw_rename: support ReFS on Windows 2022\n  mingw: support Windows Server 2016 again\n\nMatthias Aßhauer (1):\n  mingw_open_existing: handle directories better\n\n Documentation/config/core.adoc |  6 ---\n compat/mingw.c                 | 93 +++++++++-------------------------\n 2 files changed, 23 insertions(+), 76 deletions(-)\n\n\nbase-commit: 866e6a391f466baeeb98bc585845ea638322c04b\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1948%2Fdscho%2Fmingw-rename-and-open-fixes-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1948/dscho/mingw-rename-and-open-fixes-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1948\n-- \ngitgitgadget\n"},{"id":"523357","messageId":"0995ecadaff56d2ff44c965763800ec892490bad.1754256318.git.gitgitgadget@gmail.com","threadId":"63899","inReplyTo":"pull.1948.git.1754256318.gitgitgadget@gmail.com","subject":"[PATCH 1/4] mingw_open_existing: handle directories better","fromName":"Matthias Aßhauer via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-03T21:25:15Z","receivedAt":"2025-08-03T21:25:21Z","isPatch":true,"sender":{"key":"mha1993@live.de","avatar":"https://avatars.githubusercontent.com/u/6178234?v=4"},"body":"From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= <mha1993@live.de>\n\nCreateFileW() requires FILE_FLAG_BACKUP_SEMANTICS to create a directory\nhandle [1] and errors out with ERROR_ACCESS_DENIED without this flag.\nFall back to accessing Directory handles this way.\n\n[1] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#directories\n\nThis fixes https://github.com/git-for-windows/git/issues/5068\n\nSigned-off-by: Matthias Aßhauer <mha1993@live.de>\n---\n compat/mingw.c | 21 ++++++++++++++++-----\n 1 file changed, 16 insertions(+), 5 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 5d69ae32f4b9..2dd5cbcaee0d 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -588,13 +588,24 @@ static int mingw_open_existing(const wchar_t *filename, int oflags, ...)\n \t\t\t     &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n \tif (handle == INVALID_HANDLE_VALUE) {\n \t\tDWORD err = GetLastError();\n+\t\tif (err == ERROR_ACCESS_DENIED) {\n+\t\t\tDWORD attrs = GetFileAttributesW(filename);\n+\t\t\tif (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))\n+\t\t\t\thandle = CreateFileW(filename, access,\n+\t\t\t\t\t\t\tFILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,\n+\t\t\t\t\t\t\t&security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_BACKUP_SEMANTICS, NULL);\n+\t\t}\n \n-\t\t/* See `mingw_open_append()` for why we have this conversion. */\n-\t\tif (err == ERROR_INVALID_PARAMETER)\n-\t\t\terr = ERROR_PATH_NOT_FOUND;\n+\t\tif (handle == INVALID_HANDLE_VALUE) {\n+\t\t\terr = GetLastError();\n \n-\t\terrno = err_win_to_posix(err);\n-\t\treturn -1;\n+\t\t\t/* See `mingw_open_append()` for why we have this conversion. */\n+\t\t\tif (err == ERROR_INVALID_PARAMETER)\n+\t\t\t\terr = ERROR_PATH_NOT_FOUND;\n+\n+\t\t\terrno = err_win_to_posix(err);\n+\t\t\treturn -1;\n+\t\t}\n \t}\n \n \tfd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY);\n-- \ngitgitgadget\n\n"},{"id":"523358","messageId":"6b4f062d82a80d82eb927cda7304d053b2984aba.1754256318.git.gitgitgadget@gmail.com","threadId":"63899","inReplyTo":"pull.1948.git.1754256318.gitgitgadget@gmail.com","subject":"[PATCH 2/4] mingw: drop Windows 7-specific work-around","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-03T21:25:16Z","receivedAt":"2025-08-03T21:25:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn ac33519ddfa8 (mingw: restrict file handle inheritance only on Windows\n7 and later, 2019-11-22), I introduced code to safe-guard the\ndefense-in-depth handling that restricts handles' inheritance so that it\nwould work with Windows 7, too.\n\nLet's revert this patch: Git for Windows dropped supporting Windows 7 (and\nWindows 8) directly after Git for Windows v2.46.2. For full details, see\nhttps://gitforwindows.org/requirements#windows-version.\n\nActually, on second thought: revert only the part that makes this handle\ninheritance restriction logic optional and that suggests to open a bug\nreport if it fails, but keep the fall-back to try again without said\nlogic: There have been a few false positives over the past few years\n(where the warning was triggered e.g. because Defender was still\naccessing a file that Git wanted to overwrite), and the fall-back logic\nseems to have helped occasionally in such situations.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config/core.adoc |  6 ---\n compat/mingw.c                 | 68 ++--------------------------------\n 2 files changed, 4 insertions(+), 70 deletions(-)\n\ndiff --git a/Documentation/config/core.adoc b/Documentation/config/core.adoc\nindex 9fde1ab63a70..3fbe83eef161 100644\n--- a/Documentation/config/core.adoc\n+++ b/Documentation/config/core.adoc\n@@ -696,12 +696,6 @@ core.unsetenvvars::\n \tDefaults to `PERL5LIB` to account for the fact that Git for\n \tWindows insists on using its own Perl interpreter.\n \n-core.restrictinheritedhandles::\n-\tWindows-only: override whether spawned processes inherit only standard\n-\tfile handles (`stdin`, `stdout` and `stderr`) or all handles. Can be\n-\t`auto`, `true` or `false`. Defaults to `auto`, which means `true` on\n-\tWindows 7 and later, and `false` on older Windows versions.\n-\n core.createObject::\n \tYou can set this to 'link', in which case a hardlink followed by\n \ta delete of the source are used to make sure that object creation\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 2dd5cbcaee0d..c331c3ac32a8 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -244,7 +244,6 @@ enum hide_dotfiles_type {\n \tHIDE_DOTFILES_DOTGITONLY\n };\n \n-static int core_restrict_inherited_handles = -1;\n static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;\n static char *unset_environment_variables;\n \n@@ -268,15 +267,6 @@ int mingw_core_config(const char *var, const char *value,\n \t\treturn 0;\n \t}\n \n-\tif (!strcmp(var, \"core.restrictinheritedhandles\")) {\n-\t\tif (value && !strcasecmp(value, \"auto\"))\n-\t\t\tcore_restrict_inherited_handles = -1;\n-\t\telse\n-\t\t\tcore_restrict_inherited_handles =\n-\t\t\t\tgit_config_bool(var, value);\n-\t\treturn 0;\n-\t}\n-\n \treturn 0;\n }\n \n@@ -1667,7 +1657,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen\n \t\t\t      const char *dir,\n \t\t\t      int prepend_cmd, int fhin, int fhout, int fherr)\n {\n-\tstatic int restrict_handle_inheritance = -1;\n \tSTARTUPINFOEXW si;\n \tPROCESS_INFORMATION pi;\n \tLPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL;\n@@ -1687,16 +1676,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen\n \t/* Make sure to override previous errors, if any */\n \terrno = 0;\n \n-\tif (restrict_handle_inheritance < 0)\n-\t\trestrict_handle_inheritance = core_restrict_inherited_handles;\n-\t/*\n-\t * The following code to restrict which handles are inherited seems\n-\t * to work properly only on Windows 7 and later, so let's disable it\n-\t * on Windows Vista and 2008.\n-\t */\n-\tif (restrict_handle_inheritance < 0)\n-\t\trestrict_handle_inheritance = GetVersion() >> 16 >= 7601;\n-\n \tdo_unset_environment_variables();\n \n \t/* Determine whether or not we are associated to a console */\n@@ -1798,7 +1777,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen\n \twenvblk = make_environment_block(deltaenv);\n \n \tmemset(&pi, 0, sizeof(pi));\n-\tif (restrict_handle_inheritance && stdhandles_count &&\n+\tif (stdhandles_count &&\n \t    (InitializeProcThreadAttributeList(NULL, 1, 0, &size) ||\n \t     GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&\n \t    (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST)\n@@ -1819,52 +1798,13 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen\n \t\t\t     &si.StartupInfo, &pi);\n \n \t/*\n-\t * On Windows 2008 R2, it seems that specifying certain types of handles\n-\t * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an\n-\t * error. Rather than playing finicky and fragile games, let's just try\n-\t * to detect this situation and simply try again without restricting any\n-\t * handle inheritance. This is still better than failing to create\n-\t * processes.\n+\t * On the off-chance that something with the file handle restriction\n+\t * went wrong, silently fall back to trying without it.\n \t */\n-\tif (!ret && restrict_handle_inheritance && stdhandles_count) {\n+\tif (!ret && stdhandles_count) {\n \t\tDWORD err = GetLastError();\n \t\tstruct strbuf buf = STRBUF_INIT;\n \n-\t\tif (err != ERROR_NO_SYSTEM_RESOURCES &&\n-\t\t    /*\n-\t\t     * On Windows 7 and earlier, handles on pipes and character\n-\t\t     * devices are inherited automatically, and cannot be\n-\t\t     * specified in the thread handle list. Rather than trying\n-\t\t     * to catch each and every corner case (and running the\n-\t\t     * chance of *still* forgetting a few), let's just fall\n-\t\t     * back to creating the process without trying to limit the\n-\t\t     * handle inheritance.\n-\t\t     */\n-\t\t    !(err == ERROR_INVALID_PARAMETER &&\n-\t\t      GetVersion() >> 16 < 9200) &&\n-\t\t    !getenv(\"SUPPRESS_HANDLE_INHERITANCE_WARNING\")) {\n-\t\t\tDWORD fl = 0;\n-\t\t\tint i;\n-\n-\t\t\tsetenv(\"SUPPRESS_HANDLE_INHERITANCE_WARNING\", \"1\", 1);\n-\n-\t\t\tfor (i = 0; i < stdhandles_count; i++) {\n-\t\t\t\tHANDLE h = stdhandles[i];\n-\t\t\t\tstrbuf_addf(&buf, \"handle #%d: %p (type %lx, \"\n-\t\t\t\t\t    \"handle info (%d) %lx\\n\", i, h,\n-\t\t\t\t\t    GetFileType(h),\n-\t\t\t\t\t    GetHandleInformation(h, &fl),\n-\t\t\t\t\t    fl);\n-\t\t\t}\n-\t\t\tstrbuf_addstr(&buf, \"\\nThis is a bug; please report it \"\n-\t\t\t\t      \"at\\nhttps://github.com/git-for-windows/\"\n-\t\t\t\t      \"git/issues/new\\n\\n\"\n-\t\t\t\t      \"To suppress this warning, please set \"\n-\t\t\t\t      \"the environment variable\\n\\n\"\n-\t\t\t\t      \"\\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1\"\n-\t\t\t\t      \"\\n\");\n-\t\t}\n-\t\trestrict_handle_inheritance = 0;\n \t\tflags &= ~EXTENDED_STARTUPINFO_PRESENT;\n \t\tret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,\n \t\t\t\t     TRUE, flags, wenvblk, dir ? wdir : NULL,\n-- \ngitgitgadget\n\n"},{"id":"523359","messageId":"768a84c8c6ec063717d4a935b86d8110ba0a00c6.1754256318.git.gitgitgadget@gmail.com","threadId":"63899","inReplyTo":"pull.1948.git.1754256318.gitgitgadget@gmail.com","subject":"[PATCH 3/4] mingw_rename: support ReFS on Windows 2022","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-03T21:25:17Z","receivedAt":"2025-08-03T21:25:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nReFS is an alternative filesystem to NTFS. On Windows 2022, it seems not\nto support the rename operation using POSIX semantics that Git uses on\nWindows as of 391bceae4350 (compat/mingw: support POSIX semantics for\natomic renames, 2024-10-27).\n\nHowever, Windows 2022 reports `ERROR_NOT_SUPPORTED` in this instance.\nThis is in contrast to `ERROR_INVALID_PARAMETER` (as previous Windows\nversions would report that do not support POSIX semantics in renames at\nall).\n\nLet's handle both errors the same: by falling back to the best-effort\noption, namely to rename without POSIX semantics.\n\nThis fixes https://github.com/git-for-windows/git/issues/5427\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex c331c3ac32a8..d53ce38b7f82 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -2277,7 +2277,7 @@ repeat:\n \t\t * current system doesn't support FileRenameInfoEx. Keep us\n \t\t * from using it in future calls and retry.\n \t\t */\n-\t\tif (gle == ERROR_INVALID_PARAMETER) {\n+\t\tif (gle == ERROR_INVALID_PARAMETER || gle == ERROR_NOT_SUPPORTED) {\n \t\t\tsupports_file_rename_info_ex = 0;\n \t\t\tgoto repeat;\n \t\t}\n-- \ngitgitgadget\n\n"},{"id":"523360","messageId":"51113ab9b81555387d5c4083b3c0ec3b0c2d2596.1754256318.git.gitgitgadget@gmail.com","threadId":"63899","inReplyTo":"pull.1948.git.1754256318.gitgitgadget@gmail.com","subject":"[PATCH 4/4] mingw: support Windows Server 2016 again","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-08-03T21:25:18Z","receivedAt":"2025-08-03T21:25:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIt was reported to the Git for Windows project that a simple `git init`\nfails on Windows Server 2016:\n\n  D:\\Dev\\test> git init\n  error: could not write config file D:/Dev/test/.git/config: Function not implemented\n  fatal: could not set 'core.repositoryformatversion' to '0'\n\nAccording to https://endoflife.date/windows-server, Windows Server 2016\nis officially supported for another one-and-a-half years as of time of\nwriting, so this is not good.\n\nThe culprit is the `mingw_rename()` changes that try to use POSIX\nsemantics when available, but fail to fall back properly on Windows\nServer 2016.\n\nThis fixes https://github.com/git-for-windows/git/issues/5695.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex d53ce38b7f82..8538e3d1729d 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -2277,7 +2277,9 @@ repeat:\n \t\t * current system doesn't support FileRenameInfoEx. Keep us\n \t\t * from using it in future calls and retry.\n \t\t */\n-\t\tif (gle == ERROR_INVALID_PARAMETER || gle == ERROR_NOT_SUPPORTED) {\n+\t\tif (gle == ERROR_INVALID_PARAMETER ||\n+\t\t    gle == ERROR_NOT_SUPPORTED ||\n+\t\t    gle == ERROR_INVALID_FUNCTION) {\n \t\t\tsupports_file_rename_info_ex = 0;\n \t\t\tgoto repeat;\n \t\t}\n-- \ngitgitgadget\n"},{"id":"523366","messageId":"xmqqbjoveuwk.fsf@gitster.g","threadId":"63899","inReplyTo":"pull.1948.git.1754256318.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/4] mingw: rename and open fixes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-04T01:29:47Z","receivedAt":"2025-08-04T01:29:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> The recent change of mingw_rename() to use POSIX semantics had quite a bit\n> of fall-out, breaking in pre-Windows 11 setups that use ReFS, and in a\n> different way on Windows Server 2016.\n>\n> While at it, this patch series also upstreams two related patches that\n> matured in Git for Windows for long enough already.\n\nThanks.  What a great timing, just before the -rc0 preview release\n;-)\n\nWill apply directly to 'master'.\n\n\n\n\n> Johannes Schindelin (3):\n>   mingw: drop Windows 7-specific work-around\n>   mingw_rename: support ReFS on Windows 2022\n>   mingw: support Windows Server 2016 again\n>\n> Matthias Aßhauer (1):\n>   mingw_open_existing: handle directories better\n>\n>  Documentation/config/core.adoc |  6 ---\n>  compat/mingw.c                 | 93 +++++++++-------------------------\n>  2 files changed, 23 insertions(+), 76 deletions(-)\n>\n>\n> base-commit: 866e6a391f466baeeb98bc585845ea638322c04b\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1948%2Fdscho%2Fmingw-rename-and-open-fixes-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1948/dscho/mingw-rename-and-open-fixes-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1948\n"},{"id":"523400","messageId":"aJB1Xkr09XNjb-ON@ugly","threadId":"63899","inReplyTo":"6b4f062d82a80d82eb927cda7304d053b2984aba.1754256318.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/4] mingw: drop Windows 7-specific work-around","fromName":"Oswald Buddenhagen","fromEmail":"oswald.buddenhagen@gmx.de","sentAt":"2025-08-04T08:54:54Z","receivedAt":"2025-08-04T08:54:57Z","isPatch":true,"sender":{"key":"oswald.buddenhagen@gmx.de","avatar":"https://avatars.githubusercontent.com/u/812380?v=4"},"body":"On Sun, Aug 03, 2025 at 09:25:16PM +0000, Johannes Schindelin via GitGitGadget wrote:\n>From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>\n>In ac33519ddfa8 (mingw: restrict file handle inheritance only on Windows\n>7 and later, 2019-11-22), I introduced code to safe-guard the\n>defense-in-depth handling that restricts handles' inheritance so that it\n>would work with Windows 7, too.\n>\n>Let's revert this patch: Git for Windows dropped supporting Windows 7 (and\n>Windows 8) directly after Git for Windows v2.46.2.\n>\nit doesn't follow from this why it's apparently ok to remove this for \neven newer versions.\n\n>+\t * On the off-chance that something with the file handle restriction\n>+\t * went wrong, silently fall back to trying without it.\n> \t */\n>+\tif (!ret && stdhandles_count) {\n>\nthe comment should really spell out what that off chance is, so one \ndoesn't have to check the log.\n\nit may also make sense to elaborate why just dropping the restrictions \nisn't a problem - my first thought is \"huh, doesn't this open the door \nfor security holes, at least theoretically?\"\n\n"}]}