git_quick_add/git/
stage.rs1use crate::models::path_items::PathItems;
2use git2::Repository;
3use std::path::Path;
4
5pub fn git_add_selected(repo: &Repository, paths: &Vec<PathItems>) -> Result<(), git2::Error> {
11 let mut index = repo.index()?;
12
13 println!("{}", console::style("Changes Made:").bold());
14
15 let mut logs = vec![];
16
17 for item in paths {
18 if item.is_staged && !item.is_selected {
20 let target = repo.head()?.peel(git2::ObjectType::Commit)?;
21 repo.reset_default(Some(&target), &[&item.path])?;
22
23 logs.push(format!(
24 " - {} {}",
25 console::style("Unstaged:").yellow(),
26 item.path.clone()
27 ));
28 } else if !item.is_staged && item.is_selected {
30 let p = Path::new(&item.path);
31
32 index.add_path(p).unwrap_or_else(|error| {
33 eprintln!(
34 "{} {} - {}",
35 console::style("Failed to add path for").red(),
36 console::style(&item.path).yellow(),
37 error
38 );
39 });
40
41 index.write().unwrap_or_else(|error| {
42 eprintln!(
43 "{} {} - {}",
44 console::style("Failed to write index for").red(),
45 console::style(&item.path).yellow(),
46 error
47 );
48 });
49
50 logs.push(format!(
51 " - {} {}",
52 console::style("Staged:").green(),
53 item.path
54 ));
55 } else {
56 if item.is_staged {
57 logs.push(format!(
58 " - {} {}",
59 console::style("Staged:").green(),
60 item.path.clone()
61 ));
62 } else {
63 logs.push(format!(
64 " - {} {}",
65 console::style("Unstaged:").yellow(),
66 item.path.clone()
67 ));
68 }
69 }
70 }
71
72 println!("{}", logs.join("\n"));
73
74 Ok(())
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use std::fs::File;
81 use std::io::Write;
82 use tempfile::TempDir;
83
84 fn init_repo() -> (TempDir, Repository) {
86 let tmp_dir = TempDir::new().expect("create temp dir");
87 let repo = Repository::init(tmp_dir.path()).expect("init repo");
88 (tmp_dir, repo)
89 }
90
91 #[test]
92 fn test_git_add_selected() {
93 let (_tmp, repo) = init_repo();
94
95 let file_path = "test.txt";
97 let file_full_path = repo.workdir().unwrap().join(file_path);
98 let mut file = File::create(&file_full_path).unwrap();
99 writeln!(file, "test content").unwrap();
100
101 let paths = vec![PathItems {
102 path: String::from(file_path),
103 is_staged: false,
104 is_selected: true,
105 }];
106
107 git_add_selected(&repo, &paths).unwrap();
108
109 let statuses = repo.statuses(None).unwrap();
111 for status in statuses.iter() {
112 assert!(status.status().is_index_new());
113 }
114 }
115}