fix: skip all symlinks in project list walker

Replace the ends_with(".git") name check with a file_type().is_symlink()
check at both the org and repo levels of build_projects_list.

This handles three classes of symlink that all produced duplicate entries:
  1. Gitea's repo.git → repo aliases (previously caught by name check)
  2. Within-org shortcuts: quantumclaw/bbq → quantum-bbq
  3. Cross-org aliases:   clawverse/clawhdf5 → ../quantumclaw/clawhdf5

The name check only caught class 1; the symlink check catches all three.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-30 11:24:16 +00:00
co-authored by Claude Sonnet 4.6
parent c101cbe5ed
commit 720b331527
+5 -4
View File
@@ -415,10 +415,11 @@ fn build_projects_list(
for org_entry in top_entries.flatten() { for org_entry in top_entries.flatten() {
let org_path = org_entry.path(); let org_path = org_entry.path();
if !org_path.is_dir() { continue; } if !org_path.is_dir() { continue; }
// Skip all symlinks: covers Gitea's repo.git→repo aliases AND
// cross-org shortcuts (e.g. clawverse/clawhdf5→../quantumclaw/clawhdf5)
// that resolve to the same git tree and would produce duplicates.
if org_entry.file_type().map(|t| t.is_symlink()).unwrap_or(false) { continue; }
let org = org_entry.file_name().to_string_lossy().to_string(); let org = org_entry.file_name().to_string_lossy().to_string();
// Skip *.git symlinks — each real dir has a matching repo.git → repo
// symlink used by Gitea; resolving both would emit duplicate entries.
if org.ends_with(".git") { continue; }
if org_path.join(".git").exists() { if org_path.join(".git").exists() {
push(org, org_path); push(org, org_path);
@@ -426,8 +427,8 @@ fn build_projects_list(
for repo_entry in repos.flatten() { for repo_entry in repos.flatten() {
let repo_path = repo_entry.path(); let repo_path = repo_entry.path();
if !repo_path.is_dir() || !repo_path.join(".git").exists() { continue; } if !repo_path.is_dir() || !repo_path.join(".git").exists() { continue; }
if repo_entry.file_type().map(|t| t.is_symlink()).unwrap_or(false) { continue; }
let repo = repo_entry.file_name().to_string_lossy().to_string(); let repo = repo_entry.file_name().to_string_lossy().to_string();
if repo.ends_with(".git") { continue; }
let key = format!("{}/{}", org, repo); let key = format!("{}/{}", org, repo);
push(key, repo_path); push(key, repo_path);
} }