refactor(git): replace git stderr matching with exit codes (#39866)

Matching git's stderr text is fragile because it breaks silently when
git rewords a message. Where git offers an exit code or a query with a
defined answer, use that instead, and drop matches that could never
trigger. Follow-up to the discussion in https://github.com/go-gitea/gitea/pull/39857.

- Detect a missing remote by `git remote` exit code 2
- Resolve annotated tags to their tree with cat-file `^{tree}` instead
of spawning `ls-tree` when listing tree entries
- Skip the wiki page lookup when the default branch doesn't exist yet
- Remove unreachable "no merge base" and "unknown revision" checks
This commit is contained in:
silverwind authored and GitHub committed 2026-10-20 21:00:32 +00:00
1 parent 52eb515751
commit 738ff1d65a
12 files changed
+57 -92

No files matched your search

+6 -6
View File
@@ -15,7 +15,6 @@ import (
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/globallock"
"gitea.dev/modules/graceful"
"gitea.dev/modules/log"
@@ -50,17 +49,18 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error {
}
// prepareGitPath try to find a suitable file path with file name by the given raw wiki name.
// An empty defaultWikiBranch means the branch doesn't exist yet.
// return: existence, prepared file path with name, error
func prepareGitPath(ctx context.Context, gitRepo *git.Repository, defaultWikiBranch string, wikiPath WebPath) (bool, string, error) {
unescaped := string(wikiPath) + ".md"
gitPath := WebPathToGitPath(wikiPath)
if defaultWikiBranch == "" {
return false, gitPath, nil
}
// Look for both files
filesInIndex, err := gitRepo.LsTree(ctx, defaultWikiBranch, unescaped, gitPath)
if err != nil {
if gitcmd.IsStderr(err, gitcmd.StderrNotValidObjectName) {
return false, gitPath, nil // branch doesn't exist
}
log.Error("Wiki LsTree failed, err: %v", err)
return false, gitPath, err
}
@@ -136,7 +136,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
}
}
isWikiExist, newWikiPath, err := prepareGitPath(ctx, gitRepo, repo.DefaultWikiBranch, newWikiName)
isWikiExist, newWikiPath, err := prepareGitPath(ctx, gitRepo, cloneOpts.Branch, newWikiName)
if err != nil {
return err
}
@@ -152,7 +152,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
isOldWikiExist := true
oldWikiPath := newWikiPath
if oldWikiName != newWikiName {
isOldWikiExist, oldWikiPath, err = prepareGitPath(ctx, gitRepo, repo.DefaultWikiBranch, oldWikiName)
isOldWikiExist, oldWikiPath, err = prepareGitPath(ctx, gitRepo, cloneOpts.Branch, oldWikiName)
if err != nil {
return err
}
+1 -12
View File
@@ -300,18 +300,7 @@ func TestPrepareWikiFileName(t *testing.T) {
}
func TestPrepareWikiFileName_FirstPage(t *testing.T) {
// Now create a temporaryDirectory
tmpDir := t.TempDir()
err := git.InitRepositoryLocal(t.Context(), tmpDir, true, git.Sha1ObjectFormat.Name(), "")
assert.NoError(t, err)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), tmpDir)
require.NoError(t, err)
defer gitRepo.Close()
existence, newWikiPath, err := prepareGitPath(t.Context(), gitRepo, "master", "Home")
existence, newWikiPath, err := prepareGitPath(t.Context(), nil, "", "Home")
assert.False(t, existence)
assert.NoError(t, err)
assert.Equal(t, "Home.md", newWikiPath)