mirror of
https://gitea.com/gitea/tea.git
synced 2026-09-10 07:26:33 -04:00
Fix locale-dependent git error handling (#1089)
Force the C locale for git subprocesses so git output used for error classification remains stable and parseable regardless of the user shell language. Add a regression test that simulates a localized git "not a repository" error and verifies it is classified as ErrRepositoryNotExists. Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
ee531914cd
commit
67f1b1a8f2
|
|
@ -258,6 +258,21 @@ func (e *gitCommandError) Unwrap() error {
|
|||
return e.err
|
||||
}
|
||||
|
||||
func gitCommandEnv(authEnv []string) []string {
|
||||
baseEnv := os.Environ()
|
||||
env := make([]string, 0, len(baseEnv)+len(authEnv)+3)
|
||||
for _, value := range baseEnv {
|
||||
if strings.HasPrefix(value, "LC_ALL=") ||
|
||||
strings.HasPrefix(value, "LANG=") ||
|
||||
strings.HasPrefix(value, "LANGUAGE=") {
|
||||
continue
|
||||
}
|
||||
env = append(env, value)
|
||||
}
|
||||
env = append(env, authEnv...)
|
||||
return append(env, "LC_ALL=C", "LANG=C", "LANGUAGE=C")
|
||||
}
|
||||
|
||||
func runGitCommand(dir string, auth *AuthMethod, extraConfigs []string, args ...string) (string, error) {
|
||||
authConfigs, authEnv, cleanup, err := prepareCLIAuth(auth)
|
||||
if err != nil {
|
||||
|
|
@ -278,7 +293,7 @@ func runGitCommand(dir string, auth *AuthMethod, extraConfigs []string, args ...
|
|||
if dir != "" {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
cmd.Env = append(os.Environ(), authEnv...)
|
||||
cmd.Env = gitCommandEnv(authEnv)
|
||||
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
|
|
|
|||
40
modules/git/cli_backend_test.go
Normal file
40
modules/git/cli_backend_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOpenClassifiesLocalizedNotRepoError(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("test uses a POSIX shell script as fake git")
|
||||
}
|
||||
|
||||
fakeGitDir := t.TempDir()
|
||||
fakeGit := filepath.Join(fakeGitDir, "git")
|
||||
script := `#!/bin/sh
|
||||
locale="${LC_ALL:-${LANG:-C}}"
|
||||
if [ "$locale" = "C" ]; then
|
||||
echo "fatal: not a git repository (or any of the parent directories): .git" >&2
|
||||
else
|
||||
echo "fatal: Kein Git-Repository (oder irgendein Elternverzeichnis bis zum Einhangepunkt /)" >&2
|
||||
fi
|
||||
exit 128
|
||||
`
|
||||
require.NoError(t, os.WriteFile(fakeGit, []byte(script), 0o755))
|
||||
|
||||
t.Setenv("PATH", fakeGitDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
t.Setenv("LC_ALL", "de_DE.UTF-8")
|
||||
t.Setenv("LANG", "de_DE.UTF-8")
|
||||
t.Setenv("LANGUAGE", "de_DE:de")
|
||||
|
||||
_, err := (cliBackend{}).Open(t.TempDir())
|
||||
require.ErrorIs(t, err, ErrRepositoryNotExists)
|
||||
}
|
||||
Loading…
Reference in a new issue