Use case-insensitive matching for Git error "Not a valid object name" (#36728)
Fixes #36727 Git is lowercasing the `fatal: Not a valid object name` error message to follow its CodingGuidelines. This change makes the string matching case-insensitive so it works with both the current and future Git versions. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -49,9 +50,11 @@ func TestRunWithContextStd(t *testing.T) {
|
|||||||
stdout, stderr, err := cmd.RunStdString(t.Context())
|
stdout, stderr, err := cmd.RunStdString(t.Context())
|
||||||
if assert.Error(t, err) {
|
if assert.Error(t, err) {
|
||||||
assert.Equal(t, stderr, err.Stderr())
|
assert.Equal(t, stderr, err.Stderr())
|
||||||
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
|
stderrLower := strings.ToLower(stderr) // see: IsStdErrorNotValidObjectName
|
||||||
|
assert.Equal(t, "fatal: not a valid object name no-such\n", stderrLower)
|
||||||
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such", err.Error())
|
errLower := strings.ToLower(err.Error())
|
||||||
|
assert.Equal(t, "exit status 128 - fatal: not a valid object name no-such", errLower)
|
||||||
assert.Empty(t, stdout)
|
assert.Empty(t, stdout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,9 +64,11 @@ func TestRunWithContextStd(t *testing.T) {
|
|||||||
stdout, stderr, err := cmd.RunStdBytes(t.Context())
|
stdout, stderr, err := cmd.RunStdBytes(t.Context())
|
||||||
if assert.Error(t, err) {
|
if assert.Error(t, err) {
|
||||||
assert.Equal(t, string(stderr), err.Stderr())
|
assert.Equal(t, string(stderr), err.Stderr())
|
||||||
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
|
stderrLower := strings.ToLower(err.Stderr()) // see: IsStdErrorNotValidObjectName
|
||||||
|
assert.Equal(t, "fatal: not a valid object name no-such\n", stderrLower)
|
||||||
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
|
||||||
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such", err.Error())
|
errLower := strings.ToLower(err.Error())
|
||||||
|
assert.Equal(t, "exit status 128 - fatal: not a valid object name no-such", errLower)
|
||||||
assert.Empty(t, stdout)
|
assert.Empty(t, stdout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ func IsErrorCanceledOrKilled(err error) bool {
|
|||||||
return errors.Is(err, context.Canceled) || IsErrorSignalKilled(err)
|
return errors.Is(err, context.Canceled) || IsErrorSignalKilled(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsStdErrorNotValidObjectName(err error) bool {
|
||||||
|
stderr, ok := ErrorAsStderr(err)
|
||||||
|
// 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 ok && strings.Contains(strings.ToLower(stderr), "fatal: not a valid object name")
|
||||||
|
}
|
||||||
|
|
||||||
type pipelineError struct {
|
type pipelineError struct {
|
||||||
error
|
error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func (t *Tree) ListEntries() (Entries, error) {
|
|||||||
|
|
||||||
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).WithDir(t.repo.Path).RunStdBytes(t.repo.Ctx)
|
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).WithDir(t.repo.Path).RunStdBytes(t.repo.Ctx)
|
||||||
if runErr != nil {
|
if runErr != nil {
|
||||||
if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") {
|
if gitcmd.IsStdErrorNotValidObjectName(runErr) || strings.Contains(runErr.Error(), "fatal: not a tree object") {
|
||||||
return nil, ErrNotExist{
|
return nil, ErrNotExist{
|
||||||
ID: t.ID.String(),
|
ID: t.ID.String(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
|
|||||||
compareInfo, err := git_service.GetCompareInfo(ctx, ctx.Repo.Repository, ctx.Repo.Repository, ctx.Repo.GitRepo,
|
compareInfo, err := git_service.GetCompareInfo(ctx, ctx.Repo.Repository, ctx.Repo.Repository, ctx.Repo.GitRepo,
|
||||||
git.RefName(baseCommit), git.RefName(pull.GetGitHeadRefName()), false, false)
|
git.RefName(baseCommit), git.RefName(pull.GetGitHeadRefName()), false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
if gitcmd.IsStdErrorNotValidObjectName(err) || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
ctx.Data["BaseTarget"] = pull.BaseBranch
|
ctx.Data["BaseTarget"] = pull.BaseBranch
|
||||||
ctx.Data["NumCommits"] = 0
|
ctx.Data["NumCommits"] = 0
|
||||||
@@ -442,7 +442,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git_s
|
|||||||
compareInfo, err := git_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo,
|
compareInfo, err := git_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo,
|
||||||
git.RefName(pull.MergeBase), git.RefName(pull.GetGitHeadRefName()), false, false)
|
git.RefName(pull.MergeBase), git.RefName(pull.GetGitHeadRefName()), false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
if gitcmd.IsStdErrorNotValidObjectName(err) {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
ctx.Data["BaseTarget"] = pull.BaseBranch
|
ctx.Data["BaseTarget"] = pull.BaseBranch
|
||||||
ctx.Data["NumCommits"] = 0
|
ctx.Data["NumCommits"] = 0
|
||||||
@@ -584,7 +584,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git_s
|
|||||||
compareInfo, err := git_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo,
|
compareInfo, err := git_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo,
|
||||||
git.RefNameFromBranch(pull.BaseBranch), git.RefName(pull.GetGitHeadRefName()), false, false)
|
git.RefNameFromBranch(pull.BaseBranch), git.RefName(pull.GetGitHeadRefName()), false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
if gitcmd.IsStdErrorNotValidObjectName(err) {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
ctx.Data["BaseTarget"] = pull.BaseBranch
|
ctx.Data["BaseTarget"] = pull.BaseBranch
|
||||||
ctx.Data["NumCommits"] = 0
|
ctx.Data["NumCommits"] = 0
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
@@ -16,6 +15,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/unit"
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/globallock"
|
"code.gitea.io/gitea/modules/globallock"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
@@ -59,7 +59,7 @@ func prepareGitPath(gitRepo *git.Repository, defaultWikiBranch string, wikiPath
|
|||||||
// Look for both files
|
// Look for both files
|
||||||
filesInIndex, err := gitRepo.LsTree(defaultWikiBranch, unescaped, gitPath)
|
filesInIndex, err := gitRepo.LsTree(defaultWikiBranch, unescaped, gitPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "Not a valid object name") {
|
if gitcmd.IsStdErrorNotValidObjectName(err) {
|
||||||
return false, gitPath, nil // branch doesn't exist
|
return false, gitPath, nil // branch doesn't exist
|
||||||
}
|
}
|
||||||
log.Error("Wiki LsTree failed, err: %v", err)
|
log.Error("Wiki LsTree failed, err: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user