git_claw/workflow/
spike.rs1use crate::cli::output::print_success;
4use crate::infra::git::{resolve_git_common_dir, resolve_toplevel};
5use crate::infra::lock::SlotLock;
6use crate::infra::registry::SlotRegistry;
7use crate::infra::worktree::{delete_branch, remove_worktree};
8use crate::workflow::error::WorkflowError;
9use std::path::{Path, PathBuf};
10
11pub struct DropSpikeOptions<'a> {
12 pub name: &'a str,
13 pub repo_root: Option<&'a Path>,
14}
15
16pub fn drop_spike(options: DropSpikeOptions<'_>) -> Result<(), WorkflowError> {
18 let toplevel = resolve_toplevel(options.repo_root)?;
19 let common_dir = resolve_git_common_dir(Some(&toplevel))?;
20
21 let registry_path = common_dir.join("claw/slots.json");
22 let lock_path = common_dir.join("claw/slots.lock");
23
24 let _lock = SlotLock::acquire(&lock_path)?;
25 let mut registry = SlotRegistry::load_or_empty(®istry_path)?;
26
27 let slot = registry
28 .find_by_name(options.name)
29 .cloned()
30 .ok_or_else(|| WorkflowError::WorktreeNotFound(options.name.to_string()))?;
31
32 let worktree_path = PathBuf::from(&slot.path);
33
34 let _ = remove_worktree(&toplevel, &worktree_path, true);
36
37 let _ = delete_branch(&toplevel, &slot.branch, true);
39
40 registry.remove_by_id(slot.id);
42 registry.save_atomic(®istry_path)?;
43
44 print_success(format!(
45 "Spike worktree '{}' (Slot {}) and branch '{}' dropped successfully without merging",
46 slot.name, slot.id, slot.branch
47 ));
48
49 Ok(())
50}