|
| 1 | +(copy)= |
| 2 | + |
| 3 | +# Copy Utilities |
| 4 | + |
| 5 | +```{module} libvcs._internal.copy |
| 6 | +``` |
| 7 | + |
| 8 | +Copy utilities with reflink (copy-on-write) support for optimized directory operations. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +This module provides `copytree_reflink()`, an optimized directory copy function that |
| 13 | +leverages filesystem-level copy-on-write (CoW) when available, with automatic fallback |
| 14 | +to standard `shutil.copytree()` on unsupported filesystems. |
| 15 | + |
| 16 | +## Why Reflinks? |
| 17 | + |
| 18 | +Traditional file copying reads source bytes and writes them to the destination. On |
| 19 | +modern copy-on-write filesystems like **Btrfs**, **XFS**, and **APFS**, reflinks |
| 20 | +provide a more efficient alternative: |
| 21 | + |
| 22 | +| Operation | Traditional Copy | Reflink Copy | |
| 23 | +|-----------|------------------|--------------| |
| 24 | +| Bytes transferred | All file data | Metadata only | |
| 25 | +| Time complexity | O(file size) | O(1) | |
| 26 | +| Disk usage | 2x original | ~0 (shared blocks) | |
| 27 | +| On modification | Original unchanged | CoW creates new blocks | |
| 28 | + |
| 29 | +### Filesystem Support |
| 30 | + |
| 31 | +| Filesystem | Reflink Support | Notes | |
| 32 | +|------------|-----------------|-------| |
| 33 | +| Btrfs | ✅ Native | Full CoW support | |
| 34 | +| XFS | ✅ Native | Requires reflink=1 mount option | |
| 35 | +| APFS | ✅ Native | macOS 10.13+ | |
| 36 | +| ext4 | ❌ Fallback | Falls back to byte copy | |
| 37 | +| NTFS | ❌ Fallback | Windows uses shutil.copytree | |
| 38 | + |
| 39 | +## Usage |
| 40 | + |
| 41 | +```python |
| 42 | +from libvcs._internal.copy import copytree_reflink |
| 43 | +import pathlib |
| 44 | + |
| 45 | +src = pathlib.Path("/path/to/source") |
| 46 | +dst = pathlib.Path("/path/to/destination") |
| 47 | + |
| 48 | +# Simple copy |
| 49 | +copytree_reflink(src, dst) |
| 50 | + |
| 51 | +# With ignore patterns |
| 52 | +import shutil |
| 53 | +copytree_reflink( |
| 54 | + src, |
| 55 | + dst, |
| 56 | + ignore=shutil.ignore_patterns("*.pyc", "__pycache__"), |
| 57 | +) |
| 58 | +``` |
| 59 | + |
| 60 | +## API Reference |
| 61 | + |
| 62 | +```{eval-rst} |
| 63 | +.. autofunction:: libvcs._internal.copy.copytree_reflink |
| 64 | +``` |
| 65 | + |
| 66 | +## Implementation Details |
| 67 | + |
| 68 | +### Strategy |
| 69 | + |
| 70 | +The function uses a **reflink-first + fallback** strategy: |
| 71 | + |
| 72 | +1. **Try `cp --reflink=auto`** - On Linux, this command attempts a reflink copy |
| 73 | + and silently falls back to regular copy if the filesystem doesn't support it |
| 74 | +2. **Fallback to `shutil.copytree()`** - If `cp` fails (not found, permission issues, |
| 75 | + or Windows), use Python's standard library |
| 76 | + |
| 77 | +### Ignore Patterns |
| 78 | + |
| 79 | +When using ignore patterns with `cp --reflink=auto`, the approach differs from |
| 80 | +`shutil.copytree()`: |
| 81 | + |
| 82 | +- **shutil.copytree**: Applies patterns during copy (never copies ignored files) |
| 83 | +- **cp --reflink**: Copies everything, then deletes ignored files |
| 84 | + |
| 85 | +This difference is acceptable because: |
| 86 | +- The overhead of post-copy deletion is minimal for typical ignore patterns |
| 87 | +- The performance gain from reflinks far outweighs this overhead on CoW filesystems |
| 88 | + |
| 89 | +## Use in pytest Fixtures |
| 90 | + |
| 91 | +This module is used by the `*_repo` fixtures in `libvcs.pytest_plugin` to create |
| 92 | +isolated test workspaces from cached master copies: |
| 93 | + |
| 94 | +```python |
| 95 | +# From pytest_plugin.py |
| 96 | +from libvcs._internal.copy import copytree_reflink |
| 97 | + |
| 98 | +@pytest.fixture |
| 99 | +def git_repo(...): |
| 100 | + # ... |
| 101 | + copytree_reflink( |
| 102 | + master_copy, |
| 103 | + new_checkout_path, |
| 104 | + ignore=shutil.ignore_patterns(".libvcs_master_initialized"), |
| 105 | + ) |
| 106 | + # ... |
| 107 | +``` |
| 108 | + |
| 109 | +### Benefits for Test Fixtures |
| 110 | + |
| 111 | +1. **Faster on CoW filesystems** - Users on Btrfs/XFS see 10-100x speedup |
| 112 | +2. **No regression elsewhere** - ext4/Windows users see no performance change |
| 113 | +3. **Safe for writable workspaces** - Tests can modify files; master stays unchanged |
| 114 | +4. **Future-proof** - As more systems adopt CoW filesystems, benefits increase |
0 commit comments