Files
gitks/tag/get_tag.rs
T
zhenyi dcb0fb74c5 feat(core): implement Git repository operations with gRPC services
- Add advertise_refs functionality for Git protocol communication
- Implement archive service with TAR/ZIP format support and streaming
- Create blame service for Git file annotation with line tracking
- Add branch management including create, delete, rename and compare operations
- Implement merge checking with conflict detection and fast-forward handling
- Add cherry-pick functionality for applying commits between branches
- Integrate gix library for Git repository operations and object handling
- Add comprehensive test suite covering all Git operations
- Implement proper error handling and repository validation
- Add pagination support for large result sets
- Create protobuf definitions for all Git operations and data structures
- Add build system for gRPC code generation and dependency management
2026-06-04 13:05:38 +08:00

64 lines
2.2 KiB
Rust

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