use anyhow::Result;
use worktree_io::git::{create_worktree, git_worktree_prune};
use worktree_io::ttl::WorkspaceRegistry;
pub fn cmd_restore() -> Result<()> {
let home = dirs::home_dir().expect("could not determine home directory");
let local_prefix = home.join("worktrees").join("local");
let registry = WorkspaceRegistry::load()?;
let orphaned: Vec<_> = registry
.workspace
.iter()
.filter(|r| !r.path.exists())
.collect();
if orphaned.is_empty() {
eprintln!("No orphaned worktrees found.");
return Ok(());
}
eprintln!("Found {} orphaned worktree(s).", orphaned.len());
for record in &orphaned {
let path = &record.path;
if path.starts_with(&local_prefix) {
eprintln!(
"Skipping local worktree: {}\n Run `worktree open <issue-ref>` to restore it.",
path.display()
);
continue;
}
let Some(branch) = path.file_name().and_then(|n| n.to_str()) else {
continue;
};
let bare_path = path.parent().expect("non-root path must have a parent");
if !bare_path.exists() {
eprintln!(
"Skipping {} — bare clone no longer exists at {}.",
path.display(),
bare_path.display()
);
continue;
}
eprintln!("Restoring {}…", path.display());
if let Err(e) = git_worktree_prune(bare_path) {
eprintln!(" Warning: worktree prune failed: {e}");
}
match create_worktree(bare_path, path, branch, "", true) {
Ok(()) => eprintln!(" Restored: {}", path.display()),
Err(e) => eprintln!(" Failed to restore {}: {e}", path.display()),
}
}
Ok(())
}