From 45ff2c021c6d46694fc861f216527e31874a1a95 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Wed, 10 May 2023 17:26:42 +0000 Subject: [PATCH 01/13] Add status indicator on main home screen for each repo It will show the latest commit status state on the latest commit on the default branch of the each repository in the dashboard repo list Signed-off-by: Yarden Shoham --- modules/structs/repo.go | 57 +++++++++++---------- routers/web/repo/repo.go | 54 +++++++++++++++---- templates/swagger/v1_json.tmpl | 3 ++ web_src/js/components/DashboardRepoList.vue | 7 +++ web_src/js/svg.js | 6 +++ 5 files changed, 89 insertions(+), 38 deletions(-) diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 01239188c2cd5..884b197236d52 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -48,34 +48,35 @@ type ExternalWiki struct { // Repository represents a repository type Repository struct { - ID int64 `json:"id"` - Owner *User `json:"owner"` - Name string `json:"name"` - FullName string `json:"full_name"` - Description string `json:"description"` - Empty bool `json:"empty"` - Private bool `json:"private"` - Fork bool `json:"fork"` - Template bool `json:"template"` - Parent *Repository `json:"parent"` - Mirror bool `json:"mirror"` - Size int `json:"size"` - Language string `json:"language"` - LanguagesURL string `json:"languages_url"` - HTMLURL string `json:"html_url"` - Link string `json:"link"` - SSHURL string `json:"ssh_url"` - CloneURL string `json:"clone_url"` - OriginalURL string `json:"original_url"` - Website string `json:"website"` - Stars int `json:"stars_count"` - Forks int `json:"forks_count"` - Watchers int `json:"watchers_count"` - OpenIssues int `json:"open_issues_count"` - OpenPulls int `json:"open_pr_counter"` - Releases int `json:"release_counter"` - DefaultBranch string `json:"default_branch"` - Archived bool `json:"archived"` + ID int64 `json:"id"` + Owner *User `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent *Repository `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + Language string `json:"language"` + LanguagesURL string `json:"languages_url"` + HTMLURL string `json:"html_url"` + Link string `json:"link"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_url"` + Website string `json:"website"` + Stars int `json:"stars_count"` + Forks int `json:"forks_count"` + Watchers int `json:"watchers_count"` + OpenIssues int `json:"open_issues_count"` + OpenPulls int `json:"open_pr_counter"` + Releases int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + CommitStatusState CommitStatusState `json:"commit_status_state"` + Archived bool `json:"archived"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 2f87e190228a5..fea25f6e6e3fa 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -579,16 +580,17 @@ func SearchRepo(ctx *context.Context) { results := make([]*api.Repository, len(repos)) for i, repo := range repos { results[i] = &api.Repository{ - ID: repo.ID, - FullName: repo.FullName(), - Fork: repo.IsFork, - Private: repo.IsPrivate, - Template: repo.IsTemplate, - Mirror: repo.IsMirror, - Stars: repo.NumStars, - HTMLURL: repo.HTMLURL(), - Link: repo.Link(), - Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + ID: repo.ID, + FullName: repo.FullName(), + Fork: repo.IsFork, + Private: repo.IsPrivate, + Template: repo.IsTemplate, + Mirror: repo.IsMirror, + Stars: repo.NumStars, + HTMLURL: repo.HTMLURL(), + Link: repo.Link(), + Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + CommitStatusState: getLatestCommitStatusState(ctx, repo), } } @@ -597,3 +599,35 @@ func SearchRepo(ctx *context.Context) { Data: results, }) } + +// getLatestCommitStatusState returns the commit status state returns the latest commit status state of the latest +// commit on the default branch of the given repository +func getLatestCommitStatusState(ctx *context.Context, repo *repo_model.Repository) api.CommitStatusState { + branches, branchCount, _ := repo_service.GetBranches(ctx, repo, 0, 0) + if branchCount == 0 { + return "" + } + + for _, branch := range branches { + // find the default branch + if repo.DefaultBranch == branch.Name { + commit, err := branch.GetCommit() + if err != nil { + log.Error("GetCommit: %v", err) + return "" + } + + statuses, statusCount, err := git_model.GetLatestCommitStatus(ctx, repo.ID, commit.ID.String(), db.ListOptions{}) + if err != nil { + log.Error("GetLatestCommitStatus: %v", err) + return "" + } + if statusCount == 0 { + return "" + } + + return git_model.CalcCommitStatus(statuses).State + } + } + return "" +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 35cbc71c8baf3..dfc4c60630fb9 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -20339,6 +20339,9 @@ "type": "string", "x-go-name": "CloneURL" }, + "commit_status_state": { + "$ref": "#/definitions/CommitStatusState" + }, "created_at": { "type": "string", "format": "date-time", diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index 5cedbcb000180..712be465291e8 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -79,6 +79,13 @@ + + + + + + + diff --git a/web_src/js/svg.js b/web_src/js/svg.js index 0894bbb169c25..49376c16434a8 100644 --- a/web_src/js/svg.js +++ b/web_src/js/svg.js @@ -2,10 +2,12 @@ import {h} from 'vue'; import giteaDoubleChevronLeft from '../../public/img/svg/gitea-double-chevron-left.svg'; import giteaDoubleChevronRight from '../../public/img/svg/gitea-double-chevron-right.svg'; import giteaEmptyCheckbox from '../../public/img/svg/gitea-empty-checkbox.svg'; +import giteaExclamation from '../../public/img/svg/gitea-exclamation.svg'; import octiconArchive from '../../public/img/svg/octicon-archive.svg'; import octiconArrowSwitch from '../../public/img/svg/octicon-arrow-switch.svg'; import octiconBlocked from '../../public/img/svg/octicon-blocked.svg'; import octiconBold from '../../public/img/svg/octicon-bold.svg'; +import octiconCheck from '../../public/img/svg/octicon-check.svg'; import octiconCheckbox from '../../public/img/svg/octicon-checkbox.svg'; import octiconCheckCircleFill from '../../public/img/svg/octicon-check-circle-fill.svg'; import octiconChevronDown from '../../public/img/svg/octicon-chevron-down.svg'; @@ -19,6 +21,7 @@ import octiconDiffAdded from '../../public/img/svg/octicon-diff-added.svg'; import octiconDiffModified from '../../public/img/svg/octicon-diff-modified.svg'; import octiconDiffRemoved from '../../public/img/svg/octicon-diff-removed.svg'; import octiconDiffRenamed from '../../public/img/svg/octicon-diff-renamed.svg'; +import octiconDotFill from '../../public/img/svg/octicon-dot-fill.svg'; import octiconEye from '../../public/img/svg/octicon-eye.svg'; import octiconFile from '../../public/img/svg/octicon-file.svg'; import octiconFileDirectoryFill from '../../public/img/svg/octicon-file-directory-fill.svg'; @@ -67,10 +70,12 @@ const svgs = { 'gitea-double-chevron-left': giteaDoubleChevronLeft, 'gitea-double-chevron-right': giteaDoubleChevronRight, 'gitea-empty-checkbox': giteaEmptyCheckbox, + 'gitea-exclamation': giteaExclamation, 'octicon-archive': octiconArchive, 'octicon-arrow-switch': octiconArrowSwitch, 'octicon-blocked': octiconBlocked, 'octicon-bold': octiconBold, + 'octicon-check': octiconCheck, 'octicon-check-circle-fill': octiconCheckCircleFill, 'octicon-checkbox': octiconCheckbox, 'octicon-chevron-down': octiconChevronDown, @@ -84,6 +89,7 @@ const svgs = { 'octicon-diff-modified': octiconDiffModified, 'octicon-diff-removed': octiconDiffRemoved, 'octicon-diff-renamed': octiconDiffRenamed, + 'octicon-dot-fill': octiconDotFill, 'octicon-eye': octiconEye, 'octicon-file': octiconFile, 'octicon-file-directory-fill': octiconFileDirectoryFill, From 2279f7cba86757831b0d14105afb77d9db9647e8 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Wed, 10 May 2023 20:45:37 +0300 Subject: [PATCH 02/13] Update modules/structs/repo.go Co-authored-by: delvh --- modules/structs/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 884b197236d52..f880ec344af25 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -75,7 +75,7 @@ type Repository struct { OpenPulls int `json:"open_pr_counter"` Releases int `json:"release_counter"` DefaultBranch string `json:"default_branch"` - CommitStatusState CommitStatusState `json:"commit_status_state"` + LatestCommitStatusState CommitStatusState `json:"latest_commit_status_state"` Archived bool `json:"archived"` // swagger:strfmt date-time Created time.Time `json:"created_at"` From 62a589a85d598eb3a55fe092e9550e304be7146b Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Wed, 10 May 2023 17:48:37 +0000 Subject: [PATCH 03/13] prefix `latest` --- routers/web/repo/repo.go | 22 ++++++++++----------- templates/swagger/v1_json.tmpl | 6 +++--- web_src/js/components/DashboardRepoList.vue | 12 +++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index fea25f6e6e3fa..5a33320c6cb62 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -580,17 +580,17 @@ func SearchRepo(ctx *context.Context) { results := make([]*api.Repository, len(repos)) for i, repo := range repos { results[i] = &api.Repository{ - ID: repo.ID, - FullName: repo.FullName(), - Fork: repo.IsFork, - Private: repo.IsPrivate, - Template: repo.IsTemplate, - Mirror: repo.IsMirror, - Stars: repo.NumStars, - HTMLURL: repo.HTMLURL(), - Link: repo.Link(), - Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, - CommitStatusState: getLatestCommitStatusState(ctx, repo), + ID: repo.ID, + FullName: repo.FullName(), + Fork: repo.IsFork, + Private: repo.IsPrivate, + Template: repo.IsTemplate, + Mirror: repo.IsMirror, + Stars: repo.NumStars, + HTMLURL: repo.HTMLURL(), + Link: repo.Link(), + Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + LatestCommitStatusState: getLatestCommitStatusState(ctx, repo), } } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index dfc4c60630fb9..13595d4361b7f 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -20339,9 +20339,6 @@ "type": "string", "x-go-name": "CloneURL" }, - "commit_status_state": { - "$ref": "#/definitions/CommitStatusState" - }, "created_at": { "type": "string", "format": "date-time", @@ -20446,6 +20443,9 @@ "type": "string", "x-go-name": "LanguagesURL" }, + "latest_commit_status_state": { + "$ref": "#/definitions/CommitStatusState" + }, "link": { "type": "string", "x-go-name": "Link" diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index 712be465291e8..2efaa87d6c452 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -80,12 +80,12 @@ - - - - - - + + + + + + From 3a2722aa6c6facace86969ed1a3ad20d4b0a3842 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Wed, 10 May 2023 18:50:43 +0000 Subject: [PATCH 04/13] Don't touch the API --- modules/structs/miscellaneous.go | 6 ++ modules/structs/repo.go | 63 +++++++++++---------- routers/web/repo/repo.go | 28 ++++----- templates/swagger/v1_json.tmpl | 3 - web_src/js/components/DashboardRepoList.vue | 2 +- web_src/js/features/org-team.js | 4 +- web_src/js/features/repo-issue.js | 4 +- web_src/js/features/repo-template.js | 4 +- 8 files changed, 62 insertions(+), 52 deletions(-) diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go index bff10f95b7c55..0ab4b92ea96e1 100644 --- a/modules/structs/miscellaneous.go +++ b/modules/structs/miscellaneous.go @@ -9,6 +9,12 @@ type SearchResults struct { Data []*Repository `json:"data"` } +// WebSearchResults results of a successful web search +type WebSearchResults struct { + OK bool `json:"ok"` + Data []*WebSearchRepository `json:"data"` +} + // SearchError error of a failed search type SearchError struct { OK bool `json:"ok"` diff --git a/modules/structs/repo.go b/modules/structs/repo.go index f880ec344af25..9230f256fe9e2 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -46,37 +46,42 @@ type ExternalWiki struct { ExternalWikiURL string `json:"external_wiki_url"` } +// WebSearchRepository represents a repository returned by web search +type WebSearchRepository struct { + Repository *Repository `json:"repository"` + LatestCommitStatusState CommitStatusState `json:"latest_commit_status_state"` +} + // Repository represents a repository type Repository struct { - ID int64 `json:"id"` - Owner *User `json:"owner"` - Name string `json:"name"` - FullName string `json:"full_name"` - Description string `json:"description"` - Empty bool `json:"empty"` - Private bool `json:"private"` - Fork bool `json:"fork"` - Template bool `json:"template"` - Parent *Repository `json:"parent"` - Mirror bool `json:"mirror"` - Size int `json:"size"` - Language string `json:"language"` - LanguagesURL string `json:"languages_url"` - HTMLURL string `json:"html_url"` - Link string `json:"link"` - SSHURL string `json:"ssh_url"` - CloneURL string `json:"clone_url"` - OriginalURL string `json:"original_url"` - Website string `json:"website"` - Stars int `json:"stars_count"` - Forks int `json:"forks_count"` - Watchers int `json:"watchers_count"` - OpenIssues int `json:"open_issues_count"` - OpenPulls int `json:"open_pr_counter"` - Releases int `json:"release_counter"` - DefaultBranch string `json:"default_branch"` - LatestCommitStatusState CommitStatusState `json:"latest_commit_status_state"` - Archived bool `json:"archived"` + ID int64 `json:"id"` + Owner *User `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent *Repository `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + Language string `json:"language"` + LanguagesURL string `json:"languages_url"` + HTMLURL string `json:"html_url"` + Link string `json:"link"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_url"` + Website string `json:"website"` + Stars int `json:"stars_count"` + Forks int `json:"forks_count"` + Watchers int `json:"watchers_count"` + OpenIssues int `json:"open_issues_count"` + OpenPulls int `json:"open_pr_counter"` + Releases int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + Archived bool `json:"archived"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 5a33320c6cb62..08f17980a2aef 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -577,24 +577,26 @@ func SearchRepo(ctx *context.Context) { return } - results := make([]*api.Repository, len(repos)) + results := make([]*api.WebSearchRepository, len(repos)) for i, repo := range repos { - results[i] = &api.Repository{ - ID: repo.ID, - FullName: repo.FullName(), - Fork: repo.IsFork, - Private: repo.IsPrivate, - Template: repo.IsTemplate, - Mirror: repo.IsMirror, - Stars: repo.NumStars, - HTMLURL: repo.HTMLURL(), - Link: repo.Link(), - Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + results[i] = &api.WebSearchRepository{ + Repository: &api.Repository{ + ID: repo.ID, + FullName: repo.FullName(), + Fork: repo.IsFork, + Private: repo.IsPrivate, + Template: repo.IsTemplate, + Mirror: repo.IsMirror, + Stars: repo.NumStars, + HTMLURL: repo.HTMLURL(), + Link: repo.Link(), + Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, + }, LatestCommitStatusState: getLatestCommitStatusState(ctx, repo), } } - ctx.JSON(http.StatusOK, api.SearchResults{ + ctx.JSON(http.StatusOK, api.WebSearchResults{ OK: true, Data: results, }) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 13595d4361b7f..35cbc71c8baf3 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -20443,9 +20443,6 @@ "type": "string", "x-go-name": "LanguagesURL" }, - "latest_commit_status_state": { - "$ref": "#/definitions/CommitStatusState" - }, "link": { "type": "string", "x-go-name": "Link" diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index 2efaa87d6c452..d0596eb24da4f 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -394,7 +394,7 @@ const sfc = { } if (searchedURL === this.searchURL) { - this.repos = json.data; + this.repos = json.data.map((webSearchRepo) => {return {...webSearchRepo.repository, latest_commit_status_state: webSearchRepo.latest_commit_status_state}}); const count = response.headers.get('X-Total-Count'); if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') { this.reposTotalCount = count; diff --git a/web_src/js/features/org-team.js b/web_src/js/features/org-team.js index 3640bb96f740d..957dce02d8e37 100644 --- a/web_src/js/features/org-team.js +++ b/web_src/js/features/org-team.js @@ -26,8 +26,8 @@ export function initOrgTeamSearchRepoBox() { const items = []; $.each(response.data, (_i, item) => { items.push({ - title: item.full_name.split('/')[1], - description: item.full_name + title: item.repository.full_name.split('/')[1], + description: item.repository.full_name }); }); diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index d2942cd93331d..3723e0f627e63 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -291,8 +291,8 @@ export function initRepoIssueReferenceRepositorySearch() { const filteredResponse = {success: true, results: []}; $.each(response.data, (_r, repo) => { filteredResponse.results.push({ - name: htmlEscape(repo.full_name), - value: repo.full_name + name: htmlEscape(repo.repository.full_name), + value: repo.repository.full_name }); }); return filteredResponse; diff --git a/web_src/js/features/repo-template.js b/web_src/js/features/repo-template.js index 0c5ea5233af96..1e83e74780fbd 100644 --- a/web_src/js/features/repo-template.js +++ b/web_src/js/features/repo-template.js @@ -34,8 +34,8 @@ export function initRepoTemplateSearch() { // Parse the response from the api to work with our dropdown $.each(response.data, (_r, repo) => { filteredResponse.results.push({ - name: htmlEscape(repo.full_name), - value: repo.id + name: htmlEscape(repo.repository.full_name), + value: repo.repository.id }); }); return filteredResponse; From e414a41bf97e15e9dff15888150b67aca3ce73a2 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 16:49:03 +0000 Subject: [PATCH 05/13] Deduplicate code for svg selection --- web_src/js/components/DashboardRepoList.vue | 24 +++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index d0596eb24da4f..13e8d4bde77e8 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -80,12 +80,7 @@ - - - - - - + @@ -161,6 +156,15 @@ import {SvgIcon} from '../svg.js'; const {appSubUrl, assetUrlPrefix, pageData} = window.config; +const commitStatus = { + pending: {name: 'octicon-dot-fill', color: 'grey'}, + running: {name: 'octicon-dot-fill', color: 'yellow'}, + success: {name: 'octicon-check', color: 'green'}, + error: {name: 'gitea-exclamation', color: 'red'}, + failure: {name: 'octicon-x', color: 'red'}, + warning: {name: 'gitea-exclamation', color: 'yellow'}, +}; + const sfc = { components: {SvgIcon}, data() { @@ -419,6 +423,14 @@ const sfc = { return 'octicon-repo'; } return 'octicon-repo'; + }, + + statusIcon(status) { + return commitStatus[status].name; + }, + + statusColor(status) { + return commitStatus[status].color; } }, }; From 00717f63935099e867811a23503368c5a6dd77d4 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 18:47:42 +0000 Subject: [PATCH 06/13] Use `O(1)` database calls instead of `O(n)` --- models/git/commit_status.go | 55 +++++++++++++++++++++++++++++ routers/web/repo/repo.go | 69 +++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 33 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 82cbb2363739f..1af944de0a94c 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -23,6 +23,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" "xorm.io/xorm" ) @@ -240,6 +241,60 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp return statuses, count, db.GetEngine(ctx).In("id", ids).Find(&statuses) } +// GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs +func GetLatestCommitStatusForPairs(ctx context.Context, repoIDs []int64, shas []string, listOptions db.ListOptions) (map[int64][]*CommitStatus, error) { + if len(repoIDs) != len(shas) { + return nil, errors.New("repoIDs and shas must have the same length") + } + + type Result struct { + ID int64 + RepoID int64 + } + + results := make([]Result, 0) + + sess := db.GetEngine(ctx).Table(&CommitStatus{}) + + // Create a disjunction of conditions for each repoID and SHA pair + conds := make([]builder.Cond, 0, len(repoIDs)) + for i := range repoIDs { + conds = append(conds, builder.And(builder.Eq{"repo_id": repoIDs[i]}, builder.Eq{"sha": shas[i]})) + } + sess = sess.Where(builder.Or(conds...)). + Select("max( id ) as id, repo_id"). + GroupBy("context_hash, repo_id").OrderBy("max( id ) desc") + + sess = db.SetSessionPagination(sess, &listOptions) + + err := sess.Find(&results) + if err != nil { + return nil, err + } + + ids := make([]int64, 0, len(results)) + repoStatuses := make(map[int64][]*CommitStatus) + for _, result := range results { + ids = append(ids, result.ID) + repoStatuses[result.RepoID] = nil + } + + statuses := make([]*CommitStatus, 0, len(ids)) + if len(ids) > 0 { + err = db.GetEngine(ctx).In("id", ids).Find(&statuses) + if err != nil { + return nil, err + } + + // Group the statuses by repo ID + for _, status := range statuses { + repoStatuses[status.RepoID] = append(repoStatuses[status.RepoID], status) + } + } + + return repoStatuses, nil +} + // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { start := timeutil.TimeStampNow().AddDuration(-before) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 08f17980a2aef..53b58e10b488d 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -577,6 +577,41 @@ func SearchRepo(ctx *context.Context) { return } + // collect the latest commit of each repo + repoIDsWithCommitStatuses := make([]int64, 0, len(repos)) + commitsWithCommitStatuses := make([]string, 0, len(repos)) + for _, repo := range repos { + branches, branchCount, err := repo_service.GetBranches(ctx, repo, 0, 0) + if err != nil { + log.Error("GetBranches: %v", err) + continue + } + if branchCount == 0 { + continue + } + + for _, branch := range branches { + // find the default branch + if repo.DefaultBranch == branch.Name { + commit, err := branch.GetCommit() + if err != nil { + log.Error("GetCommit: %v", err) + break + } + repoIDsWithCommitStatuses = append(repoIDsWithCommitStatuses, repo.ID) + commitsWithCommitStatuses = append(commitsWithCommitStatuses, commit.ID.String()) + break + } + } + } + + // call the database O(1) times to get the commit statuses for all repos + repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsWithCommitStatuses, commitsWithCommitStatuses, db.ListOptions{}) + if err != nil { + log.Error("GetLatestCommitStatusForPairs: %v", err) + return + } + results := make([]*api.WebSearchRepository, len(repos)) for i, repo := range repos { results[i] = &api.WebSearchRepository{ @@ -592,7 +627,7 @@ func SearchRepo(ctx *context.Context) { Link: repo.Link(), Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, }, - LatestCommitStatusState: getLatestCommitStatusState(ctx, repo), + LatestCommitStatusState: git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID]).State, } } @@ -601,35 +636,3 @@ func SearchRepo(ctx *context.Context) { Data: results, }) } - -// getLatestCommitStatusState returns the commit status state returns the latest commit status state of the latest -// commit on the default branch of the given repository -func getLatestCommitStatusState(ctx *context.Context, repo *repo_model.Repository) api.CommitStatusState { - branches, branchCount, _ := repo_service.GetBranches(ctx, repo, 0, 0) - if branchCount == 0 { - return "" - } - - for _, branch := range branches { - // find the default branch - if repo.DefaultBranch == branch.Name { - commit, err := branch.GetCommit() - if err != nil { - log.Error("GetCommit: %v", err) - return "" - } - - statuses, statusCount, err := git_model.GetLatestCommitStatus(ctx, repo.ID, commit.ID.String(), db.ListOptions{}) - if err != nil { - log.Error("GetLatestCommitStatus: %v", err) - return "" - } - if statusCount == 0 { - return "" - } - - return git_model.CalcCommitStatus(statuses).State - } - } - return "" -} From 0e7436ece3f876db05dff9973a686852a3585310 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 20:35:38 +0000 Subject: [PATCH 07/13] Don't loop over branches, introduce `GetBranch` --- modules/git/repo_branch.go | 11 +++++++++++ routers/web/repo/repo.go | 23 ++++++----------------- services/repository/branch.go | 4 ++++ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 14dcf14d8a0da..5649b06b65565 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -106,6 +106,17 @@ func GetBranchesByPath(ctx context.Context, path string, skip, limit int) ([]*Br return gitRepo.GetBranches(skip, limit) } +// GetBranch returns a branch by its name +func GetBranch(ctx context.Context, path, branch string) (*Branch, error) { + gitRepo, err := OpenRepository(ctx, path) + if err != nil { + return nil, err + } + defer gitRepo.Close() + + return gitRepo.GetBranch(branch) +} + // GetBranches returns a slice of *git.Branch func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) { brs, countAll, err := repo.GetBranchNames(skip, limit) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 53b58e10b488d..fc426b0a6d968 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -581,28 +581,17 @@ func SearchRepo(ctx *context.Context) { repoIDsWithCommitStatuses := make([]int64, 0, len(repos)) commitsWithCommitStatuses := make([]string, 0, len(repos)) for _, repo := range repos { - branches, branchCount, err := repo_service.GetBranches(ctx, repo, 0, 0) + branch, err := repo_service.GetBranch(ctx, repo, repo.DefaultBranch) if err != nil { - log.Error("GetBranches: %v", err) continue } - if branchCount == 0 { + commit, err := branch.GetCommit() + if err != nil { + log.Error("GetCommit: %v", err) continue } - - for _, branch := range branches { - // find the default branch - if repo.DefaultBranch == branch.Name { - commit, err := branch.GetCommit() - if err != nil { - log.Error("GetCommit: %v", err) - break - } - repoIDsWithCommitStatuses = append(repoIDsWithCommitStatuses, repo.ID) - commitsWithCommitStatuses = append(commitsWithCommitStatuses, commit.ID.String()) - break - } - } + repoIDsWithCommitStatuses = append(repoIDsWithCommitStatuses, repo.ID) + commitsWithCommitStatuses = append(commitsWithCommitStatuses, commit.ID.String()) } // call the database O(1) times to get the commit statuses for all repos diff --git a/services/repository/branch.go b/services/repository/branch.go index a085026ae1563..86dd65eedb018 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -53,6 +53,10 @@ func GetBranches(ctx context.Context, repo *repo_model.Repository, skip, limit i return git.GetBranchesByPath(ctx, repo.RepoPath(), skip, limit) } +func GetBranch(ctx context.Context, repo *repo_model.Repository, branch string) (*git.Branch, error) { + return git.GetBranch(ctx, repo.RepoPath(), branch) +} + // checkBranchName validates branch name with existing repository branches func checkBranchName(ctx context.Context, repo *repo_model.Repository, name string) error { _, err := git.WalkReferences(ctx, repo.RepoPath(), func(_, refName string) error { From 0041c01abfb6b140c3221a4000098ced6b8ead18 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 23:37:03 +0300 Subject: [PATCH 08/13] Update models/git/commit_status.go Co-authored-by: delvh --- models/git/commit_status.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 1af944de0a94c..0dc79c06cead7 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -242,7 +242,7 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp } // GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs -func GetLatestCommitStatusForPairs(ctx context.Context, repoIDs []int64, shas []string, listOptions db.ListOptions) (map[int64][]*CommitStatus, error) { +func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHAs map[int64]string, listOptions db.ListOptions) (map[int64][]*CommitStatus, error) { if len(repoIDs) != len(shas) { return nil, errors.New("repoIDs and shas must have the same length") } From e858179d8065b91a764f300540db9deba9ce4230 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 20:43:04 +0000 Subject: [PATCH 09/13] Address some review comments from delvh Co-authored-by: delvh --- models/git/commit_status.go | 15 +++++---------- routers/web/repo/repo.go | 8 +++----- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 0dc79c06cead7..6028e46649325 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -243,23 +243,19 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp // GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHAs map[int64]string, listOptions db.ListOptions) (map[int64][]*CommitStatus, error) { - if len(repoIDs) != len(shas) { - return nil, errors.New("repoIDs and shas must have the same length") - } - - type Result struct { + type result struct { ID int64 RepoID int64 } - results := make([]Result, 0) + results := make([]result, 0, len(repoIDsToLatestCommitSHAs)) sess := db.GetEngine(ctx).Table(&CommitStatus{}) // Create a disjunction of conditions for each repoID and SHA pair - conds := make([]builder.Cond, 0, len(repoIDs)) - for i := range repoIDs { - conds = append(conds, builder.And(builder.Eq{"repo_id": repoIDs[i]}, builder.Eq{"sha": shas[i]})) + conds := make([]builder.Cond, 0, len(repoIDsToLatestCommitSHAs)) + for repoID, sha := range repoIDsToLatestCommitSHAs { + conds = append(conds, builder.Eq{"repo_id": repoID, "sha": sha}) } sess = sess.Where(builder.Or(conds...)). Select("max( id ) as id, repo_id"). @@ -276,7 +272,6 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA repoStatuses := make(map[int64][]*CommitStatus) for _, result := range results { ids = append(ids, result.ID) - repoStatuses[result.RepoID] = nil } statuses := make([]*CommitStatus, 0, len(ids)) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index fc426b0a6d968..c16512e9b577d 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -578,8 +578,7 @@ func SearchRepo(ctx *context.Context) { } // collect the latest commit of each repo - repoIDsWithCommitStatuses := make([]int64, 0, len(repos)) - commitsWithCommitStatuses := make([]string, 0, len(repos)) + repoIDsToLatestCommitSHAs := make(map[int64]string) for _, repo := range repos { branch, err := repo_service.GetBranch(ctx, repo, repo.DefaultBranch) if err != nil { @@ -590,12 +589,11 @@ func SearchRepo(ctx *context.Context) { log.Error("GetCommit: %v", err) continue } - repoIDsWithCommitStatuses = append(repoIDsWithCommitStatuses, repo.ID) - commitsWithCommitStatuses = append(commitsWithCommitStatuses, commit.ID.String()) + repoIDsToLatestCommitSHAs[repo.ID] = commit.ID.String() } // call the database O(1) times to get the commit statuses for all repos - repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsWithCommitStatuses, commitsWithCommitStatuses, db.ListOptions{}) + repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptions{}) if err != nil { log.Error("GetLatestCommitStatusForPairs: %v", err) return From d1267e44f9891bc2816ff81f1f839c9d6903a415 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 11 May 2023 21:02:50 +0000 Subject: [PATCH 10/13] Send the entire status --- modules/structs/miscellaneous.go | 6 ------ modules/structs/repo.go | 6 ------ routers/web/repo/repo.go | 8 ++++---- services/repository/repository.go | 14 ++++++++++++++ web_src/js/components/DashboardRepoList.vue | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go index 0ab4b92ea96e1..bff10f95b7c55 100644 --- a/modules/structs/miscellaneous.go +++ b/modules/structs/miscellaneous.go @@ -9,12 +9,6 @@ type SearchResults struct { Data []*Repository `json:"data"` } -// WebSearchResults results of a successful web search -type WebSearchResults struct { - OK bool `json:"ok"` - Data []*WebSearchRepository `json:"data"` -} - // SearchError error of a failed search type SearchError struct { OK bool `json:"ok"` diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 9230f256fe9e2..01239188c2cd5 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -46,12 +46,6 @@ type ExternalWiki struct { ExternalWikiURL string `json:"external_wiki_url"` } -// WebSearchRepository represents a repository returned by web search -type WebSearchRepository struct { - Repository *Repository `json:"repository"` - LatestCommitStatusState CommitStatusState `json:"latest_commit_status_state"` -} - // Repository represents a repository type Repository struct { ID int64 `json:"id"` diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index c16512e9b577d..a0943a2c865f0 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -599,9 +599,9 @@ func SearchRepo(ctx *context.Context) { return } - results := make([]*api.WebSearchRepository, len(repos)) + results := make([]*repo_service.WebSearchRepository, len(repos)) for i, repo := range repos { - results[i] = &api.WebSearchRepository{ + results[i] = &repo_service.WebSearchRepository{ Repository: &api.Repository{ ID: repo.ID, FullName: repo.FullName(), @@ -614,11 +614,11 @@ func SearchRepo(ctx *context.Context) { Link: repo.Link(), Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, }, - LatestCommitStatusState: git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID]).State, + LatestCommitStatus: git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID]), } } - ctx.JSON(http.StatusOK, api.WebSearchResults{ + ctx.JSON(http.StatusOK, repo_service.WebSearchResults{ OK: true, Data: results, }) diff --git a/services/repository/repository.go b/services/repository/repository.go index 0d6529383cc8d..0914a8f6ec6ad 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" @@ -20,9 +21,22 @@ import ( "code.gitea.io/gitea/modules/notification" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" pull_service "code.gitea.io/gitea/services/pull" ) +// WebSearchRepository represents a repository returned by web search +type WebSearchRepository struct { + Repository *structs.Repository `json:"repository"` + LatestCommitStatus *git.CommitStatus `json:"latest_commit_status"` +} + +// WebSearchResults results of a successful web search +type WebSearchResults struct { + OK bool `json:"ok"` + Data []*WebSearchRepository `json:"data"` +} + // CreateRepository creates a repository for the user/organization. func CreateRepository(ctx context.Context, doer, owner *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) { repo, err := repo_module.CreateRepository(doer, owner, opts) diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index 13e8d4bde77e8..86300ee86ac7b 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -398,7 +398,7 @@ const sfc = { } if (searchedURL === this.searchURL) { - this.repos = json.data.map((webSearchRepo) => {return {...webSearchRepo.repository, latest_commit_status_state: webSearchRepo.latest_commit_status_state}}); + this.repos = json.data.map((webSearchRepo) => {return {...webSearchRepo.repository, latest_commit_status_state: webSearchRepo.latest_commit_status.State}}); const count = response.headers.get('X-Total-Count'); if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') { this.reposTotalCount = count; From 927a3af52f0ac462c3f4a782d64becffdd6e334c Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 13 May 2023 17:12:54 +0000 Subject: [PATCH 11/13] Parallelize `GetBranch` calls --- routers/web/repo/repo.go | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index a0943a2c865f0..c465f21a0b891 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -9,6 +9,7 @@ import ( "fmt" "net/http" "strings" + "sync" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" @@ -579,18 +580,24 @@ func SearchRepo(ctx *context.Context) { // collect the latest commit of each repo repoIDsToLatestCommitSHAs := make(map[int64]string) + wg := sync.WaitGroup{} + wg.Add(len(repos)) for _, repo := range repos { - branch, err := repo_service.GetBranch(ctx, repo, repo.DefaultBranch) - if err != nil { - continue - } - commit, err := branch.GetCommit() - if err != nil { - log.Error("GetCommit: %v", err) - continue - } - repoIDsToLatestCommitSHAs[repo.ID] = commit.ID.String() + go func(repo *repo_model.Repository) { + defer wg.Done() + branch, err := repo_service.GetBranch(ctx, repo, repo.DefaultBranch) + if err != nil { + return + } + commit, err := branch.GetCommit() + if err != nil { + log.Error("GetCommit: %v", err) + return + } + repoIDsToLatestCommitSHAs[repo.ID] = commit.ID.String() + }(repo) } + wg.Wait() // call the database O(1) times to get the commit statuses for all repos repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptions{}) From 52cd77ea5391fa6c01de907ee9341ada20ab2653 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 13 May 2023 17:28:11 +0000 Subject: [PATCH 12/13] Cut git calls in half --- modules/git/repo_branch.go | 6 +++--- routers/web/repo/repo.go | 8 ++------ services/repository/branch.go | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 5649b06b65565..0e86495a32fcd 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -106,15 +106,15 @@ func GetBranchesByPath(ctx context.Context, path string, skip, limit int) ([]*Br return gitRepo.GetBranches(skip, limit) } -// GetBranch returns a branch by its name -func GetBranch(ctx context.Context, path, branch string) (*Branch, error) { +// GetBranchCommit returns a branch commit by its name +func GetBranchCommit(ctx context.Context, path, branch string) (*Commit, error) { gitRepo, err := OpenRepository(ctx, path) if err != nil { return nil, err } defer gitRepo.Close() - return gitRepo.GetBranch(branch) + return gitRepo.GetBranchCommit(branch) } // GetBranches returns a slice of *git.Branch diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index c465f21a0b891..43f17aef90f37 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -585,13 +585,9 @@ func SearchRepo(ctx *context.Context) { for _, repo := range repos { go func(repo *repo_model.Repository) { defer wg.Done() - branch, err := repo_service.GetBranch(ctx, repo, repo.DefaultBranch) + commit, err := repo_service.GetBranchCommit(ctx, repo, repo.DefaultBranch) if err != nil { - return - } - commit, err := branch.GetCommit() - if err != nil { - log.Error("GetCommit: %v", err) + log.Error("GetBranchCommit: %v", err) return } repoIDsToLatestCommitSHAs[repo.ID] = commit.ID.String() diff --git a/services/repository/branch.go b/services/repository/branch.go index 86dd65eedb018..6639e6ec57095 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -53,8 +53,8 @@ func GetBranches(ctx context.Context, repo *repo_model.Repository, skip, limit i return git.GetBranchesByPath(ctx, repo.RepoPath(), skip, limit) } -func GetBranch(ctx context.Context, repo *repo_model.Repository, branch string) (*git.Branch, error) { - return git.GetBranch(ctx, repo.RepoPath(), branch) +func GetBranchCommit(ctx context.Context, repo *repo_model.Repository, branch string) (*git.Commit, error) { + return git.GetBranchCommit(ctx, repo.RepoPath(), branch) } // checkBranchName validates branch name with existing repository branches From d37464b94f628ad4a90f23343d30e609f2fecc2c Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 13 May 2023 17:39:00 +0000 Subject: [PATCH 13/13] Cut git calls in half again --- modules/git/repo_branch.go | 8 ++++---- routers/web/repo/repo.go | 5 ++--- services/repository/branch.go | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 0e86495a32fcd..3bb6ef5223a26 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -106,15 +106,15 @@ func GetBranchesByPath(ctx context.Context, path string, skip, limit int) ([]*Br return gitRepo.GetBranches(skip, limit) } -// GetBranchCommit returns a branch commit by its name -func GetBranchCommit(ctx context.Context, path, branch string) (*Commit, error) { +// GetBranchCommitID returns a branch commit ID by its name +func GetBranchCommitID(ctx context.Context, path, branch string) (string, error) { gitRepo, err := OpenRepository(ctx, path) if err != nil { - return nil, err + return "", err } defer gitRepo.Close() - return gitRepo.GetBranchCommit(branch) + return gitRepo.GetBranchCommitID(branch) } // GetBranches returns a slice of *git.Branch diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 43f17aef90f37..f697d9433e15e 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -585,12 +585,11 @@ func SearchRepo(ctx *context.Context) { for _, repo := range repos { go func(repo *repo_model.Repository) { defer wg.Done() - commit, err := repo_service.GetBranchCommit(ctx, repo, repo.DefaultBranch) + commitID, err := repo_service.GetBranchCommitID(ctx, repo, repo.DefaultBranch) if err != nil { - log.Error("GetBranchCommit: %v", err) return } - repoIDsToLatestCommitSHAs[repo.ID] = commit.ID.String() + repoIDsToLatestCommitSHAs[repo.ID] = commitID }(repo) } wg.Wait() diff --git a/services/repository/branch.go b/services/repository/branch.go index 6639e6ec57095..cafad34cef170 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -53,8 +53,8 @@ func GetBranches(ctx context.Context, repo *repo_model.Repository, skip, limit i return git.GetBranchesByPath(ctx, repo.RepoPath(), skip, limit) } -func GetBranchCommit(ctx context.Context, repo *repo_model.Repository, branch string) (*git.Commit, error) { - return git.GetBranchCommit(ctx, repo.RepoPath(), branch) +func GetBranchCommitID(ctx context.Context, repo *repo_model.Repository, branch string) (string, error) { + return git.GetBranchCommitID(ctx, repo.RepoPath(), branch) } // checkBranchName validates branch name with existing repository branches