git_proc/
worktree.rs

1use std::path::Path;
2
3use crate::CommandError;
4
5/// Create a new `git worktree list` command builder.
6#[must_use]
7pub fn list() -> List<'static> {
8    List::new()
9}
10
11/// Create a new `git worktree add` command builder.
12#[must_use]
13pub fn add(path: &Path) -> Add<'_> {
14    Add::new(path)
15}
16
17/// Create a new `git worktree remove` command builder.
18#[must_use]
19pub fn remove(worktree: &Path) -> Remove<'_> {
20    Remove::new(worktree)
21}
22
23/// Builder for `git worktree list` command.
24///
25/// See `git worktree --help` for full documentation.
26#[derive(Debug)]
27pub struct List<'a> {
28    repo_path: Option<&'a Path>,
29}
30
31impl<'a> List<'a> {
32    #[must_use]
33    fn new() -> Self {
34        Self { repo_path: None }
35    }
36
37    /// Set the repository path (`-C <path>`).
38    #[must_use]
39    pub fn repo_path(mut self, path: &'a Path) -> Self {
40        self.repo_path = Some(path);
41        self
42    }
43
44    /// Capture stdout from this command.
45    #[must_use]
46    pub fn stdout(self) -> cmd_proc::Capture {
47        self.build().stdout()
48    }
49
50    fn build(self) -> cmd_proc::Command {
51        crate::base_command(self.repo_path)
52            .argument("worktree")
53            .argument("list")
54    }
55}
56
57impl Default for List<'_> {
58    fn default() -> Self {
59        Self::new()
60    }
61}
62
63#[cfg(feature = "test-utils")]
64impl List<'_> {
65    /// Compare the built command with another command using debug representation.
66    pub fn test_eq(&self, other: &cmd_proc::Command) {
67        let command = Self {
68            repo_path: self.repo_path,
69        }
70        .build();
71        command.test_eq(other);
72    }
73}
74
75/// Builder for `git worktree add` command.
76///
77/// See `git worktree --help` for full documentation.
78#[derive(Debug)]
79pub struct Add<'a> {
80    repo_path: Option<&'a Path>,
81    path: &'a Path,
82    branch: Option<&'a str>,
83    new_branch: Option<&'a str>,
84    commit_ish: Option<&'a str>,
85}
86
87impl<'a> Add<'a> {
88    #[must_use]
89    fn new(path: &'a Path) -> Self {
90        Self {
91            repo_path: None,
92            path,
93            branch: None,
94            new_branch: None,
95            commit_ish: None,
96        }
97    }
98
99    /// Set the repository path (`-C <path>`).
100    #[must_use]
101    pub fn repo_path(mut self, path: &'a Path) -> Self {
102        self.repo_path = Some(path);
103        self
104    }
105
106    /// Checkout existing branch in the new worktree.
107    #[must_use]
108    pub fn branch(mut self, branch: &'a str) -> Self {
109        self.branch = Some(branch);
110        self
111    }
112
113    /// Create a new branch and checkout in the new worktree.
114    ///
115    /// Corresponds to `-b <branch>`.
116    #[must_use]
117    pub fn new_branch(mut self, branch: &'a str) -> Self {
118        self.new_branch = Some(branch);
119        self
120    }
121
122    /// Set the commit-ish to create the worktree from.
123    #[must_use]
124    pub fn commit_ish(mut self, commit_ish: &'a str) -> Self {
125        self.commit_ish = Some(commit_ish);
126        self
127    }
128
129    /// Execute the command and return the exit status.
130    pub fn status(self) -> Result<(), CommandError> {
131        self.build().status()
132    }
133
134    fn build(self) -> cmd_proc::Command {
135        crate::base_command(self.repo_path)
136            .argument("worktree")
137            .argument("add")
138            .optional_option("-b", self.new_branch)
139            .argument(self.path)
140            .optional_argument(self.branch)
141            .optional_argument(self.commit_ish)
142    }
143}
144
145#[cfg(feature = "test-utils")]
146impl Add<'_> {
147    /// Compare the built command with another command using debug representation.
148    pub fn test_eq(&self, other: &cmd_proc::Command) {
149        let command = Self {
150            repo_path: self.repo_path,
151            path: self.path,
152            branch: self.branch,
153            new_branch: self.new_branch,
154            commit_ish: self.commit_ish,
155        }
156        .build();
157        command.test_eq(other);
158    }
159}
160
161/// Builder for `git worktree remove` command.
162///
163/// See `git worktree --help` for full documentation.
164#[derive(Debug)]
165pub struct Remove<'a> {
166    repo_path: Option<&'a Path>,
167    worktree: &'a Path,
168    force: bool,
169}
170
171impl<'a> Remove<'a> {
172    #[must_use]
173    fn new(worktree: &'a Path) -> Self {
174        Self {
175            repo_path: None,
176            worktree,
177            force: false,
178        }
179    }
180
181    /// Set the repository path (`-C <path>`).
182    #[must_use]
183    pub fn repo_path(mut self, path: &'a Path) -> Self {
184        self.repo_path = Some(path);
185        self
186    }
187
188    crate::flag_methods! {
189        /// Force removal even if worktree is dirty.
190        ///
191        /// Corresponds to `--force`.
192        pub fn force / force_if, force, "Conditionally force removal."
193    }
194
195    /// Execute the command and return the exit status.
196    pub fn status(self) -> Result<(), CommandError> {
197        self.build().status()
198    }
199
200    fn build(self) -> cmd_proc::Command {
201        crate::base_command(self.repo_path)
202            .argument("worktree")
203            .argument("remove")
204            .optional_argument(self.force.then_some("--force"))
205            .argument(self.worktree)
206    }
207}
208
209#[cfg(feature = "test-utils")]
210impl Remove<'_> {
211    /// Compare the built command with another command using debug representation.
212    pub fn test_eq(&self, other: &cmd_proc::Command) {
213        let command = Self {
214            repo_path: self.repo_path,
215            worktree: self.worktree,
216            force: self.force,
217        }
218        .build();
219        command.test_eq(other);
220    }
221}