use anyhow::Result;
use crate::git::GitRepo;
use crate::storage::WorktreeStorage;
pub fn cleanup_worktrees() -> Result<()> {
let current_dir = std::env::current_dir()?;
let git_repo = GitRepo::open(¤t_dir)?;
let repo_path = git_repo.get_repo_path();
let storage = WorktreeStorage::new()?;
let repo_name = WorktreeStorage::get_repo_name(repo_path)?;
println!("đ Analyzing worktree state...");
let mut cleaned = Vec::new();
match git_repo.list_worktrees_with_paths() {
Ok(worktrees) => {
for (name, path, is_prunable) in worktrees {
if path == current_dir {
continue;
}
if is_prunable || !path.exists() {
println!(
"đī¸ Found orphaned git worktree reference: {}",
path.display()
);
match git_repo.remove_worktree(&name) {
Ok(_) => {
println!(" â Removed git worktree reference: {}", name);
cleaned.push(name);
}
Err(e) => println!(
" â Warning: Could not remove git worktree reference {}: {}",
name, e
),
}
}
}
}
Err(e) => {
println!(" â Warning: Could not check git worktree list: {}", e);
}
}
if let Ok(repo_worktrees) = storage.list_repo_worktrees(&repo_name) {
let git_worktree_paths: Vec<_> = git_repo
.list_worktrees_with_paths()
.unwrap_or_default()
.into_iter()
.map(|(_, path, _)| path)
.collect();
for feature_name in repo_worktrees {
let path = storage.get_worktree_path(&repo_name, &feature_name);
if path.exists() && !git_worktree_paths.contains(&path) {
println!(
"âšī¸ Worktree directory exists but may not be registered with git: {} ({})",
feature_name,
path.display()
);
}
}
}
if cleaned.is_empty() {
println!("⨠Everything looks clean! No orphaned worktree references found.");
} else {
println!("\nâ
Cleanup complete!");
println!(
" Removed {} orphaned git worktree reference(s)",
cleaned.len()
);
}
Ok(())
}