Use the database object format name but not read from git repoisitory everytime and fix possible migration wrong objectformat when migrating a sha256 repository (#29294)

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
This commit is contained in:
Lunny Xiao 2024-02-24 14:55:19 +08:00 committed by Earl Warren
parent f097799953
commit 6905540088
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
17 changed files with 40 additions and 57 deletions

View file

@ -309,12 +309,6 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return return
} }
objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
if ref := ctx.FormTrim("ref"); len(ref) > 0 { if ref := ctx.FormTrim("ref"); len(ref) > 0 {
commit, err := ctx.Repo.GitRepo.GetCommit(ref) commit, err := ctx.Repo.GitRepo.GetCommit(ref)
if err != nil { if err != nil {
@ -333,6 +327,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
} }
refName := getRefName(ctx.Base, ctx.Repo, RepoRefAny) refName := getRefName(ctx.Base, ctx.Repo, RepoRefAny)
var err error
if ctx.Repo.GitRepo.IsBranchExist(refName) { if ctx.Repo.GitRepo.IsBranchExist(refName) {
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
@ -348,7 +343,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return return
} }
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) == objectFormat.FullLength() { } else if len(refName) == ctx.Repo.GetObjectFormat().FullLength() {
ctx.Repo.CommitID = refName ctx.Repo.CommitID = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
if err != nil { if err != nil {

View file

@ -83,6 +83,10 @@ func (r *Repository) CanCreateBranch() bool {
return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch() return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
} }
func (r *Repository) GetObjectFormat() git.ObjectFormat {
return git.ObjectFormatFromName(r.Repository.ObjectFormatName)
}
// RepoMustNotBeArchived checks if a repo is archived // RepoMustNotBeArchived checks if a repo is archived
func RepoMustNotBeArchived() func(ctx *Context) { func RepoMustNotBeArchived() func(ctx *Context) {
return func(ctx *Context) { return func(ctx *Context) {
@ -831,9 +835,8 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
} }
// For legacy and API support only full commit sha // For legacy and API support only full commit sha
parts := strings.Split(path, "/") parts := strings.Split(path, "/")
objectFormat, _ := repo.GitRepo.GetObjectFormat()
if len(parts) > 0 && len(parts[0]) == objectFormat.FullLength() { if len(parts) > 0 && len(parts[0]) == git.ObjectFormatFromName(repo.Repository.ObjectFormatName).FullLength() {
repo.TreePath = strings.Join(parts[1:], "/") repo.TreePath = strings.Join(parts[1:], "/")
return parts[0] return parts[0]
} }
@ -877,9 +880,8 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
return getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsTagExist) return getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsTagExist)
case RepoRefCommit: case RepoRefCommit:
parts := strings.Split(path, "/") parts := strings.Split(path, "/")
objectFormat, _ := repo.GitRepo.GetObjectFormat()
if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= objectFormat.FullLength() { if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= repo.GetObjectFormat().FullLength() {
repo.TreePath = strings.Join(parts[1:], "/") repo.TreePath = strings.Join(parts[1:], "/")
return parts[0] return parts[0]
} }
@ -938,12 +940,6 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
} }
} }
objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat()
if err != nil {
log.Error("Cannot determine objectFormat for repository: %w", err)
ctx.Repo.Repository.MarkAsBrokenEmpty()
}
// Get default branch. // Get default branch.
if len(ctx.Params("*")) == 0 { if len(ctx.Params("*")) == 0 {
refName = ctx.Repo.Repository.DefaultBranch refName = ctx.Repo.Repository.DefaultBranch
@ -1010,7 +1006,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel return cancel
} }
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if len(refName) >= 7 && len(refName) <= objectFormat.FullLength() { } else if len(refName) >= 7 && len(refName) <= ctx.Repo.GetObjectFormat().FullLength() {
ctx.Repo.IsViewCommit = true ctx.Repo.IsViewCommit = true
ctx.Repo.CommitID = refName ctx.Repo.CommitID = refName
@ -1020,7 +1016,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel return cancel
} }
// If short commit ID add canonical link header // If short commit ID add canonical link header
if len(refName) < objectFormat.FullLength() { if len(refName) < ctx.Repo.GetObjectFormat().FullLength() {
ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"",
util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)))) util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))))
} }

View file

