use gix::Repository;
use gix::bstr::BStr;
use super::{GitError, Sha};
pub(crate) fn resolve(repo: &Repository, spec: &str) -> Result<Sha, GitError> {
if spec.is_empty() {
return Err(GitError::EmptySpec);
}
let id = repo.rev_parse_single(BStr::new(spec))?;
Ok(Sha::from_object_id(id.detach()))
}
#[cfg(test)]
mod tests {
use super::*;
use gix::actor::SignatureRef;
use gix_hash::ObjectId;
use tempfile::TempDir;
fn signature() -> SignatureRef<'static> {
SignatureRef {
name: BStr::new("Test"),
email: BStr::new("test@example.com"),
time: "0 +0000",
}
}
fn empty_repo() -> (Repository, TempDir) {
let dir = TempDir::new().expect("tempdir");
let repo = gix::init(dir.path()).expect("gix::init");
(repo, dir)
}
fn add_commit(
repo: &Repository,
ref_name: &str,
parents: &[ObjectId],
message: &str,
) -> ObjectId {
use gix::objs::tree::{Entry, EntryKind};
let blob_id = repo.write_blob(b"hello\n").expect("write blob").detach();
let tree = gix::objs::Tree {
entries: vec![Entry {
mode: EntryKind::Blob.into(),
filename: "marker".into(),
oid: blob_id,
}],
};
let tree_id = repo.write_object(&tree).expect("write tree").detach();
repo.commit_as(
signature(),
signature(),
ref_name,
message,
tree_id,
parents.iter().copied(),
)
.expect("commit_as")
.detach()
}
#[test]
fn resolve_resolves_branch_ref() {
let (repo, _dir) = empty_repo();
let oid = add_commit(&repo, "refs/heads/main", &[], "first");
let sha = resolve(&repo, "refs/heads/main").expect("resolve");
assert_eq!(sha.as_object_id(), &oid);
}
#[test]
fn resolve_resolves_full_sha() {
let (repo, _dir) = empty_repo();
let oid = add_commit(&repo, "refs/heads/main", &[], "first");
let hex = oid.to_string();
let sha = resolve(&repo, &hex).expect("resolve");
assert_eq!(sha.as_object_id(), &oid);
}
#[test]
fn resolve_unknown_returns_error() {
let (repo, _dir) = empty_repo();
add_commit(&repo, "refs/heads/main", &[], "first");
assert!(resolve(&repo, "refs/heads/does-not-exist").is_err());
}
#[test]
fn resolve_empty_returns_empty_spec() {
let (repo, _dir) = empty_repo();
add_commit(&repo, "refs/heads/main", &[], "first");
assert!(matches!(resolve(&repo, ""), Err(GitError::EmptySpec)));
}
}