Skip to content

Commit 4c75c86

Browse files
dschoGit for Windows Build Agent
authored and
Git for Windows Build Agent
committed
mingw: implement a platform-specific strbuf_realpath()
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 <[email protected]>
1 parent 7dbb0d3 commit 4c75c86

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

compat/mingw.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,37 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
12561256
return NULL;
12571257
}
12581258

1259+
char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
1260+
{
1261+
wchar_t wpath[MAX_PATH];
1262+
HANDLE h;
1263+
DWORD ret;
1264+
int len;
1265+
1266+
if (xutftowcs_path(wpath, path) < 0)
1267+
return NULL;
1268+
1269+
h = CreateFileW(wpath, 0,
1270+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
1271+
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1272+
if (h == INVALID_HANDLE_VALUE)
1273+
return NULL;
1274+
1275+
ret = GetFinalPathNameByHandleW(h, wpath, ARRAY_SIZE(wpath), 0);
1276+
CloseHandle(h);
1277+
if (!ret || ret >= ARRAY_SIZE(wpath))
1278+
return NULL;
1279+
1280+
len = wcslen(wpath) * 3;
1281+
strbuf_grow(resolved, len);
1282+
len = xwcstoutf(resolved->buf, normalize_ntpath(wpath), len);
1283+
if (len < 0)
1284+
return NULL;
1285+
resolved->len = len;
1286+
return resolved->buf;
1287+
1288+
}
1289+
12591290
char *mingw_getcwd(char *pointer, int len)
12601291
{
12611292
wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];

compat/mingw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ extern int (*win32_is_mount_point)(struct strbuf *path);
471471
#define PATH_SEP ';'
472472
char *mingw_query_user_email(void);
473473
#define query_user_email mingw_query_user_email
474+
char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path);
475+
#define platform_strbuf_realpath mingw_strbuf_realpath
474476
#if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800)
475477
#define PRIuMAX "I64u"
476478
#define PRId64 "I64d"

t/t3700-add.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ test_expect_success CASE_INSENSITIVE_FS 'path is case-insensitive' '
421421
git add "$downcased"
422422
'
423423

424-
test_expect_failure MINGW 'can add files via NTFS junctions' '
424+
test_expect_success MINGW 'can add files via NTFS junctions' '
425425
test_when_finished "cmd //c rmdir junction && rm -rf target" &&
426426
test_create_repo target &&
427427
cmd //c "mklink /j junction target" &&

0 commit comments

Comments
 (0)