perf: use CoW (copy-on-write) cloning for directory copies#122
perf: use CoW (copy-on-write) cloning for directory copies#122arwtyxouymz wants to merge 2 commits intocoderabbitai:mainfrom
Conversation
Add _fast_copy_dir() that leverages filesystem-level cloning (macOS APFS cp -c, Linux cp --reflink=auto) for near-instant directory copies on supported filesystems, with automatic fallback to standard cp -RP on ext4/NTFS/others. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WalkthroughAdds Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as Script (copy_directories)
participant Helper as _fast_copy_dir()
participant OS as OS `cp` command
participant FS as Filesystem
Caller->>Helper: request copy(src, dst, excludes)
Helper->>Helper: detect/cached OS
Helper->>OS: run CoW-aware cp (platform-specific)
OS->>FS: perform copy (reflink or full copy)
alt macOS CoW failed
Helper->>FS: remove partial dst
Helper->>OS: run standard cp fallback
OS->>FS: perform full copy
end
Helper->>Caller: return success/failure, log outcome
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@lib/copy.sh`:
- Around line 88-93: The darwin branch can leave a partially-populated
destination when cp -cRP "$src" "$dest" fails, so modify the fallback to clean
the destination before retrying: after the failed cp -cRP "$src" "$dest"
attempt, detect and remove the partially-created destination (e.g., rm -rf
"$dest" only when it was created by the failed attempt) or perform the initial
clone into a temporary directory and then atomically rename/move it into
"$dest", then run cp -RP "$src" "$dest" as the fallback; update the darwin case
where cp -cRP and cp -RP are invoked to implement this cleanup/temporal-staging
logic.
🧹 Nitpick comments (2)
lib/copy.sh (1)
84-85:detect_osis invoked on every call; consider caching for loop-heavy callers.
copy_directoriescalls_fast_copy_dironce per matched directory. Each invocation spawns a subshell fordetect_os. You could cache the result in a module-level variable on first call.Proposed optimization
+# Cached OS value for _fast_copy_dir; set on first call. +_fast_copy_os="" + _fast_copy_dir() { local src="$1" dest="$2" - local os - os=$(detect_os) + if [ -z "$_fast_copy_os" ]; then + _fast_copy_os=$(detect_os) + fi + local os="$_fast_copy_os"tests/copy_safety.bats (1)
89-101: Temp directory cleanup won't run if an assertion fails.If
[ -f "$dst/mydir/sub/file.txt" ]fails on line 98, lines 100 (rm -rf) is never reached. Same pattern in the other two tests. Consider using a BATSteardownfunction or the$BATS_TEST_TMPDIRbuilt-in (BATS 1.4+) for automatic cleanup.Example using teardown
+teardown() { + # Clean up any temp dirs created during tests + [ -n "${_test_tmpdir:-}" ] && rm -rf "$_test_tmpdir" +} + `@test` "_fast_copy_dir copies directory contents" { - local src dst - src=$(mktemp -d) - dst=$(mktemp -d) + _test_tmpdir=$(mktemp -d) + local src="$_test_tmpdir/src" dst="$_test_tmpdir/dst" + mkdir -p "$src" "$dst" mkdir -p "$src/mydir/sub" echo "hello" > "$src/mydir/sub/file.txt" _fast_copy_dir "$src/mydir" "$dst/" [ -f "$dst/mydir/sub/file.txt" ] [ "$(cat "$dst/mydir/sub/file.txt")" = "hello" ] - rm -rf "$src" "$dst" }
- Clean up partial clone output before fallback in Darwin _fast_copy_dir - Cache detect_os result to avoid repeated subshell calls - Use teardown function in copy_safety tests for reliable tmpdir cleanup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
_fast_copy_dir()tolib/copy.shthat uses CoW file cloning when supported by the filesystemcp -cRP(clone) with fallback tocp -RPcp --reflink=auto -RP(auto-fallback built in)cp -RP(no behavior change)cp -RPincopy_directories()with_fast_copy_dir_fast_copy_dir(contents, symlinks, error handling)Motivation
Copying large directories like
node_modulesor.venvviagtr.copy.includeDirscan be slow. On CoW-capable filesystems (APFS, Btrfs, XFS), file cloning is near-instant regardless of directory size, as only metadata is copied.Risk
cp -RPbehaviorcopy_patterns) are intentionally unchanged, as CoW overhead outweighs benefit for small config files🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Tests