use std::process::Command; use crate::bare::GitBare; use crate::error::{GitError, GitResult}; use crate::pb::{ArchiveChunk, ArchiveRequest, archive_options, object_selector}; impl GitBare { pub fn get_archive(&self, request: ArchiveRequest) -> GitResult> { let revision = match request.treeish.and_then(|s| s.selector) { Some(object_selector::Selector::Oid(oid)) => oid.hex, Some(object_selector::Selector::Revision(name)) => name.revision, None => "HEAD".into(), }; let options = request.options.unwrap_or_default(); let format = archive_options::Format::try_from(options.format) .unwrap_or(archive_options::Format::ArchiveFormatTar); let mut args = vec!["archive".to_string()]; args.push(match format { archive_options::Format::ArchiveFormatZip => "--format=zip".into(), _ => "--format=tar".into(), }); if !options.prefix.is_empty() { args.push(format!("--prefix={}", options.prefix)); } args.push(revision); if !options.pathspec.is_empty() { args.push("--".into()); args.extend(options.pathspec); } let output = Command::new("git") .arg("--git-dir") .arg(&self.bare_dir) .args(&args) .output()?; if !output.status.success() { return Err(GitError::CommandFailed { status_code: output.status.code(), stderr: String::from_utf8_lossy(&output.stderr).into_owned(), }); } Ok(vec![ArchiveChunk { data: output.stdout, }]) } }