Page: Commits and fix #249
This commit is contained in:
parent
93ee0838eb
commit
5bbeeb0f1b
13 changed files with 160 additions and 40 deletions
|
@ -258,6 +258,15 @@ issues = Issues
|
||||||
commits = Commits
|
commits = Commits
|
||||||
releases = Releases
|
releases = Releases
|
||||||
|
|
||||||
|
commits.commits = Commits
|
||||||
|
commits.search = Search commits
|
||||||
|
commits.find = Find
|
||||||
|
commits.author = Author
|
||||||
|
commits.message = Message
|
||||||
|
commits.date = Date
|
||||||
|
commits.older = Older
|
||||||
|
commits.newer = Newer
|
||||||
|
|
||||||
settings = Settings
|
settings = Settings
|
||||||
settings.options = Options
|
settings.options = Options
|
||||||
settings.collaboration = Collaboration
|
settings.collaboration = Collaboration
|
||||||
|
|
|
@ -258,6 +258,15 @@ issues = 工单管理
|
||||||
commits = 提交历史
|
commits = 提交历史
|
||||||
releases = 版本发布
|
releases = 版本发布
|
||||||
|
|
||||||
|
commits.commits = 次代码提交
|
||||||
|
commits.search = 搜索提交历史
|
||||||
|
commits.find = 查找
|
||||||
|
commits.author = 作者
|
||||||
|
commits.message = 备注
|
||||||
|
commits.date = 提交日期
|
||||||
|
commits.older = 更旧的提交
|
||||||
|
commits.newer = 更新的提交
|
||||||
|
|
||||||
settings = 仓库设置
|
settings = 仓库设置
|
||||||
settings.options = 基本设置
|
settings.options = 基本设置
|
||||||
settings.collaboration = 管理协作者
|
settings.collaboration = 管理协作者
|
||||||
|
|
|
@ -1081,6 +1081,13 @@ func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// __ __ __ .__
|
||||||
|
// / \ / \_____ _/ |_ ____ | |__
|
||||||
|
// \ \/\/ /\__ \\ __\/ ___\| | \
|
||||||
|
// \ / / __ \| | \ \___| Y \
|
||||||
|
// \__/\ / (____ /__| \___ >___| /
|
||||||
|
// \/ \/ \/ \/
|
||||||
|
|
||||||
// Watch is connection request for receiving repository notifycation.
|
// Watch is connection request for receiving repository notifycation.
|
||||||
type Watch struct {
|
type Watch struct {
|
||||||
Id int64
|
Id int64
|
||||||
|
@ -1151,6 +1158,13 @@ func NotifyWatchers(act *Action) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _________ __
|
||||||
|
// / _____// |______ _______
|
||||||
|
// \_____ \\ __\__ \\_ __ \
|
||||||
|
// / \| | / __ \| | \/
|
||||||
|
// /_______ /|__| (____ /__|
|
||||||
|
// \/ \/
|
||||||
|
|
||||||
type Star struct {
|
type Star struct {
|
||||||
Id int64
|
Id int64
|
||||||
Uid int64 `xorm:"UNIQUE(s)"`
|
Uid int64 `xorm:"UNIQUE(s)"`
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"container/list"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -513,6 +514,34 @@ func GetUserIdsByNames(names []string) []int64 {
|
||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserCommit represtns a commit with validation of user.
|
||||||
|
type UserCommit struct {
|
||||||
|
UserName string
|
||||||
|
*git.Commit
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidCommitsWithEmails checks if authors' e-mails of commits are correcponding to users.
|
||||||
|
func ValidCommitsWithEmails(oldCommits *list.List) *list.List {
|
||||||
|
newCommits := list.New()
|
||||||
|
e := oldCommits.Front()
|
||||||
|
for e != nil {
|
||||||
|
c := e.Value.(*git.Commit)
|
||||||
|
|
||||||
|
uname := ""
|
||||||
|
u, err := GetUserByEmail(c.Author.Email)
|
||||||
|
if err == nil {
|
||||||
|
uname = u.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
newCommits.PushBack(UserCommit{
|
||||||
|
UserName: uname,
|
||||||
|
Commit: c,
|
||||||
|
})
|
||||||
|
e = e.Next()
|
||||||
|
}
|
||||||
|
return newCommits
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserByEmail returns the user object by given e-mail if exists.
|
// GetUserByEmail returns the user object by given e-mail if exists.
|
||||||
func GetUserByEmail(email string) (*User, error) {
|
func GetUserByEmail(email string) (*User, error) {
|
||||||
if len(email) == 0 {
|
if len(email) == 0 {
|
||||||
|
|
|
@ -20,6 +20,11 @@ img.avatar-16 {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
img.avatar-20 {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
img.avatar-24 {
|
img.avatar-24 {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
@ -1446,6 +1451,27 @@ The register and sign-in page style
|
||||||
width: 100%;
|
width: 100%;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
#commits-list {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.commit-list th {
|
||||||
|
background-color: #FFF;
|
||||||
|
line-height: 28px !important;
|
||||||
|
}
|
||||||
|
.commit-list .date {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.commit-list .author {
|
||||||
|
padding-left: 20px;
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
|
.commit-list .author img {
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
.commit-list .sha a {
|
||||||
|
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
#admin-wrapper,
|
#admin-wrapper,
|
||||||
#setting-wrapper {
|
#setting-wrapper {
|
||||||
padding-bottom: 100px;
|
padding-bottom: 100px;
|
||||||
|
|
|
@ -732,6 +732,10 @@ ul.menu-radius > li:last-child > a {
|
||||||
.label-green {
|
.label-green {
|
||||||
background-color: #65ad4e;
|
background-color: #65ad4e;
|
||||||
}
|
}
|
||||||
|
.label-green:hover {
|
||||||
|
background-color: #71bf57;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
.label-orange {
|
.label-orange {
|
||||||
background-color: #df7514;
|
background-color: #df7514;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,11 @@ img.avatar-16 {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
img.avatar-20 {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
img.avatar-24 {
|
img.avatar-24 {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
#repo-header {
|
#repo-header {
|
||||||
height: 69px;
|
height: 69px;
|
||||||
border-bottom: 1px solid@repoHeaderBorderColor;
|
border-bottom: 1px solid@repoHeaderBorderColor;
|
||||||
|
|
||||||
background-color: @repoHeaderBgColor;
|
background-color: @repoHeaderBgColor;
|
||||||
|
|
||||||
}
|
}
|
||||||
#repo-header-name {
|
#repo-header-name {
|
||||||
line-height: 66px;
|
line-height: 66px;
|
||||||
|
@ -495,3 +493,26 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
#commits-list {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
.commit-list {
|
||||||
|
th {
|
||||||
|
background-color: #FFF;
|
||||||
|
line-height: 28px !important;
|
||||||
|
}
|
||||||
|
.date {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.author {
|
||||||
|
padding-left: 20px;
|
||||||
|
min-width: 180px;
|
||||||
|
img {
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sha a {
|
||||||
|
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,11 +16,13 @@
|
||||||
.label-gray {
|
.label-gray {
|
||||||
background-color: @labelGrayColor;
|
background-color: @labelGrayColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-green {
|
.label-green {
|
||||||
background-color: @labelGreenColor;
|
background-color: @labelGreenColor;
|
||||||
|
&:hover {
|
||||||
|
background-color: @btnHoverGreenColor;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-orange {
|
.label-orange {
|
||||||
background-color: @labelOrangeColor;
|
background-color: @labelOrangeColor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,12 +56,14 @@ func Commits(ctx *middleware.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both `git log branchName` and `git log commitId` work.
|
// Both `git log branchName` and `git log commitId` work.
|
||||||
ctx.Data["Commits"], err = ctx.Repo.Commit.CommitsByRange(page)
|
commits, err := ctx.Repo.Commit.CommitsByRange(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "CommitsByRange", err)
|
ctx.Handle(500, "CommitsByRange", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
commits = models.ValidCommitsWithEmails(commits)
|
||||||
|
|
||||||
|
ctx.Data["Commits"] = commits
|
||||||
ctx.Data["Username"] = userName
|
ctx.Data["Username"] = userName
|
||||||
ctx.Data["Reponame"] = repoName
|
ctx.Data["Reponame"] = repoName
|
||||||
ctx.Data["CommitCount"] = commitsCount
|
ctx.Data["CommitCount"] = commitsCount
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
</table>
|
</table>
|
||||||
{{if or .LastPageNum .NextPageNum}}
|
{{if or .LastPageNum .NextPageNum}}
|
||||||
<ul class="pagination">
|
<ul class="pagination">
|
||||||
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« Prev.</a></li>{{end}}
|
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« {{.i18n.Tr "admin.prev"}}</a></li>{{end}}
|
||||||
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» Next</a></li>{{end}}
|
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» {{.i18n.Tr "admin.next"}}</a></li>{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{{template "base/head" .}}
|
{{template "ng/base/head" .}}
|
||||||
{{template "base/navbar" .}}
|
{{template "ng/base/header" .}}
|
||||||
{{template "repo/nav" .}}
|
<div id="repo-wrapper">
|
||||||
{{template "repo/toolbar" .}}
|
{{template "repo/header" .}}
|
||||||
<div id="body" class="container">
|
<div class="container clear">
|
||||||
{{template "repo/commits_table" .}}
|
{{template "repo/commits_table" .}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{template "base/footer" .}}
|
{{template "ng/base/footer" .}}
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
<div id="commits">
|
<div id="commits-list">
|
||||||
<div class="panel panel-default commit-box info-box">
|
<div class="panel panel-radius">
|
||||||
<div class="panel-heading info-head">
|
<div class="panel-header">
|
||||||
<form class="search pull-right col-md-3" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form">
|
<form class="search pull-right" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form">
|
||||||
<div class="input-group">
|
<input class="ipt ipt-radius" type="search" name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" />
|
||||||
<input class="form-control search" type="search" placeholder="search commit" name="q" value="{{.Keyword}}" />
|
<button class="btn btn-black btn-small btn-radius">{{.i18n.Tr "repo.commits.find"}}</button>
|
||||||
<div class="input-group-btn">
|
|
||||||
<button type="submit" class="btn btn-default">Find</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
<h4>{{.CommitCount}} Commits</h4>
|
<h4>{{.CommitCount}} {{.i18n.Tr "repo.commits.commits"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<table class="panel-footer table commit-list table table-striped">
|
<table class="panel-body table commit-list table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="author">Author</th>
|
<th class="author">{{.i18n.Tr "repo.commits.author"}}</th>
|
||||||
<th class="sha">SHA1</th>
|
<th class="sha">SHA1</th>
|
||||||
<th class="message">Message</th>
|
<th class="message">{{.i18n.Tr "repo.commits.message"}}</th>
|
||||||
<th class="date">Date</th>
|
<th class="date">{{.i18n.Tr "repo.commits.date"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -26,8 +22,8 @@
|
||||||
{{$r := List .Commits}}
|
{{$r := List .Commits}}
|
||||||
{{range $r}}
|
{{range $r}}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="{{AppSubUrl}}/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td>
|
<td class="author"><img class="avatar-20" src="{{AvatarLink .Author.Email}}" alt=""/> {{if .UserName}}<a href="{{AppSubUrl}}/{{.UserName}}">{{.Author.Name}}</a>{{else}}{{.Author.Name}}{{end}}</td>
|
||||||
<td class="sha"><a rel="nofollow" class="label label-success" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td>
|
<td class="sha"><a rel="nofollow" class="label label-green" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td>
|
||||||
<td class="message">{{.Summary}} </td>
|
<td class="message">{{.Summary}} </td>
|
||||||
<td class="date">{{TimeSince .Author.When $.Lang}}</td>
|
<td class="date">{{TimeSince .Author.When $.Lang}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -35,8 +31,10 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{{if not .IsSearchPage}}<ul class="pagination" id="commits-pager">
|
{{if not .IsSearchPage}}
|
||||||
{{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}}
|
<ul class="pagination">
|
||||||
{{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}}
|
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« {{.i18n.Tr "repo.commits.newer"}}</a></li>{{end}}
|
||||||
</ul>{{end}}
|
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» {{.i18n.Tr "repo.commits.older"}}</a></li>{{end}}
|
||||||
|
</ul>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in a new issue