changeset_git/repository/
files.rs1use std::path::Path;
2
3use crate::{GitError, Result};
4
5use super::Repository;
6
7impl Repository {
8 pub fn delete_file(&self, path: &Path) -> Result<()> {
12 let absolute_path = if path.is_absolute() {
13 path.to_path_buf()
14 } else {
15 self.root().join(path)
16 };
17
18 std::fs::remove_file(&absolute_path).map_err(|source| GitError::FileDelete {
19 path: absolute_path,
20 source,
21 })?;
22
23 let relative_path = self.to_relative_path(path);
24
25 let mut index = self.inner.index()?;
26 index.remove_path(&relative_path)?;
27 index.write()?;
28
29 Ok(())
30 }
31
32 pub fn delete_files(&self, paths: &[&Path]) -> Result<()> {
36 for path in paths {
37 self.delete_file(path)?;
38 }
39 Ok(())
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::super::tests::setup_test_repo;
46 use crate::GitError;
47 use std::fs;
48 use std::path::Path;
49
50 #[test]
51 fn delete_single_file() -> anyhow::Result<()> {
52 let (dir, repo) = setup_test_repo()?;
53
54 fs::write(dir.path().join("file.txt"), "content")?;
55 repo.stage_files(&[Path::new("file.txt")])?;
56
57 let sig = git2::Signature::now("Test", "test@example.com")?;
58 let mut index = repo.inner.index()?;
59 let tree_id = index.write_tree()?;
60 let tree = repo.inner.find_tree(tree_id)?;
61 let parent = repo.inner.head()?.peel_to_commit()?;
62 repo.inner
63 .commit(Some("HEAD"), &sig, &sig, "Add file", &tree, &[&parent])?;
64
65 repo.delete_file(Path::new("file.txt"))?;
66
67 assert!(!dir.path().join("file.txt").exists());
68
69 let index = repo.inner.index()?;
70 assert!(index.get_path(Path::new("file.txt"), 0).is_none());
71
72 Ok(())
73 }
74
75 #[test]
76 fn delete_multiple_files() -> anyhow::Result<()> {
77 let (dir, repo) = setup_test_repo()?;
78
79 fs::write(dir.path().join("file1.txt"), "content1")?;
80 fs::write(dir.path().join("file2.txt"), "content2")?;
81 repo.stage_files(&[Path::new("file1.txt"), Path::new("file2.txt")])?;
82
83 let sig = git2::Signature::now("Test", "test@example.com")?;
84 let mut index = repo.inner.index()?;
85 let tree_id = index.write_tree()?;
86 let tree = repo.inner.find_tree(tree_id)?;
87 let parent = repo.inner.head()?.peel_to_commit()?;
88 repo.inner
89 .commit(Some("HEAD"), &sig, &sig, "Add files", &tree, &[&parent])?;
90
91 repo.delete_files(&[Path::new("file1.txt"), Path::new("file2.txt")])?;
92
93 assert!(!dir.path().join("file1.txt").exists());
94 assert!(!dir.path().join("file2.txt").exists());
95
96 Ok(())
97 }
98
99 #[test]
100 fn delete_nonexistent_file_fails() -> anyhow::Result<()> {
101 let (_dir, repo) = setup_test_repo()?;
102
103 let result = repo.delete_file(Path::new("nonexistent.txt"));
104 assert!(matches!(result, Err(GitError::FileDelete { .. })));
105
106 Ok(())
107 }
108}