2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-27 07:16:40 +00:00

Merge pull request #5006 from MichaelEischer/restore-time-last

restic: restore timestamps after extended attributes
This commit is contained in:
Michael Eischer 2024-08-26 16:21:02 +02:00 committed by GitHub
commit 2063bf5de4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 11 deletions

View File

@ -0,0 +1,7 @@
Bugfix: Correctly restore timestamp for files with resource forks on macOS
On macOS, timestamps were incorrectly restored for files with resource forks.
This has been fixed.
https://github.com/restic/restic/issues/4969
https://github.com/restic/restic/pull/5006

View File

@ -249,13 +249,6 @@ func (node Node) restoreMetadata(path string, warn func(msg string)) error {
firsterr = errors.WithStack(err) firsterr = errors.WithStack(err)
} }
if err := node.RestoreTimestamps(path); err != nil {
debug.Log("error restoring timestamps for dir %v: %v", path, err)
if firsterr == nil {
firsterr = err
}
}
if err := node.restoreExtendedAttributes(path); err != nil { if err := node.restoreExtendedAttributes(path); err != nil {
debug.Log("error restoring extended attributes for %v: %v", path, err) debug.Log("error restoring extended attributes for %v: %v", path, err)
if firsterr == nil { if firsterr == nil {
@ -270,6 +263,13 @@ func (node Node) restoreMetadata(path string, warn func(msg string)) error {
} }
} }
if err := node.RestoreTimestamps(path); err != nil {
debug.Log("error restoring timestamps for %v: %v", path, err)
if firsterr == nil {
firsterr = err
}
}
// Moving RestoreTimestamps and restoreExtendedAttributes calls above as for readonly files in windows // Moving RestoreTimestamps and restoreExtendedAttributes calls above as for readonly files in windows
// calling Chmod below will no longer allow any modifications to be made on the file and the // calling Chmod below will no longer allow any modifications to be made on the file and the
// calls above would fail. // calls above would fail.

View File

@ -197,6 +197,20 @@ var nodeTests = []Node{
{"user.foo", []byte("bar")}, {"user.foo", []byte("bar")},
}, },
}, },
{
Name: "testXattrFileMacOSResourceFork",
Type: "file",
Content: IDs{},
UID: uint32(os.Getuid()),
GID: uint32(os.Getgid()),
Mode: 0604,
ModTime: parseTime("2005-05-14 21:07:03.111"),
AccessTime: parseTime("2005-05-14 21:07:04.222"),
ChangeTime: parseTime("2005-05-14 21:07:05.333"),
ExtendedAttributes: []ExtendedAttribute{
{"com.apple.ResourceFork", []byte("bar")},
},
},
} }
func TestNodeRestoreAt(t *testing.T) { func TestNodeRestoreAt(t *testing.T) {
@ -216,6 +230,11 @@ func TestNodeRestoreAt(t *testing.T) {
extAttrArr[i].Name = strings.ToUpper(extAttrArr[i].Name) extAttrArr[i].Name = strings.ToUpper(extAttrArr[i].Name)
} }
} }
for _, attr := range test.ExtendedAttributes {
if strings.HasPrefix(attr.Name, "com.apple.") && runtime.GOOS != "darwin" {
t.Skipf("attr %v only relevant on macOS", attr.Name)
}
}
// tempdir might be backed by a filesystem that does not support // tempdir might be backed by a filesystem that does not support
// extended attributes // extended attributes
@ -229,10 +248,6 @@ func TestNodeRestoreAt(t *testing.T) {
rtest.OK(t, test.CreateAt(context.TODO(), nodePath, nil)) rtest.OK(t, test.CreateAt(context.TODO(), nodePath, nil))
rtest.OK(t, test.RestoreMetadata(nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) })) rtest.OK(t, test.RestoreMetadata(nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) }))
if test.Type == "dir" {
rtest.OK(t, test.RestoreTimestamps(nodePath))
}
fi, err := os.Lstat(nodePath) fi, err := os.Lstat(nodePath)
rtest.OK(t, err) rtest.OK(t, err)