Skip to main content

parley/git/
history.rs

1use anyhow::{Context, Result};
2use git2::{Repository, Sort};
3
4#[derive(Debug, Clone)]
5pub struct CommitSummary {
6    pub oid: String,
7    pub short_oid: String,
8    pub summary: String,
9}
10
11pub fn recent_commits(limit: usize) -> Result<Vec<CommitSummary>> {
12    if limit == 0 {
13        return Ok(Vec::new());
14    }
15
16    let repo = Repository::discover(".").context("failed to locate git repository")?;
17    let mut revwalk = repo.revwalk().context("failed to create git revwalk")?;
18    revwalk
19        .set_sorting(Sort::TOPOLOGICAL | Sort::TIME)
20        .context("failed to configure git revwalk sorting")?;
21    revwalk
22        .push_head()
23        .context("failed to start git revwalk from HEAD")?;
24
25    let mut commits = Vec::with_capacity(limit);
26    for oid_result in revwalk.take(limit) {
27        let oid = oid_result.context("failed to walk git history")?;
28        let commit = repo
29            .find_commit(oid)
30            .with_context(|| format!("failed to load commit {oid}"))?;
31        let summary = commit
32            .summary()
33            .unwrap_or("(no commit message)")
34            .to_string();
35        let oid_text = oid.to_string();
36        let short_oid: String = oid_text.chars().take(12).collect();
37        commits.push(CommitSummary {
38            oid: oid_text,
39            short_oid,
40            summary,
41        });
42    }
43
44    Ok(commits)
45}