diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index a8aac4ce8d8e94a5c26e43ec9b32f481307d626a..05c0da4611ff7d410a1c947c8a42c066a7247b69 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -1162,42 +1162,8 @@ impl GitRepository for RealGitRepository { return Ok(()); } - let working_directory = working_directory?; - let mut child = new_smol_command(&git_binary_path) - .current_dir(&working_directory) - .envs(env.iter()) - .args([ - "checkout", - &commit, - "--pathspec-from-file=-", - "--pathspec-file-nul", - ]) - .stdin(Stdio::piped()) - .stdout(Stdio::null()) - .stderr(Stdio::piped()) - .spawn() - .context("failed to spawn git checkout")?; - - let mut stdin = child.stdin.take().context("failed to get stdin")?; - for path in &paths { - stdin.write_all(path.as_unix_str().as_bytes()).await?; - stdin.write_all(b"\0").await?; - } - drop(stdin); - - let output = child.output().await?; - if output.status.success() { - return Ok(()); - } - - let stderr = String::from_utf8_lossy(&output.stderr); - if !stderr.contains("pathspec-from-file") { - anyhow::bail!("Failed to checkout files:\n{}", stderr); - } - - // Fallback for older git versions: pass paths as command-line arguments let output = new_smol_command(&git_binary_path) - .current_dir(&working_directory) + .current_dir(&working_directory?) .envs(env.iter()) .args(["checkout", &commit, "--"]) .args(paths.iter().map(|path| path.as_unix_str())) @@ -1884,33 +1850,20 @@ impl GitRepository for RealGitRepository { let git_binary_path = self.any_git_binary_path.clone(); self.executor .spawn(async move { - if paths.is_empty() { - return Ok(()); - } - - let mut child = new_smol_command(&git_binary_path) - .current_dir(&working_directory?) - .envs(env.iter()) - .args(["update-index", "--add", "--remove", "-z", "--stdin"]) - .stdin(Stdio::piped()) - .stdout(Stdio::null()) - .stderr(Stdio::piped()) - .spawn() - .context("failed to spawn git update-index")?; - - let mut stdin = child.stdin.take().context("failed to get stdin")?; - for path in &paths { - stdin.write_all(path.as_unix_str().as_bytes()).await?; - stdin.write_all(b"\0").await?; + if !paths.is_empty() { + let output = new_smol_command(&git_binary_path) + .current_dir(&working_directory?) + .envs(env.iter()) + .args(["update-index", "--add", "--remove", "--"]) + .args(paths.iter().map(|p| p.as_unix_str())) + .output() + .await?; + anyhow::ensure!( + output.status.success(), + "Failed to stage paths:\n{}", + String::from_utf8_lossy(&output.stderr), + ); } - drop(stdin); - - let output = child.output().await?; - anyhow::ensure!( - output.status.success(), - "Failed to stage paths:\n{}", - String::from_utf8_lossy(&output.stderr), - ); Ok(()) }) .boxed() @@ -1926,57 +1879,21 @@ impl GitRepository for RealGitRepository { self.executor .spawn(async move { - if paths.is_empty() { - return Ok(()); - } - - let working_directory = working_directory?; - let mut child = new_smol_command(&git_binary_path) - .current_dir(&working_directory) - .envs(env.iter()) - .args([ - "reset", - "--quiet", - "--pathspec-from-file=-", - "--pathspec-file-nul", - ]) - .stdin(Stdio::piped()) - .stdout(Stdio::null()) - .stderr(Stdio::piped()) - .spawn() - .context("failed to spawn git reset")?; - - let mut stdin = child.stdin.take().context("failed to get stdin")?; - for path in &paths { - stdin.write_all(path.as_unix_str().as_bytes()).await?; - stdin.write_all(b"\0").await?; - } - drop(stdin); - - let output = child.output().await?; - if output.status.success() { - return Ok(()); - } + if !paths.is_empty() { + let output = new_smol_command(&git_binary_path) + .current_dir(&working_directory?) + .envs(env.iter()) + .args(["reset", "--quiet", "--"]) + .args(paths.iter().map(|p| p.as_std_path())) + .output() + .await?; - let stderr = String::from_utf8_lossy(&output.stderr); - if !stderr.contains("pathspec-from-file") { - anyhow::bail!("Failed to unstage:\n{}", stderr); + anyhow::ensure!( + output.status.success(), + "Failed to unstage:\n{}", + String::from_utf8_lossy(&output.stderr), + ); } - - // Fallback for older git versions: pass paths as command-line arguments - let output = new_smol_command(&git_binary_path) - .current_dir(&working_directory) - .envs(env.iter()) - .args(["reset", "--quiet", "--"]) - .args(paths.iter().map(|p| p.as_std_path())) - .output() - .await?; - - anyhow::ensure!( - output.status.success(), - "Failed to unstage:\n{}", - String::from_utf8_lossy(&output.stderr), - ); Ok(()) }) .boxed()