copyfile: add a option callback for failed hardlinking
authorPierre-Yves David <pierre-yves.david@octobus.net>
Tue, 08 Jun 2021 02:31:17 +0200
changeset 47445 d756fc11cfb9
parent 47444 2f4ca4807033
child 47446 09ff5d532a25
copyfile: add a option callback for failed hardlinking Local clone, adjust its UI depending on the success of using hardlinking, so we add a small callback making it possible for `copyfile` to signal if the requested hardlinking failed. Differential Revision: https://phab.mercurial-scm.org/D10853
mercurial/util.py
--- a/mercurial/util.py	Tue Jun 08 02:06:02 2021 +0200
+++ b/mercurial/util.py	Tue Jun 08 02:31:17 2021 +0200
@@ -1910,7 +1910,13 @@
 
 
 def copyfile(
-    src, dest, hardlink=False, copystat=False, checkambig=False, nb_bytes=None
+    src,
+    dest,
+    hardlink=False,
+    copystat=False,
+    checkambig=False,
+    nb_bytes=None,
+    no_hardlink_cb=None,
 ):
     """copy a file, preserving mode and optionally other stat info like
     atime/mtime
@@ -1937,6 +1943,8 @@
         except OSError:
             fstype = None
         if fstype not in _hardlinkfswhitelist:
+            if no_hardlink_cb is not None:
+                no_hardlink_cb()
             hardlink = False
     if hardlink:
         try:
@@ -1945,8 +1953,10 @@
                 m = "the `nb_bytes` argument is incompatible with `hardlink`"
                 raise error.ProgrammingError(m)
             return
-        except (IOError, OSError):
-            pass  # fall back to normal copy
+        except (IOError, OSError) as exc:
+            if exc.errno != errno.EEXIST and no_hardlink_cb is not None:
+                no_hardlink_cb()
+            # fall back to normal copy
     if os.path.islink(src):
         os.symlink(os.readlink(src), dest)
         # copytime is ignored for symlinks, but in general copytime isn't needed