Skip to main content

git_spawn/command/
rebase.rs

1//! `git rebase` — reapply commits on top of another base tip.
2
3use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7/// Builder for `git rebase`.
8#[derive(Debug, Clone, Default)]
9pub struct RebaseCommand {
10    /// Shared executor.
11    pub executor: CommandExecutor,
12    /// Upstream base.
13    pub upstream: Option<String>,
14    /// Branch to rebase.
15    pub branch: Option<String>,
16    /// `--onto`.
17    pub onto: Option<String>,
18    /// `--interactive` / `-i`.
19    pub interactive: bool,
20    /// `--autosquash`.
21    pub autosquash: bool,
22    /// `--autostash`.
23    pub autostash: bool,
24    /// `--abort`.
25    pub abort: bool,
26    /// `--continue`.
27    pub cont: bool,
28    /// `--skip`.
29    pub skip: bool,
30    /// `--quit`.
31    pub quit: bool,
32    /// `--root`.
33    pub root: bool,
34    /// `--strategy`.
35    pub strategy: Option<String>,
36}
37
38impl RebaseCommand {
39    /// New `rebase`.
40    #[must_use]
41    pub fn new() -> Self {
42        Self::default()
43    }
44
45    /// Upstream base.
46    pub fn upstream(&mut self, u: impl Into<String>) -> &mut Self {
47        self.upstream = Some(u.into());
48        self
49    }
50
51    /// Branch to rebase.
52    pub fn branch(&mut self, b: impl Into<String>) -> &mut Self {
53        self.branch = Some(b.into());
54        self
55    }
56
57    /// `--onto`.
58    pub fn onto(&mut self, o: impl Into<String>) -> &mut Self {
59        self.onto = Some(o.into());
60        self
61    }
62
63    /// Interactive mode.
64    pub fn interactive(&mut self) -> &mut Self {
65        self.interactive = true;
66        self
67    }
68
69    /// `--autosquash`.
70    pub fn autosquash(&mut self) -> &mut Self {
71        self.autosquash = true;
72        self
73    }
74
75    /// `--autostash`.
76    pub fn autostash(&mut self) -> &mut Self {
77        self.autostash = true;
78        self
79    }
80
81    /// `--abort`.
82    pub fn abort(&mut self) -> &mut Self {
83        self.abort = true;
84        self
85    }
86
87    /// `--continue`.
88    pub fn cont(&mut self) -> &mut Self {
89        self.cont = true;
90        self
91    }
92
93    /// `--skip`.
94    pub fn skip(&mut self) -> &mut Self {
95        self.skip = true;
96        self
97    }
98
99    /// `--quit`.
100    pub fn quit(&mut self) -> &mut Self {
101        self.quit = true;
102        self
103    }
104
105    /// `--root`.
106    pub fn root(&mut self) -> &mut Self {
107        self.root = true;
108        self
109    }
110
111    /// Merge strategy.
112    pub fn strategy(&mut self, s: impl Into<String>) -> &mut Self {
113        self.strategy = Some(s.into());
114        self
115    }
116}
117
118#[async_trait]
119impl GitCommand for RebaseCommand {
120    type Output = CommandOutput;
121    fn get_executor(&self) -> &CommandExecutor {
122        &self.executor
123    }
124    fn get_executor_mut(&mut self) -> &mut CommandExecutor {
125        &mut self.executor
126    }
127    fn build_command_args(&self) -> Vec<String> {
128        let mut args = vec!["rebase".to_string()];
129        if self.abort {
130            args.push("--abort".into());
131            return args;
132        }
133        if self.cont {
134            args.push("--continue".into());
135            return args;
136        }
137        if self.skip {
138            args.push("--skip".into());
139            return args;
140        }
141        if self.quit {
142            args.push("--quit".into());
143            return args;
144        }
145        if self.interactive {
146            args.push("--interactive".into());
147        }
148        if self.autosquash {
149            args.push("--autosquash".into());
150        }
151        if self.autostash {
152            args.push("--autostash".into());
153        }
154        if self.root {
155            args.push("--root".into());
156        }
157        if let Some(o) = &self.onto {
158            args.push("--onto".into());
159            args.push(o.clone());
160        }
161        if let Some(s) = &self.strategy {
162            args.push(format!("--strategy={s}"));
163        }
164        if let Some(u) = &self.upstream {
165            args.push(u.clone());
166        }
167        if let Some(b) = &self.branch {
168            args.push(b.clone());
169        }
170        args
171    }
172    async fn execute(&self) -> Result<CommandOutput> {
173        self.execute_raw().await
174    }
175}