|
8 | 8 | //! <SHA,SHA,…>`, which deletes the targeted `pick` lines from the |
9 | 9 | //! todo before git replays the rebase. |
10 | 10 |
|
11 | | -use std::path::{Path, PathBuf}; |
12 | | -use std::process::Command; |
| 11 | +use std::path::Path; |
13 | 12 |
|
14 | 13 | use mergify_core::CliError; |
15 | 14 |
|
16 | 15 | use crate::change_id; |
| 16 | +use crate::git::{resolve_repo_toplevel, run_git_capture, shell_quote, spawn_rebase}; |
17 | 17 | use crate::local_commits::{self, LocalCommit}; |
18 | 18 | use crate::trunk; |
19 | 19 |
|
@@ -91,7 +91,7 @@ pub fn run(opts: &Options<'_>) -> Result<Outcome, CliError> { |
91 | 91 |
|
92 | 92 | let shas: Vec<String> = resolved.iter().map(|c| c.sha.clone()).collect(); |
93 | 93 | let editor = build_sequence_editor(opts.mergify_binary, &shas); |
94 | | - spawn_rebase(&repo_dir, &base, &editor)?; |
| 94 | + spawn_rebase(&repo_dir, &base, Some(&editor))?; |
95 | 95 | Ok(Outcome::Dropped { dropped: resolved }) |
96 | 96 | } |
97 | 97 |
|
@@ -140,55 +140,6 @@ fn build_sequence_editor(binary: &Path, shas: &[String]) -> String { |
140 | 140 | format!("{bin} _internal rebase-todo-rewrite --action drop --shas {shas}") |
141 | 141 | } |
142 | 142 |
|
143 | | -fn shell_quote(value: &str) -> String { |
144 | | - let escaped = value.replace('\'', "'\\''"); |
145 | | - format!("'{escaped}'") |
146 | | -} |
147 | | - |
148 | | -fn resolve_repo_toplevel(repo_dir: Option<&Path>) -> Result<PathBuf, CliError> { |
149 | | - let raw = run_git_capture(repo_dir, &["rev-parse", "--show-toplevel"])?; |
150 | | - Ok(PathBuf::from(raw)) |
151 | | -} |
152 | | - |
153 | | -fn spawn_rebase(repo_dir: &Path, base: &str, sequence_editor: &str) -> Result<(), CliError> { |
154 | | - let status = Command::new("git") |
155 | | - .arg("-C") |
156 | | - .arg(repo_dir) |
157 | | - .args(["rebase", "-i", base]) |
158 | | - .env("GIT_SEQUENCE_EDITOR", sequence_editor) |
159 | | - .status() |
160 | | - .map_err(|e| CliError::Generic(format!("failed to spawn `git rebase -i`: {e}")))?; |
161 | | - if !status.success() { |
162 | | - return Err(CliError::Generic(format!( |
163 | | - "`git rebase -i {base}` exited {status}" |
164 | | - ))); |
165 | | - } |
166 | | - Ok(()) |
167 | | -} |
168 | | - |
169 | | -fn run_git_capture(repo_dir: Option<&Path>, args: &[&str]) -> Result<String, CliError> { |
170 | | - let mut cmd = Command::new("git"); |
171 | | - if let Some(dir) = repo_dir { |
172 | | - cmd.arg("-C").arg(dir); |
173 | | - } |
174 | | - cmd.args(args); |
175 | | - let output = cmd |
176 | | - .output() |
177 | | - .map_err(|e| CliError::Generic(format!("failed to spawn `git {}`: {e}", args.join(" "))))?; |
178 | | - if !output.status.success() { |
179 | | - let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string(); |
180 | | - return Err(CliError::Generic(if stderr.is_empty() { |
181 | | - format!("`git {}` failed", args.join(" ")) |
182 | | - } else { |
183 | | - stderr |
184 | | - })); |
185 | | - } |
186 | | - let stdout = String::from_utf8(output.stdout).map_err(|e| { |
187 | | - CliError::Generic(format!("`git {}` output is not UTF-8: {e}", args.join(" "))) |
188 | | - })?; |
189 | | - Ok(stdout.trim_end().to_string()) |
190 | | -} |
191 | | - |
192 | 143 | #[cfg(test)] |
193 | 144 | mod tests { |
194 | 145 | use super::*; |
|
0 commit comments