[PATCH 12/18] mingw: allow `mingw_chdir()` to change to symlink-resolved directories
- From
Karsten Blees via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Dec 17, 2025, 14:08 UTC
- Message-ID
- <49920839bb2f9e21d1cf91e54024ecd986fe32a9.1765980535.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2018.git.1765980535.gitgitgadget@gmail.com>
From: Karsten Blees <blees@dcon.de>
If symlinks are enabled, resolve all symlinks when changing directories, as required by POSIX.
Note: Git's `real_path()` function bases its link resolution algorithm on this property of `chdir()`. Unfortunately, the current directory on Windows is limited to only MAX_PATH (260) characters. Therefore using symlinks and long paths in combination may be problematic.
Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- compat/mingw.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/compat/mingw.c b/compat/mingw.c index 55f0bb478e..5d2a8c247c 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -866,9 +866,27 @@ int mingw_access(const char *filename, int mode) int mingw_chdir(const char *dirname) { wchar_t wdirname[MAX_PATH]; + if (xutftowcs_path(wdirname, dirname) < 0) return -1; - return _wchdir(wdirname); + + if (has_symlinks) { + HANDLE hnd = CreateFileW(wdirname, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (hnd == INVALID_HANDLE_VALUE) { + errno = err_win_to_posix(GetLastError()); + return -1; + } + if (!GetFinalPathNameByHandleW(hnd, wdirname, ARRAY_SIZE(wdirname), 0)) { + errno = err_win_to_posix(GetLastError()); + CloseHandle(hnd); + return -1; + } + CloseHandle(hnd); + } + + return _wchdir(normalize_ntpath(wdirname)); } int mingw_chmod(const char *filename, int mode)
-- gitgitgadget