From 0782a9fe6d2831dd460de1833e41e4f10f06e428 Mon Sep 17 00:00:00 2001 From: zhenyi <434836402@qq.com> Date: Wed, 10 Jun 2026 18:32:42 +0800 Subject: [PATCH] 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. --- refs/update_refs.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/refs/update_refs.rs b/refs/update_refs.rs index e65ee71..7de7ad8 100644 --- a/refs/update_refs.rs +++ b/refs/update_refs.rs @@ -26,7 +26,7 @@ impl GitBare { return Ok(UpdateReferencesResponse::default()); } - let output = std::process::Command::new("git") + let mut child = std::process::Command::new("git") .args([ "--git-dir", &self.bare_dir.to_string_lossy(), @@ -37,12 +37,29 @@ impl GitBare { .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) - .output() + .spawn() .map_err(|e| crate::error::GitError::CommandFailed { status_code: None, 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(); if !output.status.success() { return Ok(UpdateReferencesResponse {