gitdataai/lib/git/cmd/archive/zip.rs
2026-05-30 01:38:40 +08:00

56 lines
1.6 KiB
Rust

use gix::error::ResultExt;
use crate::{
bare::GitBare,
cmd::archive::{ArchiveOptions, ArchiveResult},
errors::{GitError, GitResult},
};
impl GitBare {
pub fn archive_zip(
&self,
options: ArchiveOptions,
) -> GitResult<ArchiveResult> {
let repo = self.gix_repo()?;
let gix_id: gix::hash::ObjectId = (&options.tree).try_into()?;
let tree_id = {
let gix_id = gix_id;
if let Ok(tree) = repo.find_tree(gix_id) {
tree.id().detach()
} else {
let commit = repo
.find_commit(gix_id)
.map_err(|e| GitError::Gix(e.to_string()))?;
commit
.tree_id()
.map_err(|e| GitError::Gix(e.to_string()))?
.detach()
}
};
let (mut stream, _index) = repo
.worktree_stream(tree_id)
.map_err(|e| GitError::Gix(e.to_string()))?;
let mut buf: Vec<u8> = Vec::new();
let archive_opts = gix_archive::Options {
format: gix_archive::Format::Zip {
compression_level: None,
},
tree_prefix: options.prefix.map(|p| gix::bstr::BString::from(p)),
..Default::default()
};
gix_archive::write_stream_seek(
&mut stream,
|stream| stream.next_entry().or_erased(),
std::io::Cursor::new(&mut buf),
archive_opts,
)
.map_err(|e| GitError::Gix(e.to_string()))?;
Ok(ArchiveResult { bytes: buf })
}
}