fs/diff: support symlink to abspath with second-precision mtime
Previously, `Changes()` for a symlink to absolute path, with second-precision mtime of the link itself always resulted in ENOENT. This is because `compareFileContent()` was called for the link target path, without changing the root path. Fix moby/buildkit#172 Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
25
fs/path.go
25
fs/path.go
@@ -74,11 +74,14 @@ func sameFile(f1, f2 *currentPath) (bool, error) {
|
||||
// If the timestamp may have been truncated in one of the
|
||||
// files, check content of file to determine difference
|
||||
if t1.Nanosecond() == 0 || t2.Nanosecond() == 0 {
|
||||
if f1.f.Size() > 0 {
|
||||
eq, err := compareFileContent(f1.fullPath, f2.fullPath)
|
||||
if err != nil || !eq {
|
||||
return eq, err
|
||||
}
|
||||
var eq bool
|
||||
if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink {
|
||||
eq, err = compareSymlinkTarget(f1.fullPath, f2.fullPath)
|
||||
} else if f1.f.Size() > 0 {
|
||||
eq, err = compareFileContent(f1.fullPath, f2.fullPath)
|
||||
}
|
||||
if err != nil || !eq {
|
||||
return eq, err
|
||||
}
|
||||
} else if t1.Nanosecond() != t2.Nanosecond() {
|
||||
return false, nil
|
||||
@@ -88,6 +91,18 @@ func sameFile(f1, f2 *currentPath) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func compareSymlinkTarget(p1, p2 string) (bool, error) {
|
||||
t1, err := os.Readlink(p1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
t2, err := os.Readlink(p2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t1 == t2, nil
|
||||
}
|
||||
|
||||
const compareChuckSize = 32 * 1024
|
||||
|
||||
// compareFileContent compares the content of 2 same sized files
|
||||
|
Reference in New Issue
Block a user