use anyhow::Result;
use endringer_core::types::CommitId;
use gix::Repository;
use crate::util::gix_id_to_commit_id;
fn parse_oid(id: &CommitId) -> Result<gix::ObjectId> {
gix::ObjectId::from_hex(id.to_string().as_bytes())
.map_err(|_| anyhow::anyhow!("invalid commit id '{}'", id))
}
pub(crate) fn merge_base(
repo: &Repository,
a: &CommitId,
b: &CommitId,
) -> Result<Option<CommitId>> {
let a_oid = parse_oid(a)?;
let b_oid = parse_oid(b)?;
match repo.merge_base(a_oid, b_oid) {
Ok(id) => Ok(Some(gix_id_to_commit_id(id.detach()))),
Err(e) => {
let msg = e.to_string();
if msg.contains("not found") || msg.contains("NotFound") {
Ok(None)
} else {
Err(anyhow::anyhow!("merge_base failed: {e}"))
}
}
}
}
pub(crate) fn is_ancestor(
repo: &Repository,
candidate: &CommitId,
descendant: &CommitId,
) -> Result<bool> {
if candidate == descendant {
return Ok(true);
}
match merge_base(repo, candidate, descendant)? {
Some(base) => Ok(base == *candidate),
None => Ok(false),
}
}