| @@ -166,6 +166,8 @@ type SearchRepoOptions struct { | |||
| Archived util.OptionalBool | |||
| // only search topic name | |||
| TopicOnly bool | |||
| //search by Specific TopicName | |||
| TopicName string | |||
| // include description in keyword search | |||
| IncludeDescription bool | |||
| // None -> include has milestones AND has no milestone | |||
| @@ -327,6 +329,18 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | |||
| } | |||
| cond = cond.And(keywordCond) | |||
| } | |||
| if opts.TopicName != "" { | |||
| var subQueryCond = builder.NewCond() | |||
| subQueryCond = subQueryCond.Or(builder.Eq{"topic.name": opts.TopicName}) | |||
| subQuery := builder.Select("repo_topic.repo_id").From("repo_topic"). | |||
| Join("INNER", "topic", "topic.id = repo_topic.topic_id"). | |||
| Where(subQueryCond). | |||
| GroupBy("repo_topic.repo_id") | |||
| var topicNameCond = builder.In("id", subQuery) | |||
| cond = cond.And(topicNameCond) | |||
| } | |||
| if opts.Fork != util.OptionalBoolNone { | |||
| cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue}) | |||
| @@ -87,7 +87,7 @@ write = Write | |||
| preview = Preview | |||
| loading = Loading… | |||
| error404_index = Request forbidden by administrative rules | |||
| error404_index = Request forbidden by administrative rules | |||
| error500_index = Internal Server Error | |||
| error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it. | |||
| error500= Sorry, the site has encountered some problems, we are trying to <strong>fix the page</strong>, please try again later. | |||
| @@ -1246,6 +1246,11 @@ pulls.reject_count_1 = "%d change request" | |||
| pulls.reject_count_n = "%d change requests" | |||
| pulls.waiting_count_1 = "%d waiting review" | |||
| pulls.waiting_count_n = "%d waiting reviews" | |||
| pulls.commits_count_1=This branch is %d commit behind the upstream. | |||
| pulls.commits_count_n=This branch is %d commit behind the upstream. | |||
| pulls.fetch_upstream=Fetch upstream | |||
| pulls.upstream_up_to_date=No new commits to fetch | |||
| pulls.upstream_error=Cannot get upstream info | |||
| pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled. | |||
| pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually. | |||
| @@ -1248,6 +1248,11 @@ pulls.reject_count_1=%d 变更请求 | |||
| pulls.reject_count_n=%d 变更请求 | |||
| pulls.waiting_count_1=%d 个正在等待审核 | |||
| pulls.waiting_count_n=%d 个正在等待审核 | |||
| pulls.commits_count_1=当前分支落后上游分支 %d 个提交 | |||
| pulls.commits_count_n=当前分支落后上游分支 %d 个提交 | |||
| pulls.fetch_upstream=拉取上游更新 | |||
| pulls.upstream_up_to_date=上游分支没有新的更新 | |||
| pulls.upstream_error=获取上游分支信息错误 | |||
| pulls.no_merge_desc=由于未启用合并选项,此合并请求无法被合并。 | |||
| pulls.no_merge_helper=在项目设置中启用合并选项或者手工合并请求。 | |||
| @@ -149,8 +149,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||
| //todo:support other topics | |||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||
| topicOnly := ctx.QueryBool("topic") | |||
| ctx.Data["TopicOnly"] = topicOnly | |||
| topic := strings.Trim(ctx.Query("topic"), " ") | |||
| repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| @@ -164,7 +163,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||
| OwnerID: opts.OwnerID, | |||
| AllPublic: true, | |||
| AllLimited: true, | |||
| TopicOnly: topicOnly, | |||
| TopicName: topic, | |||
| IncludeDescription: setting.UI.SearchRepoDescription, | |||
| }) | |||
| if err != nil { | |||
| @@ -177,6 +176,8 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||
| repo.Active = int64(repo.NumIssues) + int64(repo.NumPulls) + int64(repo.NumCommit) | |||
| } | |||
| ctx.Data["Keyword"] = keyword | |||
| ctx.Data["Topic"] = topic | |||
| ctx.Data["Total"] = count | |||
| ctx.Data["Repos"] = repos | |||
| ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | |||
| @@ -790,6 +790,44 @@ func renderCode(ctx *context.Context) { | |||
| } | |||
| } | |||
| //如果是fork的仓库 | |||
| if ctx.Repo.Repository.IsFork { | |||
| //获得fetchUpstream对应的分支参数 | |||
| /* | |||
| // 1. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headBranch} | |||
| // 2. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headOwner}:{:headBranch} | |||
| // 3. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headOwner}/{:headRepoName}:{:headBranch} | |||
| */ | |||
| baseGitRepo, err := git.OpenRepository(ctx.Repo.Repository.BaseRepo.RepoPath()) | |||
| defer baseGitRepo.Close() | |||
| if err != nil { | |||
| log.Error("error open baseRepo:%s",ctx.Repo.Repository.BaseRepo.RepoPath()) | |||
| ctx.Data["FetchUpstreamCnt"] = -1 // minus value indicates error | |||
| }else{ | |||
| if _,error:= baseGitRepo.GetBranch(ctx.Repo.BranchName);error==nil{ | |||
| //base repo has the same branch, then compare between current repo branch and base repo's branch | |||
| compareUrl := ctx.Repo.BranchName + "..." + ctx.Repo.Repository.BaseRepo.OwnerName + "/" + ctx.Repo.Repository.BaseRepo.Name + ":" + ctx.Repo.BranchName | |||
| ctx.SetParams("*",compareUrl) | |||
| }else{ | |||
| //else, compare between current repo branch and base repo's default branch | |||
| compareUrl := ctx.Repo.BranchName + "..." + ctx.Repo.Repository.BaseRepo.OwnerName + "/" + ctx.Repo.Repository.BaseRepo.Name + ":" + ctx.Repo.Repository.BaseRepo.DefaultBranch | |||
| ctx.SetParams("*",compareUrl) | |||
| } | |||
| _, _, headGitRepo, compareInfo, _, _ := ParseCompareInfo(ctx) | |||
| defer headGitRepo.Close() | |||
| if compareInfo!= nil { | |||
| if compareInfo.Commits!=nil { | |||
| log.Info("compareInfoCommits数量:%d",compareInfo.Commits.Len()) | |||
| ctx.Data["FetchUpstreamCnt"] = compareInfo.Commits.Len() | |||
| }else{ | |||
| log.Info("compareInfo nothing different") | |||
| ctx.Data["FetchUpstreamCnt"] = 0 | |||
| } | |||
| }else{ | |||
| ctx.Data["FetchUpstreamCnt"] = -1 // minus value indicates error | |||
| } | |||
| } | |||
| } | |||
| ctx.Data["Paths"] = paths | |||
| ctx.Data["TreeLink"] = treeLink | |||
| ctx.Data["TreeNames"] = treeNames | |||
| @@ -154,6 +154,21 @@ | |||
| <a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button">{{if .PullRequestCtx.Allowed}}{{.i18n.Tr "repo.pulls.compare_changes"}}{{else}}{{.i18n.Tr "action.compare_branch"}}{{end}}</button> | |||
| </a> | |||
| {{if and .Repository.IsFork .PullRequestCtx.Allowed}} | |||
| {{if gt .FetchUpstreamCnt 0 }} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{$.i18n.Tr (TrN $.i18n.Lang .FetchUpstreamCnt "repo.pulls.commits_count_1" "repo.pulls.commits_count_n") .FetchUpstreamCnt}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else if lt .FetchUpstreamCnt 0}} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_error"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else}} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_up_to_date"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| {{else}} | |||
| @@ -3,12 +3,7 @@ | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <div class="ui three column stackable grid"> | |||
| <div class="column" style="display: flex;align-items: center;"> | |||
| <div class="ui large breadcrumb"> | |||
| <a href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a> | |||
| <div class="divider"> / </div> | |||
| </div> | |||
| <div class="column" style="display: flex;align-items: center;"> | |||
| </div> | |||
| <div class="column center aligned"> | |||
| {{template "repo/issue/search" .}} | |||
| @@ -197,13 +197,13 @@ export default { | |||
| }) | |||
| }, | |||
| postTopic(){ | |||
| const patter = /^[\u4e00-\u9fa5a-z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,35}$/ | |||
| const patter = /^[\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,34}$/ | |||
| let regexp = patter.test(this.input) | |||
| console.log("regexp",regexp) | |||
| if(!regexp){ | |||
| this.$notify({ | |||
| message: '主题必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符', | |||
| message: '标签名必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符', | |||
| duration: 3000, | |||
| type:'error' | |||
| }); | |||