Skip to content

Commit 635d700

Browse files
authored
Merge pull request #1110 from Letiste/leo.sale/export-packbuilder-write-fn
Expose git_packbuilder_write fn
2 parents 68aa1ad + a1dabe6 commit 635d700

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

Diff for: src/packbuilder.rs

+91-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use libc::{c_int, c_uint, c_void, size_t};
22
use std::marker;
3+
use std::path::Path;
34
use std::ptr;
45
use std::slice;
56
use std::str;
67

8+
use crate::odb::{write_pack_progress_cb, OdbPackwriterCb};
79
use crate::util::Binding;
10+
use crate::IntoCString;
811
use crate::{panic, raw, Buf, Error, Oid, Repository, Revwalk};
912

1013
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
@@ -84,6 +87,26 @@ impl<'repo> PackBuilder<'repo> {
8487
Ok(())
8588
}
8689

90+
/// Write the new pack and corresponding index file to path.
91+
/// To set a progress callback, use `set_progress_callback` before calling this method.
92+
pub fn write(&mut self, path: &Path, mode: u32) -> Result<(), Error> {
93+
let path = path.into_c_string()?;
94+
let progress_cb: raw::git_indexer_progress_cb = Some(write_pack_progress_cb);
95+
let progress_payload = Box::new(OdbPackwriterCb { cb: None });
96+
let progress_payload_ptr = Box::into_raw(progress_payload);
97+
98+
unsafe {
99+
try_call!(raw::git_packbuilder_write(
100+
self.raw,
101+
path,
102+
mode,
103+
progress_cb,
104+
progress_payload_ptr as *mut _
105+
));
106+
}
107+
Ok(())
108+
}
109+
87110
/// Create the new pack and pass each object to the callback.
88111
pub fn foreach<F>(&mut self, mut cb: F) -> Result<(), Error>
89112
where
@@ -270,7 +293,10 @@ extern "C" fn progress_c(
270293

271294
#[cfg(test)]
272295
mod tests {
273-
use crate::Buf;
296+
use crate::{Buf, Oid};
297+
298+
// hash of a packfile constructed without any objects in it
299+
const EMPTY_PACKFILE_OID: &str = "029d08823bd8a8eab510ad6ac75c823cfd3ed31e";
274300

275301
fn pack_header(len: u8) -> Vec<u8> {
276302
[].iter()
@@ -314,6 +340,18 @@ mod tests {
314340
assert_eq!(&*buf, &*empty_pack_header());
315341
}
316342

343+
#[test]
344+
fn smoke_write() {
345+
let (_td, repo) = crate::test::repo_init();
346+
let mut builder = t!(repo.packbuilder());
347+
t!(builder.write(repo.path(), 0));
348+
#[allow(deprecated)]
349+
{
350+
assert!(builder.hash().unwrap() == Oid::from_str(EMPTY_PACKFILE_OID).unwrap());
351+
}
352+
assert!(builder.name().unwrap() == EMPTY_PACKFILE_OID);
353+
}
354+
317355
#[test]
318356
fn smoke_foreach() {
319357
let (_td, repo) = crate::test::repo_init();
@@ -367,6 +405,41 @@ mod tests {
367405
assert_eq!(&buf[0..12], &*pack_header(3));
368406
}
369407

408+
#[test]
409+
fn insert_write() {
410+
let (_td, repo) = crate::test::repo_init();
411+
let mut builder = t!(repo.packbuilder());
412+
let (commit, _tree) = crate::test::commit(&repo);
413+
t!(builder.insert_object(commit, None));
414+
assert_eq!(builder.object_count(), 1);
415+
t!(builder.write(repo.path(), 0));
416+
t!(repo.find_commit(commit));
417+
}
418+
419+
#[test]
420+
fn insert_tree_write() {
421+
let (_td, repo) = crate::test::repo_init();
422+
let mut builder = t!(repo.packbuilder());
423+
let (_commit, tree) = crate::test::commit(&repo);
424+
// will insert the tree itself and the blob, 2 objects
425+
t!(builder.insert_tree(tree));
426+
assert_eq!(builder.object_count(), 2);
427+
t!(builder.write(repo.path(), 0));
428+
t!(repo.find_tree(tree));
429+
}
430+
431+
#[test]
432+
fn insert_commit_write() {
433+
let (_td, repo) = crate::test::repo_init();
434+
let mut builder = t!(repo.packbuilder());
435+
let (commit, _tree) = crate::test::commit(&repo);
436+
// will insert the commit, its tree and the blob, 3 objects
437+
t!(builder.insert_commit(commit));
438+
assert_eq!(builder.object_count(), 3);
439+
t!(builder.write(repo.path(), 0));
440+
t!(repo.find_commit(commit));
441+
}
442+
370443
#[test]
371444
fn progress_callback() {
372445
let mut progress_called = false;
@@ -402,6 +475,23 @@ mod tests {
402475
assert_eq!(progress_called, false);
403476
}
404477

478+
#[test]
479+
fn progress_callback_with_write() {
480+
let mut progress_called = false;
481+
{
482+
let (_td, repo) = crate::test::repo_init();
483+
let mut builder = t!(repo.packbuilder());
484+
let (commit, _tree) = crate::test::commit(&repo);
485+
t!(builder.set_progress_callback(|_, _, _| {
486+
progress_called = true;
487+
true
488+
}));
489+
t!(builder.insert_commit(commit));
490+
t!(builder.write(repo.path(), 0));
491+
}
492+
assert_eq!(progress_called, true);
493+
}
494+
405495
#[test]
406496
fn set_threads() {
407497
let (_td, repo) = crate::test::repo_init();

0 commit comments

Comments
 (0)