diff --git a/src/git.rs b/src/git.rs index a5093fa..ddf9bbc 100644 --- a/src/git.rs +++ b/src/git.rs @@ -8,6 +8,7 @@ mod branch; mod cherry_pick; mod fetch; mod log; +mod push; mod rev_list; mod switch; @@ -15,6 +16,7 @@ pub use branch::{branch, StartingPoint}; pub use cherry_pick::cherry_pick; pub use fetch::fetch; pub use log::log; +pub use push::push; pub use rev_list::rev_list; pub use switch::switch; @@ -49,6 +51,7 @@ impl Format { pub struct Branch>(pub T); pub struct Commit>(pub T); +pub struct Remote>(pub T); pub trait GitCmd: Sized { // FIXME: Spawn needs to check the exit code and encode that in its return type - non-zero should be Err diff --git a/src/git/push.rs b/src/git/push.rs new file mode 100644 index 0000000..7ca6c75 --- /dev/null +++ b/src/git/push.rs @@ -0,0 +1,40 @@ +use std::process::Command; + +use super::{Branch, GitCmd, Remote}; + +#[derive(Default)] +pub struct Push { + upstream: Option, + refspecs: Vec, +} + +pub fn push() -> Push { + Push::default() +} + +impl Push { + pub fn upstream>(self, Remote(upstream): Remote) -> Push { + Push { + upstream: Some(upstream.into()), + ..self + } + } + + pub fn branch>(self, Branch(branch): Branch) -> Push { + let mut refspecs = self.refspecs; + refspecs.push(branch.into()); + + Push { refspecs, ..self } + } +} + +impl GitCmd for Push { + fn setup(self, cmd: &mut Command) { + cmd.arg("push"); + + self.upstream.map(|remote| cmd.arg("-u").arg(remote)); + self.refspecs.iter().for_each(|r| { + cmd.arg(r); + }); + } +} diff --git a/src/upstream.rs b/src/upstream.rs index e4e5f51..0c1bd75 100644 --- a/src/upstream.rs +++ b/src/upstream.rs @@ -196,10 +196,11 @@ pub async fn prepare_commits( })?; info!("pushing branch..."); - std::process::Command::new("git") - .args(["push", "-u", "origin", "HEAD"]) - .spawn()? - .wait_with_output()?; + git::push() + .upstream(git::Remote("origin")) + // TODO: Rename? This should be .refspec()? + .branch(git::Branch("HEAD")) + .spawn()?; if let Some(token) = token { info!("creating pull-request...");