use crate::bare::GitBare; use crate::error::GitResult; use crate::pb::*; impl GitBare { /// Get sizes for a list of objects by OID. pub fn objects_size(&self, request: ObjectsSizeRequest) -> GitResult { if request.oids.is_empty() { return Ok(ObjectsSizeResponse::default()); } let mut input = String::new(); for oid in &request.oids { crate::sanitize::validate_revision(oid)?; input.push_str(oid); input.push('\n'); } let mut child = std::process::Command::new("git") .args([ "--git-dir", &self.bare_dir.to_string_lossy(), "cat-file", "--batch-check=%(objectname) %(objectsize)", ]) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) .spawn() .map_err(|e| crate::error::GitError::CommandFailed { status_code: None, stderr: e.to_string(), })?; use std::io::Write; if let Some(ref mut stdin) = child.stdin { stdin.write_all(input.as_bytes()).map_err(|e| { crate::error::GitError::CommandFailed { status_code: None, stderr: e.to_string(), } })?; } let output = child.wait_with_output().map_err(|e| { crate::error::GitError::CommandFailed { status_code: None, stderr: e.to_string(), } })?; let stdout = String::from_utf8_lossy(&output.stdout); let mut sizes = Vec::new(); for line in stdout.lines() { let parts: Vec<&str> = line.split_whitespace().collect(); if parts.len() >= 2 { let oid = parts[0]; let found = parts.get(1).map_or(true, |&s| s != "missing"); let size = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0); sizes.push(ObjectSize { oid: oid.to_string(), size, found, }); } } Ok(ObjectsSizeResponse { sizes }) } /// Get total repository size on disk. pub fn repository_size(&self) -> GitResult { let output = std::process::Command::new("du") .args(["-sb", &self.bare_dir.to_string_lossy()]) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) .output() .map_err(|e| crate::error::GitError::CommandFailed { status_code: None, stderr: e.to_string(), })?; let stdout = String::from_utf8_lossy(&output.stdout); let size = stdout .split_whitespace() .next() .and_then(|s| s.parse().ok()) .unwrap_or(0); Ok(RepositorySizeResponse { size_bytes: size }) } }