use crate::command::GitCommand;
use crate::command::log::LogCommand;
use crate::error::Result;
use crate::parse::{LOG_FORMAT, parse_log};
use crate::repo::Repository;
pub use crate::parse::CommitEntry as Commit;
#[derive(Debug)]
pub struct HistoryWalk<'a> {
repo: &'a Repository,
revisions: Vec<String>,
paths: Vec<String>,
max_count: Option<u32>,
skip: Option<u32>,
since: Option<String>,
until: Option<String>,
author: Option<String>,
grep: Option<String>,
reverse: bool,
}
impl<'a> HistoryWalk<'a> {
fn new(repo: &'a Repository) -> Self {
Self {
repo,
revisions: Vec::new(),
paths: Vec::new(),
max_count: None,
skip: None,
since: None,
until: None,
author: None,
grep: None,
reverse: false,
}
}
#[must_use]
pub fn max_count(mut self, n: u32) -> Self {
self.max_count = Some(n);
self
}
#[must_use]
pub fn skip(mut self, n: u32) -> Self {
self.skip = Some(n);
self
}
#[must_use]
pub fn since(mut self, s: impl Into<String>) -> Self {
self.since = Some(s.into());
self
}
#[must_use]
pub fn until(mut self, s: impl Into<String>) -> Self {
self.until = Some(s.into());
self
}
#[must_use]
pub fn author(mut self, s: impl Into<String>) -> Self {
self.author = Some(s.into());
self
}
#[must_use]
pub fn grep(mut self, s: impl Into<String>) -> Self {
self.grep = Some(s.into());
self
}
#[must_use]
pub fn revision(mut self, r: impl Into<String>) -> Self {
self.revisions.push(r.into());
self
}
#[must_use]
pub fn path(mut self, p: impl Into<String>) -> Self {
self.paths.push(p.into());
self
}
#[must_use]
pub fn reverse(mut self) -> Self {
self.reverse = true;
self
}
pub async fn execute(self) -> Result<Vec<Commit>> {
let mut cmd = LogCommand::new();
cmd.format(LOG_FORMAT);
if let Some(n) = self.max_count {
cmd.max_count(n);
}
if let Some(n) = self.skip {
cmd.skip(n);
}
if let Some(s) = self.since {
cmd.since(s);
}
if let Some(s) = self.until {
cmd.until(s);
}
if let Some(s) = self.author {
cmd.author(s);
}
if let Some(s) = self.grep {
cmd.grep(s);
}
if self.reverse {
cmd.reverse();
}
for r in self.revisions {
cmd.revision(r);
}
for p in self.paths {
cmd.path(p);
}
cmd.current_dir(self.repo.path());
let out = cmd.execute().await?;
parse_log(&out.stdout)
}
}
impl Repository {
#[must_use]
pub fn history(&self) -> HistoryWalk<'_> {
HistoryWalk::new(self)
}
}