git: Improve error messages (#35946)

Jacob and Conrad Irwin created

Release Notes:

- Improved git error messages

Includes stderr in the error message for git commands, provides better
output for things like errors when switching branches.

Before:
<img width="702" height="330" alt="image"
src="https://github.com/user-attachments/assets/f32402ae-b85c-4b0b-aae8-789607e8ec9e"
/>

After:
<img width="650" height="575" alt="image"
src="https://github.com/user-attachments/assets/308dbe3c-1ff9-40b9-a187-1e12d2488c80"
/>

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>

Change summary

crates/git/src/repository.rs          | 4 +++-
crates/workspace/src/notifications.rs | 7 ++++++-
2 files changed, 9 insertions(+), 2 deletions(-)

Detailed changes

crates/git/src/repository.rs 🔗

@@ -1814,6 +1814,7 @@ impl GitBinary {
             output.status.success(),
             GitBinaryCommandError {
                 stdout: String::from_utf8_lossy(&output.stdout).to_string(),
+                stderr: String::from_utf8_lossy(&output.stderr).to_string(),
                 status: output.status,
             }
         );
@@ -1836,9 +1837,10 @@ impl GitBinary {
 }
 
 #[derive(Error, Debug)]
-#[error("Git command failed: {stdout}")]
+#[error("Git command failed:\n{stdout}{stderr}\n")]
 struct GitBinaryCommandError {
     stdout: String,
+    stderr: String,
     status: ExitStatus,
 }
 

crates/workspace/src/notifications.rs 🔗

@@ -1077,8 +1077,13 @@ where
             if let Err(err) = result.as_ref() {
                 log::error!("{err:?}");
                 if let Ok(prompt) = cx.update(|window, cx| {
+                    let mut display = format!("{err}");
+                    if !display.ends_with('\n') {
+                        display.push('.');
+                        display.push(' ')
+                    }
                     let detail =
-                        f(err, window, cx).unwrap_or_else(|| format!("{err}. Please try again."));
+                        f(err, window, cx).unwrap_or_else(|| format!("{display}Please try again."));
                     window.prompt(PromptLevel::Critical, &msg, Some(&detail), &["Ok"], cx)
                 }) {
                     prompt.await.ok();