feat(gateway): implement remote service forwarding for distributed git operations
- Add remote client functions for archive, blame, and branch services - Implement fallback logic to forward requests to remote storage nodes - Add logging for forwarding operations with route details - Update Cargo.lock with new dependencies including ractor cluster libraries - Extend .gitignore with IDE and build system files - Remove outdated comments from bare repository implementation
This commit is contained in:
@@ -13,8 +13,6 @@ impl GitBare {
|
||||
Self { bare_dir }
|
||||
}
|
||||
|
||||
/// Open the gix repository. Callers should open once per logical operation
|
||||
/// and reuse the handle for all gix lookups within that operation.
|
||||
pub fn gix_repo(&self) -> GitResult<gix::Repository> {
|
||||
tracing::debug!(repo = %self.bare_dir.display(), "opening gix repository");
|
||||
gix::open(&self.bare_dir).map_err(|e| {
|
||||
@@ -39,7 +37,6 @@ impl GitBare {
|
||||
}
|
||||
PathBuf::from(p)
|
||||
} else if !relative_path.is_empty() {
|
||||
// relative_path alone is rejected unless absolute
|
||||
return Err(GitError::InvalidArgument(
|
||||
"relative_path requires storage_path to be set".into(),
|
||||
));
|
||||
@@ -47,14 +44,11 @@ impl GitBare {
|
||||
return Err(GitError::InvalidArgument("empty repository path".into()));
|
||||
};
|
||||
|
||||
// Join relative_path if provided
|
||||
let bare_dir = if !relative_path.is_empty() && !storage_path.is_empty() {
|
||||
let candidate = base.join(relative_path);
|
||||
// Canonicalize to resolve any `..` / symlinks, then check still under base
|
||||
let canonical = candidate
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| candidate.clone());
|
||||
// Path traversal check: canonical resolved dir must start with base
|
||||
let base_canon = base.canonicalize().unwrap_or_else(|_| base.clone());
|
||||
if !canonical.starts_with(&base_canon) {
|
||||
tracing::warn!(
|
||||
@@ -73,7 +67,6 @@ impl GitBare {
|
||||
return Err(GitError::InvalidArgument("empty repository path".into()));
|
||||
};
|
||||
|
||||
// Validate bare_dir exists, is a directory, and is readable
|
||||
if !bare_dir.exists() {
|
||||
tracing::warn!(path = %bare_dir.display(), "repository not found");
|
||||
return Err(GitError::RepoNotFound);
|
||||
@@ -85,10 +78,8 @@ impl GitBare {
|
||||
)));
|
||||
}
|
||||
|
||||
// Accept either bare repos (HEAD file) or non-bare (HEAD + .git)
|
||||
let head_path = bare_dir.join("HEAD");
|
||||
if !head_path.exists() {
|
||||
// Maybe it's a non-bare repo
|
||||
let git_dir = bare_dir.join(".git");
|
||||
if git_dir.is_dir() && git_dir.join("HEAD").exists() {
|
||||
tracing::debug!(path = %git_dir.display(), "resolved non-bare repo via .git subdir");
|
||||
@@ -100,7 +91,6 @@ impl GitBare {
|
||||
Ok(Self { bare_dir })
|
||||
}
|
||||
|
||||
/// Detect the repository's object format (SHA-1 or SHA-256).
|
||||
pub fn object_format(&self) -> crate::pb::ObjectFormat {
|
||||
let repo = self.gix_repo().ok();
|
||||
let kind = repo
|
||||
|
||||
Reference in New Issue
Block a user