Skip to content

Commit 204cce6

Browse files
committed
win32: add symbolic link support
Enable `p_symlink` to actually create symbolic links, not just create a fake link (a text file containing the link target). This now means that `core.symlinks=true` works on Windows platforms where symbolic links are enabled (likely due to running in Developer Mode).
1 parent e4ac400 commit 204cce6

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

src/win32/posix_w32.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
3030
#endif
3131

32+
#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
33+
# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x02
34+
#endif
35+
3236
/* Allowable mode bits on Win32. Using mode bits that are not supported on
3337
* Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it
3438
* so we simply remove them.
@@ -390,12 +394,20 @@ int p_readlink(const char *path, char *buf, size_t bufsiz)
390394
return (int)bufsiz;
391395
}
392396

393-
int p_symlink(const char *old, const char *new)
397+
int p_symlink(const char *target, const char *path)
394398
{
395-
/* Real symlinks on NTFS require admin privileges. Until this changes,
396-
* libgit2 just creates a text file with the link target in the contents.
397-
*/
398-
return git_futils_fake_symlink(old, new);
399+
git_win32_path target_w, path_w;
400+
wchar_t *target_p;
401+
402+
if (git_win32_path_from_utf8(path_w, path) < 0 ||
403+
git__utf8_to_16(target_w, MAX_PATH, target) < 0)
404+
return -1;
405+
406+
if (!CreateSymbolicLinkW(path_w, target_w,
407+
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
408+
return -1;
409+
410+
return 0;
399411
}
400412

401413
struct open_opts {

0 commit comments

Comments
 (0)