mirror of https://github.com/go-gitea/gitea.git
update git vendor to fix wrong release commit id and add migrations (#6224)
* update git vendor to fix wrong release commit id and add migrations * fix count * fix migration release * fix tests
This commit is contained in:
parent
2315019fef
commit
4334fe754e
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:0a001725d6e1b35faccf15cbc4f782b67a0d77f4bbf56e51a4b244f92e7c60ca"
|
digest = "1:0f0ada42a7b1bd64794bf8fea917c2cd626d6b0539173e3704cd764b93eb5312"
|
||||||
name = "code.gitea.io/git"
|
name = "code.gitea.io/git"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
revision = "0aea7f12d36ed49bcac560b61301cff88e478e5c"
|
revision = "8983773ac6fef49203e7ee8cdbfde3e118bc3421"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
|
@ -217,6 +217,8 @@ var migrations = []Migration{
|
||||||
NewMigration("add is locked to issues", addIsLockedToIssues),
|
NewMigration("add is locked to issues", addIsLockedToIssues),
|
||||||
// v81 -> v82
|
// v81 -> v82
|
||||||
NewMigration("update U2F counter type", changeU2FCounterType),
|
NewMigration("update U2F counter type", changeU2FCounterType),
|
||||||
|
// v82 -> v83
|
||||||
|
NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// Migrate database to current version
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/git"
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
|
||||||
|
type Release struct {
|
||||||
|
ID int64
|
||||||
|
RepoID int64
|
||||||
|
Sha1 string
|
||||||
|
TagName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update release sha1
|
||||||
|
const batchSize = 100
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
count int
|
||||||
|
gitRepoCache = make(map[int64]*git.Repository)
|
||||||
|
repoCache = make(map[int64]*models.Repository)
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for start := 0; ; start += batchSize {
|
||||||
|
releases := make([]*Release, 0, batchSize)
|
||||||
|
if err = sess.Limit(batchSize, start).Asc("id").Where("is_tag=?", false).Find(&releases); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(releases) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, release := range releases {
|
||||||
|
gitRepo, ok := gitRepoCache[release.RepoID]
|
||||||
|
if !ok {
|
||||||
|
repo, ok := repoCache[release.RepoID]
|
||||||
|
if !ok {
|
||||||
|
repo, err = models.GetRepositoryByID(release.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
repoCache[release.RepoID] = repo
|
||||||
|
}
|
||||||
|
|
||||||
|
gitRepo, err = git.OpenRepository(repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gitRepoCache[release.RepoID] = gitRepo
|
||||||
|
}
|
||||||
|
|
||||||
|
release.Sha1, err = gitRepo.GetTagCommitID(release.TagName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.ID(release.ID).Cols("sha1").Update(release); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if count >= 1000 {
|
||||||
|
if err = sess.Commit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
|
@ -110,10 +110,6 @@ func (repo *Repository) CheckBranchName(name string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := gitRepo.GetTag(name); err == nil {
|
|
||||||
return ErrTagAlreadyExists{name}
|
|
||||||
}
|
|
||||||
|
|
||||||
branches, err := repo.GetBranches()
|
branches, err := repo.GetBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -127,6 +123,11 @@ func (repo *Repository) CheckBranchName(name string) error {
|
||||||
return ErrBranchNameConflict{branch.Name}
|
return ErrBranchNameConflict{branch.Name}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := gitRepo.GetTag(name); err == nil {
|
||||||
|
return ErrTagAlreadyExists{name}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
||||||
}
|
}
|
||||||
entries.CustomSort(base.NaturalSortLess)
|
entries.CustomSort(base.NaturalSortLess)
|
||||||
|
|
||||||
ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath)
|
ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetCommitsInfo", err)
|
ctx.ServerError("GetCommitsInfo", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
// LastCommitCache cache
|
||||||
|
type LastCommitCache interface {
|
||||||
|
Get(repoPath, ref, entryPath string) (*Commit, error)
|
||||||
|
Put(repoPath, ref, entryPath string, commit *Commit) error
|
||||||
|
}
|
|
@ -72,13 +72,20 @@ func (state *getCommitsInfoState) getTargetedEntryPath() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// repeatedly perform targeted searches for unpopulated entries
|
// repeatedly perform targeted searches for unpopulated entries
|
||||||
func targetedSearch(state *getCommitsInfoState, done chan error) {
|
func targetedSearch(state *getCommitsInfoState, done chan error, cache LastCommitCache) {
|
||||||
for {
|
for {
|
||||||
entryPath := state.getTargetedEntryPath()
|
entryPath := state.getTargetedEntryPath()
|
||||||
if len(entryPath) == 0 {
|
if len(entryPath) == 0 {
|
||||||
done <- nil
|
done <- nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if cache != nil {
|
||||||
|
commit, err := cache.Get(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath)
|
||||||
|
if err == nil && commit != nil {
|
||||||
|
state.update(entryPath, commit)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath)
|
command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath)
|
||||||
output, err := command.RunInDir(state.headCommit.repo.Path)
|
output, err := command.RunInDir(state.headCommit.repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,6 +103,9 @@ func targetedSearch(state *getCommitsInfoState, done chan error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state.update(entryPath, commit)
|
state.update(entryPath, commit)
|
||||||
|
if cache != nil {
|
||||||
|
cache.Put(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath, commit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +128,9 @@ func initGetCommitInfoState(entries Entries, headCommit *Commit, treePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommitsInfo gets information of all commits that are corresponding to these entries
|
// GetCommitsInfo gets information of all commits that are corresponding to these entries
|
||||||
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string) ([][]interface{}, error) {
|
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, error) {
|
||||||
state := initGetCommitInfoState(tes, commit, treePath)
|
state := initGetCommitInfoState(tes, commit, treePath)
|
||||||
if err := getCommitsInfo(state); err != nil {
|
if err := getCommitsInfo(state, cache); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(state.commits) < len(state.entryPaths) {
|
if len(state.commits) < len(state.entryPaths) {
|
||||||
|
@ -188,7 +198,7 @@ func (state *getCommitsInfoState) update(entryPath string, commit *Commit) bool
|
||||||
|
|
||||||
const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
|
const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
|
||||||
|
|
||||||
func getCommitsInfo(state *getCommitsInfoState) error {
|
func getCommitsInfo(state *getCommitsInfoState, cache LastCommitCache) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
@ -215,7 +225,7 @@ func getCommitsInfo(state *getCommitsInfoState) error {
|
||||||
numThreads := runtime.NumCPU()
|
numThreads := runtime.NumCPU()
|
||||||
done := make(chan error, numThreads)
|
done := make(chan error, numThreads)
|
||||||
for i := 0; i < numThreads; i++ {
|
for i := 0; i < numThreads; i++ {
|
||||||
go targetedSearch(state, done)
|
go targetedSearch(state, done, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner := bufio.NewScanner(readCloser)
|
scanner := bufio.NewScanner(readCloser)
|
||||||
|
|
|
@ -32,7 +32,14 @@ func (repo *Repository) GetBranchCommitID(name string) (string, error) {
|
||||||
|
|
||||||
// GetTagCommitID returns last commit ID string of given tag.
|
// GetTagCommitID returns last commit ID string of given tag.
|
||||||
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
||||||
return repo.GetRefCommitID(TagPrefix + name)
|
stdout, err := NewCommand("rev-list", "-n", "1", name).RunInDir(repo.Path)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "unknown revision or path") {
|
||||||
|
return "", ErrNotExist{name, ""}
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(stdout), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseCommitData parses commit information from the (uncompressed) raw
|
// parseCommitData parses commit information from the (uncompressed) raw
|
||||||
|
|
|
@ -76,12 +76,12 @@ func (repo *Repository) getTag(id SHA1) (*Tag, error) {
|
||||||
|
|
||||||
// GetTag returns a Git tag by given name.
|
// GetTag returns a Git tag by given name.
|
||||||
func (repo *Repository) GetTag(name string) (*Tag, error) {
|
func (repo *Repository) GetTag(name string) (*Tag, error) {
|
||||||
stdout, err := NewCommand("show-ref", "--tags", name).RunInDir(repo.Path)
|
idStr, err := repo.GetTagCommitID(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := NewIDFromString(strings.Split(stdout, " ")[0])
|
id, err := NewIDFromString(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue