feat(parity): rsync-parity cycle 2.29 (120/10/27, no wire change) #305

Merged
TapTap merged 8 commits from feat/parity-2.29 into dev 2026-09-20 15:10:18 +02:00
Owner

rsync-parity cycle 2.29 (no wire change)

Burns down the ⚠️ residuals against real rsync 3.4.1. Matrix moves
116 ✅ / 14 ⚠️ / 27 ❌ → 120 ✅ / 10 ⚠️ / 27 ❌ (157 rows). PROTOCOL_VERSION
stays 2.28.0 (no wire change was needed).

Closed (rows now ✅)

  • Scanner order — the sequential scanner walks each directory's entries in
    rsync's flist order (non-directories ascending, then directories ascending,
    depth-first), making --info=name, --delete-during/--delete-delay/-n
    would-delete order and the partial --max-delete survivor set byte-identical
    to rsync. --threads stays unordered (no rsync analogue).
  • Delete timing — the complete per-directory plan set is sent before the
    first data frame (abort boundary = rsync's generator); -d/--dirs uses
    per-directory plans instead of the end-of-transfer commit. Flips
    -n, --delete, --del/--delete-during, --delete-delay to ✅.
  • Basis relative-DIR — resolves against the destination directory with the
    transfer-relative name appended, exactly like rsync.
  • -y/--fuzzy eligibility — no longer inherits the delta engine's 16 KiB
    minimum / 10× ratio bound.

Improved (rows stay ⚠️, residuals documented)

  • --info=mount (rsync's -xx mount-point line; -x repeatable) and
    --info=stats.
  • --stats dir: breakdown under a plain -r scan.
  • --debug real output for flist/del/hash/deltasum/recv/filter/send.

Deferred (documented in CHANGELOG.md/HANDOFF.md)

  • --progress/--info receiver→sender event channel (root ./, ancestor
    suppression, skip/backup echo, symlink/empty-dir quick-check) — needs a
    wire bump.
  • --delete-before phase-0 keep-set (blocked: single-pass data model).
  • General >256 MiB single-file streaming limit (affects non-basis runs too).

Verification

  • ./build-ci/tests 44/44; full integration 880 passed; differential parity
    62 passed; strict-warnings build clean; ASan unit 44/44; clang-format +
    cppcheck clean.
  • New differential tests: test_parity_order.py, test_parity_basis_fuzzy.py,
    test_delete_boundary_parity.py, test_parity_info_mount_stats.py,
    test_parity_debug.py (+ test_output_parity.py extension).
## rsync-parity cycle 2.29 (no wire change) Burns down the ⚠️ residuals against real `rsync 3.4.1`. Matrix moves **116 ✅ / 14 ⚠️ / 27 ❌ → 120 ✅ / 10 ⚠️ / 27 ❌** (157 rows). `PROTOCOL_VERSION` stays **2.28.0** (no wire change was needed). ### Closed (rows now ✅) - **Scanner order** — the sequential scanner walks each directory's entries in rsync's flist order (non-directories ascending, then directories ascending, depth-first), making `--info=name`, `--delete-during`/`--delete-delay`/`-n` would-delete order and the partial `--max-delete` survivor set byte-identical to rsync. `--threads` stays unordered (no rsync analogue). - **Delete timing** — the complete per-directory plan set is sent before the first data frame (abort boundary = rsync's generator); `-d/--dirs` uses per-directory plans instead of the end-of-transfer commit. Flips `-n`, `--delete`, `--del`/`--delete-during`, `--delete-delay` to ✅. - **Basis relative-DIR** — resolves against the destination directory with the transfer-relative name appended, exactly like rsync. - **`-y`/`--fuzzy` eligibility** — no longer inherits the delta engine's 16 KiB minimum / 10× ratio bound. ### Improved (rows stay ⚠️, residuals documented) - `--info=mount` (rsync's `-xx` mount-point line; `-x` repeatable) and `--info=stats`. - `--stats` `dir:` breakdown under a plain `-r` scan. - `--debug` real output for `flist`/`del`/`hash`/`deltasum`/`recv`/`filter`/`send`. ### Deferred (documented in `CHANGELOG.md`/`HANDOFF.md`) - `--progress`/`--info` receiver→sender event channel (root `./`, ancestor suppression, `skip`/`backup` echo, symlink/empty-dir quick-check) — needs a wire bump. - `--delete-before` phase-0 keep-set (blocked: single-pass data model). - General >256 MiB single-file streaming limit (affects non-basis runs too). ### Verification - `./build-ci/tests` 44/44; full integration 880 passed; differential `parity` 62 passed; strict-warnings build clean; ASan unit 44/44; clang-format + cppcheck clean. - New differential tests: `test_parity_order.py`, `test_parity_basis_fuzzy.py`, `test_delete_boundary_parity.py`, `test_parity_info_mount_stats.py`, `test_parity_debug.py` (+ `test_output_parity.py` extension).
TapTap added 8 commits 2026-09-20 15:03:22 +02:00
Collect each directory's entries up front and process extraneous
subdirectories first (descending name, depth-first), then extraneous
files (descending name), then descend into kept subdirectories in
ascending order.  Emit a trailing slash for deleted directories in
observers/dry-run output.  This matches rsync's delete order for
--delete-before/--delete-after/--delete-delay and for dry-run listings.
Resolve a relative --compare-dest/--copy-dest/--link-dest DIR against the
destination directory and append the file's transfer-relative name, as
rsync 3.4.1 does, instead of appending FastSync's source-mirrored wire
path (the historical spelling stays as a fallback for existing layouts).

Stop inheriting the ordinary delta engine's 16 KiB minimum and 10x size
ratio in the -y/--fuzzy candidate search: rsync's find_fuzzy has no
delta-size gate, so an oversized or sub-16-KiB sibling is now reused.
The ordinary delta path's bounds are unchanged.
Buffer and sort each directory's inspected entries (non-directories
ascending, then directories ascending) and walk them depth-first via a
LIFO directory stack, so the sequential scanner's stream matches rsync
3.4.1's flist order.  This makes the --info=name transfer order and the
--delete-during/--delete-delay deletion sequence byte-identical to rsync
(differential tests in test_parity_order.py); --threads stays unordered
(no rsync analogue) and is documented as such.

Adds LIFO queue_push/queue_pop over the existing ring buffer.
Transmit the complete --delete-during/--delete-delay per-directory plan
set before the first data frame, so a mid-transfer abort has already
applied every planned removal like rsync's generator; completed runs are
unchanged.  Route -d/--dirs through the same per-directory plans: the
generator records only directories whose direct children it enumerated,
so extras directly inside a listed directory are removed while an
untraversed subdirectory's mirror is shielded (rsync's -d DIR/ --delete).
Also shields a -x mount point's untraversed destination content.
--info=mount now prints rsync's mount-point skip line (matching rsync
3.4.1, which emits it for repeated -xx and drops the mount-point dir);
--info=stats enables the same block as --stats; -x is repeatable.
--stats counts traversed directories for the Number of files breakdown
even when no directory metadata is captured (-r without -t/-p).
--debug enables real output for flist/del/hash/deltasum/recv/filter/send
at their natural FastSync events (synthetic categories stay inert).

--stats and --debug rows keep their documented residual status.
test: assert partial --max-delete survivor order matches rsync
CI / lint (pull_request) Successful in 1m58s
CI / parity-full (pull_request) Skipped
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / parity-fast (pull_request) Successful in 18s
CI / build-and-test (pull_request) Successful in 54s
9b05972375
TapTap merged commit 0fbb9de915 into dev 2026-09-20 15:10:18 +02:00
TapTap deleted branch feat/parity-2.29 2026-09-20 15:10:18 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: TapTap/FastSync#305