TapTap
a2a82dd856
feat: implement --delay-updates receiver staging and publication
...
CI / lint (pull_request) Failing after 22s
CI / build-and-test (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
Stage every successfully written file under a private 0700 .fastsync-stage
directory inside the receive root and atomically publish all staged files
only after the whole protocol stream (manifest/delete handling included)
has completed, immediately before the success/outcome frame. On any
abort/error before publication nothing is installed and staging is removed;
a publish failure aborts the transfer with best-effort cleanup of the
remainder (already-published files are not rolled back). Crash leftovers
are wiped when the next delayed transfer starts.
Wire: new delay_updates config flag (selection-options block), protocol
version bumped to 2.6.0, client/server validation rejects --inplace.
CLI/usage/validation updated. Works in single-threaded and -m modes
(exactly one write_thread stages files; the staged-file registry is
mutex-protected; publication runs once after both threads join).
--existing/--ignore-existing/--update decide against the final destination
at stage time; --backup is deferred to publication. remove_source_files
outcomes are only sent after publication so skipped/unpublished sources are
never deleted. Default (no flag) behavior is unchanged.
Tests: config wire round-trip, CLI parse, --inplace rejection, new
test_delay_updates unit suite (27 suites total), and integration
TestDelayUpdates covering single/-m parity, incremental reruns, remove
source files, receiver-skip ordering, and a deterministic publish-failure
abort path.
2026-09-06 13:20:03 +02:00
TapTap
88ab4f65cb
Merge feat/p2-itemize-output: structured change output (-i, --list-only, --out-format, --log-file-format)
...
Client-only per-file event/format model (change_list.c). Reviewed
(c-review APPROVE WITH NITS, all fixed); PR #263 .
2026-09-06 12:52:46 +02:00
TapTap
9fbb86ca68
Merge feat/p2-temp-dir: implement --temp-dir
...
Receiver writes temps into a confined scratch dir and atomically renames
into place; EXDEV aborts; inplace/partial bypass; thread-safe temp names.
Uses existing wire field; no protocol bump. Reviewed (c-review APPROVE
WITH NITS, all fixed); PR #262 .
2026-09-06 12:52:11 +02:00
TapTap
1b67f5ffcf
docs: clarify %b semantics, temper thread-safety claim, harden %M scan; add -m coverage
...
CI / lint (pull_request) Successful in 20s
CI / sanitizers (undefined) (pull_request) Successful in 41s
CI / sanitizers (address) (pull_request) Successful in 41s
CI / fuzz-build (pull_request) Successful in 16s
CI / coverage (pull_request) Successful in 35s
CI / build-and-test (pull_request) Successful in 1m22s
CI / valgrind (pull_request) Successful in 36s
Address c-review nits on the itemize/output feature:
- RSYNC_COMPAT.md: state that %b is the source length (always == %l) because
no wire-byte counter exists; keep Summary equal to the matrix (recounted:
54 implemented / 84 not-implemented, 147 rows total - four rows flipped).
- change_list.h/.c: document bytes_sent == size; note itemize/out-format lines
never interleave with each other but may interleave with legacy log
messages sharing the stream; mark the %M stat() path best-effort.
- change_render_format scan in format_uses_mtime now mirrors the tokenizer
(skips '%%' and unknown '%X' pairs) so a literal '%%M' no longer triggers
the stat() fallback.
- Integration tests: --list-only under -m; a changed file on a second
--incremental run emits exactly one '>f' line while unchanged files print
nothing; --log-file + --log-file-format under -m.
2026-09-06 12:49:49 +02:00
TapTap
2d841405e6
test: cover -x cross-device skip without root; harden OneFileSystem tests
...
CI / lint (pull_request) Failing after 20s
CI / build-and-test (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
Add a rootless unit test that reaches the actual st_dev skip branch in both
the sequential and parallel (-m) scanners: a symlink nested under the scan
root points at a directory on /dev/shm (a different device than the build
fs) and, under --copy-links semantics, -x must drop that subtree while a
plain scan includes it. Skips only when no cross-device target exists.
Integration OneFileSystem test now cleans both dest dirs up front and
reports a busy test mountpoint instead of ignoring the umount result.
RSYNC_COMPAT.md notes that cross-filesystem mount-point subdirectories are
dropped entirely (rsync parity).
2026-09-06 12:49:26 +02:00
TapTap
00e8df4bcd
fix: address c-review nits for --temp-dir engine
CI / lint (pull_request) Failing after 21s
CI / build-and-test (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
2026-09-06 12:48:07 +02:00
TapTap
7f5547e900
feat: add structured per-file change output model (-i, --list-only, --out-format, --log-file-format)
...
Implement rsync-style itemized output backed by one shared change-event
engine (src/client/change_list.c):
- -i/--itemize-changes prints ">f+++++++++ <path>" for files actually sent
(single-threaded and -m); unchanged files print nothing.
- --list-only prints an ls-style listing of files that would be transferred
without contacting the server or writing anything.
- --out-format=FORMAT prints a printf-style template per changed file
(tokens %%f %%n %%l %%b %%M %%%%; unknown escapes preserved).
- --log-file-format=FMT logs each transferred file when --log-file is set.
Events are emitted from the per-file sender path shared by both transfer
modes, so the single sender thread is the only reporter (no races).
2026-09-06 12:34:10 +02:00
TapTap
19e6fc2205
feat: implement rsync --temp-dir for atomic receiver installs
2026-09-06 12:21:36 +02:00
TapTap
2bcc20aa08
feat: add -x/--one-file-system to stay within the source filesystem
...
Capture the transfer root's device (st_dev) at scanner creation and skip
descending into any subdirectory on a different device (a mount point).
Implemented sender/client-side only: sequential BFS and parallel (-m) root
scan apply the same scanner_same_filesystem decision; no wire/protocol change
and default behavior is unchanged. Unit tests cover the pure decision, same
device scanning in both modes, and CLI parsing; integration tests prove -x
leaves a single-filesystem tree byte-identical and, when root can mount a
tmpfs, skips a genuine cross-device subtree.
2026-09-06 12:18:43 +02:00
TapTap
f7c6c91e13
fix: set *failed on delta oversize branch; add -m RSF skip test
...
CI / lint (push) Successful in 20s
CI / sanitizers (address) (push) Successful in 41s
CI / sanitizers (undefined) (push) Successful in 39s
CI / fuzz-build (push) Successful in 16s
CI / coverage (push) Successful in 34s
CI / build-and-test (push) Successful in 1m23s
CI / valgrind (push) Successful in 35s
Review nits from independent review of the four fix branches:
- receive_delta_file STATUS_NEXT oversize branch now sets *failed=true
- receive_incremental_check oversize branch returns NULL (receiver sends the
single STATUS_ERROR) instead of double-sending
- add multithreaded -m --ignore-existing --remove-source-files integration
coverage so the writer-thread outcome path is exercised
2026-09-05 13:16:42 +02:00
TapTap
3704a6adaa
test: integration coverage for #251 #252 #253 #257
...
- remove-source-files keeps sources skipped by --existing/--ignore-existing/
--update (rsync reference behavior)
- --backup keeps <file>~, --suffix .bak, and --backup-dir backups
- --partial --partial-dir installs completed files in the destination
- a 100 MB file transfers end to end (>64 MiB whole-file cap regression)
2026-09-05 12:46:47 +02:00
TapTap
8689778233
Merge remote-tracking branch 'origin/feat/rsync-no-options' into dev
2026-09-05 02:30:50 +02:00
TapTap
cf0d10fccb
Merge remote-tracking branch 'origin/feat/rsync-info' into dev
2026-09-05 02:25:36 +02:00
TapTap
6a95efbe41
Merge remote-tracking branch 'origin/feat/skip-compress' into dev
2026-09-04 18:35:19 +02:00
TapTap
3b013bf9d2
Merge remote-tracking branch 'origin/feat/rsync-compression-aliases' into dev
2026-09-04 18:24:21 +02:00
TapTap
4f21498ee6
Merge remote-tracking branch 'origin/feat/chmod' into dev
2026-09-04 18:20:08 +02:00
TapTap
315e572d18
Merge remote-tracking branch 'origin/feat/executability' into dev
2026-09-04 18:13:34 +02:00
TapTap
55172ff6de
Merge remote-tracking branch 'origin/feat/ignore-existing' into dev
2026-09-04 17:59:50 +02:00
TapTap
c650f9a3d0
Merge remote-tracking branch 'origin/feat/existing' into dev
2026-09-04 17:50:55 +02:00
TapTap
192aff8c46
Merge remote-tracking branch 'origin/feat/update' into dev
...
# Conflicts:
# src/client/client_cli.c
# src/client/usage.c
# src/shared/file.c
# src/shared/file.h
# src/shared/file_receive.c
# tests/test_client_cli.c
2026-09-04 17:44:07 +02:00
TapTap
6d10116d50
Merge remote-tracking branch 'origin/feat/modify-window' into dev
...
# Conflicts:
# RSYNC_COMPAT.md
# src/client/client_cli.c
# src/client/usage.c
# src/server/receiver.c
# src/server/server.c
# src/shared/config.c
# src/shared/config.h
# src/shared/file_receive.c
# tests/integration/test_features.py
# tests/test_client_cli.c
# tests/test_config.c
2026-09-04 17:40:16 +02:00
TapTap
e42df1bde3
Merge remote-tracking branch 'origin/feat/size-only' into dev
...
# Conflicts:
# src/client/client_cli.c
# src/client/usage.c
# src/server/receiver.c
# src/server/server.c
# src/shared/config.c
# src/shared/config.h
# tests/integration/test_features.py
# tests/test_config.c
2026-09-04 17:30:14 +02:00
TapTap
9fc1e72972
Merge remote-tracking branch 'origin/feat/ignore-times' into dev
...
# Conflicts:
# src/shared/config.c
# tests/integration/test_features.py
# tests/test_client_cli.c
# tests/test_config.c
2026-09-04 17:27:04 +02:00
TapTap
71f1529222
Merge remote-tracking branch 'origin/feat/whole-file' into dev
...
# Conflicts:
# tests/test_client_cli.c
# tests/test_config.c
2026-09-04 17:24:22 +02:00
TapTap
8e1bc9bb9c
Merge remote-tracking branch 'origin/feat/human-readable' into dev
...
# Conflicts:
# RSYNC_COMPAT.md
# src/client/client_send.c
# tests/test_client_cli.c
2026-09-04 17:16:24 +02:00
TapTap
421a94773f
Merge remote-tracking branch 'origin/feat/quiet' into dev
...
# Conflicts:
# src/client/client_send.c
2026-09-04 17:14:45 +02:00
TapTap
605f79a450
fix: make rsync info none override verbose
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 36s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 16s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 22:44:44 +02:00
TapTap
98cbf3495d
fix: complete skip-compress protocol handling
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m17s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 22:19:00 +02:00
TapTap
245a34fa11
fix: guard source removal against file replacement
CI / lint (pull_request) Successful in 11s
CI / sanitizers (undefined) (pull_request) Successful in 38s
CI / sanitizers (address) (pull_request) Successful in 39s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 22:11:18 +02:00
TapTap
68aaf89da7
fix: address update option review findings
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 34s
2026-09-03 21:59:55 +02:00
TapTap
1ebe261e05
fix: complete ignore-times incremental handling
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 21:49:10 +02:00
TapTap
4152bf379e
fix: honor compression choice aliases
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 36s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 21:44:21 +02:00
TapTap
21e6b1c1bc
fix: address rsync info review findings
CI / lint (pull_request) Successful in 12s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 21:25:56 +02:00
TapTap
fb96c21d93
test: complete human-readable progress coverage
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 36s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 16s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 21:14:49 +02:00
TapTap
17b5b31845
fix: complete quiet option handling
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 34s
2026-09-03 21:12:43 +02:00
TapTap
2a08a7ba5c
feat: add skip-compress option
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 36s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 17:56:27 +02:00
TapTap
36a373ff5d
Add executability preservation option
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 17:39:50 +02:00
TapTap
3b85658024
Add remove-source-files option
CI / lint (pull_request) Successful in 11s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 17:33:52 +02:00
TapTap
5e67a721a4
feat: add rsync-compatible update option
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 39s
CI / sanitizers (undefined) (pull_request) Successful in 39s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 17:07:02 +02:00
TapTap
0b5b1a8643
feat: add rsync modify-window option
CI / lint (pull_request) Successful in 14s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 38s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Failing after 1m15s
CI / valgrind (pull_request) Successful in 32s
2026-09-03 17:01:45 +02:00
TapTap
2afb1d9649
feat: add rsync-compatible size-only option
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 16:54:07 +02:00
TapTap
230401c629
feat: add ignore-times incremental option
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 16:50:07 +02:00
TapTap
c91db3266a
feat: add whole-file transfer mode
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 38s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 16:47:02 +02:00
TapTap
2ff2688ef1
feat: support rsync no-option handling
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 16:22:18 +02:00
TapTap
4872d425a3
feat: add rsync info flags
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 16:13:56 +02:00
TapTap
8ab5026224
feat: add human-readable output flag
CI / lint (pull_request) Successful in 12s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 34s
2026-09-03 15:58:48 +02:00
TapTap
dbacc4f0e5
feat: add quiet client option
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 32s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s
2026-09-03 15:52:36 +02:00
TapTap
d64666d456
fix: close remaining PR 208 security gaps
CI / lint (pull_request) Failing after 3s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
2026-08-09 11:52:15 +02:00
TapTap
cc143316b2
Merge latest dev into triage remediation
CI / lint (pull_request) Successful in 25s
CI / sanitizers (address) (pull_request) Successful in 35s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
2026-08-09 11:30:08 +02:00
TapTap
2450b90dd0
feat: add checksum-aware incremental sync
2026-08-08 20:27:26 +02:00