Initial upload: GitPulse - Developer Productivity Analyzer CLI tool
Some checks failed
CI / test (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-04 15:45:32 +00:00
parent b54349c031
commit 59035e0144

67
src/git/walker.rs Normal file
View File

@@ -0,0 +1,67 @@
use crate::git::Commit;
use anyhow::Result;
use git2::{Sort, Sortable};
pub struct CommitWalker<'a> {
repo: &'a git2::Repository,
revwalk: git2::Revwalk<'a>,
}
impl<'a> CommitWalker<'a> {
pub fn new(repo: &'a git2::Repository) -> Result<Self> {
let mut revwalk = repo.revwalk()?;
revwalk.set_sorting(Sort::TIME)?;
revwalk.push_head()?;
Ok(Self { repo, revwalk })
}
pub fn with_sorting(repo: &'a git2::Repository, sorting: Sort) -> Result<Self> {
let mut revwalk = repo.revwalk()?;
revwalk.set_sorting(sorting)?;
revwalk.push_head()?;
Ok(Self { repo, revwalk })
}
pub fn hide(&mut self, oid: git2::Oid) -> Result<()> {
self.revwalk.hide(oid)?;
Ok(())
}
pub fn push(&mut self, oid: git2::Oid) -> Result<()> {
self.revwalk.push(oid)?;
Ok(())
}
pub fn push_head(&mut self) -> Result<()> {
self.revwalk.push_head()?;
Ok(())
}
pub fn simplify_first_parent(&mut self) {
self.revwalk.simplify_first_parent();
}
pub fn count(&self) -> usize {
let mut count = 0;
for _ in self.clone() {
count += 1;
}
count
}
}
impl<'a> Iterator for CommitWalker<'a> {
type Item = Result<Commit<'a>>;
fn next(&mut self) -> Option<Self::Item> {
self.revwalk
.next()
.map(|oid| match oid {
Ok(oid) => match self.repo.find_commit(oid) {
Ok(commit) => Ok(Commit::new(commit)),
Err(e) => Err(anyhow::anyhow!("Failed to find commit {}: {}", oid, e)),
},
Err(e) => Err(anyhow::anyhow!("Revwalk error: {}", e)),
})
}
}