Skip to content

Commit

Permalink
Bind the git_remote_push API
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Aug 13, 2015
1 parent 75542e0 commit aaa2b69
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
2 changes: 1 addition & 1 deletion libgit2-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,10 +771,10 @@ pub enum LIBSSH2_USERAUTH_KBDINT_PROMPT {}
pub enum LIBSSH2_USERAUTH_KBDINT_RESPONSE {}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct git_push_options {
pub version: c_uint,
pub pb_parallelism: c_uint,
pub callbacks: git_remote_callbacks,
}

pub type git_tag_foreach_cb = extern fn(name: *const c_char,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub use pathspec::{PathspecDiffEntries, PathspecEntries};
pub use reference::{Reference, References, ReferenceNames};
pub use reflog::{Reflog, ReflogEntry, ReflogIter};
pub use refspec::Refspec;
pub use remote::{Remote, Refspecs, RemoteHead, FetchOptions};
pub use remote::{Remote, Refspecs, RemoteHead, FetchOptions, PushOptions};
pub use remote_callbacks::{RemoteCallbacks, Credentials, TransferProgress};
pub use remote_callbacks::{TransportMessage, Progress, UpdateTips};
pub use repo::{Repository, RepositoryInitOptions};
Expand Down
82 changes: 82 additions & 0 deletions src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ pub struct FetchOptions<'cb> {
download_tags: AutotagOption,
}

/// Options to control the behavior of a git push.
pub struct PushOptions<'cb> {
callbacks: Option<RemoteCallbacks<'cb>>,
pb_parallelism: u32,
}

impl<'repo> Remote<'repo> {
/// Ensure the remote name is well-formed.
pub fn is_valid_name(remote_name: &str) -> bool {
Expand Down Expand Up @@ -178,6 +184,21 @@ impl<'repo> Remote<'repo> {
Ok(())
}

/// Perform a push
///
/// Perform all the steps for a push. If no refspecs are passed then the
/// configured refspecs will be used.
pub fn push(&mut self,
refspecs: &[&str],
opts: Option<&mut PushOptions>) -> Result<(), Error> {
let (_a, _b, arr) = try!(::util::iter2cstrs(refspecs.iter()));
let raw = opts.map(|o| o.raw());
unsafe {
try_call!(raw::git_remote_push(self.raw, &arr, raw.as_ref()));
}
Ok(())
}

/// Get the statistics structure that is filled in by the fetch operation.
pub fn stats(&self) -> Progress {
unsafe {
Expand Down Expand Up @@ -335,6 +356,49 @@ impl<'cb> Binding for FetchOptions<'cb> {
}
}

impl<'cb> PushOptions<'cb> {
/// Creates a new blank set of push options
pub fn new() -> PushOptions<'cb> {
PushOptions {
callbacks: None,
pb_parallelism: 1,
}
}

/// Set the callbacks to use for the fetch operation.
pub fn remote_callbacks(&mut self, cbs: RemoteCallbacks<'cb>) -> &mut Self {
self.callbacks = Some(cbs);
self
}

/// If the transport being used to push to the remote requires the creation
/// of a pack file, this controls the number of worker threads used by the
/// packbuilder when creating that pack file to be sent to the remote.
///
/// if set to 0 the packbuilder will auto-detect the number of threads to
/// create, and the default value is 1.
pub fn packbuilder_parallelism(&mut self, parallel: u32) -> &mut Self {
self.pb_parallelism = parallel;
self
}
}

impl<'cb> Binding for PushOptions<'cb> {
type Raw = raw::git_push_options;

unsafe fn from_raw(_raw: raw::git_push_options) -> PushOptions<'cb> {
panic!("unimplemented");
}
fn raw(&self) -> raw::git_push_options {
raw::git_push_options {
version: 1,
callbacks: self.callbacks.as_ref().map(|m| m.raw())
.unwrap_or(unsafe { mem::zeroed() }),
pb_parallelism: self.pb_parallelism as libc::c_uint,
}
}
}

#[cfg(test)]
mod tests {
use std::cell::Cell;
Expand Down Expand Up @@ -469,4 +533,22 @@ mod tests {
}
assert!(progress_hit.get());
}

#[test]
fn push() {
let (_td, repo) = ::test::repo_init();
let td2 = TempDir::new("git1").unwrap();
let td3 = TempDir::new("git2").unwrap();
let url = ::test::path2url(&td2.path());

Repository::init_bare(td2.path()).unwrap();
// git push
let mut remote = repo.remote("origin", &url).unwrap();
remote.push(&["refs/heads/master"], None).unwrap();

let repo = Repository::clone(&url, td3.path()).unwrap();
let commit = repo.head().unwrap().target().unwrap();
let commit = repo.find_commit(commit).unwrap();
assert_eq!(commit.message(), Some("initial"));
}
}

0 comments on commit aaa2b69

Please sign in to comment.