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}