9
9
#include "win32/lazyload.h"
10
10
#include "../config.h"
11
11
#include "dir.h"
12
+ #include "../attr.h"
12
13
13
14
#define HCAST (type , handle ) ((type)(intptr_t)handle)
14
15
@@ -2404,7 +2405,38 @@ int link(const char *oldpath, const char *newpath)
2404
2405
return 0 ;
2405
2406
}
2406
2407
2407
- int symlink (const char * target , const char * link )
2408
+ enum symlink_type {
2409
+ SYMLINK_TYPE_UNSPECIFIED = 0 ,
2410
+ SYMLINK_TYPE_FILE ,
2411
+ SYMLINK_TYPE_DIRECTORY ,
2412
+ };
2413
+
2414
+ static enum symlink_type check_symlink_attr (struct index_state * index , const char * link )
2415
+ {
2416
+ static struct attr_check * check ;
2417
+ const char * value ;
2418
+
2419
+ if (!index )
2420
+ return SYMLINK_TYPE_UNSPECIFIED ;
2421
+
2422
+ if (!check )
2423
+ check = attr_check_initl ("symlink" , NULL );
2424
+
2425
+ git_check_attr (index , link , check );
2426
+
2427
+ value = check -> items [0 ].value ;
2428
+ if (ATTR_UNSET (value ))
2429
+ return SYMLINK_TYPE_UNSPECIFIED ;
2430
+ if (!strcmp (value , "file" ))
2431
+ return SYMLINK_TYPE_FILE ;
2432
+ if (!strcmp (value , "dir" ) || !strcmp (value , "directory" ))
2433
+ return SYMLINK_TYPE_DIRECTORY ;
2434
+
2435
+ warning (_ ("ignoring invalid symlink type '%s' for '%s'" ), value , link );
2436
+ return SYMLINK_TYPE_UNSPECIFIED ;
2437
+ }
2438
+
2439
+ int mingw_create_symlink (struct index_state * index , const char * target , const char * link )
2408
2440
{
2409
2441
wchar_t wtarget [MAX_LONG_PATH ], wlink [MAX_LONG_PATH ];
2410
2442
int len ;
@@ -2424,7 +2456,31 @@ int symlink(const char *target, const char *link)
2424
2456
if (wtarget [len ] == '/' )
2425
2457
wtarget [len ] = '\\' ;
2426
2458
2427
- return create_phantom_symlink (wtarget , wlink );
2459
+ switch (check_symlink_attr (index , link )) {
2460
+ case SYMLINK_TYPE_UNSPECIFIED :
2461
+ /* Create a phantom symlink: it is initially created as a file
2462
+ * symlink, but may change to a directory symlink later if/when
2463
+ * the target exists. */
2464
+ return create_phantom_symlink (wtarget , wlink );
2465
+ case SYMLINK_TYPE_FILE :
2466
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags ))
2467
+ break ;
2468
+ return 0 ;
2469
+ case SYMLINK_TYPE_DIRECTORY :
2470
+ if (!CreateSymbolicLinkW (wlink , wtarget ,
2471
+ symlink_directory_flags ))
2472
+ break ;
2473
+ /* There may be dangling phantom symlinks that point at this
2474
+ * one, which should now morph into directory symlinks. */
2475
+ process_phantom_symlinks ();
2476
+ return 0 ;
2477
+ default :
2478
+ BUG ("unhandled symlink type" );
2479
+ }
2480
+
2481
+ /* CreateSymbolicLinkW failed. */
2482
+ errno = err_win_to_posix (GetLastError ());
2483
+ return -1 ;
2428
2484
}
2429
2485
2430
2486
#ifndef _WINNT_H
0 commit comments