Skip to content

Commit

Permalink
mingw: implement a platform-specific strbuf_realpath()
Browse files Browse the repository at this point in the history
There is a Win32 API function to resolve symbolic links, and we can use
that instead of resolving them manually. Even better, this function also
resolves NTFS junction points (which are somewhat similar to bind
mounts).

This fixes #2481.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho authored and Git for Windows Build Agent committed Feb 1, 2020
1 parent 25bb30c commit 11583be
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
31 changes: 31 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,37 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
return NULL;
}

char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
{
wchar_t wpath[MAX_PATH];
HANDLE h;
DWORD ret;
int len;

if (xutftowcs_path(wpath, path) < 0)
return NULL;

h = CreateFileW(wpath, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return NULL;

ret = GetFinalPathNameByHandleW(h, wpath, ARRAY_SIZE(wpath), 0);
CloseHandle(h);
if (!ret || ret >= ARRAY_SIZE(wpath))
return NULL;

len = wcslen(wpath) * 3;
strbuf_grow(resolved, len);
len = xwcstoutf(resolved->buf, normalize_ntpath(wpath), len);
if (len < 0)
return NULL;
resolved->len = len;
return resolved->buf;

}

char *mingw_getcwd(char *pointer, int len)
{
wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
Expand Down
2 changes: 2 additions & 0 deletions compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ extern int (*win32_is_mount_point)(struct strbuf *path);
#define PATH_SEP ';'
char *mingw_query_user_email(void);
#define query_user_email mingw_query_user_email
char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path);
#define platform_strbuf_realpath mingw_strbuf_realpath
#if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800)
#define PRIuMAX "I64u"
#define PRId64 "I64d"
Expand Down
2 changes: 1 addition & 1 deletion t/t3700-add.sh
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ test_expect_success CASE_INSENSITIVE_FS 'path is case-insensitive' '
git add "$downcased"
'

test_expect_failure MINGW 'can add files via NTFS junctions' '
test_expect_success MINGW 'can add files via NTFS junctions' '
test_when_finished "cmd //c rmdir junction && rm -rf target" &&
test_create_repo target &&
cmd //c "mklink /j junction target" &&
Expand Down

0 comments on commit 11583be

Please sign in to comment.