diff --git a/cli/src/git_util.rs b/cli/src/git_util.rs index a19b160ebf..5b4f0b834e 100644 --- a/cli/src/git_util.rs +++ b/cli/src/git_util.rs @@ -94,30 +94,22 @@ fn pinentry_get_pw(url: &str) -> Option { .stdout(Stdio::piped()) .spawn() .ok()?; - #[rustfmt::skip] - pinentry - .stdin - .take() - .unwrap() - .write_all( - format!( - "SETTITLE jj passphrase\n\ - SETDESC Enter passphrase for {url}\n\ - SETPROMPT Passphrase:\n\ - GETPIN\n" - ) - .as_bytes(), - ) - .ok()?; - let mut out = String::new(); - pinentry - .stdout - .take() - .unwrap() - .read_to_string(&mut out) - .ok()?; + let mut interact = || -> std::io::Result<_> { + #[rustfmt::skip] + let req = format!( + "SETTITLE jj passphrase\n\ + SETDESC Enter passphrase for {url}\n\ + SETPROMPT Passphrase:\n\ + GETPIN\n" + ); + pinentry.stdin.take().unwrap().write_all(req.as_bytes())?; + let mut out = String::new(); + pinentry.stdout.take().unwrap().read_to_string(&mut out)?; + Ok(out) + }; + let maybe_out = interact(); _ = pinentry.wait(); - for line in out.split('\n') { + for line in maybe_out.ok()?.split('\n') { if !line.starts_with("D ") { continue; } diff --git a/cli/src/merge_tools/external.rs b/cli/src/merge_tools/external.rs index d3f9ce2850..d3e25ad7f4 100644 --- a/cli/src/merge_tools/external.rs +++ b/cli/src/merge_tools/external.rs @@ -552,7 +552,7 @@ pub fn generate_diff( tool_binary: tool.program.clone(), source, })?; - io::copy(&mut child.stdout.take().unwrap(), writer).map_err(ExternalToolError::Io)?; + let copy_result = io::copy(&mut child.stdout.take().unwrap(), writer); // Non-zero exit code isn't an error. For example, the traditional diff command // will exit with 1 if inputs are different. let exit_status = child.wait().map_err(ExternalToolError::Io)?; @@ -560,6 +560,7 @@ pub fn generate_diff( if !exit_status.success() { writeln!(ui.warning(), "{}", format_tool_aborted(&exit_status)).ok(); } + copy_result.map_err(ExternalToolError::Io)?; Ok(()) }