1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2024-12-22 07:43:03 +00:00

Merge pull request #4526 from dnnr/detect-bitrot-in-diff

Add bitrot detection to "diff" command
This commit is contained in:
Michael Eischer 2024-01-06 19:18:34 +00:00 committed by GitHub
commit b2b7669ca0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 1 deletions

View file

@ -0,0 +1,11 @@
Enhancement: Add bitrot detection to `diff` command
The output of the `diff` command now includes the modifier `?` for files
to indicate bitrot in backed up files. It will appear whenever there is a
difference in content while the metadata is exactly the same. Since files with
unchanged metadata are normally not read again when creating a backup, the
detection is only effective if the right-hand side of the diff has been created
with "backup --force".
https://github.com/restic/restic/issues/805
https://github.com/restic/restic/pull/4526

View file

@ -27,6 +27,10 @@ directory:
* U The metadata (access mode, timestamps, ...) for the item was updated * U The metadata (access mode, timestamps, ...) for the item was updated
* M The file's content was modified * M The file's content was modified
* T The type was changed, e.g. a file was made a symlink * T The type was changed, e.g. a file was made a symlink
* ? Bitrot detected: The file's content has changed but all metadata is the same
Metadata comparison will likely not work if a backup was created using the
'--ignore-inode' or '--ignore-ctime' option.
To only compare files in specific subfolders, you can use the To only compare files in specific subfolders, you can use the
"<snapshotID>:<subfolder>" syntax, where "subfolder" is a path within the "<snapshotID>:<subfolder>" syntax, where "subfolder" is a path within the
@ -272,6 +276,16 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
!reflect.DeepEqual(node1.Content, node2.Content) { !reflect.DeepEqual(node1.Content, node2.Content) {
mod += "M" mod += "M"
stats.ChangedFiles++ stats.ChangedFiles++
node1NilContent := *node1
node2NilContent := *node2
node1NilContent.Content = nil
node2NilContent.Content = nil
// the bitrot detection may not work if `backup --ignore-inode` or `--ignore-ctime` were used
if node1NilContent.Equals(node2NilContent) {
// probable bitrot detected
mod += "?"
}
} else if c.opts.ShowMetadata && !node1.Equals(*node2) { } else if c.opts.ShowMetadata && !node1.Equals(*node2) {
mod += "U" mod += "U"
} }

View file

@ -201,7 +201,8 @@ change
+------------------+--------------------------------------------------------------+ +------------------+--------------------------------------------------------------+
| ``modifier`` | Type of change, a concatenation of the following characters: | | ``modifier`` | Type of change, a concatenation of the following characters: |
| | "+" = added, "-" = removed, "T" = entry type changed, | | | "+" = added, "-" = removed, "T" = entry type changed, |
| | "M" = file content changed, "U" = metadata changed | | | "M" = file content changed, "U" = metadata changed, |
| | "?" = bitrot detected |
+------------------+--------------------------------------------------------------+ +------------------+--------------------------------------------------------------+
statistics statistics