fix: correct stdErr match in isErrBlameNotFoundOrNotEnoughLines (#39309)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Abhay Pratap Singh
2026-09-14 14:59:18 +00:00
committed by GitHub
co-authored by wxiaoguang
parent 13033827b1
commit 85cbf477e5
6 changed files with 73 additions and 59 deletions
+42 -18
View File
@@ -10,6 +10,7 @@ import (
"os/exec"
"strings"
"gitea.dev/modules/regexplru"
"gitea.dev/modules/setting"
"gitea.dev/modules/util"
)
@@ -70,43 +71,66 @@ func IsErrorCanceledOrKilled(err error) bool {
return errors.Is(err, context.Canceled) || IsErrorSignalKilled(err)
}
type StderrCheck interface {
internalOnly()
}
type (
StderrPrefix string
StderrWildcard string
StderrPrefix string
StderrRegexp string
)
func (StderrPrefix) internalOnly() {}
func (StderrRegexp) internalOnly() {}
const (
StderrNotValidObjectName StderrPrefix = "fatal: not a valid object name"
StderrNotTreeObject StderrPrefix = "fatal: not a tree object"
StderrPathSpec StderrPrefix = "fatal: pathspec"
StderrBadRevision StderrPrefix = "fatal: bad revision"
StderrNoSuchPath StderrPrefix = "fatal: no such path"
StderrNoSuchRemote1 StderrPrefix = "fatal: no such remote" // git < 2.30, exit status 128
StderrNoSuchRemote2 StderrPrefix = "error: no such remote" // git >= 2.30. exit status 2
StderrUnknownRevisionOrPath StderrWildcard = "fatal: *: unknown revision or path not in the working tree"
StderrNoMergeBase StderrWildcard = "fatal: *: no merge base"
StderrUnknownRevisionOrPath StderrRegexp = "^fatal: .*: unknown revision or path not in the working tree"
StderrNoMergeBase StderrRegexp = "^fatal: .*: no merge base"
StderrFileNoEnoughLines StderrRegexp = `^fatal: file .* has only \d+ lines?`
)
func IsStderr[T StderrPrefix | StderrWildcard](err error, check T) bool {
func matchStderrCheck(stderr string, checkIntf StderrCheck) (match bool) {
switch check := any(checkIntf).(type) {
case StderrPrefix:
checkLen := len(check)
if len(stderr) >= checkLen {
// Git is lowercasing the "fatal: Not a valid object name" error message
// ref: https://lore.kernel.org/git/pull.2052.git.1771836302101.gitgitgadget@gmail.com
match = util.AsciiEqualFold(stderr[:checkLen], string(check))
}
case StderrRegexp:
re, err := regexplru.SystemCache().GetCompiled(string(check))
if err != nil {
setting.PanicInDevOrTesting("invalid stderr regexp %s", check)
} else {
match = re.MatchString(stderr)
}
default:
setting.PanicInDevOrTesting("invalid stderr type %T", checkIntf)
}
return match
}
func IsStderr(err error, checks ...StderrCheck) bool {
stderr, ok := ErrorAsStderr(err)
if !ok {
return false
}
checkLen := len(check)
if len(stderr) < checkLen {
return false
for _, checkIntf := range checks {
if matchStderrCheck(stderr, checkIntf) {
return true
}
}
switch any(check).(type) {
case StderrPrefix:
// Git is lowercasing the "fatal: Not a valid object name" error message
// ref: https://lore.kernel.org/git/pull.2052.git.1771836302101.gitgitgadget@gmail.com
return util.AsciiEqualFold(stderr[:checkLen], string(check))
case StderrWildcard:
prefix, remaining, _ := strings.Cut(string(check), "*")
return strings.HasPrefix(stderr, prefix) && strings.Contains(stderr, remaining)
}
setting.PanicInDevOrTesting("invalid stderr type %T", check)
return false
}