rusync2 0.10.0

Maintained fork of rusync: adds --include/--exclude filters and a --sleep-interval watch mode
docs.rs failed to build rusync2-0.10.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

rusync2

Minimalist rsync implementation in Rust.

This is a maintained fork of the unmaintained dmerejkowsky/rusync. The package is published to crates.io as rusync2 and installs both the rusync and the rusync2 commands.

Usage

$ cargo install rusync2
$ rusync test/src test/dest
:: Syncing from test/src to test/dest …
 50% 24/50 Downloads/archlinux.iso   00:01:30

Caveat

We do everything we can to make sure data loss is impossible, but despite our best efforts, it may still happen.

Please make sure your files files are backed up if necessary before using rusync on sensitive data.

Thank you for your understanding!

Features

  • Easy to remember command line syntax.

  • Print progress on one line at every stage — while scanning the source tree, while comparing files, and while copying — and erase it when done, thus avoiding flooding your terminal with useless noise.

  • Displays a reliable ETA, without sacrificing speed.

  • Few syscalls per entry, so that syncing trees with many small files stays fast.

  • Unsurprising behavior: missing directories are created on the fly, files are only copied if:

    • destination is missing
    • destination exists but is older than the source
    • or source and destination have different sizes

Command line options

  • --no-perms: prevents rusync from trying to preserve file permissions (useful if you copy data from a Linux partition to NTFS for instance).
  • --err-list FILE: write name of entries that caused errors in the given file, separated by \n
  • --include REGEX: only synchronize paths matching this regex (may be repeated)
  • --exclude REGEX: skip paths matching this regex (may be repeated)
  • --sleep-interval INTERVAL: after each sync, sleep for INTERVAL, then sync again until interrupted. Plain numbers mean seconds; suffixes s, m, h, d and combinations like 1h30m are supported.

Path matching

--include and --exclude take regular expressions, matched against the path relative to the source directory, with path components joined by / (everywhere, including on Windows). Matching is case-sensitive and unanchored: use ^ and $ to anchor.

Rules:

  • If any --include is given, only paths matching at least one of them are synchronized.
  • A path matching any --exclude is always skipped; --exclude takes precedence over --include.
  • A directory matching an exclude pattern is not descended into. Include patterns never prevent descent, since files below a directory may still match them.

Examples:

rusync xxx yyy --exclude '\.log$'                        # skip every .log file
rusync xxx yyy --exclude '(^|/)target$'                   # skip every target/ directory
rusync xxx yyy --include '^docs/' --exclude '\.tmp$'    # only docs/, without .tmp files

Watch mode

Passing --sleep-interval makes rusync sync, then sleep, then sync again, until you interrupt it with Ctrl-C. After every round, rusync prints the time the sync completed and the time of the next sync, and shows a progress bar while waiting:

 ✓ Synced 4 files (0 up to date)
 :: Sync completed at 2026-08-20 17:30:00, next sync at 2026-08-20 17:32:00
 waiting [#####.....]  50% (00:01:00/00:02:00) next sync at 2026-08-20 17:32:00

A plain number means seconds; s, m, h and d suffixes are supported, and groups are summed, so all of these are valid intervals: 30, 10m, 3h, 1d, 1h30m.

State of the project

I consider this project done - I don't intend on adding new features. The goal was to learn more about Rust and I've learned plenty of things already. If there's a feature present in rsync that is not available in rusync, just use rsync - or try and implement the feature yourself, I'll be happy to review and merge your changes :)