use crate::{git_config_get, git_read_tag};
use git2::{Commit, Repository};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GitCommit {
pub commit_id: String,
pub message: String,
pub time: i64,
pub tag: Option<String>,
}
pub fn git_commit(repo: &Repository, msg: &str) -> anyhow::Result<()> {
let mut index = repo.index()?;
let tree_id = index.write_tree()?;
let tree = repo.find_tree(tree_id)?;
let (_, _, _, sig) = git_config_get(&repo)?;
let parent_commit = if let Ok(parent_commit) = repo.head().and_then(|r| r.peel_to_commit()) {
Some(parent_commit)
} else {
None
};
let parents: Vec<&Commit> = parent_commit.as_ref().into_iter().collect();
repo.commit(Some("HEAD"), &sig, &sig, msg, &tree, &parents)?;
Ok(())
}
pub fn git_read_commits(repo: &Repository) -> anyhow::Result<Vec<GitCommit>> {
let tags = git_read_tag(repo)?;
let mut rev_walk = repo.revwalk()?;
rev_walk.push_head()?;
let mut r = vec![];
for oid in rev_walk {
let commit = repo.find_commit(oid?)?;
let commit_id = commit.id().to_string();
let option = tags
.iter()
.find(|tag| tag.commit_id == commit_id)
.and_then(|t| Some((*t.name).to_string()));
let commit = GitCommit {
commit_id,
message: commit.message().unwrap().to_string(),
time: commit.time().seconds(),
tag: option,
};
r.push(commit);
}
Ok(r)
}