@ -72,7 +72,7 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str
// ConvertToObjectID returns a full-length SHA1 from a potential ID string // ConvertToObjectID returns a full-length SHA1 from a potential ID string
func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) { func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) {
objectFormat, _ := repo.GitRepo.GetObjectFormat() objectFormat := repo.GetObjectFormat()
if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) { if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
sha, err := git.NewIDFromString(commitID) sha, err := git.NewIDFromString(commitID)
if err == nil { if err == nil {

View file

@ -145,7 +145,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
gitRepo := ctx.Repo.GitRepo gitRepo := ctx.Repo.GitRepo
objectFormat, _ := gitRepo.GetObjectFormat() objectFormat := ctx.Repo.GetObjectFormat()
if branchName == repo.DefaultBranch && newCommitID == objectFormat.EmptyObjectID().String() { if branchName == repo.DefaultBranch && newCommitID == objectFormat.EmptyObjectID().String() {
log.Warn("Forbidden: Branch: %s is the default branch in %-v and cannot be deleted", branchName, repo) log.Warn("Forbidden: Branch: %s is the default branch in %-v and cannot be deleted", branchName, repo)

View file

@ -112,10 +112,7 @@ type blameResult struct {
func performBlame(ctx *context.Context, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) { func performBlame(ctx *context.Context, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) {
repoPath := ctx.Repo.Repository.RepoPath() repoPath := ctx.Repo.Repository.RepoPath()
objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat() objectFormat := ctx.Repo.GetObjectFormat()
if err != nil {
return nil, err
}
blameReader, err := git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, bypassBlameIgnore) blameReader, err := git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, bypassBlameIgnore)
if err != nil { if err != nil {

View file

@ -312,14 +312,14 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch) baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch)
baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch) baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch)
baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch) baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch)
objectFormat, _ := ctx.Repo.GitRepo.GetObjectFormat()
if !baseIsCommit && !baseIsBranch && !baseIsTag { if !baseIsCommit && !baseIsBranch && !baseIsTag {
// Check if baseBranch is short sha commit hash // Check if baseBranch is short sha commit hash
if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(ci.BaseBranch); baseCommit != nil { if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(ci.BaseBranch); baseCommit != nil {
ci.BaseBranch = baseCommit.ID.String() ci.BaseBranch = baseCommit.ID.String()
ctx.Data["BaseBranch"] = ci.BaseBranch ctx.Data["BaseBranch"] = ci.BaseBranch
baseIsCommit = true baseIsCommit = true
} else if ci.BaseBranch == objectFormat.EmptyObjectID().String() { } else if ci.BaseBranch == ctx.Repo.GetObjectFormat().EmptyObjectID().String() {
if isSameRepo { if isSameRepo {
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch)) ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch))
} else { } else {

View file

@ -388,7 +388,7 @@ func LFSFileFind(ctx *context.Context) {
sha := ctx.FormString("sha") sha := ctx.FormString("sha")
ctx.Data["Title"] = oid ctx.Data["Title"] = oid
ctx.Data["PageIsSettingsLFS"] = true ctx.Data["PageIsSettingsLFS"] = true
objectFormat, _ := ctx.Repo.GitRepo.GetObjectFormat() objectFormat := ctx.Repo.GetObjectFormat()
var objectID git.ObjectID var objectID git.ObjectID
if len(sha) == 0 { if len(sha) == 0 {
pointer := lfs.Pointer{Oid: oid, Size: size} pointer := lfs.Pointer{Oid: oid, Size: size}

View file

@ -28,10 +28,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
title, hasTitle := opts.GitPushOptions["title"] title, hasTitle := opts.GitPushOptions["title"]
description, hasDesc := opts.GitPushOptions["description"] description, hasDesc := opts.GitPushOptions["description"]
objectFormat, err := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
if err != nil {
return nil, fmt.Errorf("couldn't get object format of the repository: %w", err)
}
pusher, err := user_model.GetUserByID(ctx, opts.UserID) pusher, err := user_model.GetUserByID(ctx, opts.UserID)
if err != nil { if err != nil {

View file

@ -140,10 +140,20 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
if err != nil { if err != nil {
return err return err
} }
g.gitRepo, err = gitrepo.OpenRepository(g.ctx, r) g.gitRepo, err = gitrepo.OpenRepository(g.ctx, g.repo)
if err != nil {
return err return err
} }
// detect object format from git repository and update to database
objectFormat, err := g.gitRepo.GetObjectFormat()
if err != nil {
return err
}
g.repo.ObjectFormatName = objectFormat.Name()
return repo_model.UpdateRepositoryCols(g.ctx, g.repo, "object_format_name")
}
// Close closes this uploader // Close closes this uploader
func (g *GiteaLocalUploader) Close() { func (g *GiteaLocalUploader) Close() {
if g.gitRepo != nil { if g.gitRepo != nil {
@ -901,7 +911,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {
comment.UpdatedAt = comment.CreatedAt comment.UpdatedAt = comment.CreatedAt
} }
objectFormat, _ := g.gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(g.repo.ObjectFormatName)
if !objectFormat.IsValid(comment.CommitID) { if !objectFormat.IsValid(comment.CommitID) {
log.Warn("Invalid comment CommitID[%s] on comment[%d] in PR #%d of %s/%s replaced with %s", comment.CommitID, pr.Index, g.repoOwner, g.repoName, headCommitID) log.Warn("Invalid comment CommitID[%s] on comment[%d] in PR #%d of %s/%s replaced with %s", comment.CommitID, pr.Index, g.repoOwner, g.repoName, headCommitID)
comment.CommitID = headCommitID comment.CommitID = headCommitID

View file

@ -222,10 +222,7 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
} }
defer gitRepo.Close() defer gitRepo.Close()
objectFormat, err := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
if err != nil {
return nil, fmt.Errorf("%-v GetObjectFormat: %w", pr.BaseRepo, err)
}
// Get the commit from BaseBranch where the pull request got merged // Get the commit from BaseBranch where the pull request got merged
mergeCommit, _, err := git.NewCommand(ctx, "rev-list", "--ancestry-path", "--merges", "--reverse"). mergeCommit, _, err := git.NewCommand(ctx, "rev-list", "--ancestry-path", "--merges", "--reverse").

View file

@ -503,7 +503,7 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use
return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: repo_model.MergeStyleManuallyMerged} return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: repo_model.MergeStyleManuallyMerged}
} }
objectFormat, _ := baseGitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
if len(commitID) != objectFormat.FullLength() { if len(commitID) != objectFormat.FullLength() {
return fmt.Errorf("Wrong commit ID") return fmt.Errorf("Wrong commit ID")
} }

View file

@ -88,7 +88,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel
created = true created = true
rel.LowerTagName = strings.ToLower(rel.TagName) rel.LowerTagName = strings.ToLower(rel.TagName)
objectFormat, _ := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(rel.Repo.ObjectFormatName)
commits := repository.NewPushCommits() commits := repository.NewPushCommits()
commits.HeadCommit = repository.CommitToPushCommit(commit) commits.HeadCommit = repository.CommitToPushCommit(commit)
commits.CompareURL = rel.Repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), commit.ID.String()) commits.CompareURL = rel.Repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), commit.ID.String())

View file

@ -369,11 +369,6 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R
return fmt.Errorf("GetBranch: %v", err) return fmt.Errorf("GetBranch: %v", err)
} }
objectFormat, err := gitRepo.GetObjectFormat()
if err != nil {
return err
}
if rawBranch.IsDeleted { if rawBranch.IsDeleted {
return nil return nil
} }
@ -395,6 +390,8 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R
return err return err
} }
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
// Don't return error below this // Don't return error below this
if err := PushUpdate( if err := PushUpdate(
&repo_module.PushUpdateOptions{ &repo_module.PushUpdateOptions{

View file

@ -30,10 +30,8 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
} }
defer closer.Close() defer closer.Close()
objectFormat, err := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
if err != nil {
return fmt.Errorf("GetObjectFormat[%s]: %w", repoPath, err)
}
commit, err := gitRepo.GetCommit(sha) commit, err := gitRepo.GetCommit(sha)
if err != nil { if err != nil {
gitRepo.Close() gitRepo.Close()

View file

@ -37,7 +37,7 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
} }
apiURL := repo.APIURL() apiURL := repo.APIURL()
apiURLLen := len(apiURL) apiURLLen := len(apiURL)
objectFormat, _ := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
hashLen := objectFormat.FullLength() hashLen := objectFormat.FullLength()
const gitBlobsPath = "/git/blobs/" const gitBlobsPath = "/git/blobs/"

View file

@ -79,7 +79,7 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R
store := lfs.NewContentStore() store := lfs.NewContentStore()
errStop := errors.New("STOPERR") errStop := errors.New("STOPERR")
objectFormat, _ := gitRepo.GetObjectFormat() objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
err = git_model.IterateLFSMetaObjectsForRepo(ctx, repo.ID, func(ctx context.Context, metaObject *git_model.LFSMetaObject, count int64) error { err = git_model.IterateLFSMetaObjectsForRepo(ctx, repo.ID, func(ctx context.Context, metaObject *git_model.LFSMetaObject, count int64) error {
if opts.NumberToCheckPerRepo > 0 && total > opts.NumberToCheckPerRepo { if opts.NumberToCheckPerRepo > 0 && total > opts.NumberToCheckPerRepo {

View file

@ -93,11 +93,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
} }
defer gitRepo.Close() defer gitRepo.Close()
objectFormat, err := gitRepo.GetObjectFormat()
if err != nil {
return fmt.Errorf("unknown repository ObjectFormat [%s]: %w", repo.FullName(), err)
}
if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
return fmt.Errorf("Failed to update size for repository: %v", err) return fmt.Errorf("Failed to update size for repository: %v", err)
} }
@ -105,6 +100,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
addTags := make([]string, 0, len(optsList)) addTags := make([]string, 0, len(optsList))
delTags := make([]string, 0, len(optsList)) delTags := make([]string, 0, len(optsList))
var pusher *user_model.User var pusher *user_model.User
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
for _, opts := range optsList { for _, opts := range optsList {
log.Trace("pushUpdates: %-v %s %s %s", repo, opts.OldCommitID, opts.NewCommitID, opts.RefFullName) log.Trace("pushUpdates: %-v %s %s %s", repo, opts.OldCommitID, opts.NewCommitID, opts.RefFullName)