feat(api): extend commit and diff services with new functionality

- Add FindCommit, ListCommitsByOid, CommitIsAncestor RPCs to CommitService
- Add CheckObjectsExist, CommitsByMessage, GetCommitStats RPCs to CommitService
- Add LastCommitForPath, CountCommits, CountDivergingCommits RPCs to CommitService
- Add RawDiff, RawPatch, FindChangedPaths RPCs to DiffService
- Add FindMergeBase, WriteRef, SearchFilesByContent RPCs to RepositoryService
- Add SearchFilesByName, ObjectsSize, RepositorySize RPCs to RepositoryService
- Add FindLicense, OptimizeRepository, GetRawChanges RPCs to RepositoryService
- Add FetchRemote, CreateRepositoryFromURL RPCs to RepositoryService
- Implement server handlers for all new RPC methods
- Add new modules for commit counting, finding, and querying features
- Add new modules for diff changed paths and raw operations
- Add new modules for refs and remote operations
- Remove unnecessary comments from various source files
- Update proto definitions with new message types and service methods
This commit is contained in:
zhenyi
2026-06-08 15:37:08 +08:00
parent 8f472a0443
commit 66afd932ed
43 changed files with 3070 additions and 75 deletions
+158 -3
View File
@@ -446,7 +446,6 @@ impl repository_service_server::RepositoryService for GitksService {
Ok(tonic::Response::new(resp))
}
// ── Hooks Management ────────────────────────────────────────────
async fn list_hooks(
&self,
@@ -508,7 +507,6 @@ impl repository_service_server::RepositoryService for GitksService {
Ok(tonic::Response::new(()))
}
// ── Snapshot Operations ──────────────────────────────────────────
async fn create_snapshot(
&self,
@@ -614,7 +612,6 @@ impl repository_service_server::RepositoryService for GitksService {
Ok(tonic::Response::new(()))
}
// ── Repository Move ──────────────────────────────────────────────
type FetchRepositoryDataStream =
ReceiverStream<Result<FetchRepositoryDataResponse, tonic::Status>>;
@@ -706,4 +703,162 @@ impl repository_service_server::RepositoryService for GitksService {
Ok(tonic::Response::new(ReceiverStream::new(rx)))
}
async fn find_merge_base(
&self,
request: tonic::Request<FindMergeBaseRequest>,
) -> Result<tonic::Response<FindMergeBaseResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/FindMergeBase");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.find_merge_base(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn write_ref(
&self,
request: tonic::Request<WriteRefRequest>,
) -> Result<tonic::Response<WriteRefResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/WriteRef");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.write_ref(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn search_files_by_content(
&self,
request: tonic::Request<SearchFilesByContentRequest>,
) -> Result<tonic::Response<SearchFilesByContentResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/SearchFilesByContent");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.search_files_by_content(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn search_files_by_name(
&self,
request: tonic::Request<SearchFilesByNameRequest>,
) -> Result<tonic::Response<SearchFilesByNameResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/SearchFilesByName");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.search_files_by_name(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn objects_size(
&self,
request: tonic::Request<ObjectsSizeRequest>,
) -> Result<tonic::Response<ObjectsSizeResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/ObjectsSize");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.objects_size(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn repository_size(
&self,
request: tonic::Request<RepositorySizeRequest>,
) -> Result<tonic::Response<RepositorySizeResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/RepositorySize");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.repository_size().map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn fetch_remote(
&self,
request: tonic::Request<FetchRemoteRequest>,
) -> Result<tonic::Response<FetchRemoteResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/FetchRemote");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.fetch_remote(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn create_repository_from_url(
&self,
request: tonic::Request<CreateRepositoryFromUrlRequest>,
) -> Result<tonic::Response<CreateRepositoryFromUrlResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/CreateRepositoryFromURL");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let bare_dir = self.resolve_for_init(inner.repository.as_ref())?;
let gb = crate::bare::GitBare::new(bare_dir);
gb.create_repository_from_url(&inner.remote_url, inner.mirror)
.map_err(into_status)?;
if let Some(ref hm) = self.hook_manager {
hm.install_hooks(&gb.bare_dir).map_err(into_status)?;
}
self.notify_ref_update(&self.repo_label(inner.repository.as_ref()), "HEAD", "", "");
m.record("ok");
Ok(tonic::Response::new(CreateRepositoryFromUrlResponse {
repository: Some(Repository {
header: inner.repository,
bare: true,
..Default::default()
}),
}))
}
async fn find_license(
&self,
request: tonic::Request<FindLicenseRequest>,
) -> Result<tonic::Response<FindLicenseResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/FindLicense");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.find_license().map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn optimize_repository(
&self,
request: tonic::Request<OptimizeRepositoryRequest>,
) -> Result<tonic::Response<OptimizeRepositoryResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/OptimizeRepository");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.optimize_repository(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
async fn get_raw_changes(
&self,
request: tonic::Request<GetRawChangesRequest>,
) -> Result<tonic::Response<GetRawChangesResponse>, tonic::Status> {
let m = crate::metrics::RequestMetrics::new("gitks.RepositoryService/GetRawChanges");
let inner = request.into_inner();
let _rate = self.acquire_rate_limit(inner.repository.as_ref()).await?;
let gb = self.resolve(inner.repository.as_ref())?;
let resp = gb.get_raw_changes(inner).map_err(into_status)?;
m.record("ok");
Ok(tonic::Response::new(resp))
}
}