7b02b53
ZhenYi
feat(lib/git): add SSH transport (server, git_service, handler/auth/channel/command/git_op)
7b02b53
use std::path::Path;
use std::process::Command;
use crate::sync::error::{SyncError, SyncResult};
pub async fn run_gc(repo_dir: &Path) {
let dir_str = repo_dir.display().to_string();
let dir = repo_dir.to_path_buf();
let result = tokio::task::spawn_blocking(move || {
let _ = run_git(&dir, &["gc", "--prune=now", "--quiet"]);
})
.await
.map_err(|e| SyncError::Internal(format!("join error: {e}")));
if let Err(e) = result {
tracing::warn!(repo_dir = %dir_str, error = %e, "git gc failed");
}
}
pub async fn run_fsck(repo_dir: &Path) {
let dir_str = repo_dir.display().to_string();
let dir = repo_dir.to_path_buf();
let result = tokio::task::spawn_blocking(move || run_git(&dir, &["fsck", "--no-progress"]))
.await
.map_err(|e| SyncError::Internal(format!("join error: {e}")));
match result {
Ok(Ok(stdout)) if stdout.contains("error") || stdout.contains("broken") => {
tracing::warn!(
repo_dir = %dir_str,
output = %stdout.trim(),
"fsck reported integrity issues"
);
}
Ok(_) => {}
Err(e) => {
tracing::warn!(repo_dir = %dir_str, error = %e, "fsck failed");
}
}
}
fn run_git(repo_dir: &Path, args: &[&str]) -> SyncResult<String> {
let output = Command::new("git")
.arg("-C")
.arg(repo_dir)
.args(args)
.output()
.map_err(|e| SyncError::Internal(format!("spawn git: {e}")))?;
if !output.status.success() {
return Err(SyncError::Internal(format!(
"git {} exited {}: {}",
args.join(" "),
output.status.code().unwrap_or(-1),
String::from_utf8_lossy(&output.stderr).trim()
)));
}
Ok(String::from_utf8_lossy(&output.stdout).into_owned())
}