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
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
use crate::bare::GitBare;
|
||||
use crate::error::GitResult;
|
||||
use crate::pb::{AdvertiseRefsRequest, AdvertiseRefsResponse, ReferenceAdvertisement};
|
||||
|
||||
impl GitBare {
|
||||
pub fn advertise_refs(
|
||||
&self,
|
||||
_request: AdvertiseRefsRequest,
|
||||
) -> GitResult<AdvertiseRefsResponse> {
|
||||
let repo = self.gix_repo()?;
|
||||
let mut references = Vec::new();
|
||||
for r in repo.references()?.all()? {
|
||||
let mut r = match r {
|
||||
Ok(r) => r,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let name = r.name().to_string();
|
||||
let target_oid = r.peel_to_id().ok().map(|id| self.oid_to_pb(id.to_string()));
|
||||
let is_symbolic = r.target().try_id().is_none();
|
||||
let symbolic_target = if is_symbolic {
|
||||
match r.target() {
|
||||
gix::refs::TargetRef::Symbolic(name) => name.to_string(),
|
||||
_ => String::new(),
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
// Peel past tags to get the commit OID if this is a tag ref
|
||||
let peeled_oid = if name.starts_with("refs/tags/") {
|
||||
r.peel_to_id().ok().map(|id| self.oid_to_pb(id.to_string()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
references.push(ReferenceAdvertisement {
|
||||
name,
|
||||
target_oid,
|
||||
peeled_oid,
|
||||
symbolic: is_symbolic,
|
||||
symbolic_target,
|
||||
});
|
||||
}
|
||||
// Sort by name for deterministic output
|
||||
references.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
Ok(AdvertiseRefsResponse {
|
||||
references,
|
||||
capabilities: vec![
|
||||
"report-status".into(),
|
||||
"delete-refs".into(),
|
||||
"side-band-64k".into(),
|
||||
"ofs-delta".into(),
|
||||
"multi_ack_detailed".into(),
|
||||
"multi_ack".into(),
|
||||
"symref=HEAD".into(),
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user