fix: Deduplicate database paths when symlinks present (#354)
Fixes a bug where FindAllDatabases() would return the same database multiple times when symlinks were present in the directory hierarchy. The issue occurred because the function walked up the directory tree without resolving symlinks or checking if a database had already been discovered. This led to confusing warnings about "multiple databases" even when only one physical database existed. Changes: - Added symlink resolution using filepath.EvalSymlinks() - Implemented deduplication using a seen map with canonical paths - Added comprehensive tests for symlink scenarios This ensures that each unique database is reported exactly once, regardless of how many symlinks point to it in the directory tree. Resolves duplicate database warnings when symlinks are present.
This commit is contained in:
@@ -346,7 +346,8 @@ func findDatabaseInTree() string {
|
||||
// closest to CWD (most relevant) to the furthest (least relevant).
|
||||
func FindAllDatabases() []DatabaseInfo {
|
||||
var databases []DatabaseInfo
|
||||
|
||||
seen := make(map[string]bool) // Track canonical paths to avoid duplicates
|
||||
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return databases
|
||||
@@ -359,9 +360,28 @@ func FindAllDatabases() []DatabaseInfo {
|
||||
// Found .beads/ directory, look for *.db files
|
||||
matches, err := filepath.Glob(filepath.Join(beadsDir, "*.db"))
|
||||
if err == nil && len(matches) > 0 {
|
||||
dbPath := matches[0]
|
||||
|
||||
// Resolve symlinks to get canonical path for deduplication
|
||||
canonicalPath := dbPath
|
||||
if resolved, err := filepath.EvalSymlinks(dbPath); err == nil {
|
||||
canonicalPath = resolved
|
||||
}
|
||||
|
||||
// Skip if we've already seen this database (via symlink or other path)
|
||||
if seen[canonicalPath] {
|
||||
// Move up one directory
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
break
|
||||
}
|
||||
dir = parent
|
||||
continue
|
||||
}
|
||||
seen[canonicalPath] = true
|
||||
|
||||
// Count issues if we can open the database (best-effort)
|
||||
issueCount := -1
|
||||
dbPath := matches[0]
|
||||
// Don't fail if we can't open/query the database - it might be locked
|
||||
// or corrupted, but we still want to detect and warn about it
|
||||
ctx := context.Background()
|
||||
@@ -372,7 +392,7 @@ func FindAllDatabases() []DatabaseInfo {
|
||||
}
|
||||
_ = store.Close()
|
||||
}
|
||||
|
||||
|
||||
databases = append(databases, DatabaseInfo{
|
||||
Path: dbPath,
|
||||
BeadsDir: beadsDir,
|
||||
|
||||
Reference in New Issue
Block a user