git_proc/
push.rs

1use std::path::Path;
2
3use crate::CommandError;
4use crate::url::Remote;
5
6/// Create a new `git push` command builder.
7#[must_use]
8pub fn new() -> Push<'static> {
9    Push::new()
10}
11
12/// Builder for `git push` command.
13///
14/// See `git push --help` for full documentation.
15#[derive(Debug)]
16pub struct Push<'a> {
17    repo_path: Option<&'a Path>,
18    force: bool,
19    remote: Option<&'a Remote>,
20    refspec: Option<&'a str>,
21}
22
23impl<'a> Push<'a> {
24    #[must_use]
25    fn new() -> Self {
26        Self {
27            repo_path: None,
28            force: false,
29            remote: None,
30            refspec: None,
31        }
32    }
33
34    /// Set the repository path (`-C <path>`).
35    #[must_use]
36    pub fn repo_path(mut self, path: &'a Path) -> Self {
37        self.repo_path = Some(path);
38        self
39    }
40
41    crate::flag_methods! {
42        /// Force push (overwrite remote refs).
43        ///
44        /// Corresponds to `--force`.
45        pub fn force / force_if, force, "Conditionally force push."
46    }
47
48    /// Set the remote to push to.
49    #[must_use]
50    pub fn remote(mut self, remote: &'a Remote) -> Self {
51        self.remote = Some(remote);
52        self
53    }
54
55    /// Set the refspec to push.
56    #[must_use]
57    pub fn refspec(mut self, refspec: &'a str) -> Self {
58        self.refspec = Some(refspec);
59        self
60    }
61
62    /// Execute the command and return the exit status.
63    pub fn status(self) -> Result<(), CommandError> {
64        self.build().status()
65    }
66
67    /// Capture stdout from this command.
68    #[must_use]
69    pub fn stdout(self) -> cmd_proc::Capture {
70        self.build().stdout()
71    }
72
73    /// Execute and return full output regardless of exit status.
74    ///
75    /// Use this when you need to inspect stderr on failure.
76    pub fn output(self) -> Result<cmd_proc::Output, CommandError> {
77        self.build().output()
78    }
79
80    fn build(self) -> cmd_proc::Command {
81        crate::base_command(self.repo_path)
82            .argument("push")
83            .optional_argument(self.force.then_some("--force"))
84            .optional_argument(self.remote)
85            .optional_argument(self.refspec)
86    }
87}
88
89impl Default for Push<'_> {
90    fn default() -> Self {
91        Self::new()
92    }
93}
94
95#[cfg(feature = "test-utils")]
96impl Push<'_> {
97    /// Compare the built command with another command using debug representation.
98    pub fn test_eq(&self, other: &cmd_proc::Command) {
99        let command = Self {
100            repo_path: self.repo_path,
101            force: self.force,
102            remote: self.remote,
103            refspec: self.refspec,
104        }
105        .build();
106        command.test_eq(other);
107    }
108}