mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-11-27 20:26:09 +01:00
6905540088
Now we can get object format name from git command line or from the database repository table. Assume the column is right, we don't need to read from git command line every time. This also fixed a possible bug that the object format is wrong when migrating a sha256 repository from external. <img width="658" alt="image" src="https://github.com/go-gitea/gitea/assets/81045/6e9a9dcf-13bf-4267-928b-6bf2c2560423"> (cherry picked from commit b79c30435f439af8243ee281310258cdf141e27b) Conflicts: routers/web/repo/blame.go services/agit/agit.go context
100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package utils
|
|
|
|
import (
|
|
gocontext "context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/gitrepo"
|
|
"code.gitea.io/gitea/modules/log"
|
|
)
|
|
|
|
// ResolveRefOrSha resolve ref to sha if exist
|
|
func ResolveRefOrSha(ctx *context.APIContext, ref string) string {
|
|
if len(ref) == 0 {
|
|
ctx.Error(http.StatusBadRequest, "ref not given", nil)
|
|
return ""
|
|
}
|
|
|
|
sha := ref
|
|
// Search branches and tags
|
|
for _, refType := range []string{"heads", "tags"} {
|
|
refSHA, lastMethodName, err := searchRefCommitByType(ctx, refType, ref)
|
|
if err != nil {
|
|
ctx.Error(http.StatusInternalServerError, lastMethodName, err)
|
|
return ""
|
|
}
|
|
if refSHA != "" {
|
|
sha = refSHA
|
|
break
|
|
}
|
|
}
|
|
|
|
sha = MustConvertToSHA1(ctx, ctx.Repo, sha)
|
|
|
|
if ctx.Repo.GitRepo != nil {
|
|
err := ctx.Repo.GitRepo.AddLastCommitCache(ctx.Repo.Repository.GetCommitsCountCacheKey(ref, ref != sha), ctx.Repo.Repository.FullName(), sha)
|
|
if err != nil {
|
|
log.Error("Unable to get commits count for %s in %s. Error: %v", sha, ctx.Repo.Repository.FullName(), err)
|
|
}
|
|
}
|
|
|
|
return sha
|
|
}
|
|
|
|
// GetGitRefs return git references based on filter
|
|
func GetGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, string, error) {
|
|
if ctx.Repo.GitRepo == nil {
|
|
return nil, "", fmt.Errorf("no open git repo found in context")
|
|
}
|
|
if len(filter) > 0 {
|
|
filter = "refs/" + filter
|
|
}
|
|
refs, err := ctx.Repo.GitRepo.GetRefsFiltered(filter)
|
|
return refs, "GetRefsFiltered", err
|
|
}
|
|
|
|
func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (string, string, error) {
|
|
refs, lastMethodName, err := GetGitRefs(ctx, refType+"/"+filter) // Search by type
|
|
if err != nil {
|
|
return "", lastMethodName, err
|
|
}
|
|
if len(refs) > 0 {
|
|
return refs[0].Object.String(), "", nil // Return found SHA
|
|
}
|
|
return "", "", nil
|
|
}
|
|
|
|
// ConvertToObjectID returns a full-length SHA1 from a potential ID string
|
|
func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) {
|
|
objectFormat := repo.GetObjectFormat()
|
|
if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
|
|
sha, err := git.NewIDFromString(commitID)
|
|
if err == nil {
|
|
return sha, nil
|
|
}
|
|
}
|
|
|
|
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo.Repository)
|
|
if err != nil {
|
|
return objectFormat.EmptyObjectID(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
|
|
}
|
|
defer closer.Close()
|
|
|
|
return gitRepo.ConvertToGitID(commitID)
|
|
}
|
|
|
|
// MustConvertToSHA1 returns a full-length SHA1 string from a potential ID string, or returns origin input if it can't convert to SHA1
|
|
func MustConvertToSHA1(ctx gocontext.Context, repo *context.Repository, commitID string) string {
|
|
sha, err := ConvertToObjectID(ctx, repo, commitID)
|
|
if err != nil {
|
|
return commitID
|
|
}
|
|
return sha.String()
|
|
}
|