From bace4607bfe424a66d1d11dca10d7121578c36ef Mon Sep 17 00:00:00 2001 From: Florian Weingarten Date: Wed, 13 May 2015 23:11:31 -0400 Subject: [PATCH] Fix ModTime for directories --- cmd/dirdiff/main.go | 3 ++- node.go | 15 +++++++++++++-- restorer.go | 12 ++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) mode change 100644 => 100755 node.go diff --git a/cmd/dirdiff/main.go b/cmd/dirdiff/main.go index 94ffe47a5..23182f5bf 100644 --- a/cmd/dirdiff/main.go +++ b/cmd/dirdiff/main.go @@ -62,7 +62,8 @@ func (e *entry) equals(other *entry) bool { if e.fi.ModTime() != other.fi.ModTime() { fmt.Printf("%s: ModTime does not match\n", e.path) - // TODO: Fix ModTime for directories, return false + // TODO: Fix ModTime for symlinks, return false + // see http://grokbase.com/t/gg/golang-nuts/154wnph4y8/go-nuts-no-way-to-utimes-a-symlink return true } diff --git a/node.go b/node.go old mode 100644 new mode 100755 index 7785e7099..13d44ca04 --- a/node.go +++ b/node.go @@ -155,12 +155,23 @@ func (node Node) restoreMetadata(path string) error { return errors.Annotate(err, "Chmod") } + if node.Type != "dir" { + err = node.RestoreTimestamps(path) + if err != nil { + return err + } + } + + return nil +} + +func (node Node) RestoreTimestamps(path string) error { var utimes = []syscall.Timespec{ syscall.NsecToTimespec(node.AccessTime.UnixNano()), syscall.NsecToTimespec(node.ModTime.UnixNano()), } - err = syscall.UtimesNano(path, utimes) - if err != nil { + + if err := syscall.UtimesNano(path, utimes); err != nil { return errors.Annotate(err, "UtimesNano") } diff --git a/restorer.go b/restorer.go index 9511d3bc9..8ba401af4 100644 --- a/restorer.go +++ b/restorer.go @@ -64,6 +64,18 @@ func (res *Restorer) restoreTo(dst string, dir string, treeID backend.ID) error } } + // Restore directory timestamps at the end. If we would do it earlier, restoring files within + // those directories would overwrite the timestamp of the directories they are in. + for _, node := range tree.Nodes { + if node.Type != "dir" { + continue + } + + if err := node.RestoreTimestamps(filepath.Join(dst, dir, node.Name)); err != nil { + return err + } + } + return nil }