git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/5] mingw: do resolve symlinks in `getcwd()`

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Dec 16, 2025, 15:33 UTC
Message-ID
<1928738b464915e3fb796145688bbfcfcc0fee3c.1765899229.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.2017.git.1765899229.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>

As pointed out in https://github.com/git-for-windows/git/issues/1676, the `git rev-parse --is-inside-work-tree` command currently fails when the current directory's path contains symbolic links.

The underlying reason for this bug is that `getcwd()` is supposed to resolve symbolic links, but our `mingw_getcwd()` implementation did not.

We do have all the building blocks for that, though: the `GetFinalPathByHandleW()` function will resolve symbolic links. However, we only called that function if `GetLongPathNameW()` failed, for historical reasons: the latter function was supported for a long time, but the former API function was introduced only with Windows Vista, and we used to support also Windows XP. With that support having been dropped, we are free to call the symbolic link-resolving function right away.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 compat/mingw.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index ba1b7b6dd1..7215b127cc 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1251,18 +1251,16 @@ char *mingw_getcwd(char *pointer, int len)
 {
 	wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
 	DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);
+	HANDLE hnd;
 
 	if (!ret || ret >= ARRAY_SIZE(cwd)) {
 		errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
 		return NULL;
 	}
-	ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
-	if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
-		HANDLE hnd = CreateFileW(cwd, 0,
-			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
-			OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-		if (hnd == INVALID_HANDLE_VALUE)
-			return NULL;
+	hnd = CreateFileW(cwd, 0,
+			  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+			  OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+	if (hnd != INVALID_HANDLE_VALUE) {
 		ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
 		CloseHandle(hnd);
 		if (!ret || ret >= ARRAY_SIZE(wpointer))
@@ -1271,13 +1269,11 @@ char *mingw_getcwd(char *pointer, int len)
 			return NULL;
 		return pointer;
 	}
-	if (!ret || ret >= ARRAY_SIZE(wpointer))
-		return NULL;
-	if (GetFileAttributesW(wpointer) == INVALID_FILE_ATTRIBUTES) {
+	if (GetFileAttributesW(cwd) == INVALID_FILE_ATTRIBUTES) {
 		errno = ENOENT;
 		return NULL;
 	}
-	if (xwcstoutf(pointer, wpointer, len) < 0)
+	if (xwcstoutf(pointer, cwd, len) < 0)
 		return NULL;
 	convert_slashes(pointer);
 	return pointer;
-- 
gitgitgadget
Previous: Johannes Schindelin via GitGitGadgetNext: Patrick Steinhardt
Message 2 of 21 in “Last preparations before upstreaming Git for Windows' symlink support”
  1. 0/5 Last preparations before upstreaming Git for Windows' symlink supportJohannes Schindelin via GitGitGadget, Dec 16, 2025
  2. 1/5 mingw: do resolve symlinks in `getcwd()`Johannes Schindelin via GitGitGadget, Dec 16, 2025
  3. Patrick SteinhardtDec 17, 2025
  4. 2/5 init: do parse _all_ core.* settings earlyJohannes Schindelin via GitGitGadget, Dec 16, 2025
  5. Patrick SteinhardtDec 17, 2025
  6. 3/5 strbuf_readlink(): avoid calling `readlink()` twice in corner-casesKarsten Blees via GitGitGadget, Dec 16, 2025
  7. 4/5 strbuf_readlink(): support link targets that exceed PATH_MAXKarsten Blees via GitGitGadget, Dec 16, 2025
  8. Patrick SteinhardtDec 17, 2025
  9. Johannes SchindelinDec 19, 2025
  10. Patrick SteinhardtDec 19, 2025
  11. Junio C HamanoDec 30, 2025
  12. Junio C HamanoDec 17, 2025
  13. 5/5 trim_last_path_component(): avoid hard-coding the directory separatorKarsten Blees via GitGitGadget, Dec 16, 2025
  14. 0/5 Last preparations before upstreaming Git for Windows' symlink supportJohannes Schindelin via GitGitGadget, Jan 9, 2026
  15. 1/5 mingw: do resolve symlinks in `getcwd()`Johannes Schindelin via GitGitGadget, Jan 9, 2026
  16. 2/5 init: do parse _all_ core.* settings earlyJohannes Schindelin via GitGitGadget, Jan 9, 2026
  17. 3/5 strbuf_readlink(): avoid calling `readlink()` twice in corner-casesKarsten Blees via GitGitGadget, Jan 9, 2026
  18. 4/5 strbuf_readlink(): support link targets that exceed 2*PATH_MAXJohannes Schindelin via GitGitGadget, Jan 9, 2026
  19. 5/5 trim_last_path_component(): avoid hard-coding the directory separatorKarsten Blees via GitGitGadget, Jan 9, 2026
  20. Junio C HamanoJan 11, 2026
  21. Patrick SteinhardtJan 12, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.