{"thread":{"id":"49648","subject":"[PATCH 0/2] Work around case-insensitivity issues with cwd on Windows","startedAt":"2018-10-23T10:52:50Z","lastAt":"2018-10-25T04:12:01Z","messageCount":12,"participants":["Johannes Schindelin via GitGitGadget","Anton Serbulov via GitGitGadget","Stephen & Linda Smith","Stephen Smith","Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"361278","messageId":"pull.54.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":null,"subject":"[PATCH 0/2] Work around case-insensitivity issues with cwd on Windows","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-23T10:52:46Z","receivedAt":"2018-10-23T10:52:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"On Windows, file names are recorded case-sensitively, but looked up\ncase-insensitively. Therefore, it is possible to switch to a directory by\nusing incorrect case, e.g. cd documentation will still get you into the \nDocumentation subdirectory.\n\nIn Powershell, doing so will however report the current directory with the\nspecified spelling rather than the one recorded on disk, and Git will get\nconfused.\n\nTo remedy that, we fixed this in Git for Windows more than three years ago,\nand needed only a small fix a couple of months later to accommodate for the\ndiverse scenarios encountered by the many Git for Windows users.\n\nNot only to keep the story closer to what happened historically, but also to\nmake it easier to follow, I refrained from squashing these two patches.\n\nSide note: the second patch is technically not battle-tested for that long:\nit uses an API function that requires Windows Vista or later, and we only\nrecently started to clean up Git for Windows' code to drop fallbacks for\nWindows XP. Read: this code used to load the GetFinalPathNameByHandle() \nfunction dynamically, and that is the only difference to the code that has\nbeen \"battle-tested\" for close to three years.\n\nAnton Serbulov (1):\n  mingw: fix getcwd when the parent directory cannot be queried\n\nJohannes Schindelin (1):\n  mingw: ensure `getcwd()` reports the correct case\n\n compat/mingw.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 file changed, 48 insertions(+), 2 deletions(-)\n\n\nbase-commit: c4df23f7927d8d00e666a3c8d1b3375f1dc8a3c1\nPublished-As: https://github.com/gitgitgadget/git/releases/tags/pr-54%2Fdscho%2Fmingw-getcwd-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-54/dscho/mingw-getcwd-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/54\n-- \ngitgitgadget\n"},{"id":"361279","messageId":"e13ae233822c8e4a4504e3294adf3e0de38a1990.1540291965.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":"pull.54.git.gitgitgadget@gmail.com","subject":"[PATCH 1/2] mingw: ensure `getcwd()` reports the correct case","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-23T10:52:48Z","receivedAt":"2018-10-23T10:52:51Z","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\nWhen switching the current working directory, say, in PowerShell, it is\nquite possible to use a different capitalization than the one that is\nrecorded on disk. While doing the same in `cmd.exe` adjusts the\ncapitalization magically, that does not happen in PowerShell so that\n`getcwd()` returns the current directory in a different way than is\nrecorded on disk.\n\nTypically this creates no problems except when you call\n\n\tgit log .\n\nin a subdirectory called, say, \"GIT/\" but you switched to \"Git/\" and\nyour `getcwd()` reports the latter, then Git won't understand that you\nwanted to see the history as per the `GIT/` subdirectory but it thinks you\nwanted to see the history of some directory that may have existed in the\npast (but actually never did).\n\nSo let's be extra careful to adjust the capitalization of the current\ndirectory before working with it.\n\nReported by a few PowerShell power users ;-)\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 11 +++++++++--\n 1 file changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 18caf2196..2c3e27ce9 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -917,8 +917,15 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)\n \n char *mingw_getcwd(char *pointer, int len)\n {\n-\twchar_t wpointer[MAX_PATH];\n-\tif (!_wgetcwd(wpointer, ARRAY_SIZE(wpointer)))\n+\twchar_t cwd[MAX_PATH], wpointer[MAX_PATH];\n+\tDWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);\n+\n+\tif (!ret || ret >= ARRAY_SIZE(cwd)) {\n+\t\terrno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());\n+\t\treturn NULL;\n+\t}\n+\tret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));\n+\tif (!ret || ret >= ARRAY_SIZE(wpointer))\n \t\treturn NULL;\n \tif (xwcstoutf(pointer, wpointer, len) < 0)\n \t\treturn NULL;\n-- \ngitgitgadget\n\n"},{"id":"361280","messageId":"3e3b1c3b1ff3363b216574f09d2c9cf22d25ad30.1540291965.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":"pull.54.git.gitgitgadget@gmail.com","subject":"[PATCH 2/2] mingw: fix getcwd when the parent directory cannot be queried","fromName":"Anton Serbulov via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-23T10:52:49Z","receivedAt":"2018-10-23T10:52:53Z","isPatch":true,"sender":{"key":"name:Anton Serbulov","avatar":null},"body":"From: Anton Serbulov <aserbulov@plesk.com>\n\n`GetLongPathName()` function may fail when it is unable to query\nthe parent directory of a path component to determine the long name\nfor that component. It happens, because of it uses `FindFirstFile()`\nfunction for each next short part of path. The `FindFirstFile()`\nrequires `List Directory` and `Synchronize` desired access for a calling\nprocess.\n\nIn case of lacking such permission for some part of path,\nthe `GetLongPathName()` returns 0 as result and `GetLastError()`\nreturns ERROR_ACCESS_DENIED.\n\n`GetFinalPathNameByHandle()` function can help in such cases, because\nit requires `Read Attributes` and `Synchronize` desired access to the\ntarget path only.\n\nThe `GetFinalPathNameByHandle()` function was introduced on\n`Windows Server 2008/Windows Vista`. So we need to load it dynamically.\n\n`CreateFile()` parameters:\n    `lpFileName` = path to the current directory\n    `dwDesiredAccess` = 0 (it means `Read Attributes` and `Synchronize`)\n    `dwShareMode` = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE\n                    (it prevents `Sharing Violation`)\n    `lpSecurityAttributes` = NULL (default security attributes)\n    `dwCreationDisposition` = OPEN_EXISTING\n                              (required to obtain a directory handle)\n    `dwFlagsAndAttributes` = FILE_FLAG_BACKUP_SEMANTICS\n                             (required to obtain a directory handle)\n    `hTemplateFile` = NULL (when opening an existing file or directory,\n                            `CreateFile` ignores this parameter)\n\nThe string that is returned by `GetFinalPathNameByHandle()` function\nuses the \\\\?\\ syntax. To skip the prefix and convert backslashes\nto slashes, the `normalize_ntpath()` mingw function will be used.\n\nNote: `GetFinalPathNameByHandle()` function returns a final path.\nIt is the path that is returned when a path is fully resolved.\nFor example, for a symbolic link named \"C:\\tmp\\mydir\" that points to\n\"D:\\yourdir\", the final path would be \"D:\\yourdir\".\n\nSigned-off-by: Anton Serbulov <aserbulov@plesk.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 39 +++++++++++++++++++++++++++++++++++++++\n 1 file changed, 39 insertions(+)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 2c3e27ce9..19addfa5d 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -202,6 +202,31 @@ static int ask_yes_no_if_possible(const char *format, ...)\n \t}\n }\n \n+/* Normalizes NT paths as returned by some low-level APIs. */\n+static wchar_t *normalize_ntpath(wchar_t *wbuf)\n+{\n+\tint i;\n+\t/* fix absolute path prefixes */\n+\tif (wbuf[0] == '\\\\') {\n+\t\t/* strip NT namespace prefixes */\n+\t\tif (!wcsncmp(wbuf, L\"\\\\??\\\\\", 4) ||\n+\t\t    !wcsncmp(wbuf, L\"\\\\\\\\?\\\\\", 4))\n+\t\t\twbuf += 4;\n+\t\telse if (!wcsnicmp(wbuf, L\"\\\\DosDevices\\\\\", 12))\n+\t\t\twbuf += 12;\n+\t\t/* replace remaining '...UNC\\' with '\\\\' */\n+\t\tif (!wcsnicmp(wbuf, L\"UNC\\\\\", 4)) {\n+\t\t\twbuf += 2;\n+\t\t\t*wbuf = '\\\\';\n+\t\t}\n+\t}\n+\t/* convert backslashes to slashes */\n+\tfor (i = 0; wbuf[i]; i++)\n+\t\tif (wbuf[i] == '\\\\')\n+\t\t\twbuf[i] = '/';\n+\treturn wbuf;\n+}\n+\n int mingw_unlink(const char *pathname)\n {\n \tint ret, tries = 0;\n@@ -925,6 +950,20 @@ char *mingw_getcwd(char *pointer, int len)\n \t\treturn NULL;\n \t}\n \tret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));\n+\tif (!ret && GetLastError() == ERROR_ACCESS_DENIED) {\n+\t\tHANDLE hnd = CreateFileW(cwd, 0,\n+\t\t\tFILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,\n+\t\t\tOPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\n+\t\tif (hnd == INVALID_HANDLE_VALUE)\n+\t\t\treturn NULL;\n+\t\tret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);\n+\t\tCloseHandle(hnd);\n+\t\tif (!ret || ret >= ARRAY_SIZE(wpointer))\n+\t\t\treturn NULL;\n+\t\tif (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)\n+\t\t\treturn NULL;\n+\t\treturn pointer;\n+\t}\n \tif (!ret || ret >= ARRAY_SIZE(wpointer))\n \t\treturn NULL;\n \tif (xwcstoutf(pointer, wpointer, len) < 0)\n-- \ngitgitgadget\n"},{"id":"361285","messageId":"6700297.8bfoVLpaf1@thunderbird","threadId":"49648","inReplyTo":"3e3b1c3b1ff3363b216574f09d2c9cf22d25ad30.1540291965.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/2] mingw: fix getcwd when the parent directory cannot be queried","fromName":"Stephen & Linda Smith","fromEmail":"ischis2@cox.net","sentAt":"2018-10-23T13:16:43Z","receivedAt":"2018-10-23T13:16:48Z","isPatch":true,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"On Tuesday, October 23, 2018 3:52:49 AM MST you wrote:\n> From: Anton Serbulov <aserbulov@plesk.com>\n> \n> `GetLongPathName()` function may fail when it is unable to query\n> the parent directory of a path component to determine the long name\n> for that component. It happens, because of it uses `FindFirstFile()`\ns/of it/it/\n\n> function for each next short part of path. The `FindFirstFile()`\n> requires `List Directory` and `Synchronize` desired access for a calling\n> process.\n\n\n\n\n\n"},{"id":"361286","messageId":"31438048.4iejHa56lk@thunderbird","threadId":"49648","inReplyTo":"6700297.8bfoVLpaf1@thunderbird","subject":"Re: [PATCH 2/2] mingw: fix getcwd when the parent directory cannot be queried","fromName":"Stephen Smith","fromEmail":"ischis2@cox.net","sentAt":"2018-10-23T13:20:27Z","receivedAt":"2018-10-23T13:20:29Z","isPatch":true,"sender":{"key":"ishchis2@gmail.com","avatar":null},"body":"On Tuesday, October 23, 2018 6:16:43 AM MST Stephen Smith wrote:\n> On Tuesday, October 23, 2018 3:52:49 AM MST you wrote:\n> > From: Anton Serbulov <aserbulov@plesk.com>\n> > \n> > `GetLongPathName()` function may fail when it is unable to query\n> > the parent directory of a path component to determine the long name\n> > for that component. It happens, because of it uses `FindFirstFile()`\n> \n> s/of it/it/\n> \n> > function for each next short part of path. The `FindFirstFile()`\n> > requires `List Directory` and `Synchronize` desired access for a calling\n> > process.\n\nBTW - It was \"Stephen\" that sent the email. :-)\n\n\n\n\n\n"},{"id":"361395","messageId":"nycvar.QRO.7.76.6.1810241118460.4546@tvgsbejvaqbjf.bet","threadId":"49648","inReplyTo":"6700297.8bfoVLpaf1@thunderbird","subject":"Re: [PATCH 2/2] mingw: fix getcwd when the parent directory cannot be queried","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-10-24T09:19:01Z","receivedAt":"2018-10-24T09:19:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stephen,\n\nOn Tue, 23 Oct 2018, Stephen & Linda Smith wrote:\n\n> On Tuesday, October 23, 2018 3:52:49 AM MST you wrote:\n> > From: Anton Serbulov <aserbulov@plesk.com>\n> > \n> > `GetLongPathName()` function may fail when it is unable to query\n> > the parent directory of a path component to determine the long name\n> > for that component. It happens, because of it uses `FindFirstFile()`\n> s/of it/it/\n\nThanks, fixed in v2,\nDscho\n\n> \n> > function for each next short part of path. The `FindFirstFile()`\n> > requires `List Directory` and `Synchronize` desired access for a calling\n> > process.\n> \n> \n> \n> \n> \n> \n"},{"id":"361396","messageId":"pull.54.v2.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":"pull.54.git.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] Work around case-insensitivity issues with cwd on Windows","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-24T09:19:39Z","receivedAt":"2018-10-24T09:19:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"On Windows, file names are recorded case-sensitively, but looked up\ncase-insensitively. Therefore, it is possible to switch to a directory by\nusing incorrect case, e.g. cd documentation will still get you into the \nDocumentation subdirectory.\n\nIn Powershell, doing so will however report the current directory with the\nspecified spelling rather than the one recorded on disk, and Git will get\nconfused.\n\nTo remedy that, we fixed this in Git for Windows more than three years ago,\nand needed only a small fix a couple of months later to accommodate for the\ndiverse scenarios encountered by the many Git for Windows users.\n\nNot only to keep the story closer to what happened historically, but also to\nmake it easier to follow, I refrained from squashing these two patches.\n\nSide note: the second patch is technically not battle-tested for that long:\nit uses an API function that requires Windows Vista or later, and we only\nrecently started to clean up Git for Windows' code to drop fallbacks for\nWindows XP. Read: this code used to load the GetFinalPathNameByHandle() \nfunction dynamically, and that is the only difference to the code that has\nbeen \"battle-tested\" for close to three years.\n\nChanges since v1:\n\n * Fixed a grammar mistake in the second commit message.\n\nAnton Serbulov (1):\n  mingw: fix getcwd when the parent directory cannot be queried\n\nJohannes Schindelin (1):\n  mingw: ensure `getcwd()` reports the correct case\n\n compat/mingw.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 file changed, 48 insertions(+), 2 deletions(-)\n\n\nbase-commit: c4df23f7927d8d00e666a3c8d1b3375f1dc8a3c1\nPublished-As: https://github.com/gitgitgadget/git/releases/tags/pr-54%2Fdscho%2Fmingw-getcwd-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-54/dscho/mingw-getcwd-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/54\n\nRange-diff vs v1:\n\n 1:  e13ae2338 = 1:  e13ae2338 mingw: ensure `getcwd()` reports the correct case\n 2:  3e3b1c3b1 ! 2:  87ef9ac63 mingw: fix getcwd when the parent directory cannot be queried\n     @@ -4,7 +4,7 @@\n      \n          `GetLongPathName()` function may fail when it is unable to query\n          the parent directory of a path component to determine the long name\n     -    for that component. It happens, because of it uses `FindFirstFile()`\n     +    for that component. It happens, because it uses `FindFirstFile()`\n          function for each next short part of path. The `FindFirstFile()`\n          requires `List Directory` and `Synchronize` desired access for a calling\n          process.\n\n-- \ngitgitgadget\n"},{"id":"361397","messageId":"87ef9ac6349fff6afc4d5cfc513f682f335a28f4.1540372778.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":"pull.54.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] mingw: fix getcwd when the parent directory cannot be queried","fromName":"Anton Serbulov via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-24T09:19:42Z","receivedAt":"2018-10-24T09:19:45Z","isPatch":true,"sender":{"key":"name:Anton Serbulov","avatar":null},"body":"From: Anton Serbulov <aserbulov@plesk.com>\n\n`GetLongPathName()` function may fail when it is unable to query\nthe parent directory of a path component to determine the long name\nfor that component. It happens, because it uses `FindFirstFile()`\nfunction for each next short part of path. The `FindFirstFile()`\nrequires `List Directory` and `Synchronize` desired access for a calling\nprocess.\n\nIn case of lacking such permission for some part of path,\nthe `GetLongPathName()` returns 0 as result and `GetLastError()`\nreturns ERROR_ACCESS_DENIED.\n\n`GetFinalPathNameByHandle()` function can help in such cases, because\nit requires `Read Attributes` and `Synchronize` desired access to the\ntarget path only.\n\nThe `GetFinalPathNameByHandle()` function was introduced on\n`Windows Server 2008/Windows Vista`. So we need to load it dynamically.\n\n`CreateFile()` parameters:\n    `lpFileName` = path to the current directory\n    `dwDesiredAccess` = 0 (it means `Read Attributes` and `Synchronize`)\n    `dwShareMode` = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE\n                    (it prevents `Sharing Violation`)\n    `lpSecurityAttributes` = NULL (default security attributes)\n    `dwCreationDisposition` = OPEN_EXISTING\n                              (required to obtain a directory handle)\n    `dwFlagsAndAttributes` = FILE_FLAG_BACKUP_SEMANTICS\n                             (required to obtain a directory handle)\n    `hTemplateFile` = NULL (when opening an existing file or directory,\n                            `CreateFile` ignores this parameter)\n\nThe string that is returned by `GetFinalPathNameByHandle()` function\nuses the \\\\?\\ syntax. To skip the prefix and convert backslashes\nto slashes, the `normalize_ntpath()` mingw function will be used.\n\nNote: `GetFinalPathNameByHandle()` function returns a final path.\nIt is the path that is returned when a path is fully resolved.\nFor example, for a symbolic link named \"C:\\tmp\\mydir\" that points to\n\"D:\\yourdir\", the final path would be \"D:\\yourdir\".\n\nSigned-off-by: Anton Serbulov <aserbulov@plesk.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 39 +++++++++++++++++++++++++++++++++++++++\n 1 file changed, 39 insertions(+)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 2c3e27ce9..19addfa5d 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -202,6 +202,31 @@ static int ask_yes_no_if_possible(const char *format, ...)\n \t}\n }\n \n+/* Normalizes NT paths as returned by some low-level APIs. */\n+static wchar_t *normalize_ntpath(wchar_t *wbuf)\n+{\n+\tint i;\n+\t/* fix absolute path prefixes */\n+\tif (wbuf[0] == '\\\\') {\n+\t\t/* strip NT namespace prefixes */\n+\t\tif (!wcsncmp(wbuf, L\"\\\\??\\\\\", 4) ||\n+\t\t    !wcsncmp(wbuf, L\"\\\\\\\\?\\\\\", 4))\n+\t\t\twbuf += 4;\n+\t\telse if (!wcsnicmp(wbuf, L\"\\\\DosDevices\\\\\", 12))\n+\t\t\twbuf += 12;\n+\t\t/* replace remaining '...UNC\\' with '\\\\' */\n+\t\tif (!wcsnicmp(wbuf, L\"UNC\\\\\", 4)) {\n+\t\t\twbuf += 2;\n+\t\t\t*wbuf = '\\\\';\n+\t\t}\n+\t}\n+\t/* convert backslashes to slashes */\n+\tfor (i = 0; wbuf[i]; i++)\n+\t\tif (wbuf[i] == '\\\\')\n+\t\t\twbuf[i] = '/';\n+\treturn wbuf;\n+}\n+\n int mingw_unlink(const char *pathname)\n {\n \tint ret, tries = 0;\n@@ -925,6 +950,20 @@ char *mingw_getcwd(char *pointer, int len)\n \t\treturn NULL;\n \t}\n \tret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));\n+\tif (!ret && GetLastError() == ERROR_ACCESS_DENIED) {\n+\t\tHANDLE hnd = CreateFileW(cwd, 0,\n+\t\t\tFILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,\n+\t\t\tOPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\n+\t\tif (hnd == INVALID_HANDLE_VALUE)\n+\t\t\treturn NULL;\n+\t\tret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);\n+\t\tCloseHandle(hnd);\n+\t\tif (!ret || ret >= ARRAY_SIZE(wpointer))\n+\t\t\treturn NULL;\n+\t\tif (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)\n+\t\t\treturn NULL;\n+\t\treturn pointer;\n+\t}\n \tif (!ret || ret >= ARRAY_SIZE(wpointer))\n \t\treturn NULL;\n \tif (xwcstoutf(pointer, wpointer, len) < 0)\n-- \ngitgitgadget\n"},{"id":"361398","messageId":"e13ae233822c8e4a4504e3294adf3e0de38a1990.1540372778.git.gitgitgadget@gmail.com","threadId":"49648","inReplyTo":"pull.54.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] mingw: ensure `getcwd()` reports the correct case","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2018-10-24T09:19:40Z","receivedAt":"2018-10-24T09:19:46Z","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\nWhen switching the current working directory, say, in PowerShell, it is\nquite possible to use a different capitalization than the one that is\nrecorded on disk. While doing the same in `cmd.exe` adjusts the\ncapitalization magically, that does not happen in PowerShell so that\n`getcwd()` returns the current directory in a different way than is\nrecorded on disk.\n\nTypically this creates no problems except when you call\n\n\tgit log .\n\nin a subdirectory called, say, \"GIT/\" but you switched to \"Git/\" and\nyour `getcwd()` reports the latter, then Git won't understand that you\nwanted to see the history as per the `GIT/` subdirectory but it thinks you\nwanted to see the history of some directory that may have existed in the\npast (but actually never did).\n\nSo let's be extra careful to adjust the capitalization of the current\ndirectory before working with it.\n\nReported by a few PowerShell power users ;-)\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 11 +++++++++--\n 1 file changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 18caf2196..2c3e27ce9 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -917,8 +917,15 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)\n \n char *mingw_getcwd(char *pointer, int len)\n {\n-\twchar_t wpointer[MAX_PATH];\n-\tif (!_wgetcwd(wpointer, ARRAY_SIZE(wpointer)))\n+\twchar_t cwd[MAX_PATH], wpointer[MAX_PATH];\n+\tDWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);\n+\n+\tif (!ret || ret >= ARRAY_SIZE(cwd)) {\n+\t\terrno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());\n+\t\treturn NULL;\n+\t}\n+\tret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));\n+\tif (!ret || ret >= ARRAY_SIZE(wpointer))\n \t\treturn NULL;\n \tif (xwcstoutf(pointer, wpointer, len) < 0)\n \t\treturn NULL;\n-- \ngitgitgadget\n\n"},{"id":"361403","messageId":"xmqqin1rmynw.fsf@gitster-ct.c.googlers.com","threadId":"49648","inReplyTo":"pull.54.v2.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] Work around case-insensitivity issues with cwd on Windows","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-10-24T10:22:59Z","receivedAt":"2018-10-24T10:23:05Z","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> Changes since v1:\n>\n>  * Fixed a grammar mistake in the second commit message.\n\nThanks.  I think this matches what I earlier queued on 'pu' with\nStephen's typofix squashed in, so we are good already.\n\n"},{"id":"361419","messageId":"nycvar.QRO.7.76.6.1810241720200.4546@tvgsbejvaqbjf.bet","threadId":"49648","inReplyTo":"xmqqin1rmynw.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v2 0/2] Work around case-insensitivity issues with cwd on Windows","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-10-24T15:20:43Z","receivedAt":"2018-10-24T15:20:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 24 Oct 2018, Junio C Hamano wrote:\n\n> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n> writes:\n> \n> > Changes since v1:\n> >\n> >  * Fixed a grammar mistake in the second commit message.\n> \n> Thanks.  I think this matches what I earlier queued on 'pu' with\n> Stephen's typofix squashed in, so we are good already.\n\nPerfect. Sorry that I forgot to check.\n\nCiao,\nDscho\n"},{"id":"361466","messageId":"xmqq8t2mll6b.fsf@gitster-ct.c.googlers.com","threadId":"49648","inReplyTo":"nycvar.QRO.7.76.6.1810241720200.4546@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/2] Work around case-insensitivity issues with cwd on Windows","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-10-25T04:11:56Z","receivedAt":"2018-10-25T04:12:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Wed, 24 Oct 2018, Junio C Hamano wrote:\n>\n>> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n>> writes:\n>> \n>> > Changes since v1:\n>> >\n>> >  * Fixed a grammar mistake in the second commit message.\n>> \n>> Thanks.  I think this matches what I earlier queued on 'pu' with\n>> Stephen's typofix squashed in, so we are good already.\n>\n> Perfect. Sorry that I forgot to check.\n\nThanks for double-checking, and I do appreciate the final version,\neven if it matches the version I would have in 'pu' if I perfectly\nfollowed all what was said in the review thread, as I am not always\nperfect.\n\n"}]}