Files
gitks/tag/get_tag.rs
T

67 lines
2.3 KiB
Rust

//! Copyright (c) 2022-2026 GitDataAi All rights reserved.
use gix::bstr::ByteSlice;
use crate::bare::GitBare;
use crate::error::GitResult;
use crate::pb::{GetTagRequest, ObjectType, Tag};
impl GitBare {
pub fn get_tag(&self, request: GetTagRequest) -> GitResult<Tag> {
crate::sanitize::validate_ref_name(&request.name)?;
let repo = self.gix_repo()?;
let refname = format!("refs/tags/{}", request.name);
let mut r = repo.find_reference(refname.as_str())?;
let full_ref = r.name().as_bstr().to_string();
let raw_target_hex = r.target().try_id().map(|id| id.to_string());
let peeled_hex = r.peel_to_id()?.to_string();
let is_annotated = raw_target_hex
.as_ref()
.is_some_and(|raw| *raw != peeled_hex);
let mut tag = Tag {
name: request.name,
full_ref,
target_oid: Some(self.oid_to_pb(peeled_hex)),
target_type: ObjectType::Commit as i32,
tag_oid: None,
annotated: false,
tagger: None,
message: String::new(),
signature: None,
raw: Vec::new(),
};
if is_annotated
&& let Some(ref raw_hex) = raw_target_hex
&& let Ok(id) = gix::hash::ObjectId::from_hex(raw_hex.as_bytes())
{
tag.tag_oid = Some(self.oid_to_pb(raw_hex.clone()));
if let Ok(obj) = repo.find_object(id)
&& let Ok(tag_obj) = obj.try_into_tag()
{
tag.annotated = true;
if let Ok(Some(tagger)) = tag_obj.tagger() {
tag.tagger = Some(crate::pb::Signature {
identity: Some(crate::pb::Identity {
name: tagger.name.to_string(),
email: tagger.email.to_string(),
}),
when: None,
timezone_offset: 0,
});
}
if let Ok(decoded) = tag_obj.decode() {
tag.message = String::from_utf8_lossy(decoded.message.trim()).into_owned();
}
if request.include_raw {
tag.raw = tag_obj.data.clone();
}
}
}
Ok(tag)
}
}