[PATCH v2 12/18] mingw: allow `mingw_chdir()` to change to symlink-resolved directories
- From
Karsten Blees via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Jan 9, 2026, 20:05 UTC
- Message-ID
- <f79cf31dab8fab373978a382d71877803d89c8f7.1767989115.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2018.v2.git.1767989115.gitgitgadget@gmail.com>
From: Karsten Blees <karsten.blees@gmail.com>
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 <karsten.blees@gmail.com> 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