From 6ba311f38dcf8ae607802c7101682156067be62a Mon Sep 17 00:00:00 2001 From: Randalix Date: Fri, 9 Oct 2026 15:12:08 +0200 Subject: [PATCH 1/2] fix(git): pin git's locale for clone, so failures classify on any host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit classifyGitFailure() matches git's English stderr, but cloneRepository() spawned git with gitNonInteractiveEnv(), which left the host's locale in place. Under de_DE.UTF-8 a missing ref came back as FAILED / 422 instead of REF_NOT_FOUND / 400, and a missing repository as 422 instead of 404; the clone dialog showed "git failed: Schwerwiegend: …". gitNonInteractiveEnv() now sets LC_ALL=C and LANG=C, as git-workspace-status.ts already does. Two tests depended on the locale on their own: - git-status-routes: the spy runner called git without the production runner's LC_ALL=C, so "Kein Git-Repository" was not recognised. - custom-model-run-menu-ui: the modal formats with toLocaleString(), the test hard-coded 16,384 and 40,000. Full suite under de_DE.UTF-8: 5 failed before, 0 after. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/git-clone.ts | 4 ++++ test/custom-model-run-menu-ui.test.ts | 4 ++-- test/routes/git-status-routes.test.ts | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/git-clone.ts b/src/git-clone.ts index b9cd3708..ef3380e8 100644 --- a/src/git-clone.ts +++ b/src/git-clone.ts @@ -495,6 +495,10 @@ export function gitNonInteractiveEnv(base: NodeJS.ProcessEnv = process.env): Nod SSH_ASKPASS_REQUIRE: 'never', DISPLAY: '', GCM_INTERACTIVE: 'never', + // classifyGitFailure() matches git's ENGLISH stderr; a German or French locale would + // turn a missing ref into a generic FAILED (422 instead of 400). + LC_ALL: 'C', + LANG: 'C', GIT_SSH_COMMAND: base.GIT_SSH_COMMAND || 'ssh -oBatchMode=yes -oStrictHostKeyChecking=accept-new -oConnectTimeout=10', }; diff --git a/test/custom-model-run-menu-ui.test.ts b/test/custom-model-run-menu-ui.test.ts index d1832113..336b9c5d 100644 --- a/test/custom-model-run-menu-ui.test.ts +++ b/test/custom-model-run-menu-ui.test.ts @@ -1342,8 +1342,8 @@ describe('Custom Model Endpoint Profiles: _confirmContextWarning (in-app modal, expect(modal.classList.contains('active')).toBe(true); const message = win.document.getElementById('customModelContextWarningMessage')!.textContent!; expect(message).toContain('qwen3.8-27b-ud-q4_k_xl'); - expect(message).toContain('16,384'); - expect(message).toContain('40,000'); + expect(message).toContain((16384).toLocaleString()); // the modal formats for the user's locale + expect(message).toContain((40000).toLocaleString()); expect(message).toMatch(/llama-swap/i); expect(message).toMatch(/fit-ctx/i); diff --git a/test/routes/git-status-routes.test.ts b/test/routes/git-status-routes.test.ts index b8f24e9d..5b1c6036 100644 --- a/test/routes/git-status-routes.test.ts +++ b/test/routes/git-status-routes.test.ts @@ -14,6 +14,8 @@ import { clearGitStatusCache, runGit, type GitRunner } from '../../src/git-works const ENV = { ...process.env, + // As the production runner (git-workspace-status.ts): git's not-a-repo message is matched in English. + LC_ALL: 'C', GIT_AUTHOR_NAME: 'T', GIT_AUTHOR_EMAIL: 't@example.com', GIT_COMMITTER_NAME: 'T', From abc8598100caa0124a90aaeaa9098352f1af5a6a Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Fri, 9 Oct 2026 17:50:07 +0200 Subject: [PATCH 2/2] test(git): pin gitNonInteractiveEnv()'s locale so a revert fails in CI CI runs in an English locale, where git already answers in English, so the real-git clone tests stay green even if the LC_ALL/LANG pin from the previous commit is dropped. A pure assertion on the env is the only check that fails then. It also covers LANGUAGE, which gettext ignores once LC_ALL is C. Refs #568 Co-Authored-By: Claude Opus 5.5 (1M context) --- test/git-clone.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/git-clone.test.ts b/test/git-clone.test.ts index 9b588055..9da829e8 100644 --- a/test/git-clone.test.ts +++ b/test/git-clone.test.ts @@ -239,6 +239,14 @@ describe('gitNonInteractiveEnv', () => { it("does not override a user's own GIT_SSH_COMMAND", () => { expect(gitNonInteractiveEnv({ GIT_SSH_COMMAND: 'ssh -F /custom' }).GIT_SSH_COMMAND).toBe('ssh -F /custom'); }); + + // Issue #568. CI runs in an English locale, so the real-git tests below cannot + // catch a revert: only this assertion fails if the pin is dropped. + it("pins git's messages to English over the host's locale, since classifyGitFailure() matches English stderr", () => { + const env = gitNonInteractiveEnv({ LC_ALL: 'de_DE.UTF-8', LANG: 'de_DE.UTF-8', LANGUAGE: 'de' }); + expect(env.LC_ALL).toBe('C'); + expect(env.LANG).toBe('C'); + }); }); describe('parseLsRemoteOutput', () => {