--- a/mercurial/util.py Tue Mar 21 17:39:49 2017 -0400
+++ b/mercurial/util.py Sun Mar 12 00:23:07 2017 -0800
@@ -1060,6 +1060,18 @@
# This is a variable so extensions can opt-in to using them.
allowhardlinks = False
+# a whilelist of known filesystems where hardlink works reliably
+_hardlinkfswhitelist = set([
+ 'btrfs',
+ 'ext2',
+ 'ext3',
+ 'ext4',
+ 'jfs',
+ 'reiserfs',
+ 'tmpfs',
+ 'xfs',
+])
+
def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False):
'''copy a file, preserving mode and optionally other stat info like
atime/mtime
@@ -1076,6 +1088,13 @@
if checkambig:
oldstat = checkambig and filestat(dest)
unlink(dest)
+ if hardlink:
+ # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks
+ # unless we are confident that dest is on a whitelisted filesystem.
+ destdir = os.path.dirname(dest)
+ fstype = getattr(osutil, 'getfstype', lambda x: None)(destdir)
+ if fstype not in _hardlinkfswhitelist:
+ hardlink = False
if allowhardlinks and hardlink:
try:
oslink(src, dest)