| @@ -528,6 +528,11 @@ func runWeb(ctx *cli.Context) { | |||
| m.Get("/archive/*", repo.Download) | |||
| m.Get("/pulls2/", repo.PullRequest2) | |||
| m.Group("/pulls/:index", func() { | |||
| m.Get("/commits", repo.ViewPullCommits) | |||
| m.Get("/files", repo.ViewPullFiles) | |||
| }) | |||
| m.Group("", func() { | |||
| m.Get("/src/*", repo.Home) | |||
| m.Get("/raw/*", repo.SingleDownload) | |||
| @@ -462,12 +462,20 @@ issues.label_deletion_success = Label has been deleted successfully! | |||
| pulls.compare_changes = Compare Changes | |||
| pulls.compare_changes_desc = Compare two branches and make a pull request for changes. | |||
| pulls.compare_base = base | |||
| pulls.compare_compare = compare | |||
| pulls.filter_branch = Filter branch | |||
| pulls.no_results = No results found. | |||
| pulls.create = Create Pull Request | |||
| pulls.title_desc = wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> | |||
| pulls.tab_conversation = Conversation | |||
| pulls.tab_commits = Commits | |||
| pulls.tab_files = Files changed | |||
| pulls.reopen_to_merge = Please reopen this pull request to perform merge operation. | |||
| pulls.can_auto_merge_desc = You can perform auto-merge operation on this pull request. | |||
| pulls.cannot_auto_merge_desc = You can't perform auto-merge operation because there are conflicts between commits. | |||
| pulls.cannot_auto_merge_helper = Please use commond line tool to solve it. | |||
| pulls.merge_pull_request = Merge Pull Request | |||
| milestones.new = New Milestone | |||
| milestones.open_tab = %d Open | |||
| @@ -857,6 +857,7 @@ type PullRepo struct { | |||
| MergeBase string `xorm:"VARCHAR(40)"` | |||
| Type PullRequestType | |||
| CanAutoMerge bool | |||
| HasMerged bool | |||
| } | |||
| func (pr *PullRepo) AfterSet(colName string, _ xorm.Cell) { | |||
| @@ -7,6 +7,7 @@ package git | |||
| import ( | |||
| "bufio" | |||
| "container/list" | |||
| "net/http" | |||
| "strings" | |||
| ) | |||
| @@ -132,3 +133,30 @@ func (c *Commit) GetSubModules() (map[string]*SubModule, error) { | |||
| return c.submodules, nil | |||
| } | |||
| func isImageFile(data []byte) (string, bool) { | |||
| contentType := http.DetectContentType(data) | |||
| if strings.Index(contentType, "image/") != -1 { | |||
| return contentType, true | |||
| } | |||
| return contentType, false | |||
| } | |||
| func (c *Commit) IsImageFile(name string) bool { | |||
| blob, err := c.GetBlobByPath(name) | |||
| if err != nil { | |||
| return false | |||
| } | |||
| dataRc, err := blob.Data() | |||
| if err != nil { | |||
| return false | |||
| } | |||
| buf := make([]byte, 1024) | |||
| n, _ := dataRc.Read(buf) | |||
| if n > 0 { | |||
| buf = buf[:n] | |||
| } | |||
| _, isImage := isImageFile(buf) | |||
| return isImage | |||
| } | |||
| @@ -171,6 +171,12 @@ | |||
| box-shadow: none; | |||
| background-color: inherit; | |||
| } | |||
| .merge.box { | |||
| .avatar { | |||
| margin-left: 10px; | |||
| margin-top: 10px; | |||
| } | |||
| } | |||
| } | |||
| .comment-list { | |||
| &:before { | |||
| @@ -204,25 +204,6 @@ func Diff(ctx *middleware.Context) { | |||
| return | |||
| } | |||
| isImageFile := func(name string) bool { | |||
| blob, err := ctx.Repo.Commit.GetBlobByPath(name) | |||
| if err != nil { | |||
| return false | |||
| } | |||
| dataRc, err := blob.Data() | |||
| if err != nil { | |||
| return false | |||
| } | |||
| buf := make([]byte, 1024) | |||
| n, _ := dataRc.Read(buf) | |||
| if n > 0 { | |||
| buf = buf[:n] | |||
| } | |||
| _, isImage := base.IsImageFile(buf) | |||
| return isImage | |||
| } | |||
| parents := make([]string, commit.ParentCount()) | |||
| for i := 0; i < commit.ParentCount(); i++ { | |||
| sha, err := commit.ParentId(i) | |||
| @@ -235,7 +216,7 @@ func Diff(ctx *middleware.Context) { | |||
| ctx.Data["Username"] = userName | |||
| ctx.Data["Reponame"] = repoName | |||
| ctx.Data["IsImageFile"] = isImageFile | |||
| ctx.Data["IsImageFile"] = commit.IsImageFile | |||
| ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID) | |||
| ctx.Data["Commit"] = commit | |||
| ctx.Data["Author"] = models.ValidateCommitWithEmail(commit) | |||
| @@ -271,25 +252,6 @@ func CompareDiff(ctx *middleware.Context) { | |||
| return | |||
| } | |||
| isImageFile := func(name string) bool { | |||
| blob, err := commit.GetBlobByPath(name) | |||
| if err != nil { | |||
| return false | |||
| } | |||
| dataRc, err := blob.Data() | |||
| if err != nil { | |||
| return false | |||
| } | |||
| buf := make([]byte, 1024) | |||
| n, _ := dataRc.Read(buf) | |||
| if n > 0 { | |||
| buf = buf[:n] | |||
| } | |||
| _, isImage := base.IsImageFile(buf) | |||
| return isImage | |||
| } | |||
| commits, err := commit.CommitsBeforeUntil(beforeCommitID) | |||
| if err != nil { | |||
| ctx.Handle(500, "CommitsBeforeUntil", err) | |||
| @@ -304,7 +266,7 @@ func CompareDiff(ctx *middleware.Context) { | |||
| ctx.Data["AfterCommitID"] = afterCommitID | |||
| ctx.Data["Username"] = userName | |||
| ctx.Data["Reponame"] = repoName | |||
| ctx.Data["IsImageFile"] = isImageFile | |||
| ctx.Data["IsImageFile"] = commit.IsImageFile | |||
| ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID) + " · " + userName + "/" + repoName | |||
| ctx.Data["Commit"] = commit | |||
| ctx.Data["Diff"] = diff | |||
| @@ -18,7 +18,6 @@ import ( | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/auth" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/git" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/mailer" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| @@ -427,7 +426,6 @@ func UploadIssueAttachment(ctx *middleware.Context) { | |||
| } | |||
| func ViewIssue(ctx *middleware.Context) { | |||
| ctx.Data["PageIsIssueList"] = true | |||
| ctx.Data["RequireDropzone"] = true | |||
| renderAttachmentSettings(ctx) | |||
| @@ -451,6 +449,13 @@ func ViewIssue(ctx *middleware.Context) { | |||
| return | |||
| } | |||
| if issue.IsPull { | |||
| ctx.Data["PageIsPullList"] = true | |||
| ctx.Data["PageIsPullConversation"] = true | |||
| } else { | |||
| ctx.Data["PageIsIssueList"] = true | |||
| } | |||
| if err = issue.GetPoster(); err != nil { | |||
| ctx.Handle(500, "GetPoster", err) | |||
| return | |||
| @@ -461,29 +466,10 @@ func ViewIssue(ctx *middleware.Context) { | |||
| // Get more information if it's a pull request. | |||
| if issue.IsPull { | |||
| ctx.Data["HeadTarget"] = issue.PullRepo.HeadUserName + "/" + issue.PullRepo.HeadBarcnh | |||
| ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + issue.PullRepo.BaseBranch | |||
| headRepoPath, err := issue.PullRepo.HeadRepo.RepoPath() | |||
| if err != nil { | |||
| ctx.Handle(500, "PullRepo.HeadRepo.RepoPath", err) | |||
| return | |||
| } | |||
| headGitRepo, err := git.OpenRepository(headRepoPath) | |||
| if err != nil { | |||
| ctx.Handle(500, "OpenRepository", err) | |||
| return | |||
| } | |||
| prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name), | |||
| issue.PullRepo.BaseBranch, issue.PullRepo.HeadBarcnh) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetPullRequestInfo", err) | |||
| PrepareViewPullInfo(ctx, issue) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| ctx.Data["NumCommits"] = prInfo.Commits.Len() | |||
| ctx.Data["NumFiles"] = prInfo.NumFiles | |||
| } | |||
| // Metas. | |||
| @@ -23,6 +23,8 @@ const ( | |||
| FORK base.TplName = "repo/pulls/fork" | |||
| COMPARE_PULL base.TplName = "repo/pulls/compare" | |||
| PULLS base.TplName = "repo/pulls" | |||
| PULL_COMMITS base.TplName = "repo/pulls/commits" | |||
| PULL_FILES base.TplName = "repo/pulls/files" | |||
| ) | |||
| func getForkRepository(ctx *middleware.Context) *models.Repository { | |||
| @@ -131,7 +133,140 @@ func Pulls(ctx *middleware.Context) { | |||
| ctx.HTML(200, PULLS) | |||
| } | |||
| // func ViewPull | |||
| func checkPullInfo(ctx *middleware.Context) *models.Issue { | |||
| pull, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) | |||
| if err != nil { | |||
| if models.IsErrIssueNotExist(err) { | |||
| ctx.Handle(404, "GetIssueByIndex", err) | |||
| } else { | |||
| ctx.Handle(500, "GetIssueByIndex", err) | |||
| } | |||
| return nil | |||
| } | |||
| ctx.Data["Title"] = pull.Name | |||
| ctx.Data["Issue"] = pull | |||
| if !pull.IsPull { | |||
| ctx.Handle(404, "ViewPullCommits", nil) | |||
| return nil | |||
| } | |||
| if err = pull.GetPoster(); err != nil { | |||
| ctx.Handle(500, "GetPoster", err) | |||
| return nil | |||
| } | |||
| if ctx.IsSigned { | |||
| // Update issue-user. | |||
| if err = pull.ReadBy(ctx.User.Id); err != nil { | |||
| ctx.Handle(500, "ReadBy", err) | |||
| return nil | |||
| } | |||
| } | |||
| return pull | |||
| } | |||
| func PrepareViewPullInfo(ctx *middleware.Context, pull *models.Issue) *git.PullRequestInfo { | |||
| repo := ctx.Repo.Repository | |||
| ctx.Data["HeadTarget"] = pull.PullRepo.HeadUserName + "/" + pull.PullRepo.HeadBarcnh | |||
| ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.PullRepo.BaseBranch | |||
| headRepoPath, err := pull.PullRepo.HeadRepo.RepoPath() | |||
| if err != nil { | |||
| ctx.Handle(500, "PullRepo.HeadRepo.RepoPath", err) | |||
| return nil | |||
| } | |||
| headGitRepo, err := git.OpenRepository(headRepoPath) | |||
| if err != nil { | |||
| ctx.Handle(500, "OpenRepository", err) | |||
| return nil | |||
| } | |||
| prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name), | |||
| pull.PullRepo.BaseBranch, pull.PullRepo.HeadBarcnh) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetPullRequestInfo", err) | |||
| return nil | |||
| } | |||
| ctx.Data["NumCommits"] = prInfo.Commits.Len() | |||
| ctx.Data["NumFiles"] = prInfo.NumFiles | |||
| return prInfo | |||
| } | |||
| func ViewPullCommits(ctx *middleware.Context) { | |||
| ctx.Data["PageIsPullCommits"] = true | |||
| pull := checkPullInfo(ctx) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| prInfo := PrepareViewPullInfo(ctx, pull) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| prInfo.Commits = models.ValidateCommitsWithEmails(prInfo.Commits) | |||
| ctx.Data["Commits"] = prInfo.Commits | |||
| ctx.HTML(200, PULL_COMMITS) | |||
| } | |||
| func ViewPullFiles(ctx *middleware.Context) { | |||
| ctx.Data["PageIsPullFiles"] = true | |||
| pull := checkPullInfo(ctx) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| prInfo := PrepareViewPullInfo(ctx, pull) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| _ = prInfo | |||
| headRepoPath := models.RepoPath(pull.PullRepo.HeadUserName, pull.PullRepo.HeadRepo.Name) | |||
| headGitRepo, err := git.OpenRepository(headRepoPath) | |||
| if err != nil { | |||
| ctx.Handle(500, "OpenRepository", err) | |||
| return | |||
| } | |||
| headCommitID, err := headGitRepo.GetCommitIdOfBranch(pull.PullRepo.HeadBarcnh) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetCommitIdOfBranch", err) | |||
| return | |||
| } | |||
| diff, err := models.GetDiffRange(headRepoPath, | |||
| prInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetDiffRange", err) | |||
| return | |||
| } | |||
| ctx.Data["Diff"] = diff | |||
| ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 | |||
| headCommit, err := headGitRepo.GetCommit(headCommitID) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetCommit", err) | |||
| return | |||
| } | |||
| headTarget := path.Join(pull.PullRepo.HeadUserName, pull.PullRepo.HeadRepo.Name) | |||
| ctx.Data["Username"] = pull.PullRepo.HeadUserName | |||
| ctx.Data["Reponame"] = pull.PullRepo.HeadRepo.Name | |||
| ctx.Data["IsImageFile"] = headCommit.IsImageFile | |||
| ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", headCommitID) | |||
| ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", prInfo.MergeBase) | |||
| ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", headCommitID) | |||
| ctx.HTML(200, PULL_FILES) | |||
| } | |||
| func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) { | |||
| // Get compare branch information. | |||
| @@ -248,34 +383,18 @@ func PrepareCompareDiff( | |||
| ctx.Handle(500, "GetCommit", err) | |||
| return | |||
| } | |||
| isImageFile := func(name string) bool { | |||
| blob, err := headCommit.GetBlobByPath(name) | |||
| if err != nil { | |||
| return false | |||
| } | |||
| dataRc, err := blob.Data() | |||
| if err != nil { | |||
| return false | |||
| } | |||
| buf := make([]byte, 1024) | |||
| n, _ := dataRc.Read(buf) | |||
| if n > 0 { | |||
| buf = buf[:n] | |||
| } | |||
| _, isImage := base.IsImageFile(buf) | |||
| return isImage | |||
| } | |||
| prInfo.Commits = models.ValidateCommitsWithEmails(prInfo.Commits) | |||
| ctx.Data["Commits"] = prInfo.Commits | |||
| ctx.Data["CommitCount"] = prInfo.Commits.Len() | |||
| ctx.Data["Username"] = headUser.Name | |||
| ctx.Data["Reponame"] = headRepo.Name | |||
| ctx.Data["IsImageFile"] = isImageFile | |||
| ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headUser.Name, repo.Name, "src", headCommitID) | |||
| ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headUser.Name, repo.Name, "src", prInfo.MergeBase) | |||
| ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headUser.Name, repo.Name, "raw", headCommitID) | |||
| ctx.Data["IsImageFile"] = headCommit.IsImageFile | |||
| headTarget := path.Join(headUser.Name, repo.Name) | |||
| ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", headCommitID) | |||
| ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", prInfo.MergeBase) | |||
| ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", headCommitID) | |||
| } | |||
| func CompareAndPullRequest(ctx *middleware.Context) { | |||
| @@ -11,23 +11,7 @@ | |||
| <div class="ui divider"></div> | |||
| {{if .Issue.IsPull}} | |||
| {{template "repo/issue/view_title" .}} | |||
| <div class="ui top attached pull tabular menu"> | |||
| <a class="item active" href="{{.RepoLink}}/pulls/{{.Issue.Index}}"> | |||
| <span class="octicon octicon-comment-discussion"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_conversation"}} | |||
| <span class="ui label">{{.Issue.NumComments}}</span> | |||
| </a> | |||
| <a class="item" href="{{.RepoLink}}/pulls/{{.Issue.Index}}/commits"> | |||
| <span class="octicon octicon-git-commit"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_commits"}} | |||
| <span class="ui label">{{.NumCommits}}</span> | |||
| </a> | |||
| <a class="item" href="{{.RepoLink}}/pulls/{{.Issue.Index}}/files"> | |||
| <span class="octicon octicon-diff"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_files"}} | |||
| <span class="ui label">{{.NumFiles}}</span> | |||
| </a> | |||
| </div> | |||
| {{template "repo/pulls/tab_menu" .}} | |||
| <div class="ui bottom attached tab pull segment active" data-tab="request-{{.ID}}"> | |||
| {{template "repo/issue/view_content" .}} | |||
| </div> | |||
| @@ -129,6 +129,43 @@ | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| {{if .Issue.IsPull}} | |||
| <div class="comment merge box"> | |||
| <a class="avatar text {{if .Issue.IsClosed}}grey{{else if .Issue.PullRepo.CanAutoMerge}}green{{else}}red{{end}}"> | |||
| <span class="mega-octicon octicon-git-merge"></span> | |||
| </a> | |||
| <div class="content"> | |||
| <div class="ui merge segment"> | |||
| {{if .Issue.IsClosed}} | |||
| <div class="item text grey"> | |||
| {{$.i18n.Tr "repo.pulls.reopen_to_merge"}} | |||
| </div> | |||
| {{else if .Issue.PullRepo.CanAutoMerge}} | |||
| <div class="item text green"> | |||
| <span class="octicon octicon-check"></span> | |||
| {{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}} | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| <div> | |||
| <button class="ui green button"> | |||
| <span class="octicon octicon-git-merge"></span> {{$.i18n.Tr "repo.pulls.merge_pull_request"}} | |||
| </button> | |||
| </div> | |||
| {{else}} | |||
| <div class="item text red"> | |||
| <span class="octicon octicon-x"></span> | |||
| {{$.i18n.Tr "repo.pulls.cannot_auto_merge_desc"}} | |||
| </div> | |||
| <div class="item text grey"> | |||
| <span class="octicon octicon-info"></span> | |||
| {{$.i18n.Tr "repo.pulls.cannot_auto_merge_helper"}} | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{if .IsSigned}} | |||
| @@ -0,0 +1,19 @@ | |||
| {{template "base/head" .}} | |||
| <div class="repository view issue pull commits"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <div class="navbar"> | |||
| {{template "repo/issue/navbar" .}} | |||
| <div class="ui right"> | |||
| <a class="ui green button" href="{{$.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| {{template "repo/issue/view_title" .}} | |||
| {{template "repo/pulls/tab_menu" .}} | |||
| <div class="ui bottom attached tab pull segment active"> | |||
| {{template "repo/commits_table" .}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -1,5 +1,5 @@ | |||
| {{template "base/head" .}} | |||
| <div class="repository compare pull"> | |||
| <div class="repository compare pull diff"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <div class="sixteen wide column page grid"> | |||
| @@ -11,13 +11,13 @@ | |||
| <span class="octicon octicon-git-compare"></span> | |||
| <div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}"> | |||
| <div class="ui basic small button"> | |||
| <span class="text">base: {{$.BaseBranch}}</span> | |||
| <span class="text">{{.i18n.Tr "repo.pulls.compare_base"}}: {{$.BaseBranch}}</span> | |||
| <i class="dropdown icon"></i> | |||
| </div> | |||
| <div class="menu"> | |||
| <div class="ui icon search input"> | |||
| <i class="filter icon"></i> | |||
| <input name="search" placeholder="Filter branch..."> | |||
| <input name="search" placeholder="{{.i18n.Tr "repo.pulls.filter_branch"}}..."> | |||
| </div> | |||
| <div class="scrolling menu"> | |||
| {{range .Branches}} | |||
| @@ -29,13 +29,13 @@ | |||
| ... | |||
| <div class="ui floating filter dropdown"> | |||
| <div class="ui basic small button"> | |||
| <span class="text">compare: {{$.HeadBranch}}</span> | |||
| <span class="text">{{.i18n.Tr "repo.pulls.compare_compare"}}: {{$.HeadBranch}}</span> | |||
| <i class="dropdown icon"></i> | |||
| </div> | |||
| <div class="menu"> | |||
| <div class="ui icon search input"> | |||
| <i class="filter icon"></i> | |||
| <input name="search" placeholder="Filter branch..."> | |||
| <input name="search" placeholder="{{.i18n.Tr "repo.pulls.filter_branch"}}..."> | |||
| </div> | |||
| <div class="scrolling menu"> | |||
| {{range .HeadBranches}} | |||
| @@ -0,0 +1,19 @@ | |||
| {{template "base/head" .}} | |||
| <div class="repository view issue pull files diff"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <div class="navbar"> | |||
| {{template "repo/issue/navbar" .}} | |||
| <div class="ui right"> | |||
| <a class="ui green button" href="{{$.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| {{template "repo/issue/view_title" .}} | |||
| {{template "repo/pulls/tab_menu" .}} | |||
| <div class="ui bottom attached tab pull segment active"> | |||
| {{template "repo/diff_box" .}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -0,0 +1,17 @@ | |||
| <div class="ui top attached pull tabular menu"> | |||
| <a class="item {{if .PageIsPullConversation}}active{{end}}" href="{{.RepoLink}}/pulls/{{.Issue.Index}}"> | |||
| <span class="octicon octicon-comment-discussion"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_conversation"}} | |||
| <span class="ui label">{{.Issue.NumComments}}</span> | |||
| </a> | |||
| <a class="item {{if .PageIsPullCommits}}active{{end}}" href="{{.RepoLink}}/pulls/{{.Issue.Index}}/commits"> | |||
| <span class="octicon octicon-git-commit"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_commits"}} | |||
| <span class="ui label">{{.NumCommits}}</span> | |||
| </a> | |||
| <a class="item {{if .PageIsPullFiles}}active{{end}}" href="{{.RepoLink}}/pulls/{{.Issue.Index}}/files"> | |||
| <span class="octicon octicon-diff"></span> | |||
| {{$.i18n.Tr "repo.pulls.tab_files"}} | |||
| <span class="ui label">{{.NumFiles}}</span> | |||
| </a> | |||
| </div> | |||