Skip to main content

git_side/commands/
rm.rs

1use std::path::Path;
2
3use colored::Colorize;
4
5use crate::error::{Error, Result};
6use crate::git;
7use crate::side_repo::SideRepo;
8use crate::tracked::TrackedPaths;
9
10/// Remove a path from side tracking.
11///
12/// # Errors
13///
14/// Returns an error if the path is not tracked or if unstaging fails.
15pub fn run(path: &Path) -> Result<()> {
16    let work_tree = git::repo_root()?;
17
18    // Normalize path: make it relative to work tree
19    let relative_path = if path.is_absolute() {
20        path.strip_prefix(&work_tree)
21            .map_or_else(|_| path.to_path_buf(), Path::to_path_buf)
22    } else {
23        path.to_path_buf()
24    };
25
26    // Open side repo
27    let repo = SideRepo::open()?;
28
29    if !repo.is_initialized() {
30        return Err(Error::PathNotTracked(relative_path));
31    }
32
33    // Load tracked paths
34    let mut tracked = TrackedPaths::load(&repo)?;
35
36    // Check if tracked
37    if !tracked.contains(&relative_path) {
38        return Err(Error::PathNotTracked(relative_path));
39    }
40
41    // Remove from tracked list
42    tracked.remove(&relative_path);
43    tracked.save()?;
44
45    // Unstage from side repo
46    repo.unstage(&relative_path)?;
47
48    // Stage updated .side-tracked file
49    repo.stage_tracked_file()?;
50
51    println!(
52        "{} {}",
53        "Untracked:".yellow().bold(),
54        relative_path.display()
55    );
56
57    Ok(())
58}