]> git.ipfire.org Git - thirdparty/git.git/commitdiff
mingw: do resolve symlinks in `getcwd()`
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Tue, 16 Dec 2025 15:33:45 +0000 (15:33 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 17 Dec 2025 23:21:06 +0000 (08:21 +0900)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
compat/mingw.c

index f09b49ff21ddabafd5d712d967cb89f72ff0fd1c..cf4f3c92e7a88904cc01d856cd35dd31c9b00cea 100644 (file)
@@ -1239,18 +1239,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))
@@ -1259,13 +1257,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;