@@ -72,7 +72,8 @@ impl LinkMode {
7272/// via copy-on-write, which is similar to a hard link, but allows the files to be modified
7373/// independently (that is, the file is copied upon modification).
7474///
75- /// This method uses `clonefile` on macOS, and `reflink` on Linux.
75+ /// This method uses `clonefile` on macOS, and `reflink` on Linux. See [`clone_recursive`] for
76+ /// details.
7677fn clone_wheel_files (
7778 site_packages : impl AsRef < Path > ,
7879 wheel : impl AsRef < Path > ,
@@ -81,17 +82,6 @@ fn clone_wheel_files(
8182 let mut count = 0usize ;
8283 let mut attempt = Attempt :: default ( ) ;
8384
84- // On macOS, directories can be recursively copied with a single `clonefile` call.
85- // So we only need to iterate over the top-level of the directory, and copy each file or
86- // subdirectory unless the subdirectory exists already in which case we'll need to recursively
87- // merge its contents with the existing directory.
88- //
89- // On linux, we need to always reflink recursively, as `FICLONE` ioctl does not support directories.
90- // Also note, that reflink is only supported on certain filesystems (btrfs, xfs, ...), and only when
91- // it does not cross filesystem boundaries.
92- //
93- // On windows, we also always need to reflink recursively, as `FSCTL_DUPLICATE_EXTENTS_TO_FILE` ioctl
94- // is not supported on directories. Also, it is only supported on certain filesystems (ReFS, SMB, ...).
9585 for entry in fs:: read_dir ( wheel. as_ref ( ) ) ? {
9686 clone_recursive (
9787 site_packages. as_ref ( ) ,
@@ -144,6 +134,21 @@ enum Attempt {
144134}
145135
146136/// Recursively clone the contents of `from` into `to`.
137+ ///
138+ /// Note the behavior here is platform-dependent.
139+ ///
140+ /// On macOS, directories can be recursively copied with a single `clonefile` call. So we only
141+ /// need to iterate over the top-level of the directory, and copy each file or subdirectory
142+ /// unless the subdirectory exists already in which case we'll need to recursively merge its
143+ /// contents with the existing directory.
144+ ///
145+ /// On Linux, we need to always reflink recursively, as `FICLONE` ioctl does not support
146+ /// directories. Also note, that reflink is only supported on certain filesystems (btrfs, xfs,
147+ /// ...), and only when it does not cross filesystem boundaries.
148+ ///
149+ /// On Windows, we also always need to reflink recursively, as `FSCTL_DUPLICATE_EXTENTS_TO_FILE`
150+ /// ioctl is not supported on directories. Also, it is only supported on certain filesystems
151+ /// (ReFS, SMB, ...).
147152fn clone_recursive (
148153 site_packages : & Path ,
149154 wheel : & Path ,
@@ -158,7 +163,6 @@ fn clone_recursive(
158163 trace ! ( "Cloning {} to {}" , from. display( ) , to. display( ) ) ;
159164
160165 if ( cfg ! ( windows) || cfg ! ( target_os = "linux" ) ) && from. is_dir ( ) {
161- // On Windows, reflinking directories is not supported, so we copy each file instead.
162166 fs:: create_dir_all ( & to) ?;
163167 for entry in fs:: read_dir ( from) ? {
164168 clone_recursive ( site_packages, wheel, locks, & entry?, attempt) ?;
@@ -170,7 +174,8 @@ fn clone_recursive(
170174 Attempt :: Initial => {
171175 if let Err ( err) = reflink:: reflink ( & from, & to) {
172176 if err. kind ( ) == std:: io:: ErrorKind :: AlreadyExists {
173- // If cloning/copying fails and the directory exists already, it must be merged recursively.
177+ // If cloning or copying fails and the directory exists already, it must be
178+ // merged recursively.
174179 if entry. file_type ( ) ?. is_dir ( ) {
175180 for entry in fs:: read_dir ( from) ? {
176181 clone_recursive ( site_packages, wheel, locks, & entry?, attempt) ?;
@@ -197,7 +202,7 @@ fn clone_recursive(
197202 from. display( ) ,
198203 to. display( )
199204 ) ;
200- // switch to copy fallback
205+ // Fallback to copying
201206 * attempt = Attempt :: UseCopyFallback ;
202207 clone_recursive ( site_packages, wheel, locks, entry, attempt) ?;
203208 }
0 commit comments