roborev repo list shows duplicate entries for the same physical repo when the path was registered with different separator styles:
NAME PATH REVIEWS
quarto-cli C:/Users/chris/Documents/DEV_R/quarto-cli 198
quarto-cli C:\Users\chris\Documents\DEV_R\quarto-cli 332
quarto-web C:/Users/chris/Documents/DEV_R/quarto-web 174
quarto-web C:\Users\chris\Documents\DEV_R\quarto-web 58
Same physical directories, tracked as separate repos. The backslash entries were created before #426 added filepath.ToSlash normalization to GetOrCreateRepo. New registrations (from post-commit hooks in Git Bash) now store forward-slash paths, but the old backslash entries remain in the database. The UNIQUE constraint on root_path treats C:/foo and C:\foo as distinct rows.
This splits review history. roborev summary and roborev insights only see one entry's data — roborev insights analyzed 50 reviews from the forward-slash entry, missing 332 reviews from the backslash entry.
repo merge can't fully work around this
FindRepo tries GetRepoByPath first, which normalizes with filepath.ToSlash. Both a backslash path and a forward-slash path resolve to the same forward-slash entry — the backslash entry is unreachable by path:
# Both arguments normalize to the forward-slash entry:
$ roborev repo merge "C:\Users\chris\Documents\DEV_R\quarto-cli" "C:/Users/chris/Documents/DEV_R/quarto-cli"
# → "source and target are the same repo"
# Workaround: name resolves via GetRepoByName (no path normalization):
$ roborev repo merge quarto-cli "C:/Users/chris/Documents/DEV_R/quarto-cli"
The name-based workaround only works because GetRepoByName happens to return the backslash entry first. If both entries had different names, or if the query order changed, there'd be no way to select the backslash entry for merging.
Code references
Normalization added in #426 for new registrations, but no migration for existing entries:
|
absPath = filepath.ToSlash(absPath) |
Same normalization in GetRepoByPath makes backslash entries unreachable by path lookup:
|
absPath = filepath.ToSlash(absPath) |
FindRepo tries path first, falls back to name — the only way to reach a backslash entry:
|
func (db *DB) FindRepo(identifier string) (*Repo, error) { |
|
// Try by path first |
|
absPath, _ := filepath.Abs(identifier) |
|
repo, err := db.GetRepoByPath(absPath) |
|
if err == nil { |
|
return repo, nil |
|
} |
|
if err != sql.ErrNoRows { |
|
return nil, err |
|
} |
|
|
|
// Try by name |
|
repo, err = db.GetRepoByName(identifier) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return repo, nil |
|
} |
Environment
- roborev v0.51.0, Windows 11
- Git Bash (MSYS2) for post-commit hooks + Claude Code
- PowerShell 7 for some manual commands
Happy to help test any fix on Windows.
roborev repo listshows duplicate entries for the same physical repo when the path was registered with different separator styles:Same physical directories, tracked as separate repos. The backslash entries were created before #426 added
filepath.ToSlashnormalization toGetOrCreateRepo. New registrations (from post-commit hooks in Git Bash) now store forward-slash paths, but the old backslash entries remain in the database. The UNIQUE constraint onroot_pathtreatsC:/fooandC:\fooas distinct rows.This splits review history.
roborev summaryandroborev insightsonly see one entry's data —roborev insightsanalyzed 50 reviews from the forward-slash entry, missing 332 reviews from the backslash entry.repo mergecan't fully work around thisFindRepotriesGetRepoByPathfirst, which normalizes withfilepath.ToSlash. Both a backslash path and a forward-slash path resolve to the same forward-slash entry — the backslash entry is unreachable by path:The name-based workaround only works because
GetRepoByNamehappens to return the backslash entry first. If both entries had different names, or if the query order changed, there'd be no way to select the backslash entry for merging.Code references
Normalization added in #426 for new registrations, but no migration for existing entries:
roborev/internal/storage/repos.go
Line 22 in 9b9462d
Same normalization in
GetRepoByPathmakes backslash entries unreachable by path lookup:roborev/internal/storage/repos.go
Line 97 in 9b9462d
FindRepotries path first, falls back to name — the only way to reach a backslash entry:roborev/internal/storage/repos.go
Lines 366 to 383 in 9b9462d
Environment
Happy to help test any fix on Windows.