rustic_git/commands/
add.rs1use std::path::Path;
2
3use crate::utils::git;
4use crate::{Repository, Result};
5
6impl Repository {
7 pub fn add<P: AsRef<Path>>(&self, paths: &[P]) -> Result<()> {
17 Self::ensure_git()?;
18
19 if paths.is_empty() {
20 return Ok(());
21 }
22
23 let mut args = vec!["add"];
24 let path_strings: Vec<String> = paths
25 .iter()
26 .map(|p| p.as_ref().to_string_lossy().to_string())
27 .collect();
28
29 for path_str in &path_strings {
30 args.push(path_str);
31 }
32
33 let _stdout = git(&args, Some(self.repo_path()))?;
34 Ok(())
35 }
36
37 pub fn add_all(&self) -> Result<()> {
43 Self::ensure_git()?;
44 let _stdout = git(&["add", "."], Some(self.repo_path()))?;
45 Ok(())
46 }
47
48 pub fn add_update(&self) -> Result<()> {
54 Self::ensure_git()?;
55 let _stdout = git(&["add", "-u"], Some(self.repo_path()))?;
56 Ok(())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use std::env;
64 use std::fs;
65 use std::path::{Path, PathBuf};
66
67 fn create_test_repo(path: &PathBuf) -> Repository {
68 if path.exists() {
70 fs::remove_dir_all(path).unwrap();
71 }
72
73 Repository::init(path, false).unwrap()
74 }
75
76 fn create_test_file(repo_path: &Path, filename: &str, content: &str) {
77 let file_path = repo_path.join(filename);
78 fs::write(file_path, content).unwrap();
79 }
80
81 #[test]
82 fn test_add_specific_files() {
83 let test_path = env::temp_dir().join("test_add_repo");
84 let repo = create_test_repo(&test_path);
85
86 create_test_file(&test_path, "file1.txt", "content 1");
88 create_test_file(&test_path, "file2.txt", "content 2");
89
90 let result = repo.add(&["file1.txt"]);
92 assert!(result.is_ok());
93
94 let status = repo.status().unwrap();
96 let added_files: Vec<_> = status
97 .staged_files()
98 .map(|entry| entry.path.to_str().unwrap())
99 .collect();
100
101 assert!(added_files.contains(&"file1.txt"));
102
103 fs::remove_dir_all(&test_path).unwrap();
105 }
106
107 #[test]
108 fn test_add_multiple_files() {
109 let test_path = env::temp_dir().join("test_add_multiple_repo");
110 let repo = create_test_repo(&test_path);
111
112 create_test_file(&test_path, "file1.txt", "content 1");
114 create_test_file(&test_path, "file2.txt", "content 2");
115 create_test_file(&test_path, "file3.txt", "content 3");
116
117 let result = repo.add(&["file1.txt", "file2.txt"]);
119 assert!(result.is_ok());
120
121 let status = repo.status().unwrap();
123 let added_files: Vec<_> = status
124 .staged_files()
125 .map(|entry| entry.path.to_str().unwrap())
126 .collect();
127
128 assert!(added_files.contains(&"file1.txt"));
129 assert!(added_files.contains(&"file2.txt"));
130 assert_eq!(added_files.len(), 2);
131
132 fs::remove_dir_all(&test_path).unwrap();
134 }
135
136 #[test]
137 fn test_add_all() {
138 let test_path = env::temp_dir().join("test_add_all_repo");
139 let repo = create_test_repo(&test_path);
140
141 create_test_file(&test_path, "file1.txt", "content 1");
143 create_test_file(&test_path, "file2.txt", "content 2");
144 fs::create_dir(test_path.join("subdir")).unwrap();
145 create_test_file(&test_path, "subdir/file3.txt", "content 3");
146
147 let result = repo.add_all();
149 assert!(result.is_ok());
150
151 let status = repo.status().unwrap();
153 let added_files: Vec<_> = status
154 .staged_files()
155 .map(|entry| entry.path.to_str().unwrap())
156 .collect();
157
158 assert!(added_files.contains(&"file1.txt"));
159 assert!(added_files.contains(&"file2.txt"));
160 assert!(added_files.contains(&"subdir/file3.txt"));
161
162 fs::remove_dir_all(&test_path).unwrap();
164 }
165
166 #[test]
167 fn test_add_empty_paths() {
168 let test_path = env::temp_dir().join("test_add_empty_repo");
169 let repo = create_test_repo(&test_path);
170
171 let result = repo.add::<&str>(&[]);
173 assert!(result.is_ok());
174
175 fs::remove_dir_all(&test_path).unwrap();
177 }
178
179 #[test]
180 fn test_add_nonexistent_file() {
181 let test_path = env::temp_dir().join("test_add_nonexistent_repo");
182 let repo = create_test_repo(&test_path);
183
184 let result = repo.add(&["nonexistent.txt"]);
186 assert!(result.is_err());
187
188 fs::remove_dir_all(&test_path).unwrap();
190 }
191}