diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md index 131e3b0..a30e651 100644 --- a/IMPROVEMENTS.md +++ b/IMPROVEMENTS.md @@ -138,7 +138,7 @@ Acceptance criteria: ### Define filesystem compatibility -- [ ] Document behavior for ACLs, xattrs, flags, sparse files, source hardlinks, +- [x] Document behavior for ACLs, xattrs, flags, sparse files, source hardlinks, ownership, permissions, and timestamps. - [x] Add an explicit one-filesystem policy. - [ ] Make Python and external implementations provide equivalent guarantees or diff --git a/README.md b/README.md index 2a09eb7..29f6f1a 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,24 @@ backups/ - **Symlinks are preserved as symlinks**, including ones pointing outside the source tree - their targets are never followed or copied. +- **ACLs, extended attributes, and filesystem-specific flags (e.g. + BSD/macOS `chflags`) are never preserved**, by either implementation. + The Python backend never reads or sets them; `--external-rsync` uses + `--archive` without `-A`/`-X`/`--fileflags`, so they're dropped too. +- **Sparse files are not preserved as sparse.** Both implementations + do a whole-file copy (`--whole-file` for external rsync), so holes + are read and rewritten as allocated zero blocks in the backup. +- **Hardlinks between source files are not preserved as hardlinks.** + Each hardlinked source file is backed up as an independent file; + neither backend passes rsync's `-H`. Only hardlinks *within* the + backup repository (across snapshots) are meaningful. +- **Mode and timestamps are always preserved.** The Python backend + restores mtime with nanosecond precision; `--external-rsync`'s + precision depends on the installed rsync build and destination + filesystem. **Ownership (uid/gid) is preserved only when running as + root.** In the Python backend a failed `chown` is caught and logged, + not fatal; with `--external-rsync`, rsync itself just skips + ownership it isn't permitted to set. ## Development