fix(process): apply C.UTF-8 locale across platforms for child processes

Previously LANG/LC_ALL were only set on Windows, so git stderr was
localized on macOS/Linux and substring checks for English messages
(e.g. 'unknown revision or path not in the working tree') silently
failed — empty-repo/missing-branch cases surfaced as red error
banners in the Git log panel instead of rendering as empty lists.
This commit is contained in:
xintaofei
2026-04-19 06:49:24 +08:00
parent 527dfc48d6
commit 94ebfaabdc

View File

@@ -13,9 +13,8 @@ pub fn configure_std_command(command: &mut Command) -> &mut Command {
{ {
use std::os::windows::process::CommandExt; use std::os::windows::process::CommandExt;
command.creation_flags(CREATE_NO_WINDOW); command.creation_flags(CREATE_NO_WINDOW);
set_utf8_env(command);
} }
set_utf8_env(command);
command command
} }
@@ -34,41 +33,38 @@ pub fn configure_tokio_command(
#[cfg(windows)] #[cfg(windows)]
{ {
command.creation_flags(CREATE_NO_WINDOW); command.creation_flags(CREATE_NO_WINDOW);
set_utf8_env(command);
} }
set_utf8_env(command);
command command
} }
/// Hint child processes to produce UTF-8 output on Windows. /// Force child processes to emit English, UTF-8 output.
/// ///
/// Sets environment variables recognised by common runtimes (Python, MSYS2/Git /// Why: downstream code classifies errors by substring-matching English
/// Bash, .NET console apps). Not all programs honour these, but they cover the /// git/coreutils stderr (e.g. "unknown revision or path not in the working
/// most frequent sources of mojibake in practice. /// tree"). Without pinning the locale, those matches silently fail under
#[cfg(windows)] /// non-English system locales and legitimate empty-repo cases bubble up as
/// red error banners.
fn set_utf8_env<C: SetEnv>(command: &mut C) { fn set_utf8_env<C: SetEnv>(command: &mut C) {
// Python // Python
command.env("PYTHONUTF8", "1"); command.env("PYTHONUTF8", "1");
command.env("PYTHONIOENCODING", "utf-8"); command.env("PYTHONIOENCODING", "utf-8");
// MSYS2 / Git-for-Windows / POSIX-layer tools // POSIX locale — honored by git, coreutils, MSYS2/Git-for-Windows.
command.env("LANG", "C.UTF-8"); command.env("LANG", "C.UTF-8");
command.env("LC_ALL", "C.UTF-8"); command.env("LC_ALL", "C.UTF-8");
} }
/// Abstraction over the `.env()` method shared by std and tokio Command types. /// Abstraction over the `.env()` method shared by std and tokio Command types.
#[cfg(windows)]
trait SetEnv { trait SetEnv {
fn env(&mut self, key: &str, val: &str) -> &mut Self; fn env(&mut self, key: &str, val: &str) -> &mut Self;
} }
#[cfg(windows)]
impl SetEnv for Command { impl SetEnv for Command {
fn env(&mut self, key: &str, val: &str) -> &mut Self { fn env(&mut self, key: &str, val: &str) -> &mut Self {
Command::env(self, key, val) Command::env(self, key, val)
} }
} }
#[cfg(windows)]
impl SetEnv for tokio::process::Command { impl SetEnv for tokio::process::Command {
fn env(&mut self, key: &str, val: &str) -> &mut Self { fn env(&mut self, key: &str, val: &str) -> &mut Self {
tokio::process::Command::env(self, key, val) tokio::process::Command::env(self, key, val)