Patchwork D10853: copyfile: add a option callback for failed hardlinking

login
register
mail settings
Submitter phabricator
Date June 9, 2021, 2:39 p.m.
Message ID <differential-rev-PHID-DREV-6pqhhjg2szpybapjpvv5-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49176/
State Superseded
Headers show

Comments

phabricator - June 9, 2021, 2:39 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10853

AFFECTED FILES
  mercurial/util.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1911,7 +1911,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
@@ -1938,6 +1944,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:
@@ -1946,8 +1954,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