diff options
Diffstat (limited to 'internal/dup/dup.go')
| -rw-r--r-- | internal/dup/dup.go | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/internal/dup/dup.go b/internal/dup/dup.go index 502ef31..e3c7424 100644 --- a/internal/dup/dup.go +++ b/internal/dup/dup.go @@ -381,6 +381,47 @@ func readAt(f *os.File, off int64) ([]byte, error) { return buf[:n], nil } +// SameContent reports whether a and b hold identical content: a stat and +// size check first, then the same partial/full hash comparison Lookup uses +// for scanned candidates. Neither file needs to have been scanned or +// indexed; this is the one place content identity is decided, so callers +// outside this package must not hash a second way. +func SameContent(a, b string) (bool, error) { + ai, err := os.Stat(a) + if err != nil { + return false, err + } + bi, err := os.Stat(b) + if err != nil { + return false, err + } + if ai.Size() != bi.Size() { + return false, nil + } + + aPartial, err := computePartialHash(a) + if err != nil { + return false, err + } + bPartial, err := computePartialHash(b) + if err != nil { + return false, err + } + if aPartial != bPartial { + return false, nil + } + + aFull, err := computeFullHash(a) + if err != nil { + return false, err + } + bFull, err := computeFullHash(b) + if err != nil { + return false, err + } + return aFull == bFull, nil +} + // computeFullHash hashes the whole file. func computeFullHash(path string) ([sha256.Size]byte, error) { f, err := os.Open(path) |
