diff --git a/changelog/unreleased/pull-4526 b/changelog/unreleased/pull-4526 new file mode 100644 index 000000000..3a538f57a --- /dev/null +++ b/changelog/unreleased/pull-4526 @@ -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 diff --git a/cmd/restic/cmd_diff.go b/cmd/restic/cmd_diff.go index c54fc06d4..ea40d2860 100644 --- a/cmd/restic/cmd_diff.go +++ b/cmd/restic/cmd_diff.go @@ -27,6 +27,10 @@ directory: * U The metadata (access mode, timestamps, ...) for the item was updated * M The file's content was modified * 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 ":" 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) { mod += "M" 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) { mod += "U" } diff --git a/doc/075_scripting.rst b/doc/075_scripting.rst index d94074232..f46572209 100644 --- a/doc/075_scripting.rst +++ b/doc/075_scripting.rst @@ -201,7 +201,8 @@ change +------------------+--------------------------------------------------------------+ | ``modifier`` | Type of change, a concatenation of the following characters: | | | "+" = added, "-" = removed, "T" = entry type changed, | -| | "M" = file content changed, "U" = metadata changed | +| | "M" = file content changed, "U" = metadata changed, | +| | "?" = bitrot detected | +------------------+--------------------------------------------------------------+ statistics