fix(receive): enforce dry-run no-mutation centrally

--dry-run --read-batch=FILE still wrote to the destination because
batch_read_apply -> file_save_to_disk_full bypassed the per-caller
!dry_run guards.  Guard file_save_to_disk_full and manifest_delete_all
directly (return SKIPPED/no-op) so every save/delete path is mutation-free
in dry-run, and keep the per-caller guards.  Reject --dry-run combined with
--read-batch/--only-write-batch at CLI validation with a clear error (a
dry-run of a local batch apply is not meaningful).
This commit is contained in:
2026-09-13 12:57:30 +02:00
parent a1eaa93357
commit 5b8aca5799
2 changed files with 23 additions and 0 deletions
+11
View File
@@ -22,6 +22,17 @@ bool validate_config(const Config* config) {
"--write-batch, --only-write-batch, and --read-batch are mutually exclusive");
return false;
}
/* A dry-run of a local batch apply is not meaningful: --read-batch bypasses
the client-side scan/server decision entirely, so dry-run would have no
wire state to report (and must not be used as a mutation escape hatch).
--only-write-batch likewise never contacts a receiver. Reject both up
front instead of silently ignoring --dry-run. */
if (config->dry_run && (read_batch || only_write_batch)) {
log_message(LOG_LEVEL_ERROR,
"--dry-run cannot be combined with --read-batch or --only-write-batch; "
"a dry-run of a local batch apply is not meaningful");
return false;
}
if (read_batch) {
if (!config->receive_root_directory) {
log_message(LOG_LEVEL_ERROR, "--read-batch requires a destination directory");