File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1919 "GIT_REPO" ,
2020 "GIT_DAEMON_PORT" ,
2121 "xfail_if_raises" ,
22+ "symlinks_supported" ,
23+ "requires_symlinks" ,
2224]
2325
2426import contextlib
2931import logging
3032import os
3133import os .path as osp
34+ from stat import S_ISLNK , ST_MODE
3235import subprocess
3336import sys
3437import tempfile
@@ -491,6 +494,28 @@ def _executable(self, basename):
491494 raise RuntimeError (f"no regular file or symlink { path !r} " )
492495
493496
497+ def symlinks_supported () -> bool :
498+ """Check whether this process can actually create a symlink.
499+
500+ On Windows the platform alone doesn't decide it: creating a symlink needs either
501+ Developer Mode or SeCreateSymbolicLinkPrivilege, and an unprivileged process gets
502+ OSError (WinError 1314) instead.
503+ """
504+ with tempfile .TemporaryDirectory (prefix = "gitpython-symlink-check-" ) as temp_dir :
505+ link_path = osp .join (temp_dir , "link" )
506+ try :
507+ os .symlink ("missing-target" , link_path )
508+ except (NotImplementedError , OSError ):
509+ return False
510+ return S_ISLNK (os .lstat (link_path )[ST_MODE ])
511+
512+
513+ requires_symlinks = pytest .mark .skipif (
514+ not symlinks_supported (),
515+ reason = "symlinks are unavailable, or need privileges this process doesn't have" ,
516+ )
517+
518+
494519@contextlib .contextmanager
495520def xfail_if_raises (
496521 condition : bool ,
You can’t perform that action at this time.
0 commit comments