diff options
-rw-r--r-- | integrations/compare_test.go | 24 | ||||
-rw-r--r-- | options/locale/locale_en-US.ini | 3 | ||||
-rw-r--r-- | routers/repo/compare.go | 53 | ||||
-rw-r--r-- | templates/repo/diff/compare.tmpl | 224 | ||||
-rw-r--r-- | web_src/js/index.js | 19 |
5 files changed, 229 insertions, 94 deletions
diff --git a/integrations/compare_test.go b/integrations/compare_test.go new file mode 100644 index 0000000000..08468cbfd6 --- /dev/null +++ b/integrations/compare_test.go @@ -0,0 +1,24 @@ +// Copyright 2021 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 integrations + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCompareTag(t *testing.T) { + defer prepareTestEnv(t)() + + session := loginUser(t, "user2") + req := NewRequest(t, "GET", "/user2/repo1/compare/v1.1...master") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + selection := htmlDoc.doc.Find(".choose.branch .filter.dropdown") + // A dropdown for both base and head. + assert.Lenf(t, selection.Nodes, 2, "The template has changed") +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 40e4e0c0ba..51fa316022 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1286,6 +1286,9 @@ issues.review.resolved_by = marked this conversation as resolved issues.assignee.error = Not all assignees was added due to an unexpected error. issues.reference_issue.body = Body +compare.compare_base = base +compare.compare_head = compare + pulls.desc = Enable pull requests and code reviews. pulls.new = New Pull Request pulls.compare_changes = New Pull Request diff --git a/routers/repo/compare.go b/routers/repo/compare.go index a658374d9b..d02ea0b160 100644 --- a/routers/repo/compare.go +++ b/routers/repo/compare.go @@ -391,7 +391,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * if rootRepo != nil && rootRepo.ID != headRepo.ID && rootRepo.ID != baseRepo.ID { - perm, branches, err := getBranchesForRepo(ctx.User, rootRepo) + perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, rootRepo) if err != nil { ctx.ServerError("GetBranchesForRepo", err) return nil, nil, nil, nil, "", "" @@ -399,19 +399,20 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * if perm { ctx.Data["RootRepo"] = rootRepo ctx.Data["RootRepoBranches"] = branches + ctx.Data["RootRepoTags"] = tags } } // If we have a ownForkRepo and it's different from: // 1. The computed base - // 2. The computed hea + // 2. The computed head // 3. The rootRepo (if we have one) // then get the branches from it. if ownForkRepo != nil && ownForkRepo.ID != headRepo.ID && ownForkRepo.ID != baseRepo.ID && (rootRepo == nil || ownForkRepo.ID != rootRepo.ID) { - perm, branches, err := getBranchesForRepo(ctx.User, ownForkRepo) + perm, branches, tags, err := getBranchesAndTagsForRepo(ctx.User, ownForkRepo) if err != nil { ctx.ServerError("GetBranchesForRepo", err) return nil, nil, nil, nil, "", "" @@ -419,6 +420,7 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * if perm { ctx.Data["OwnForkRepo"] = ownForkRepo ctx.Data["OwnForkRepoBranches"] = branches + ctx.Data["OwnForkRepoTags"] = tags } } @@ -572,25 +574,29 @@ func PrepareCompareDiff( return false } -func getBranchesForRepo(user *models.User, repo *models.Repository) (bool, []string, error) { +func getBranchesAndTagsForRepo(user *models.User, repo *models.Repository) (bool, []string, []string, error) { perm, err := models.GetUserRepoPermission(repo, user) if err != nil { - return false, nil, err + return false, nil, nil, err } if !perm.CanRead(models.UnitTypeCode) { - return false, nil, nil + return false, nil, nil, nil } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { - return false, nil, err + return false, nil, nil, err } defer gitRepo.Close() branches, _, err := gitRepo.GetBranches(0, 0) if err != nil { - return false, nil, err + return false, nil, nil, err } - return true, branches, nil + tags, err := gitRepo.GetTags() + if err != nil { + return false, nil, nil, err + } + return true, branches, tags, nil } // CompareDiff show different from one commit to another commit @@ -608,14 +614,29 @@ func CompareDiff(ctx *context.Context) { return } - if ctx.Data["PageIsComparePull"] == true { - headBranches, _, err := headGitRepo.GetBranches(0, 0) - if err != nil { - ctx.ServerError("GetBranches", err) - return - } - ctx.Data["HeadBranches"] = headBranches + baseGitRepo := ctx.Repo.GitRepo + baseTags, err := baseGitRepo.GetTags() + if err != nil { + ctx.ServerError("GetTags", err) + return + } + ctx.Data["Tags"] = baseTags + headBranches, _, err := headGitRepo.GetBranches(0, 0) + if err != nil { + ctx.ServerError("GetBranches", err) + return + } + ctx.Data["HeadBranches"] = headBranches + + headTags, err := headGitRepo.GetTags() + if err != nil { + ctx.ServerError("GetTags", err) + return + } + ctx.Data["HeadTags"] = headTags + + if ctx.Data["PageIsComparePull"] == true { pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch) if err != nil { if !models.IsErrPullRequestNotExist(err) { diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl index 124b4e5d1c..7959ef7bb5 100644 --- a/templates/repo/diff/compare.tmpl +++ b/templates/repo/diff/compare.tmpl @@ -3,105 +3,175 @@ {{template "repo/header" .}} <div class="ui container {{if .IsSplitStyle}}fluid padded{{end}}"> - {{if .PageIsComparePull}} - <h2 class="ui header"> - {{if and $.IsSigned (not .Repository.IsArchived)}} - {{.i18n.Tr "repo.pulls.compare_changes"}} - <div class="sub header">{{.i18n.Tr "repo.pulls.compare_changes_desc"}}</div> - {{ else }} - {{.i18n.Tr "action.compare_commits_general"}} - {{ end }} - </h2> - {{ $BaseCompareName := $.BaseName -}} - {{- $HeadCompareName := $.HeadRepo.OwnerName -}} - {{- if and (eq $.BaseName $.HeadRepo.OwnerName) (ne $.Repository.Name $.HeadRepo.Name) -}} + <h2 class="ui header"> + {{if and $.PageIsComparePull $.IsSigned (not .Repository.IsArchived)}} + {{.i18n.Tr "repo.pulls.compare_changes"}} + <div class="sub header">{{.i18n.Tr "repo.pulls.compare_changes_desc"}}</div> + {{ else }} + {{.i18n.Tr "action.compare_commits_general"}} + {{ end }} + </h2> + {{ $BaseCompareName := $.BaseName -}} + {{- $HeadCompareName := $.HeadRepo.OwnerName -}} + {{- if and (eq $.BaseName $.HeadRepo.OwnerName) (ne $.Repository.Name $.HeadRepo.Name) -}} + {{- $HeadCompareName = printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}} + {{- end -}} + {{- $OwnForkCompareName := "" -}} + {{- if .OwnForkRepo -}} + {{- $OwnForkCompareName = .OwnForkRepo.OwnerName -}} + {{- end -}} + {{- $RootRepoCompareName := "" -}} + {{- if .RootRepo -}} + {{- $RootRepoCompareName = .RootRepo.OwnerName -}} + {{- if eq $.HeadRepo.OwnerName .RootRepo.OwnerName -}} {{- $HeadCompareName = printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}} {{- end -}} - {{- $OwnForkCompareName := "" -}} {{- if .OwnForkRepo -}} - {{- $OwnForkCompareName = .OwnForkRepo.OwnerName -}} - {{- end -}} - {{- $RootRepoCompareName := "" -}} - {{- if .RootRepo -}} - {{- $RootRepoCompareName = .RootRepo.OwnerName -}} - {{- if eq $.HeadRepo.OwnerName .RootRepo.OwnerName -}} - {{- $HeadCompareName = printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}} - {{- end -}} - {{- if .OwnForkRepo -}} - {{- if eq $.OwnForkRepo.OwnerName .RootRepo.OwnerName -}} - {{- $OwnForkRepoCompareName = printf "%s/%s" $.OwnForkRepo.OwnerName $.OwnForkRepo.Name -}} - {{- end -}} + {{- if eq $.OwnForkRepo.OwnerName .RootRepo.OwnerName -}} + {{- $OwnForkRepoCompareName = printf "%s/%s" $.OwnForkRepo.OwnerName $.OwnForkRepo.Name -}} {{- end -}} {{- end -}} - <div class="ui segment choose branch"> - {{svg "octicon-git-compare"}} - <div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}"> - <div class="ui basic small button"> - <span class="text">{{.i18n.Tr "repo.pulls.compare_base"}}: {{$BaseCompareName}}:{{$.BaseBranch}}</span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} + {{- end -}} + <div class="ui segment choose branch"> + {{svg "octicon-git-compare"}} + <div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}"> + <div class="ui basic small button"> + <span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_base"}}{{else}}{{.i18n.Tr "repo.compare.compare_base"}}{{end}}: {{$BaseCompareName}}:{{$.BaseBranch}}</span> + {{svg "octicon-triangle-down" 14 "dropdown icon"}} + </div> + <div class="menu"> + <div class="ui icon search input"> + <i class="icon df ac jc m-0">{{svg "octicon-filter" 16}}</i> + <input name="search" placeholder="{{.i18n.Tr "repo.filter_branch_and_tag"}}..."> </div> - <div class="menu"> - <div class="ui icon search input"> - <i class="icon df ac jc m-0">{{svg "octicon-filter" 16}}</i> - <input name="search" placeholder="{{.i18n.Tr "repo.pulls.filter_branch"}}..."> + <div class="header"> + <div class="ui grid"> + <div class="two column row"> + <a class="reference column" href="#" data-target=".base-branch-list"> + <span class="text black"> + {{svg "octicon-git-branch" 16 "mr-2"}}{{.i18n.Tr "repo.branches"}} + </span> + </a> + <a class="reference column" href="#" data-target=".base-tag-list"> + <span class="text black"> + {{svg "octicon-tag" 16 "mr-2"}}{{.i18n.Tr "repo.tags"}} + </span> + </a> + </div> </div> - <div class="scrolling menu"> - {{range .Branches}} - <div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div> + </div> + <div class="scrolling menu reference-list-menu base-branch-list"> + {{range .Branches}} + <div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div> + {{end}} + {{if not .PullRequestCtx.SameRepo}} + {{range .HeadBranches}} + <div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div> {{end}} - {{if not .PullRequestCtx.SameRepo}} - {{range .HeadBranches}} - <div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div> - {{end}} + {{end}} + {{if .OwnForkRepo}} + {{range .OwnForkRepoBranches}} + <div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div> {{end}} - {{if .OwnForkRepo}} - {{range .OwnForkRepoBranches}} - <div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div> - {{end}} + {{end}} + {{if .RootRepo}} + {{range .RootRepoBranches}} + <div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div> {{end}} - {{if .RootRepo}} - {{range .RootRepoBranches}} - <div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div> - {{end}} + {{end}} + </div> + <div class="scrolling menu reference-list-menu base-tag-list" style="display: none"> + {{range .Tags}} + <div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-url="{{$.RepoLink}}/compare/{{EscapePound .}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound $.HeadBranch}}">{{$BaseCompareName}}:{{.}}</div> + {{end}} + {{if not .PullRequestCtx.SameRepo}} + {{range .HeadTags}} + <div class="item" data-url="{{$.HeadRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$HeadCompareName}}:{{.}}</div> {{end}} - </div> + {{end}} + {{if .OwnForkRepo}} + {{range .OwnForkRepoTags}} + <div class="item" data-url="{{$.OwnForkRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$OwnForkCompareName}}:{{.}}</div> + {{end}} + {{end}} + {{if .RootRepo}} + {{range .RootRepoTags}} + <div class="item" data-url="{{$.RootRepo.Link}}/compare/{{EscapePound .}}...{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{EscapePound $.HeadBranch}}">{{$RootRepoCompareName}}:{{.}}</div> + {{end}} + {{end}} </div> </div> - ... - <div class="ui floating filter dropdown"> - <div class="ui basic small button"> - <span class="text">{{.i18n.Tr "repo.pulls.compare_compare"}}: {{$HeadCompareName}}:{{$.HeadBranch}}</span> - {{svg "octicon-triangle-down" 14 "dropdown icon"}} + </div> + ... + <div class="ui floating filter dropdown"> + <div class="ui basic small button"> + <span class="text">{{if $.PageIsComparePull}}{{.i18n.Tr "repo.pulls.compare_compare"}}{{else}}{{.i18n.Tr "repo.compare.compare_head"}}{{end}}: {{$HeadCompareName}}:{{$.HeadBranch}}</span> + {{svg "octicon-triangle-down" 14 "dropdown icon"}} + </div> + <div class="menu"> + <div class="ui icon search input"> + <i class="icon df ac jc m-0">{{svg "octicon-filter" 16}}</i> + <input name="search" placeholder="{{.i18n.Tr "repo.filter_branch_and_tag"}}..."> </div> - <div class="menu"> - <div class="ui icon search input"> - <i class="icon df ac jc m-0">{{svg "octicon-filter" 16}}</i> - <input name="search" placeholder="{{.i18n.Tr "repo.pulls.filter_branch"}}..."> + <div class="header"> + <div class="ui grid"> + <div class="two column row"> + <a class="reference column" href="#" data-target=".head-branch-list"> + <span class="text black"> + {{svg "octicon-git-branch" 16 "mr-2"}}{{.i18n.Tr "repo.branches"}} + </span> + </a> + <a class="reference column" href="#" data-target=".head-tag-list"> + <span class="text black"> + {{svg "octicon-tag" 16 "mr-2"}}{{.i18n.Tr "repo.tags"}} + </span> + </a> + </div> </div> - <div class="scrolling menu"> - {{range .HeadBranches}} - <div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div> + </div> + <div class="scrolling menu reference-list-menu head-branch-list"> + {{range .HeadBranches}} + <div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div> + {{end}} + {{if not .PullRequestCtx.SameRepo}} + {{range .Branches}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div> {{end}} - {{if not .PullRequestCtx.SameRepo}} - {{range .Branches}} - <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div> - {{end}} + {{end}} + {{if .OwnForkRepo}} + {{range .OwnForkRepoBranches}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div> {{end}} - {{if .OwnForkRepo}} - {{range .OwnForkRepoBranches}} - <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div> - {{end}} + {{end}} + {{if .RootRepo}} + {{range .RootRepoBranches}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div> {{end}} - {{if .RootRepo}} - {{range .RootRepoBranches}} - <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div> - {{end}} + {{end}} + </div> + <div class="scrolling menu reference-list-menu head-tag-list" style="display: none"> + {{range .HeadTags}} + <div class="{{if eq $.HeadBranch .}}selected{{end}} item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{if not $.PullRequestCtx.SameRepo}}{{$.HeadUser.Name}}/{{$.HeadRepo.Name}}:{{end}}{{EscapePound .}}">{{$HeadCompareName}}:{{.}}</div> + {{end}} + {{if not .PullRequestCtx.SameRepo}} + {{range .Tags}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.BaseName}}/{{$.Repository.Name}}:{{EscapePound .}}">{{$BaseCompareName}}:{{.}}</div> {{end}} - </div> + {{end}} + {{if .OwnForkRepo}} + {{range .OwnForkRepoTags}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.OwnForkRepo.OwnerName}}/{{$.OwnForkRepo.Name}}:{{EscapePound .}}">{{$OwnForkCompareName}}:{{.}}</div> + {{end}} + {{end}} + {{if .RootRepo}} + {{range .RootRepoTags}} + <div class="item" data-url="{{$.RepoLink}}/compare/{{EscapePound $.BaseBranch}}...{{$.RootRepo.OwnerName}}/{{$.RootRepo.Name}}:{{EscapePound .}}">{{$RootRepoCompareName}}:{{.}}</div> + {{end}} + {{end}} </div> </div> </div> - {{end}} + </div> {{if .IsNothingToCompare}} {{if and $.IsSigned $.AllowEmptyPr (not .Repository.IsArchived) }} diff --git a/web_src/js/index.js b/web_src/js/index.js index 2d9f7f4caf..6ffff9cb19 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -1241,10 +1241,16 @@ async function initRepository() { $(this).select(); }); + // Compare or pull request + const $repoDiff = $('.repository.diff'); + if ($repoDiff.length) { + initBranchOrTagDropdown('.choose.branch .dropdown'); + initFilterSearchDropdown('.choose.branch .dropdown'); + } + // Pull request const $repoComparePull = $('.repository.compare.pull'); if ($repoComparePull.length > 0) { - initFilterSearchDropdown('.choose.branch .dropdown'); // show pull request form $repoComparePull.find('button.show-form').on('click', function (e) { e.preventDefault(); @@ -3447,6 +3453,17 @@ function initIssueTimetracking() { }); } +function initBranchOrTagDropdown(selector) { + $(selector).each(function() { + const $dropdown = $(this); + $dropdown.find('.reference.column').on('click', function () { + $dropdown.find('.scrolling.reference-list-menu').hide(); + $($(this).data('target')).show(); + return false; + }); + }); +} + function initFilterBranchTagDropdown(selector) { $(selector).each(function () { const $dropdown = $(this); |