Skip to content

Latest commit

 

History

4,490 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RepoGrade Ask DeepWiki

CI Interop Validation Upstream Rsync Testsuite 3.5.1

Release

oc-rsync

rsync re-implemented in Rust. The reference version is upstream rsync 3.5.1. oc-rsync speaks protocols 28 through 33 and aims to be a drop-in replacement. Known divergences are listed per test in the upstream testsuite manifests.

The binary is named oc-rsync, so it installs alongside the system rsync without conflict.


Status

Release: 0.6.4 (2026-07-18). Changes merged since then are listed under Unreleased in the CHANGELOG. All transfer modes (local, SSH, daemon), the delta algorithm, metadata preservation and compression are implemented; the table below lists the gaps.

Upstream reference. Behaviour, source citations and the testsuite gate all track rsync 3.5.1 (upstream_version in Cargo.toml). 3.5.1 raised the protocol to 33. oc-rsync speaks 33, including MSG_BLOCK_STATS and the --stats touched-blocks line (#8003). It negotiates down to 28 for older peers and caps a newer peer at 33 instead of refusing it (#7916). The options and daemon directives added in 3.5.0 are implemented (see Path confinement below). The per-CVE audit is in SECURITY.md.

Component Status
Transfer Local, SSH, daemon push/pull, daemon over remote shell (host::module)
Delta Rolling + strong checksums, block matching, parallel receive-delta pipeline
Metadata Permissions, timestamps, ownership, ACLs (-A), xattrs (-X)
File handling Sparse, hardlinks, symlinks, devices, FIFOs
Deletion --delete (before/during/after/delay), --delete-excluded
Compression zlib, zstd, lz4 with level control and negotiation
Checksums MD4, MD5, XXH3/XXH128 with SIMD (AVX2, SSE2, NEON)
Incremental recursion Advertised when oc-rsync sends. An oc-rsync client that receives (a pull) does not advertise it yet, so pulls use a full up-front file list
Batch --write-batch / --read-batch round trip
Daemon Negotiation, auth, modules, chroot, syslog, pre/post-xfer exec
Filtering --filter, --exclude, --include, .rsync-filter, --files-from
Reference dirs --compare-dest, --link-dest, --copy-dest
Options --delay-updates, --inplace, --partial, --iconv, fuzzy matching
Path confinement --confine-root, --drop-D / --no-drop-D, --insecure-links / --no-insecure-links; daemon auth digest, insecure links, proxy protocol hosts
I/O io_uring (Linux 5.6+), copy_file_range, clonefile (macOS), adaptive buffers

Upstream testsuite

Upstream's own 3.5.1 test suite runs against oc-rsync as $RSYNC on every pull request and every push to master, in eight legs: platform {Linux, macOS} x daemon transport {stdio pipe, loopback TCP} x privilege {non-root, root}. The pipe legs run the whole 360-test corpus. The TCP legs add --daemon-tests-only and run the 161 tests that start a daemon. The legs run from upstream-testsuite-3.5.1.yml, behind the 3.5.1 badge at the top.

The four Linux legs are required status checks. The four macOS legs gate on their own manifests but are not required contexts.

Outcomes, counted from each leg's committed manifest:

leg pass fail skip
Linux, non-root, pipe 269 5 86
Linux, root, pipe 296 7 57
Linux, non-root, tcp 121 6 34
Linux, root, tcp 139 6 16
macOS, non-root, pipe 247 1 112
macOS, root, pipe 273 3 84
macOS, non-root, tcp 119 5 37
macOS, root, tcp 135 5 21

Re-derive any cell, and list a release's failing tests (the outcome is the second field; a fail row carries its cause and owner in a trailing comment):

awk '!/^#/ && NF {c[$2]++; t++} END {print t, c["pass"], c["fail"], c["skip"]}' \
  tools/ci/upstream-3.5.1-expect.nonroot.txt
awk '!/^#/ && $2=="fail" {print $1}' tools/ci/upstream-3.5.1-expect.*.txt | sort -u

Eleven distinct 3.5.1 tests carry a fail row, and every one names its cause and owning task. Four are the proto-* cluster, which fails on every tcp leg. strict-basis fails on all eight legs. None fails only on macOS. The rest are 3.5.1 behaviour oc-rsync does not match yet, such as the /dev/fd/N cells and the untrusted-symlink refusal. Only a change in outcome turns a leg red, including an unexpected pass, so a divergence cannot be re-baselined silently: the PR that fixes a cell must also flip its row to pass.


Installation

Homebrew

brew tap oferchen/rsync https://github.com/oferchen/rsync
brew install oferchen/rsync/oc-rsync

Prebuilt packages

Download from the Releases page:

Platform Formats
Linux (x86_64, aarch64) .deb, .rpm, Alpine .apk, static musl .tar.gz
macOS (x86_64, aarch64) .tar.gz
Windows (x86_64) .tar.gz, .zip

Linux static tarballs come in two checksum variants:

Variant Filename Description
Pure Rust (recommended) *-musl.tar.gz No system dependencies
OpenSSL *-musl-openssl.tar.gz OpenSSL MD4/MD5, vendored and statically linked

Each release also ships three toolchain builds: stable (no suffix, recommended), beta (-beta) and nightly (-nightly).

Build from source

Requires Rust 1.89 or newer. The repository pins 1.89.0 in rust-toolchain.toml.

git clone https://github.com/oferchen/rsync.git
cd rsync
cargo build --workspace --release

Cargo features

Feature Crate(s) Default Purpose Status
zstd workspace, core, engine, transfer, compress, protocol, batch yes zstd codec and negotiation. stable
lz4 workspace, core, engine, transfer, compress, protocol yes LZ4 codec. stable
zlib-ng workspace, core, engine, transfer, compress, protocol no SIMD zlib-ng C backend instead of pure-Rust zlib. stable
xattr workspace, cli, core, transfer, daemon, metadata yes Extended attributes (-X); NTFS ADS on Windows. stable
acl workspace, cli, core, engine, transfer, daemon, metadata yes ACLs (-A) via exacl; NTFS ACLs via windows-rs. stable
iconv workspace, cli, core, transfer, daemon, protocol yes Filename charset conversion (--iconv). stable
parallel workspace, cli, engine, checksums yes Rayon-based parallel file and checksum work. stable
io_uring workspace, transfer, fast_io yes Linux 5.6+ batched I/O with runtime fallback. stable
iocp workspace, transfer, fast_io yes Windows I/O Completion Ports. stable
copy_file_range workspace, fast_io yes Compatibility alias; the syscall is always compiled with runtime detection. stable
async workspace, core, engine, daemon yes tokio for async I/O paths. stable
embedded-ssh workspace, core, rsync_io yes Built-in SSH client for ssh:// operands. stable
openssl workspace, checksums no MD4/MD5 through system OpenSSL. stable
openssl-vendored workspace, checksums no As openssl, statically linked. stable
sd-notify workspace, core, daemon no systemd sd-notify for the daemon. stable
quic workspace, cli, core, daemon no QUIC transport (see QUIC transport). opt-in
iouring-send-zc workspace, fast_io no io_uring SEND_ZC dispatch (Linux 6.0+). opt-in
daemon-seccomp workspace, daemon no seccomp allowlist for daemon workers. Once compiled in, it is on at runtime; opt out with OC_RSYNC_NO_SECCOMP=1. opt-in
incremental-flist transfer yes Gates tests only. The incremental receiver is chosen at runtime from the negotiated flags (#7968). stable
lazy-metadata engine yes Defers stat() until metadata is needed. stable
multi-producer engine no Relaxes the single-producer invariant on WorkQueueSender. experimental
thread-slab-pool engine no Per-thread slab in front of BufferPool. experimental
vmsplice fast_io, transfer no Linux vmsplice(2) + splice(2) writer. experimental
adaptive-basis-dispatch fast_io no Per-file basis-read dispatch between mmap and io_uring by recent throughput; on Windows it also selects the IOCP file reader. experimental
async-ssh core, rsync_io no Async SSH transport; enable at runtime with OC_RSYNC_ASYNC_SSH=1. experimental
ssh-socketpair-stderr rsync_io no SSH stderr over a socketpair (see Performance tuning). experimental
async-daemon daemon no tokio accept loop dispatching sync workers. experimental
concurrent-sessions daemon no Shared session state for multi-session daemons. experimental
tracing core, engine, transfer, daemon no Structured tracing instrumentation. stable

Usage

Works like rsync:

# Local sync
oc-rsync -av ./source/ ./dest/

# Remote pull / push over SSH
oc-rsync -av user@host:/remote/path/ ./local/
oc-rsync -av ./local/ user@host:/remote/path/

# Daemon pull / push
oc-rsync -av rsync://host/module/ ./local/
oc-rsync -av ./local/ rsync://host/module/

# Daemon over remote shell
oc-rsync -av host::module/path/ ./local/

# Run as a daemon
oc-rsync --daemon --config=/etc/oc-rsync/oc-rsyncd.conf

# Compression, checksum-based sync with deletion
oc-rsync -avz --compress-level=3 ./source/ ./dest/
oc-rsync -avc --delete ./source/ ./dest/

# Batch mode (record and replay)
oc-rsync -av --write-batch=changes ./source/ ./dest/
oc-rsync -av --read-batch=changes ./other-dest/

For all options: oc-rsync --help.

SSH transports

  • host:path and user@host:path spawn the system ssh, like upstream. -e/--rsh and RSYNC_RSH choose another remote shell. This path needs no cargo feature.
  • ssh://[user@]host[:port]/path is an oc-rsync extension. It uses an embedded client built on russh and spawns no subprocess. It needs the embedded-ssh feature (on by default). Without the feature an ssh:// operand fails with a diagnostic. Combining ssh:// with -e/--rsh or RSYNC_RSH is rejected.

The embedded client supports key-based (RSA, ED25519, ECDSA) and password authentication, and SSH_AUTH_SOCK agents. It reads ~/.ssh/config and /etc/ssh/ssh_config with an in-house parser (ssh-config-parse feature, on by default): Host and Match blocks, Include, first-obtained-wins precedence, ProxyCommand / ProxyJump, and the host-key and authentication families. A differential harness checks it against ssh -G in CI.

Some SSH features (for example certificate-based auth) may be missing; please open an issue. The embedded client bridges a synchronous transfer pipeline to async russh through spawn_blocking; docs/design/russh-async-native-path.md describes the planned async-native path. See also the SSH TRANSPORT section of oc-rsync(1).

QUIC transport

oc-rsync can carry the rsync protocol over QUIC (RFC 9000/9001, TLS 1.3 over UDP) instead of a plain rsync:// TCP socket. Upstream rsync has no QUIC transport. It is behind the quic cargo feature and is off by default; release builds do not carry it.

cargo build --release --features quic -p cli -p daemon

QUIC always runs TLS 1.3 with the ALPN token rsync. The client verifies the daemon certificate against the system roots, a private CA (--quic-ca), or a trust-on-first-use pin in quic_known_hosts. Mutual TLS is optional. Selecting QUIC is hard-fail: if the feature or listener is unavailable, the transfer errors out rather than falling back to TCP. The cipher defaults to AES-GCM with hardware AES and ChaCha20-Poly1305 without; --quic-cipher aes|chacha20 overrides it.

Create a self-signed daemon certificate (the SubjectAltName must match the host clients connect to):

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout quic-key.pem -out quic-cert.pem -days 365 \
  -subj "/CN=rsync.example.com" \
  -addext "subjectAltName=DNS:rsync.example.com"

For mutual TLS, also create a client CA and sign a client certificate:

openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
  -keyout ca-key.pem -out ca-cert.pem -subj "/CN=oc-rsync client CA"
openssl req -newkey rsa:2048 -nodes \
  -keyout client-key.pem -out client.csr -subj "/CN=alice"
openssl x509 -req -in client.csr -CA ca-cert.pem -CAkey ca-key.pem \
  -CAcreateserial -out client-cert.pem -days 365

Daemon configuration (oc-rsyncd.conf, global section):

quic cert file = /etc/oc-rsync/quic-cert.pem
quic key file  = /etc/oc-rsync/quic-key.pem
# quic port defaults to the module `port` (873):
# quic port = 1873
# For mutual TLS:
quic client ca file = /etc/oc-rsync/ca-cert.pem

Client usage:

oc-rsync -a quic://host/module/ dest/
oc-rsync -a --quic host::module/ dest/
oc-rsync -a --quic-ca ca-cert.pem quic://host/module/ dest/
oc-rsync -a --quic --quic-cert client-cert.pem --quic-key client-key.pem host::module/ dest/
oc-rsync -a --quic --quic-cipher chacha20 quic://host/module/ dest/

--quic-cc selects the congestion controller and --quic-window the flow-control window. Full guide: docs/quic-transport.md.

Linux io_uring

oc-rsync uses io_uring when the kernel and probed opcodes allow it, and otherwise falls back to standard read(2)/write(2). The kernel floor is Linux 5.6 (MIN_KERNEL_VERSION in crates/fast_io/src/io_uring/config.rs). Provided buffer rings need 5.19+. SEND_ZC needs Linux 6.0+ and the iouring-send-zc cargo feature, which is not in the default set. The per-opcode kernel table is in docs/audit/iouring-opcode-kernel-floor.md.

Three policies: auto (default; probe and fall back), --io-uring (require it), --no-io-uring (never use it). --version shows the active backend.

Performance tuning

Avoid double compression over SSH. SSH compression (ssh -C, or Compression yes in ssh_config) and rsync's own -z compress the same bytes twice, costing CPU for little gain. Pick one, usually rsync's -z: oc-rsync negotiates zstd when both peers support it, falls back to zlib, and honours --skip-compress.

# Good: rsync compresses, SSH carries the bytes as-is.
oc-rsync -avz user@host:/src/ /dst/

# Bad: -C on ssh re-compresses what rsync already compressed.
oc-rsync -avz -e 'ssh -C' user@host:/src/ /dst/

oc-rsync warns when it sees -C or -o Compression=yes in the SSH argv, and (with ssh-config-parse) when a Compression yes directive applies from ssh_config. It does not disable either layer.

--zero-copy and SEND_ZC. --zero-copy may use sendfile, splice, copy_file_range and io_uring SEND_ZC on Linux. SEND_ZC dispatch needs the iouring-send-zc feature (Linux 6.0+). See docs/design/iouring-send-zc.md.

Parallel delta work. Delta work is single-threaded per file by default. Opt in with --parallel-delta-scan and --checksum-threads=N.

Receiver spill. The concurrent-delta receiver keeps its reorder buffer in memory by default. Set OC_RSYNC_SPILL_THRESHOLD_BYTES (for example 64M) to spill to disk, and optionally OC_RSYNC_SPILL_DIR. The --spill-threshold-bytes and --spill-dir flags override the variables. See docs/design/spill-policy-public-api.md and docs/operator-migration-guide-vNEXT.md.

SSH stderr socketpair. The ssh-socketpair-stderr feature drains the SSH child's stderr through a socketpair(AF_UNIX, SOCK_STREAM) instead of a pipe, with event-driven shutdown. It helps with chatty remote shells and many parallel transfers; Linux is the recommended target. See docs/ssh-transport.md and docs/design/socketpair-stderr-channel.md. When the runtime cannot honour the feature, one of these warnings appears once per process:

  • SSH stderr async drain unavailable on this platform - socketpair failed; the session falls back to a pipe.
  • SSH stderr socketpair partially set up - dup(2) on the parent half failed; shutdown relies on a 50 ms timeout.
  • SSH stderr async drain falling back to Stdio::inherit() - stderr goes straight to the parent terminal and is not captured.

Known limitations

  • Two buffer pools. OC_RSYNC_BUFFER_POOL_SIZE, OC_RSYNC_BUFFER_POOL_MEMORY_CAP and OC_BUFFER_POOL_BLOCK_SIZE tune the engine BufferPool only. The io_uring registered buffer pool is sized statically and does not adapt. Its cost has not been measured separately.
  • io_uring buffer-group IDs are a 16-bit namespace, and allocation returns BgidAllocError::Exhausted rather than wrapping. No transfer path allocates one today. See docs/audits/bgid-lifecycle.md.
  • Daemon traffic is plaintext, like upstream (authentication, no encryption). There is no built-in TLS client. Use SSH, or put the daemon behind a TLS proxy (stunnel, HAProxy, nginx) and connect with a wrapper such as rsync-ssl or stunnel.
  • Windows IOCP covers sockets and disk writes. The IOCP file reader is only selected under the experimental adaptive-basis-dispatch feature.

Compatibility

Protocol and interop

Protocol Upstream versions oc-rsync status Coverage
33 3.5.1 Full support (default) Unit tests, interop matrix against 3.5.1, and the 3.5.1 testsuite legs
32 3.4.x, 3.5.0 Full support Interop matrix against 3.4.4 and 3.5.0
31 3.1.x - 3.3.x Full support Interop matrix against 3.1.3
30 3.0.x Full support Interop matrix against 3.0.9
29 2.6.4 - 2.6.9 Full support Non-blocking daemon push/pull cells against 2.6.9, plus golden-byte tests
28 2.6.0 - 2.6.3 Wire-level support Golden-byte tests in crates/protocol/tests/
<= 27 <= 2.5.x Not supported

oc-rsync advertises protocol 33 and uses the lower of its own and the peer's version, so a 3.5.0 or 3.4.x peer runs at 32. A 3.5.1 peer runs at 33. Per-version behaviour is implemented as protocol_version gates in the wire codecs, for example zlib_codec.rs.

Interop scenarios run in CI against the upstream releases listed in tools/ci/run_interop.sh: versions= for the scenario matrix, extra_build_versions= for build-only peers, and extended_matrix_versions= for the extended matrix. Push and pull are both covered, across transfer modes, deletion, compression, metadata, reference dirs, file selection, batch round trip, path handling, device nodes and daemon auth. See the interop compatibility matrix for detail.

Platform support

Platform Tier Notes
Linux x86_64 / aarch64 Tier 1 io_uring, splice, vmsplice, Landlock. Required CI runs the full nextest workspace. A seccomp syscall allowlist for daemon workers is available with --features daemon-seccomp; it is off in default builds and in released binaries.
macOS x86_64 / aarch64 Tier 1 clonefile, fcopyfile, full metadata, ACL and xattr support including AppleDouble (._foo) resource forks. Required CI runs a crate-scoped subset (core, engine, cli, metadata, apple-fs, fast_io).
Windows x86_64 Tier 2 IOCP file and socket I/O, CopyFileExW, ReFS reflink, NTFS DACLs (partial), xattrs via NTFS Alternate Data Streams. No POSIX device nodes or FIFOs. Required CI tests the core, engine, cli, metadata, fast_io and transfer crates.

Tier definitions and criteria: Platform support tiers. Windows detail: Windows support matrix and the Windows Tier 2 stub inventory.

Feature Linux macOS Windows Notes
Permissions (-p) ✓ ✓ ⚠ Windows preserves only the read-only flag.
Times (-t) ✓ ✓ ✓ Nanosecond precision.
Ownership (-o/-g) ✓ ✓ ✗ uid/gid mapping is Unix-only.
ACLs (-A) ✓ ✓ ⚠ exacl on Linux/macOS. Windows round-trips NTFS DACLs; deny ACEs, inherited ACEs, the SACL, non-rwx bits and unresolvable SIDs are dropped with a warning. See docs/design/windows-ntfs-acl-support.md.
Xattrs (-X) ✓ ✓ ✓ Windows stores xattrs as NTFS Alternate Data Streams.
Hardlinks (-H) ✓ ✓ ✓
Symlinks ✓ ✓ ⚠ Windows: directory links fall back to a junction when unprivileged; file links need Administrator or Developer Mode, otherwise they are skipped with a warning (exit 23).
Devices/specials (-D) ✓ ✓ ✗
Sparse files (-S) ✓ ✓ ⚠ Windows does not set FSCTL_SET_SPARSE.
Async I/O ✓ io_uring ⚠ standard I/O ⚠ IOCP io_uring is detected at runtime on Linux 5.6+. Windows uses IOCP for disk writes and sockets; file reads use buffered I/O.
Reflink / clone ✓ FICLONE ✓ clonefile ⚠ ReFS only
Optimized copy ✓ copy_file_range ✓ fcopyfile ✓ CopyFileExW Each falls back to standard I/O.

Legend: ✓ supported, ⚠ partial, ✗ not implemented.

Performance

Benchmark: oc-rsync vs upstream rsync

Each tagged release runs .github/workflows/benchmark.yml against upstream rsync 3.5.0 and 3.4.4 across local, SSH and daemon modes. It reports elapsed time (median, with run-to-run spread), peak RSS and corpus rate. Results are attached to the GitHub release as benchmark.png, benchmark_report.md and benchmark_results.json.

Releases up to and including v0.6.4 predate this harness: their report compares against 3.4.4 only, without peak RSS, corpus rate or spread. The chart above comes from the latest release, so read that release's benchmark_report.md for what it measured.

oc-rsync uses threads where upstream forks, while keeping the same protocol. I/O buffers are sized by file size.


Testing and CI

Developer checks

Prerequisites: Rust 1.89.0 (pinned in rust-toolchain.toml) and cargo-nextest (cargo install cargo-nextest --locked).

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features --no-deps -- -D warnings
cargo nextest run --workspace --all-features

Security

Every crate sets #![deny(unsafe_code)] at its root. Production #[allow(unsafe_code)] sites exist only in crates that wrap platform FFI or SIMD intrinsics: fast_io, metadata, checksums, platform, engine, protocol (one site) and windows-gnu-eh. Other crates allow unsafe only in tests.

Upstream CVE status, in short:

  • 2024 batch (CVE-2024-12084 to CVE-2024-12088, CVE-2024-12747): not vulnerable or mitigated.
  • rsync 3.4.3 batch (CVE-2026-29518, 43617, 43618, 43619, 43620, 45232): fixed or not vulnerable. Receiver filesystem calls go through *at syscalls anchored on a directory fd, with a Landlock layer for the daemon on Linux.
  • rsync 3.5.0 batch (33 CVEs): 24 fixed, 5 not applicable, 4 unverified, 0 open. Each has a row in SECURITY.md, with the evidence and the command that recounts them.
  • rsync 3.5.1 names no CVE. Of its nine security-relevant fixes, five are mirrored, two are open (the /dev/fd/N paths and partial-directory validation) and two do not apply.

See SECURITY.md for the per-CVE detail and how to report a vulnerability.


Contributing

  1. Fork and create a feature branch.
  2. Run cargo fmt --all locally; CI runs clippy and nextest.
  3. Open a PR with a conventional-commit prefix describing behavioural changes and interop impact.

See CONTRIBUTING.md for the full workflow and docs/contributing/ONBOARDING.md for a guided start.

Project layout

src/bin/oc-rsync.rs     # Entry point
crates/cli/             # CLI flags, help, output formatting
crates/core/            # Orchestration facade, session management, config
crates/protocol/        # Wire protocol (v28-33), multiplex framing
crates/transfer/        # Generator, receiver, delta transfer pipeline
crates/engine/          # Local copy executor, sparse writes, temp-file commit
crates/daemon/          # Daemon mode, module access control, systemd
crates/checksums/       # Rolling and strong checksums (MD4, MD5, XXH3, SIMD)
crates/filters/         # Include/exclude pattern engine, .rsync-filter
crates/metadata/        # Permissions, uid/gid, mtime, ACLs, xattrs
crates/platform/        # Process, identity, environment and signal FFI
crates/rsync_io/        # SSH stdio, rsync:// TCP transport, handshake
crates/fast_io/         # Platform I/O (io_uring, copy_file_range, sendfile)
crates/compress/        # zstd, lz4, zlib compression codecs
crates/bandwidth/       # Bandwidth limiting and rate control
crates/signature/       # Signature layout and block-size calculations
crates/matching/        # Delta matching and block search
crates/flist/           # File list generation and traversal
crates/logging/         # Logging macros and verbosity control
crates/logging-sink/    # Message sink and output formatting
crates/batch/           # Batch file read/write support
crates/branding/        # Binary naming and version metadata
crates/embedding/       # Programmatic entry points for library usage
crates/apple-fs/        # macOS filesystem operations (clonefile, FSEvents)
crates/windows-gnu-eh/  # Windows GNU exception handling shims
crates/test-support/    # Shared test utilities (dev-dependency only)

API documentation: cargo doc --workspace --no-deps --open.

Architecture

cli -> core -> engine, daemon, rsync_io, logging
                core -> protocol -> checksums, filters, compress, bandwidth -> metadata
                                                                            -> platform

License

GNU GPL v3.0 or later. See LICENSE.


Acknowledgements

Inspired by rsync by Andrew Tridgell and the Samba team.

Internal matching-engine optimisations adapted from zsync by Colin Phipps. They change only in-memory lookups, so the default wire format stays pure rsync.

Thanks to Pieter for his heroic patience in enduring months of my rsync commentary. Thanks to Elad for his endless patience hearing rsync protocol commentary as I'm introduced to it.

About

Classic rsync re-implementation in pure Rust

Resources

Contributing

Security policy

Stars

106 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages