(src, lnk, copy_function=copy2)
| 230 | |
| 231 | @errorfix_win |
| 232 | def hardlink_or_copy(src, lnk, copy_function=copy2): |
| 233 | def should_fallback_to_copy(exc): |
| 234 | if WindowsError is not None and isinstance(exc, WindowsError) and exc.winerror == 1142: # too many hardlinks |
| 235 | return True |
| 236 | # cross-device hardlink or too many hardlinks, or some known WSL error |
| 237 | if isinstance(exc, OSError) and exc.errno in ( |
| 238 | errno.EXDEV, |
| 239 | errno.EMLINK, |
| 240 | errno.EINVAL, |
| 241 | errno.EACCES, |
| 242 | errno.EPERM, |
| 243 | ): |
| 244 | return True |
| 245 | return False |
| 246 | |
| 247 | try: |
| 248 | hardlink(src, lnk) |
| 249 | except Exception as e: |
| 250 | logger.debug('Failed to hardlink %s to %s with error %s, will copy it', src, lnk, repr(e)) |
| 251 | if should_fallback_to_copy(e): |
| 252 | copy_function(src, lnk, follow_symlinks=False) |
| 253 | else: |
| 254 | raise |
| 255 | |
| 256 | |
| 257 | # Recursively hardlink directory |
nothing calls this directly
no test coverage detected