Skip to content

fix: preserve files of all sources in multi-source backup - #557

Closed
Lauri-Nomme wants to merge 1 commit into
rustic-rs:mainfrom
Lauri-Nomme:fix/multi-source-backup
Closed

fix: preserve files of all sources in multi-source backup#557
Lauri-Nomme wants to merge 1 commit into
rustic-rs:mainfrom
Lauri-Nomme:fix/multi-source-backup

Conversation

@Lauri-Nomme

Copy link
Copy Markdown

Problem

Backing up more than one source path in a single call silently drops the second source's files — or panics with StripPrefixError.

Repro:

rustic_core$ cargo test --test integration test_backup_multi_source_preserves_files_of_all_sources

before this change:

thread '<unnamed>' panicked at crates/core/src/archiver.rs:163:66:
called `Result::unwrap()` on an `Err` value: StripPrefixError(())

Reported upstream: rustic-rs/rustic#1905

Root cause

Archiver::archive received only backup_paths[0] as the single backup_path used for strip_prefix (crates/core/src/commands/backup.rs). The ignore-based walker emits absolute paths per source root for every entry. With multiple sources, an entry from the second source (.../src2/file.txt) cannot strip_prefix(backup_paths[0]), so:

  • with --as-path set: the unwrap() panics,
  • without --as-path: the second source's file blobs never get archived while its directory tree is still written — a silent, successful-looking backup missing data.

Fix

Pass the full backup_paths slice into Archiver::archive and strip each entry against the backup root it actually belongs to (falling back to the entry path unchanged if no root matches). When --as-path is used with multiple sources, keep each source as its own subtree under the target to avoid collisions between sources that contain identically-named files.

Tests

Two regression tests added in crates/core/tests/integration/backup.rs:

  • test_backup_multi_source_preserves_files_of_all_sources (with --as-path)
  • test_backup_multi_source_preserves_files_without_as_path (default mode)

Verified:

cargo test -p rustic_core            # 168 passed
cargo test --test integration        # 59 passed
cargo clippy -p rustic_core --all-targets   # no warnings

Notes

This changes the signature of Archiver::archive (backup_path &Path → backup_paths &[PathBuf]). It is pub, so downstream users calling it directly would need to update — but the normal entry points (repo.backup, repo.archive) are unchanged.

When backing up more than one source path in a single call, only the
first source's files were archived (or rustic panicked with
StripPrefixError). The archiver received only backup_paths[0] as its
strip-prefix base, so files belonging to other sources could not be
mapped into the snapshot tree and were silently dropped.

Pass the full backup_paths slice to Archiver::archive and strip each
entry against the backup root it belongs to. With --as-path and multiple
sources, keep each source as its own subtree to avoid path collisions.

Fixes rustic issue #1905.

Co-authored-by: Lauri Nomme <lauri.nomme@gmail.com>
@Lauri-Nomme

Copy link
Copy Markdown
Author

Retracting per maintainer feedback: as-path+multi-source is already rejected in the rustic CLI, and the no-as-path path needs a cleaner verification. Will pursue root-cause analysis and reopen/replace with a validated fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant