use git2::{Commit, Repository};
use std::process::Command;
pub fn get_repo() -> Result<Repository, git2::Error> {
Repository::open(".")
}
pub fn staged_files(repo: &Repository) -> Result<Vec<String>, git2::Error> {
let idx = repo.index()?;
let head = repo.head().unwrap().peel_to_tree()?;
let diff = repo.diff_tree_to_index(Some(&head), Some(&idx), None)?;
Ok(diff
.deltas()
.map(|d| {
let path = d.new_file().path();
path.map_or_else(String::new, |path| path.to_str().unwrap_or("").to_string())
})
.collect())
}
pub fn tracked_files(repo: &Repository) -> Result<Vec<String>, git2::Error> {
let mut ret = Vec::new();
let idx = repo.index()?;
idx.iter().for_each(|e| {
if let Ok(path) = String::from_utf8(e.path) {
ret.push(path);
};
});
Ok(ret)
}
pub fn diff(repo: &Repository, files: &[String]) -> Result<String, git2::Error> {
let mut ret = String::new();
let idx = repo.index()?;
let head = repo.head().unwrap().peel_to_tree()?;
let diff = repo.diff_tree_to_index(Some(&head), Some(&idx), None)?;
diff.print(git2::DiffFormat::Patch, |delta, _, line| {
if let Some(path) = delta.new_file().path() {
if files.contains(&path.to_str().unwrap_or("").to_string()) {
ret.push(line.origin());
ret.push_str(std::str::from_utf8(line.content()).unwrap_or(""));
}
}
true
})?;
Ok(ret)
}
pub fn commit(msg: String) -> anyhow::Result<()> {
Command::new("git")
.arg("commit")
.arg("-m")
.arg(msg)
.output()?;
Ok(())
}