mirror of
https://github.com/gogs/gogs.git
synced 2025-12-17 12:03:16 +01:00
repo/branches: overview and all (#2310)
This commit is contained in:
@@ -575,8 +575,11 @@ func runWeb(ctx *cli.Context) error {
|
|||||||
m.Get("/milestones", repo.Milestones)
|
m.Get("/milestones", repo.Milestones)
|
||||||
}, context.RepoRef())
|
}, context.RepoRef())
|
||||||
|
|
||||||
// m.Get("/branches", repo.Branches)
|
m.Group("/branches", func() {
|
||||||
m.Post("/branches/delete/*", reqSignIn, reqRepoWriter, repo.DeleteBranchPost)
|
m.Get("", repo.Branches)
|
||||||
|
m.Get("/all", repo.AllBranches)
|
||||||
|
m.Post("/delete/*", reqSignIn, reqRepoWriter, repo.DeleteBranchPost)
|
||||||
|
})
|
||||||
|
|
||||||
m.Group("/wiki", func() {
|
m.Group("/wiki", func() {
|
||||||
m.Get("/?:page", repo.Wiki)
|
m.Get("/?:page", repo.Wiki)
|
||||||
|
|||||||
@@ -426,8 +426,9 @@ issues = Issues
|
|||||||
pulls = Pull Requests
|
pulls = Pull Requests
|
||||||
labels = Labels
|
labels = Labels
|
||||||
milestones = Milestones
|
milestones = Milestones
|
||||||
commits = commits
|
commits = Commits
|
||||||
releases = releases
|
git_branches = Branches
|
||||||
|
releases = Releases
|
||||||
file_raw = Raw
|
file_raw = Raw
|
||||||
file_history = History
|
file_history = History
|
||||||
file_view_raw = View Raw
|
file_view_raw = View Raw
|
||||||
@@ -435,6 +436,13 @@ file_permalink = Permalink
|
|||||||
file_too_large = This file is too large to be shown
|
file_too_large = This file is too large to be shown
|
||||||
video_not_supported_in_browser = Your browser doesn't support HTML5 video tag.
|
video_not_supported_in_browser = Your browser doesn't support HTML5 video tag.
|
||||||
|
|
||||||
|
branches.overview = Overview
|
||||||
|
branches.active_branches = Active Branches
|
||||||
|
branches.stale_branches = Stale Branches
|
||||||
|
branches.all = All Branches
|
||||||
|
branches.updated_by = Updated %[1]s by %[2]s
|
||||||
|
branches.change_default_branch = Change Default Branch
|
||||||
|
|
||||||
editor.new_file = New file
|
editor.new_file = New file
|
||||||
editor.upload_file = Upload file
|
editor.upload_file = Upload file
|
||||||
editor.edit_file = Edit file
|
editor.edit_file = Edit file
|
||||||
|
|||||||
2
gogs.go
2
gogs.go
@@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/gogits/gogs/modules/setting"
|
"github.com/gogits/gogs/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VER = "0.10.14.0310"
|
const APP_VER = "0.10.15.0311"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
setting.AppVer = APP_VER
|
setting.AppVer = APP_VER
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Branch struct {
|
type Branch struct {
|
||||||
Path string
|
RepoPath string
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
|
IsProtected bool
|
||||||
|
Commit *git.Commit
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBranchesByPath(path string) ([]*Branch, error) {
|
func GetBranchesByPath(path string) ([]*Branch, error) {
|
||||||
@@ -33,8 +36,8 @@ func GetBranchesByPath(path string) ([]*Branch, error) {
|
|||||||
branches := make([]*Branch, len(brs))
|
branches := make([]*Branch, len(brs))
|
||||||
for i := range brs {
|
for i := range brs {
|
||||||
branches[i] = &Branch{
|
branches[i] = &Branch{
|
||||||
Path: path,
|
RepoPath: path,
|
||||||
Name: brs[i],
|
Name: brs[i],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return branches, nil
|
return branches, nil
|
||||||
@@ -45,8 +48,8 @@ func (repo *Repository) GetBranch(br string) (*Branch, error) {
|
|||||||
return nil, ErrBranchNotExist{br}
|
return nil, ErrBranchNotExist{br}
|
||||||
}
|
}
|
||||||
return &Branch{
|
return &Branch{
|
||||||
Path: repo.RepoPath(),
|
RepoPath: repo.RepoPath(),
|
||||||
Name: br,
|
Name: br,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ func (repo *Repository) GetBranches() ([]*Branch, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (br *Branch) GetCommit() (*git.Commit, error) {
|
func (br *Branch) GetCommit() (*git.Commit, error) {
|
||||||
gitRepo, err := git.OpenRepository(br.Path)
|
gitRepo, err := git.OpenRepository(br.RepoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1227,6 +1227,33 @@ footer .ui.language .menu {
|
|||||||
right: 0!important;
|
right: 0!important;
|
||||||
left: auto!important;
|
left: auto!important;
|
||||||
}
|
}
|
||||||
|
.repository.branches .ui.list {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item .column {
|
||||||
|
padding: 5px 15px;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item .column .octicon {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item .column code {
|
||||||
|
padding: 4px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item .column .ui.text:not(i) {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.repository.branches .ui.list > .item .column .ui.button {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
.repository.file.list #repo-desc {
|
.repository.file.list #repo-desc {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
@@ -1249,7 +1276,7 @@ footer .ui.language .menu {
|
|||||||
}
|
}
|
||||||
.repository.file.list #git-stats .list .item {
|
.repository.file.list #git-stats .list .item {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
width: 50%;
|
width: 33.33%;
|
||||||
}
|
}
|
||||||
.repository.file.list #git-stats .list .item .text b {
|
.repository.file.list #git-stats .list .item .text b {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|||||||
@@ -150,6 +150,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.branches {
|
||||||
|
.ui.list {
|
||||||
|
padding: 0;
|
||||||
|
>.item {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 2em;
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
}
|
||||||
|
.column {
|
||||||
|
padding: 5px 15px;
|
||||||
|
.octicon {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
padding: 4px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.ui.text:not(i) {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.ui.button {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.file.list {
|
&.file.list {
|
||||||
#repo-desc {
|
#repo-desc {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
@@ -174,7 +204,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
.item {
|
.item {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
width: 50%;
|
width: 33.33%;
|
||||||
.text b {
|
.text b {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,33 +5,104 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
log "gopkg.in/clog.v1"
|
log "gopkg.in/clog.v1"
|
||||||
|
|
||||||
"github.com/gogits/git-module"
|
"github.com/gogits/git-module"
|
||||||
|
|
||||||
|
"github.com/gogits/gogs/models"
|
||||||
"github.com/gogits/gogs/modules/base"
|
"github.com/gogits/gogs/modules/base"
|
||||||
"github.com/gogits/gogs/modules/context"
|
"github.com/gogits/gogs/modules/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BRANCH base.TplName = "repo/branch"
|
BRANCHES_OVERVIEW base.TplName = "repo/branches/overview"
|
||||||
|
BRANCHES_ALL base.TplName = "repo/branches/all"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Branches(ctx *context.Context) {
|
type Branch struct {
|
||||||
ctx.Data["Title"] = "Branches"
|
Name string
|
||||||
ctx.Data["IsRepoToolbarBranches"] = true
|
Commit *git.Commit
|
||||||
|
IsProtected bool
|
||||||
|
}
|
||||||
|
|
||||||
brs, err := ctx.Repo.GitRepo.GetBranches()
|
func loadBranches(ctx *context.Context) []*Branch {
|
||||||
|
rawBranches, err := ctx.Repo.Repository.GetBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "repo.Branches(GetBranches)", err)
|
ctx.Handle(500, "GetBranches", err)
|
||||||
return
|
return nil
|
||||||
} else if len(brs) == 0 {
|
}
|
||||||
ctx.Handle(404, "repo.Branches(GetBranches)", nil)
|
|
||||||
|
protectBranches, err := models.GetProtectBranchesByRepoID(ctx.Repo.Repository.ID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "GetProtectBranchesByRepoID", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
branches := make([]*Branch, len(rawBranches))
|
||||||
|
for i := range rawBranches {
|
||||||
|
commit, err := rawBranches[i].GetCommit()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "GetCommit", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
branches[i] = &Branch{
|
||||||
|
Name: rawBranches[i].Name,
|
||||||
|
Commit: commit,
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := range protectBranches {
|
||||||
|
if branches[i].Name == protectBranches[j].Name {
|
||||||
|
branches[i].IsProtected = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
func Branches(ctx *context.Context) {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("repo.git_branches")
|
||||||
|
ctx.Data["PageIsBranchesOverview"] = true
|
||||||
|
|
||||||
|
branches := loadBranches(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Branches"] = brs
|
now := time.Now()
|
||||||
ctx.HTML(200, BRANCH)
|
activeBranches := make([]*Branch, 0, 3)
|
||||||
|
staleBranches := make([]*Branch, 0, 3)
|
||||||
|
for i := range branches {
|
||||||
|
switch {
|
||||||
|
case branches[i].Name == ctx.Repo.BranchName:
|
||||||
|
ctx.Data["DefaultBranch"] = branches[i]
|
||||||
|
case branches[i].Commit.Committer.When.Add(30 * 24 * time.Hour).After(now): // 30 days
|
||||||
|
activeBranches = append(activeBranches, branches[i])
|
||||||
|
case branches[i].Commit.Committer.When.Add(3 * 30 * 24 * time.Hour).Before(now): // 90 days
|
||||||
|
staleBranches = append(staleBranches, branches[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Data["ActiveBranches"] = activeBranches
|
||||||
|
ctx.Data["StaleBranches"] = staleBranches
|
||||||
|
ctx.HTML(200, BRANCHES_OVERVIEW)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllBranches(ctx *context.Context) {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("repo.git_branches")
|
||||||
|
ctx.Data["PageIsBranchesAll"] = true
|
||||||
|
|
||||||
|
branches := loadBranches(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Branches"] = branches
|
||||||
|
|
||||||
|
ctx.HTML(200, BRANCHES_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteBranchPost(ctx *context.Context) {
|
func DeleteBranchPost(ctx *context.Context) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0.10.14.0310
|
0.10.15.0311
|
||||||
31
templates/repo/branches/all.tmpl
Normal file
31
templates/repo/branches/all.tmpl
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="repository branches all">
|
||||||
|
{{template "repo/header" .}}
|
||||||
|
<div class="ui container">
|
||||||
|
<div class="navbar">
|
||||||
|
{{template "repo/branches/navbar" .}}
|
||||||
|
</div>
|
||||||
|
<div class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.branches.all"}}
|
||||||
|
</div>
|
||||||
|
<div class="ui attached segment list">
|
||||||
|
{{range .Branches}}
|
||||||
|
<div class="item ui grid">
|
||||||
|
<div class="ui eleven wide column">
|
||||||
|
{{if .IsProtected}}<i class="octicon octicon-shield"></i> {{end}}<a class="markdown" href="{{$.RepoLink}}/src/{{.Name}}"><code>{{.Name}}</code></a>
|
||||||
|
{{$timeSince := TimeSince .Commit.Committer.When $.Lang}}
|
||||||
|
<span class="ui text light grey">{{$.i18n.Tr "repo.branches.updated_by" $timeSince .Commit.Committer.Name | Safe}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ui four wide column">
|
||||||
|
{{if eq $.BranchName .Name}}
|
||||||
|
<a class="ui basic blue button" href="{{$.RepoLink}}/settings/branches">{{$.i18n.Tr "repo.branches.change_default_branch"}}</a>
|
||||||
|
{{else}}
|
||||||
|
<a class="ui basic button" href="{{$.RepoLink}}/compare/{{$.DefaultBranch.Name}}...{{.Name}}"><i class="octicon octicon-git-pull-request"></i> {{$.i18n.Tr "repo.pulls.new"}}</a>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
||||||
4
templates/repo/branches/navbar.tmpl
Normal file
4
templates/repo/branches/navbar.tmpl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="ui compact small menu">
|
||||||
|
<a class="{{if .PageIsBranchesOverview}}active{{end}} item" href="{{.RepoLink}}/branches">{{.i18n.Tr "repo.branches.overview"}}</a>
|
||||||
|
<a class="{{if .PageIsBranchesAll}}active{{end}} item" href="{{.RepoLink}}/branches/all">{{.i18n.Tr "repo.branches.all"}}</a>
|
||||||
|
</div>
|
||||||
62
templates/repo/branches/overview.tmpl
Normal file
62
templates/repo/branches/overview.tmpl
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="repository branches overview">
|
||||||
|
{{template "repo/header" .}}
|
||||||
|
<div class="ui container">
|
||||||
|
<div class="navbar">
|
||||||
|
{{template "repo/branches/navbar" .}}
|
||||||
|
</div>
|
||||||
|
<div class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.settings.default_branch"}}
|
||||||
|
</div>
|
||||||
|
<div class="ui attached segment list">
|
||||||
|
<div class="item ui grid">
|
||||||
|
<div class="ui eleven wide column">
|
||||||
|
{{if .DefaultBranch.IsProtected}}<i class="octicon octicon-shield"></i> {{end}}<a class="markdown" href="{{$.RepoLink}}/src/{{.DefaultBranch.Name}}"><code>{{.DefaultBranch.Name}}</code></a>
|
||||||
|
{{$timeSince := TimeSince .DefaultBranch.Commit.Committer.When $.Lang}}
|
||||||
|
<span class="ui text light grey">{{$.i18n.Tr "repo.branches.updated_by" $timeSince .DefaultBranch.Commit.Committer.Name | Safe}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ui four wide column">
|
||||||
|
<a class="ui basic blue button" href="{{$.RepoLink}}/settings/branches">{{.i18n.Tr "repo.branches.change_default_branch"}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if .ActiveBranches}}
|
||||||
|
<div class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.branches.active_branches"}}
|
||||||
|
</div>
|
||||||
|
<div class="ui attached segment list">
|
||||||
|
{{range .ActiveBranches}}
|
||||||
|
<div class="item ui grid">
|
||||||
|
<div class="ui eleven wide column">
|
||||||
|
{{if .IsProtected}}<i class="octicon octicon-shield"></i> {{end}}<a class="markdown" href="{{$.RepoLink}}/src/{{.Name}}"><code>{{.Name}}</code></a>
|
||||||
|
{{$timeSince := TimeSince .Commit.Committer.When $.Lang}}
|
||||||
|
<span class="ui text light grey">{{$.i18n.Tr "repo.branches.updated_by" $timeSince .Commit.Committer.Name | Safe}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ui four wide column">
|
||||||
|
<a class="ui basic button" href="{{$.RepoLink}}/compare/{{$.DefaultBranch.Name}}...{{.Name}}"><i class="octicon octicon-git-pull-request"></i> {{$.i18n.Tr "repo.pulls.new"}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .StaleBranches}}
|
||||||
|
<div class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.branches.stale_branches"}}
|
||||||
|
</div>
|
||||||
|
<div class="ui attached segment list">
|
||||||
|
{{range .StaleBranches}}
|
||||||
|
<div class="item ui grid">
|
||||||
|
<div class="ui fourteen wide column">
|
||||||
|
{{if .IsProtected}}<i class="octicon octicon-shield"></i> {{end}}<a class="markdown" href="{{$.RepoLink}}/src/{{.Name}}"><code>{{.Name}}</code></a>
|
||||||
|
{{$timeSince := TimeSince .Commit.Committer.When $.Lang}}
|
||||||
|
<span class="ui text light grey">{{$.i18n.Tr "repo.branches.updated_by" $timeSince .Commit.Committer.Name | Safe}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
||||||
@@ -14,6 +14,9 @@
|
|||||||
<a href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}"><span class="ui text black"><i class="octicon octicon-history"></i> <b>{{.CommitsCount}}</b> {{.i18n.Tr "repo.commits"}}</span> </a>
|
<a href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}"><span class="ui text black"><i class="octicon octicon-history"></i> <b>{{.CommitsCount}}</b> {{.i18n.Tr "repo.commits"}}</span> </a>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
|
<a href="{{.RepoLink}}/branches"><span class="ui text black"><i class="octicon octicon-git-branch"></i><b>{{.BrancheCount}}</b> {{.i18n.Tr "repo.git_branches"}}</span> </a>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
<a href="{{.RepoLink}}/releases"><span class="ui text black"><i class="octicon octicon-tag"></i> <b>{{.Repository.NumTags}}</b> {{.i18n.Tr "repo.releases"}}</span> </a>
|
<a href="{{.RepoLink}}/releases"><span class="ui text black"><i class="octicon octicon-tag"></i> <b>{{.Repository.NumTags}}</b> {{.i18n.Tr "repo.releases"}}</span> </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user