You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Git currently copies files byte-for-byte through copy_file(). Local
clones separately try to hardlink object files before falling back to
copying them.
On filesystems that support copy-on-write cloning, a reflink can share
the underlying storage without making the source and destination names
refer to the same inode. This provides most of the space and I/O
benefits of hardlinks while allowing either file to be replaced or
modified independently.
On Linux, try FICLONE before performing a byte-for-byte copy. Treat
reflinking as an optimization: if the ioctl is unavailable or fails,
remove the partial destination and use the existing copy path.
For local clones, keep hardlinks as the first choice because object
files are immutable. If a hardlink cannot be created, try a reflink
before falling back to a byte-for-byte copy. The resulting order is:
- hardlink, unless --no-hardlinks was requested;
- reflink;
- byte-for-byte copy.
Preserve source timestamps when reflinking local object files. This
matches the previous hardlink and copy behavior and is important for
the expiry decisions made by prune and gc.
Add an LD_PRELOAD-based test helper that can force hardlink failure and
make FICLONE succeed, report EOPNOTSUPP, or report another error. This
exercises the reflink and fallback paths even when the test filesystem
does not support reflinks. Cover generic file copying, local clones,
--no-hardlinks, hardlink preference, reflink fallback, byte-copy
fallback, object integrity, and timestamp preservation.
The focused tests pass on three independent filesystems:
- ZFS at /home;
- ext4 at /tmp;
- tmpfs at /dev/shm.
The complete Git test suite also passes on all three filesystems with
no unexpected failures.
Signed-off-by: Vlad Petric <vlad@drpetric.com>
0 commit comments