@@ -1868,7 +1868,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
18681868 path_conv win32_oldpath;
18691869 PUNICODE_STRING final_oldpath, final_newpath;
18701870 UNICODE_STRING final_oldpath_buf;
1871- DWORD flags;
1871+ DWORD flags = 0 ;
18721872
18731873 if (isabspath (oldpath))
18741874 {
@@ -1929,14 +1929,39 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
19291929 wcpcpy (e_old, c_old);
19301930 }
19311931 }
1932- /* If the symlink target doesn't exist, don't create native symlink.
1933- Otherwise the directory flag in the symlink is potentially wrong
1934- when the target comes into existence, and native tools will fail.
1935- This is so screwball. This is no problem on AFS, fortunately . */
1936- if (! win32_oldpath.exists () && ! win32_oldpath.fs_is_afs ())
1932+
1933+ /* The directory flag in the symlink must match the target type,
1934+ otherwise native tools will fail (fortunately this is no problem
1935+ on AFS). Do our best to guess the symlink type correctly . */
1936+ if (win32_oldpath.exists () || win32_oldpath.fs_is_afs ())
19371937 {
1938- SetLastError (ERROR_FILE_NOT_FOUND);
1939- return -1 ;
1938+ /* If the target exists (or on AFS), check the target type. Note
1939+ that this may still be wrong if the target is changed after
1940+ creating the symlink (e.g. in bulk operations such as rsync,
1941+ unpacking archives or VCS checkouts). */
1942+ if (win32_oldpath.isdir ())
1943+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1944+ }
1945+ else
1946+ {
1947+ if (allow_winsymlinks == WSYM_nativestrict)
1948+ {
1949+ /* In nativestrict mode, if the target does not exist, use
1950+ trailing '/' in the target path as hint to create a
1951+ directory symlink. */
1952+ ssize_t len = strlen (oldpath);
1953+ if (len && isdirsep (oldpath[len - 1 ]))
1954+ flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
1955+ }
1956+ else
1957+ {
1958+ /* In native mode, if the target does not exist, fall back
1959+ to creating a Cygwin symlink file (or in case of MSys:
1960+ try to copy the (non-existing) target, which will of
1961+ course fail). */
1962+ SetLastError (ERROR_FILE_NOT_FOUND);
1963+ return -1 ;
1964+ }
19401965 }
19411966 /* Don't allow native symlinks to Cygwin special files. However, the
19421967 caller shoud know because this case shouldn't be covered by the
@@ -1965,7 +1990,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
19651990 final_oldpath->Buffer [1 ] = L' \\ ' ;
19661991 }
19671992 /* Try to create native symlink. */
1968- flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ;
19691993 if (wincap.has_unprivileged_createsymlink ())
19701994 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
19711995 if (!CreateSymbolicLinkW (final_newpath->Buffer , final_oldpath->Buffer ,
0 commit comments