Skip to content

Feature/accelerated file copy - #228

Open
cedric-appdirect wants to merge 5 commits into
go-git:mainfrom
cedric-appdirect:feature/accelerated-file-copy
Open

Feature/accelerated file copy#228
cedric-appdirect wants to merge 5 commits into
go-git:mainfrom
cedric-appdirect:feature/accelerated-file-copy

Conversation

@cedric-appdirect

Copy link
Copy Markdown

This is a dependency and pre work for the tier 3 of this issue: go-git/go-git#1956 . The goal is to provide an API that is clean and fast to copy file across filesystem.

@pjbgf pjbgf left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cedric-appdirect thanks for looking into this. I'm not opposed to introducing a Copy primitive, however, a few points of feedback based on the current proposal:

  1. ⚠️ The current implementation breaks the traversal resistance that os.Root brought into the project. The use of os.Open(srcAbs) in osfs/copy_linux.go weakens that satefy net and opens the osfs implementation to path traversal. We probably can get away with it by using the existing primitives and working off file descriptors.
  2. Copy sounds like a primitive that likely should be combined with a Capability. So that users can check whether a given implementation supports it.
  3. We may need to refine the API:

Instead of having:
billy.CopyFile(srcFS, "source", dstFS, "target")

We probably should move it to util instead:
util.CopyFile(srcFS, "source", dstFS, "target")

We are probably better off having Copy instead of CopyFile. And CopyFrom instead of CopyFileFrom.

@cedric-appdirect
cedric-appdirect force-pushed the feature/accelerated-file-copy branch 2 times, most recently from b9f1b6a to afe55b8 Compare July 27, 2026 22:11
Pair the copy feature with a Capability bit so callers can query support via
CapabilityCheck, and define the Copier interface plus the UnderlyingFS and
RootedWrapper helpers that util.Copy uses to unwrap wrappers to their leaf
filesystems. CopyCapability is advertised in AllCapabilities only; a generic
filesystem that does not implement Capable is assumed not to support copy.

Assisted-by: Cursor with GLM 5.2 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
Copy copies a regular file from one filesystem to another, preserving the
source mode. It unwraps both source and destination to their leaf filesystems,
dispatches to a leaf Copier when the destination implements one, and otherwise
falls back to Lstat + Open + Create + io.Copy. Symlink and directory sources are
rejected on both paths.

Assisted-by: Cursor with GLM 5.2 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
Open source and destination through each filesystem's own os.Root-backed
opener, which rejects escaping symlinks and .. traversal at open time with no
TOCTOU, and operate on the resulting file descriptors. Linux uses
copy_file_range with a sendfile fallback; other platforms use io.Copy on the
contained opens. The path-based darwin clonefile and windows CopyFileEx syscalls
are dropped, as they cannot be made provably containment-safe. Symlink sources
are rejected via Lstat.

Assisted-by: Cursor with GLM 5.2 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
Add containment regression tests proving util.Copy cannot escape the source root: a symlink whose target
is outside the root and a .. path must not place outside bytes in the destination. Also add conformance
tests for regular-file copy, mode preservation, empty files, truncate-if-exists, and rejection of directory
and symlink sources, and per-platform CopyFrom smoke tests.

Assisted-by: Cursor with GLM 5.2 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
Benchmark util.Copy across osfs and memfs source/destination pairs. osfs to
osfs may use Linux fd-based copy acceleration; pairs involving memfs use Open +
Create + io.Copy.

Assisted-by: Cursor with GLM 5.2 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
@cedric-appdirect
cedric-appdirect force-pushed the feature/accelerated-file-copy branch from afe55b8 to ec0ee82 Compare August 18, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants