fix(refs): write stdin data to git update-ref subprocess

Use spawn + write_all + wait_with_output instead of output() so that
the constructed ref update commands are actually written to the
subprocess stdin.
This commit is contained in:
zhenyi
2026-06-10 18:32:42 +08:00
parent 1dca8b3b78
commit 0782a9fe6d
+19 -2
View File
@@ -26,7 +26,7 @@ impl GitBare {
return Ok(UpdateReferencesResponse::default()); return Ok(UpdateReferencesResponse::default());
} }
let output = std::process::Command::new("git") let mut child = std::process::Command::new("git")
.args([ .args([
"--git-dir", "--git-dir",
&self.bare_dir.to_string_lossy(), &self.bare_dir.to_string_lossy(),
@@ -37,12 +37,29 @@ impl GitBare {
.stdin(std::process::Stdio::piped()) .stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped())
.output() .spawn()
.map_err(|e| crate::error::GitError::CommandFailed { .map_err(|e| crate::error::GitError::CommandFailed {
status_code: None, status_code: None,
stderr: e.to_string(), stderr: e.to_string(),
})?; })?;
if let Some(ref mut stdin) = child.stdin {
use std::io::Write;
stdin.write_all(stdin_input.as_bytes()).map_err(|e| {
crate::error::GitError::CommandFailed {
status_code: None,
stderr: format!("failed to write stdin: {e}"),
}
})?;
}
drop(child.stdin.take());
let output = child.wait_with_output().map_err(|e| {
crate::error::GitError::CommandFailed {
status_code: None,
stderr: e.to_string(),
}
})?;
let stderr = String::from_utf8_lossy(&output.stderr).into_owned(); let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
if !output.status.success() { if !output.status.success() {
return Ok(UpdateReferencesResponse { return Ok(UpdateReferencesResponse {