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:
zhenyi
2026-06-04 13:05:38 +08:00
commit dcb0fb74c5
98 changed files with 20569 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
use crate::pb::{PageInfo, Pagination};
/// Simple offset-based pagination over an in-memory slice.
/// The `page_token` is a decimal string encoding the start offset.
pub fn paginate<T: Clone>(items: &[T], pagination: Option<&Pagination>) -> (Vec<T>, PageInfo) {
let page_size = pagination
.map(|p| p.page_size as usize)
.unwrap_or(items.len().max(1))
.max(1);
let start_offset = pagination
.and_then(|p| {
if p.page_token.is_empty() {
None
} else {
p.page_token.parse::<usize>().ok()
}
})
.unwrap_or(0)
.min(items.len());
let end = std::cmp::min(start_offset + page_size, items.len());
let has_next = end < items.len();
let next_page_token = if has_next {
end.to_string()
} else {
String::new()
};
(
items[start_offset..end].to_vec(),
PageInfo {
next_page_token,
has_next_page: has_next,
total_count: items.len() as u64,
},
)
}
/// Apply sort direction. Ascending = no-op (preserves order).
/// Descending reverses the slice.
pub fn apply_sort<T>(items: &mut [T], sort_direction: i32) {
if sort_direction == crate::pb::SortDirection::Desc as i32 {
items.reverse();
}
}