use crate::git::{SEP, git_capture};
use std::collections::HashSet;
pub struct Commit {
pub hash: String,
pub short: String,
pub date: String,
pub committer: String,
pub subject: String,
}
pub struct FileEntry {
pub status: char,
pub path: String,
}
pub fn load_unpushed(repo: &str) -> HashSet<String> {
git_capture(repo, &["rev-list", "--branches", "--not", "--remotes"])
.map(|out| out.lines().map(str::to_string).collect())
.unwrap_or_default()
}
pub fn load_commits(repo: &str, extra: &[&str], limit: usize) -> Vec<Commit> {
let n = limit.to_string();
let fmt = format!("--pretty=format:%H{SEP}%h{SEP}%ad{SEP}%cn{SEP}%s");
let mut args = vec!["log", "-n", &n, "--date=format:%Y-%m-%d %H:%M", &fmt];
args.extend_from_slice(extra);
git_capture(repo, &args)
.map(|out| {
out.lines()
.filter_map(|line| {
let mut f = line.split(SEP);
Some(Commit {
hash: f.next()?.to_string(),
short: f.next()?.to_string(),
date: f.next()?.to_string(),
committer: f.next()?.to_string(),
subject: f.next().unwrap_or("").to_string(),
})
})
.collect()
})
.unwrap_or_default()
}
pub fn load_files(repo: &str, hash: &str, pathspec: &[&str]) -> Vec<FileEntry> {
let mut args = vec!["show", "--name-status", "--format=", hash];
if !pathspec.is_empty() {
args.push("--");
args.extend_from_slice(pathspec);
}
git_capture(repo, &args)
.map(|out| {
out.lines()
.filter(|l| !l.is_empty())
.filter_map(|line| {
let mut parts = line.split('\t');
let status = parts.next()?.chars().next()?;
let path = parts.next_back()?.to_string();
Some(FileEntry { status, path })
})
.collect()
})
.unwrap_or_default()
}
pub fn load_diff_raw(repo: &str, hash: &str, path: &str) -> String {
git_capture(repo, &["show", "--format=", hash, "--", path]).unwrap_or_default()
}