From c30b1ffd315e8d661497fbd598ab9784af612cae Mon Sep 17 00:00:00 2001 From: Adrian Sieber Date: Fri, 10 Jul 2026 13:59:15 +0000 Subject: [PATCH] Canonicalize scanned paths to avoid self-duplicates WalkDir yields paths relative to the base argument, so scanning "." stored "./song.mp3" while scanning an absolute path stored the full path. The same physical file reached via different spellings landed in the DB twice (the path column is UNIQUE but keyed on the string) and was reported as an "exact copy" duplicate of itself. Canonicalize each discovered path before storing so one physical file always maps to one absolute, symlink-resolved path. This also makes scan consistent with exclude/include/`find --for`, which already canonicalize. --- src/scanner.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/scanner.rs b/src/scanner.rs index f7185d0..6b55101 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -246,7 +246,18 @@ fn discover_audio_files(paths: &[PathBuf], ignore_set: &GlobSet) -> Vec if ignore_set.is_match(path) { continue; } - files.push(entry.into_path()); + // Canonicalize so the same physical file always maps to one path + // string. WalkDir yields paths relative to the base argument (e.g. + // "./song.mp3" when scanning "."), so without this the same file + // reached via different spellings — a relative scan and an absolute + // one, or two symlinks — lands in the DB twice and is reported as an + // "exact copy" duplicate of itself. This also keeps stored paths + // consistent with exclude/include/`find --for`, which canonicalize. + let path = entry + .path() + .canonicalize() + .unwrap_or_else(|_| entry.into_path()); + files.push(path); } }