mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	* make releases faster than before and resolved #490 * fix comment
This commit is contained in:
		| @@ -22,12 +22,12 @@ import ( | |||||||
|  |  | ||||||
| // Release represents a release of repository. | // Release represents a release of repository. | ||||||
| type Release struct { | type Release struct { | ||||||
| 	ID               int64 `xorm:"pk autoincr"` | 	ID               int64       `xorm:"pk autoincr"` | ||||||
| 	RepoID           int64 | 	RepoID           int64       `xorm:"index unique(n)"` | ||||||
| 	Repo             *Repository `xorm:"-"` | 	Repo             *Repository `xorm:"-"` | ||||||
| 	PublisherID      int64 | 	PublisherID      int64 | ||||||
| 	Publisher        *User `xorm:"-"` | 	Publisher        *User  `xorm:"-"` | ||||||
| 	TagName          string | 	TagName          string `xorm:"index unique(n)"` | ||||||
| 	LowerTagName     string | 	LowerTagName     string | ||||||
| 	Target           string | 	Target           string | ||||||
| 	Title            string | 	Title            string | ||||||
| @@ -213,6 +213,15 @@ func GetReleasesByRepoID(repoID int64, page, pageSize int) (rels []*Release, err | |||||||
| 	return rels, err | 	return rels, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetReleasesByRepoIDAndNames returns a list of releases of repository accroding repoID and tagNames. | ||||||
|  | func GetReleasesByRepoIDAndNames(repoID int64, tagNames []string) (rels []*Release, err error) { | ||||||
|  | 	err = x. | ||||||
|  | 		Desc("created_unix"). | ||||||
|  | 		In("tag_name", tagNames). | ||||||
|  | 		Find(&rels, Release{RepoID: repoID}) | ||||||
|  | 	return rels, err | ||||||
|  | } | ||||||
|  |  | ||||||
| type releaseSorter struct { | type releaseSorter struct { | ||||||
| 	rels []*Release | 	rels []*Release | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,8 +5,10 @@ | |||||||
| package repo | package repo | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/git" | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/auth" | 	"code.gitea.io/gitea/modules/auth" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| @@ -54,34 +56,55 @@ func Releases(ctx *context.Context) { | |||||||
| 	ctx.Data["Title"] = ctx.Tr("repo.release.releases") | 	ctx.Data["Title"] = ctx.Tr("repo.release.releases") | ||||||
| 	ctx.Data["PageIsReleaseList"] = true | 	ctx.Data["PageIsReleaseList"] = true | ||||||
|  |  | ||||||
| 	rawTags, err := ctx.Repo.GitRepo.GetTags() | 	page := ctx.QueryInt("page") | ||||||
|  | 	if page <= 1 { | ||||||
|  | 		page = 1 | ||||||
|  | 	} | ||||||
|  | 	limit := ctx.QueryInt("limit") | ||||||
|  | 	if limit <= 0 { | ||||||
|  | 		limit = 10 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rawTags, err := ctx.Repo.GitRepo.GetTagInfos(git.TagOption{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetTags", err) | 		ctx.Handle(500, "GetTags", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	page := ctx.QueryInt("page") | 	if len(rawTags) <= (page-1)*limit { | ||||||
| 	if page <= 1 { | 		ctx.Handle(500, "Releases", errors.New("no more pages")) | ||||||
| 		page = 1 | 		return | ||||||
| 	} | 	} | ||||||
| 	releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, page, 10) |  | ||||||
|  | 	var tags []*git.Tag | ||||||
|  | 	if page*limit > len(rawTags) { | ||||||
|  | 		tags = rawTags[(page-1)*limit:] | ||||||
|  | 	} else { | ||||||
|  | 		tags = rawTags[(page-1)*limit : page*limit] | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var tagNames []string | ||||||
|  | 	for _, t := range tags { | ||||||
|  | 		tagNames = append(tagNames, t.Name) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	releases, err := models.GetReleasesByRepoIDAndNames(ctx.Repo.Repository.ID, tagNames) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetReleasesByRepoID", err) | 		ctx.Handle(500, "GetReleasesByRepoIDAndNames", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Temproray cache commits count of used branches to speed up. | 	// Temproray cache commits count of used branches to speed up. | ||||||
| 	countCache := make(map[string]int64) | 	countCache := make(map[string]int64) | ||||||
|  |  | ||||||
| 	var cacheUsers = make(map[int64]*models.User) | 	var cacheUsers = make(map[int64]*models.User) | ||||||
| 	var ok bool | 	var ok bool | ||||||
| 	tags := make([]*models.Release, len(rawTags)) | 	releaseTags := make([]*models.Release, len(tags)) | ||||||
| 	for i, rawTag := range rawTags { | 	for i, rawTag := range tags { | ||||||
| 		for j, r := range releases { | 		for _, r := range releases { | ||||||
| 			if r == nil || (r.IsDraft && !ctx.Repo.IsOwner()) { | 			if r.IsDraft && !ctx.Repo.IsOwner() { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			if r.TagName == rawTag { | 			if r.TagName == rawTag.Name { | ||||||
| 				if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok { | 				if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok { | ||||||
| 					r.Publisher, err = models.GetUserByID(r.PublisherID) | 					r.Publisher, err = models.GetUserByID(r.PublisherID) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| @@ -101,64 +124,31 @@ func Releases(ctx *context.Context) { | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()) | 				r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()) | ||||||
| 				tags[i] = r | 				releaseTags[i] = r | ||||||
| 				releases[j] = nil // Mark as used. |  | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if tags[i] == nil { | 		if releaseTags[i] == nil { | ||||||
| 			commit, err := ctx.Repo.GitRepo.GetTagCommit(rawTag) | 			releaseTags[i] = &models.Release{ | ||||||
| 			if err != nil { | 				Title:   rawTag.Name, | ||||||
| 				ctx.Handle(500, "GetTagCommit", err) | 				TagName: rawTag.Name, | ||||||
| 				return | 				Sha1:    rawTag.Object.String(), | ||||||
|  | 				Note:    rawTag.Message, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			tags[i] = &models.Release{ | 			releaseTags[i].NumCommits, err = git.CommitsCount(ctx.Repo.GitRepo.Path, rawTag.Object.String()) | ||||||
| 				Title:   rawTag, |  | ||||||
| 				TagName: rawTag, |  | ||||||
| 				Sha1:    commit.ID.String(), |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			tags[i].NumCommits, err = commit.CommitsCount() |  | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(500, "CommitsCount", err) | 				ctx.Handle(500, "CommitsCount", err) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 			tags[i].NumCommitsBehind = ctx.Repo.CommitsCount - tags[i].NumCommits | 			releaseTags[i].NumCommitsBehind = ctx.Repo.CommitsCount - releaseTags[i].NumCommits | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, r := range releases { | 	pager := paginater.New(ctx.Repo.Repository.NumTags, limit, page, 5) | ||||||
| 		if r == nil { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok { |  | ||||||
| 			r.Publisher, err = models.GetUserByID(r.PublisherID) |  | ||||||
| 			if err != nil { |  | ||||||
| 				if models.IsErrUserNotExist(err) { |  | ||||||
| 					r.Publisher = models.NewGhostUser() |  | ||||||
| 				} else { |  | ||||||
| 					ctx.Handle(500, "GetUserByID", err) |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			cacheUsers[r.PublisherID] = r.Publisher |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil { |  | ||||||
| 			ctx.Handle(500, "calReleaseNumCommitsBehind", err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		r.Note = markdown.RenderString(r.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()) |  | ||||||
| 		tags = append(tags, r) |  | ||||||
| 	} |  | ||||||
| 	pager := paginater.New(ctx.Repo.Repository.NumTags, 10, page, 5) |  | ||||||
| 	ctx.Data["Page"] = pager | 	ctx.Data["Page"] = pager | ||||||
| 	models.SortReleases(tags) | 	ctx.Data["Releases"] = releaseTags | ||||||
| 	ctx.Data["Releases"] = tags |  | ||||||
| 	ctx.HTML(200, tplReleases) | 	ctx.HTML(200, tplReleases) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								vendor/code.gitea.io/git/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/code.gitea.io/git/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| Alexey Makhov <amakhov@avito.ru> (@makhov) | Alexey Makhov <amakhov@avito.ru> (@makhov) | ||||||
| Andrey Nering <andrey.nering@gmail.com> (@andreynering) | Andrey Nering <andrey.nering@gmail.com> (@andreynering) | ||||||
|  | Bo-Yi Wu <appleboy.tw@gmail.com> (@appleboy) | ||||||
| Kees de Vries <bouwko@gmail.com> (@Bwko) | Kees de Vries <bouwko@gmail.com> (@Bwko) | ||||||
| Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft) | Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft) | ||||||
| LefsFlare <nobody@nobody.tld> (@LefsFlarey) | LefsFlare <nobody@nobody.tld> (@LefsFlarey) | ||||||
|   | |||||||
							
								
								
									
										82
									
								
								vendor/code.gitea.io/git/repo_tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								vendor/code.gitea.io/git/repo_tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,6 +6,7 @@ package git | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/mcuadros/go-version" | 	"github.com/mcuadros/go-version" | ||||||
| ) | ) | ||||||
| @@ -94,6 +95,87 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { | |||||||
| 	return tag, nil | 	return tag, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TagOption describes tag options | ||||||
|  | type TagOption struct { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // parseTag parse the line | ||||||
|  | // 2016-10-14 20:54:25 +0200  (tag: translation/20161014.01) d3b76dcf2 Dirk Baeumer dirkb@microsoft.com Merge in translations | ||||||
|  | func parseTag(line string, opt TagOption) (*Tag, error) { | ||||||
|  | 	line = strings.TrimSpace(line) | ||||||
|  | 	if len(line) < 40 { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var ( | ||||||
|  | 		err error | ||||||
|  | 		tag Tag | ||||||
|  | 		sig Signature | ||||||
|  | 	) | ||||||
|  | 	sig.When, err = time.Parse("2006-01-02 15:04:05 -0700", line[0:25]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	left := strings.TrimSpace(line[25:]) | ||||||
|  | 	start := strings.Index(left, "(tag: ") | ||||||
|  | 	if start < 0 { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	end := strings.IndexByte(left[start+1:], ')') | ||||||
|  | 	if end < 0 { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	end = end + start + 1 | ||||||
|  | 	part := strings.IndexByte(left[start+6:end], ',') | ||||||
|  | 	if part > 0 { | ||||||
|  | 		tag.Name = strings.TrimSpace(left[start+6 : start+6+part]) | ||||||
|  | 	} else { | ||||||
|  | 		tag.Name = strings.TrimSpace(left[start+6 : end]) | ||||||
|  | 	} | ||||||
|  | 	next := strings.IndexByte(left[end+2:], ' ') | ||||||
|  | 	if next < 0 { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	tag.Object = MustIDFromString(strings.TrimSpace(left[end+2 : end+2+next])) | ||||||
|  | 	next = end + 2 + next | ||||||
|  |  | ||||||
|  | 	emailStart := strings.IndexByte(left[next:], '<') | ||||||
|  | 	sig.Name = strings.TrimSpace(left[next:][:emailStart-1]) | ||||||
|  | 	emailEnd := strings.IndexByte(left[next:], '>') | ||||||
|  | 	sig.Email = strings.TrimSpace(left[next:][emailStart+1 : emailEnd]) | ||||||
|  | 	tag.Tagger = &sig | ||||||
|  | 	tag.Message = strings.TrimSpace(left[next+emailEnd+1:]) | ||||||
|  | 	return &tag, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTagInfos returns all tag infos of the repository. | ||||||
|  | func (repo *Repository) GetTagInfos(opt TagOption) ([]*Tag, error) { | ||||||
|  | 	cmd := NewCommand("log", "--tags", "--simplify-by-decoration", `--pretty=format:"%ci %d %H %cn<%ce> %s"`) | ||||||
|  | 	stdout, err := cmd.RunInDir(repo.Path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tagSlices := strings.Split(stdout, "\n") | ||||||
|  | 	var tags []*Tag | ||||||
|  | 	for _, line := range tagSlices { | ||||||
|  | 		line := strings.Trim(line, `"`) | ||||||
|  | 		tag, err := parseTag(line, opt) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		if tag != nil { | ||||||
|  | 			tag.repo = repo | ||||||
|  | 			tags = append(tags, tag) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sortTagsByTime(tags) | ||||||
|  |  | ||||||
|  | 	return tags, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // GetTags returns all tags of the repository. | // GetTags returns all tags of the repository. | ||||||
| func (repo *Repository) GetTags() ([]string, error) { | func (repo *Repository) GetTags() ([]string, error) { | ||||||
| 	cmd := NewCommand("tag", "-l") | 	cmd := NewCommand("tag", "-l") | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								vendor/code.gitea.io/git/tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/code.gitea.io/git/tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,7 +4,10 @@ | |||||||
|  |  | ||||||
| package git | package git | ||||||
|  |  | ||||||
| import "bytes" | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"sort" | ||||||
|  | ) | ||||||
|  |  | ||||||
| // Tag represents a Git tag. | // Tag represents a Git tag. | ||||||
| type Tag struct { | type Tag struct { | ||||||
| @@ -64,3 +67,23 @@ l: | |||||||
| 	} | 	} | ||||||
| 	return tag, nil | 	return tag, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type tagSorter []*Tag | ||||||
|  |  | ||||||
|  | func (ts tagSorter) Len() int { | ||||||
|  | 	return len([]*Tag(ts)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ts tagSorter) Less(i, j int) bool { | ||||||
|  | 	return []*Tag(ts)[i].Tagger.When.After([]*Tag(ts)[j].Tagger.When) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ts tagSorter) Swap(i, j int) { | ||||||
|  | 	[]*Tag(ts)[i], []*Tag(ts)[j] = []*Tag(ts)[j], []*Tag(ts)[i] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // sortTagsByTime | ||||||
|  | func sortTagsByTime(tags []*Tag) { | ||||||
|  | 	sorter := tagSorter(tags) | ||||||
|  | 	sort.Sort(sorter) | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							| @@ -3,10 +3,10 @@ | |||||||
| 	"ignore": "test", | 	"ignore": "test", | ||||||
| 	"package": [ | 	"package": [ | ||||||
| 		{ | 		{ | ||||||
| 			"checksumSHA1": "mIaKLz6373W+jDLjgE/Yzt/exeo=", | 			"checksumSHA1": "zK/6EifSPy/O5Vbx7CMWfnLHExI=", | ||||||
| 			"path": "code.gitea.io/git", | 			"path": "code.gitea.io/git", | ||||||
| 			"revision": "3d0fa331865619d2f3a7a0fcf23670a389310954", | 			"revision": "a3ee12b97af51eec1b7aa0525f6a39c97520817d", | ||||||
| 			"revisionTime": "2016-12-28T14:57:51Z" | 			"revisionTime": "2017-01-05T02:48:44Z" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"checksumSHA1": "BKj0haFTDebzdC2nACpoGzp3s8A=", | 			"checksumSHA1": "BKj0haFTDebzdC2nACpoGzp3s8A=", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user