//! 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 { 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) } }