mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-05 18:32:41 +09:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cebc125f7f | ||
|
|
c975287149 | ||
|
|
b31068652a | ||
|
|
918e640590 | ||
|
|
9809fe27c4 | ||
|
|
ed6a2f2e2e | ||
|
|
a0435fcd63 | ||
|
|
a2e2045a96 | ||
|
|
b67a023bec | ||
|
|
b1a90f7286 | ||
|
|
45c8a3aeeb | ||
|
|
0e5126da22 | ||
|
|
cd3e52d91b | ||
|
|
319c92163f | ||
|
|
a15a644c05 |
@@ -8,6 +8,10 @@ groups:
|
|||||||
name: FEATURE
|
name: FEATURE
|
||||||
labels:
|
labels:
|
||||||
- kind/feature
|
- kind/feature
|
||||||
|
-
|
||||||
|
name: SECURITY
|
||||||
|
labels:
|
||||||
|
- kind/security
|
||||||
-
|
-
|
||||||
name: BUGFIXES
|
name: BUGFIXES
|
||||||
labels:
|
labels:
|
||||||
@@ -18,10 +22,6 @@ groups:
|
|||||||
- kind/enhancement
|
- kind/enhancement
|
||||||
- kind/refactor
|
- kind/refactor
|
||||||
- kind/ui
|
- kind/ui
|
||||||
-
|
|
||||||
name: SECURITY
|
|
||||||
labels:
|
|
||||||
- kind/security
|
|
||||||
-
|
-
|
||||||
name: TESTING
|
name: TESTING
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -4,6 +4,24 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.10.3](https://github.com/go-gitea/gitea/releases/tag/v1.10.3) - 2020-01-17
|
||||||
|
* SECURITY
|
||||||
|
* Hide credentials when submitting migration (#9102) (#9704)
|
||||||
|
* Never allow an empty password to validate (#9682) (#9684)
|
||||||
|
* Prevent redirect to Host (#9678) (#9680)
|
||||||
|
* Hide public repos owned by private orgs (#9609) (#9616)
|
||||||
|
* BUGFIXES
|
||||||
|
* Allow assignee on Pull Creation when Issue Unit is deactivated (#9836) (#9838)
|
||||||
|
* Fix download file wrong content-type (#9825) (#9835)
|
||||||
|
* Fix wrong identify poster on a migrated pull request when submit review (#9827) (#9831)
|
||||||
|
* Fix dump non-exist log directory (#9818) (#9820)
|
||||||
|
* Fix compare (#9808) (#9815)
|
||||||
|
* Fix missing msteam webhook on organization (#9781) (#9795)
|
||||||
|
* Fix add team on collaborator page when same name as organization (#9783)
|
||||||
|
* Fix cache problem on dashboard (#9358) (#9703)
|
||||||
|
* Send tag create and push webhook when release created on UI (#8671) (#9702)
|
||||||
|
* Branches not at ref commit ID should not be listed as Merged (#9614) (#9639)
|
||||||
|
|
||||||
## [1.10.2](https://github.com/go-gitea/gitea/releases/tag/v1.10.2) - 2020-01-02
|
## [1.10.2](https://github.com/go-gitea/gitea/releases/tag/v1.10.2) - 2020-01-02
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* Allow only specific Columns to be updated on Issue via API (#9539) (#9580)
|
* Allow only specific Columns to be updated on Issue via API (#9539) (#9580)
|
||||||
|
|||||||
@@ -145,8 +145,10 @@ func runDump(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
if com.IsExist(setting.LogRootPath) {
|
||||||
log.Fatalf("Failed to include log: %v", err)
|
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
||||||
|
log.Fatalf("Failed to include log: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = z.Close(); err != nil {
|
if err = z.Close(); err != nil {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
4a357436d925b5c974181ff12a994538ddc5a269
|
||||||
@@ -429,7 +429,7 @@ func (issue *Issue) HashTag() string {
|
|||||||
|
|
||||||
// IsPoster returns true if given user by ID is the poster.
|
// IsPoster returns true if given user by ID is the poster.
|
||||||
func (issue *Issue) IsPoster(uid int64) bool {
|
func (issue *Issue) IsPoster(uid int64) bool {
|
||||||
return issue.PosterID == uid
|
return issue.OriginalAuthorID == 0 && issue.PosterID == uid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (issue *Issue) hasLabel(e Engine, labelID int64) bool {
|
func (issue *Issue) hasLabel(e Engine, labelID int64) bool {
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func (pr *PullRequest) LoadHeadRepo() error {
|
|||||||
if has, err := x.ID(pr.HeadRepoID).Get(&repo); err != nil {
|
if has, err := x.ID(pr.HeadRepoID).Get(&repo); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return ErrRepoNotExist{ID: pr.BaseRepoID}
|
return ErrRepoNotExist{ID: pr.HeadRepoID}
|
||||||
}
|
}
|
||||||
pr.HeadRepo = &repo
|
pr.HeadRepo = &repo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ type SearchRepoOptions struct {
|
|||||||
StarredByID int64
|
StarredByID int64
|
||||||
Page int
|
Page int
|
||||||
IsProfile bool
|
IsProfile bool
|
||||||
AllPublic bool // Include also all public repositories
|
AllPublic bool // Include also all public repositories of users and public organisations
|
||||||
|
AllLimited bool // Include also all public repositories of limited organisations
|
||||||
PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
|
PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
|
||||||
// None -> include collaborative AND non-collaborative
|
// None -> include collaborative AND non-collaborative
|
||||||
// True -> include just collaborative
|
// True -> include just collaborative
|
||||||
@@ -240,7 +241,11 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opts.AllPublic {
|
if opts.AllPublic {
|
||||||
accessCond = accessCond.Or(builder.Eq{"is_private": false})
|
accessCond = accessCond.Or(builder.Eq{"is_private": false}.And(builder.In("owner_id", builder.Select("`user`.id").From("`user`").Where(builder.Eq{"`user`.visibility": structs.VisibleTypePublic}))))
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.AllLimited {
|
||||||
|
accessCond = accessCond.Or(builder.Eq{"is_private": false}.And(builder.In("owner_id", builder.Select("`user`.id").From("`user`").Where(builder.Eq{"`user`.visibility": structs.VisibleTypeLimited}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = cond.And(accessCond)
|
cond = cond.And(accessCond)
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ func TestSearchRepository(t *testing.T) {
|
|||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, AllPublic: true},
|
||||||
count: 22},
|
count: 22},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true},
|
||||||
count: 28},
|
count: 27},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
||||||
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
||||||
count: 15},
|
count: 15},
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ func (u *User) ValidatePassword(passwd string) bool {
|
|||||||
|
|
||||||
// IsPasswordSet checks if the password is set or left empty
|
// IsPasswordSet checks if the password is set or left empty
|
||||||
func (u *User) IsPasswordSet() bool {
|
func (u *User) IsPasswordSet() bool {
|
||||||
return len(u.Passwd) > 0
|
return !u.ValidatePassword("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadAvatar saves custom avatar for user.
|
// UploadAvatar saves custom avatar for user.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ func (ctx *Context) RedirectToFirst(location ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(loc)
|
u, err := url.Parse(loc)
|
||||||
if err != nil || (u.Scheme != "" && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
|
if err != nil || ((u.Scheme != "" || u.Host != "") && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
|
|||||||
repo, err := models.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
repo, err := models.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
|
||||||
Name: opts.RepoName,
|
Name: opts.RepoName,
|
||||||
Description: opts.Description,
|
Description: opts.Description,
|
||||||
OriginalURL: opts.CloneAddr,
|
OriginalURL: form.CloneAddr,
|
||||||
IsPrivate: opts.Private,
|
IsPrivate: opts.Private,
|
||||||
IsMirror: opts.Mirror,
|
IsMirror: opts.Mirror,
|
||||||
Status: models.RepositoryBeingMigrated,
|
Status: models.RepositoryBeingMigrated,
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
|||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
OwnerID: opts.OwnerID,
|
OwnerID: opts.OwnerID,
|
||||||
AllPublic: true,
|
AllPublic: true,
|
||||||
|
AllLimited: true,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/repofiles"
|
"code.gitea.io/gitea/modules/repofiles"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -32,6 +33,7 @@ type Branch struct {
|
|||||||
CommitsAhead int
|
CommitsAhead int
|
||||||
CommitsBehind int
|
CommitsBehind int
|
||||||
LatestPullRequest *models.PullRequest
|
LatestPullRequest *models.PullRequest
|
||||||
|
MergeMovedOn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Branches render repository branch page
|
// Branches render repository branch page
|
||||||
@@ -168,6 +170,12 @@ func loadBranches(ctx *context.Context) []*Branch {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repoIDToRepo := map[int64]*models.Repository{}
|
||||||
|
repoIDToRepo[ctx.Repo.Repository.ID] = ctx.Repo.Repository
|
||||||
|
|
||||||
|
repoIDToGitRepo := map[int64]*git.Repository{}
|
||||||
|
repoIDToGitRepo[ctx.Repo.Repository.ID] = ctx.Repo.GitRepo
|
||||||
|
|
||||||
branches := make([]*Branch, len(rawBranches))
|
branches := make([]*Branch, len(rawBranches))
|
||||||
for i := range rawBranches {
|
for i := range rawBranches {
|
||||||
commit, err := rawBranches[i].GetCommit()
|
commit, err := rawBranches[i].GetCommit()
|
||||||
@@ -196,11 +204,46 @@ func loadBranches(ctx *context.Context) []*Branch {
|
|||||||
ctx.ServerError("GetLatestPullRequestByHeadInfo", err)
|
ctx.ServerError("GetLatestPullRequestByHeadInfo", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
headCommit := commit.ID.String()
|
||||||
|
|
||||||
|
mergeMovedOn := false
|
||||||
if pr != nil {
|
if pr != nil {
|
||||||
|
pr.HeadRepo = ctx.Repo.Repository
|
||||||
if err := pr.LoadIssue(); err != nil {
|
if err := pr.LoadIssue(); err != nil {
|
||||||
ctx.ServerError("pr.LoadIssue", err)
|
ctx.ServerError("pr.LoadIssue", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
|
||||||
|
pr.BaseRepo = repo
|
||||||
|
} else if err := pr.LoadBaseRepo(); err != nil {
|
||||||
|
ctx.ServerError("pr.LoadBaseRepo", err)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.HasMerged {
|
||||||
|
baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
|
||||||
|
if !ok {
|
||||||
|
baseGitRepo, err = git.OpenRepository(pr.BaseRepo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("OpenRepository", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer baseGitRepo.Close()
|
||||||
|
repoIDToGitRepo[pr.BaseRepoID] = baseGitRepo
|
||||||
|
}
|
||||||
|
pullCommit, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
|
||||||
|
if err != nil && err != plumbing.ErrReferenceNotFound {
|
||||||
|
ctx.ServerError("GetBranchCommitID", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err == nil && headCommit != pullCommit {
|
||||||
|
// the head has moved on from the merge - we shouldn't delete
|
||||||
|
mergeMovedOn = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
branches[i] = &Branch{
|
branches[i] = &Branch{
|
||||||
@@ -210,6 +253,7 @@ func loadBranches(ctx *context.Context) []*Branch {
|
|||||||
CommitsAhead: divergence.Ahead,
|
CommitsAhead: divergence.Ahead,
|
||||||
CommitsBehind: divergence.Behind,
|
CommitsBehind: divergence.Behind,
|
||||||
LatestPullRequest: pr,
|
LatestPullRequest: pr,
|
||||||
|
MergeMovedOn: mergeMovedOn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,12 +152,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
defer headGitRepo.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
||||||
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -168,42 +168,40 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
baseRepo,
|
baseRepo,
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// user should have permission to read headrepo's codes
|
if !isSameRepo {
|
||||||
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
// user should have permission to read headrepo's codes
|
||||||
if err != nil {
|
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
||||||
headGitRepo.Close()
|
if err != nil {
|
||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
if !permHead.CanRead(models.UnitTypeCode) {
|
if !permHead.CanRead(models.UnitTypeCode) {
|
||||||
if log.IsTrace() {
|
if log.IsTrace() {
|
||||||
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
|
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
|
||||||
ctx.User,
|
ctx.User,
|
||||||
headRepo,
|
headRepo,
|
||||||
permHead)
|
permHead)
|
||||||
|
}
|
||||||
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
|
||||||
return nil, nil, nil, nil, "", ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if head branch is valid.
|
// Check if head branch is valid.
|
||||||
headIsCommit := ctx.Repo.GitRepo.IsCommitExist(headBranch)
|
headIsCommit := headGitRepo.IsCommitExist(headBranch)
|
||||||
headIsBranch := headGitRepo.IsBranchExist(headBranch)
|
headIsBranch := headGitRepo.IsBranchExist(headBranch)
|
||||||
headIsTag := headGitRepo.IsTagExist(headBranch)
|
headIsTag := headGitRepo.IsTagExist(headBranch)
|
||||||
if !headIsCommit && !headIsBranch && !headIsTag {
|
if !headIsCommit && !headIsBranch && !headIsTag {
|
||||||
// Check if headBranch is short sha commit hash
|
// Check if headBranch is short sha commit hash
|
||||||
if headCommit, _ := ctx.Repo.GitRepo.GetCommit(headBranch); headCommit != nil {
|
if headCommit, _ := headGitRepo.GetCommit(headBranch); headCommit != nil {
|
||||||
headBranch = headCommit.ID.String()
|
headBranch = headCommit.ID.String()
|
||||||
ctx.Data["HeadBranch"] = headBranch
|
ctx.Data["HeadBranch"] = headBranch
|
||||||
headIsCommit = true
|
headIsCommit = true
|
||||||
} else {
|
} else {
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.NotFound("IsRefExist", nil)
|
ctx.NotFound("IsRefExist", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -224,14 +222,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
baseRepo,
|
baseRepo,
|
||||||
permBase)
|
permBase)
|
||||||
}
|
}
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch)
|
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranch, headBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
headGitRepo.Close()
|
|
||||||
ctx.ServerError("GetCompareInfo", err)
|
ctx.ServerError("GetCompareInfo", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
@@ -377,7 +373,8 @@ func CompareDiff(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer headGitRepo.Close()
|
defer headGitRepo.Close()
|
||||||
if err := parseBaseRepoInfo(ctx, headRepo); err != nil {
|
var err error
|
||||||
|
if err = parseBaseRepoInfo(ctx, headRepo); err != nil {
|
||||||
ctx.ServerError("parseBaseRepoInfo", err)
|
ctx.ServerError("parseBaseRepoInfo", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -419,6 +416,11 @@ func CompareDiff(ctx *context.Context) {
|
|||||||
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
|
beforeCommitID := ctx.Data["BeforeCommitID"].(string)
|
||||||
afterCommitID := ctx.Data["AfterCommitID"].(string)
|
afterCommitID := ctx.Data["AfterCommitID"].(string)
|
||||||
|
|
||||||
|
if ctx.Data["Assignees"], err = ctx.Repo.Repository.GetAssignees(); err != nil {
|
||||||
|
ctx.ServerError("GetAssignees", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID)
|
ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID)
|
||||||
|
|
||||||
ctx.Data["IsRepoToolbarCommits"] = true
|
ctx.Data["IsRepoToolbarCommits"] = true
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/charset"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/lfs"
|
"code.gitea.io/gitea/modules/lfs"
|
||||||
@@ -33,7 +34,12 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error {
|
|||||||
name = strings.Replace(name, ",", " ", -1)
|
name = strings.Replace(name, ",", " ", -1)
|
||||||
|
|
||||||
if base.IsTextFile(buf) || ctx.QueryBool("render") {
|
if base.IsTextFile(buf) || ctx.QueryBool("render") {
|
||||||
ctx.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
cs, err := charset.DetectEncoding(buf)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Detect raw file %s charset failed: %v, using by default utf-8", name, err)
|
||||||
|
cs = "utf-8"
|
||||||
|
}
|
||||||
|
ctx.Resp.Header().Set("Content-Type", "text/plain; charset="+strings.ToLower(cs))
|
||||||
} else if base.IsImageFile(buf) || base.IsPDFFile(buf) {
|
} else if base.IsImageFile(buf) || base.IsPDFFile(buf) {
|
||||||
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name))
|
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -931,7 +931,10 @@ func ViewIssue(ctx *context.Context) {
|
|||||||
ctx.Data["IsBlockedByApprovals"] = pull.ProtectedBranch.RequiredApprovals > 0 && cnt < pull.ProtectedBranch.RequiredApprovals
|
ctx.Data["IsBlockedByApprovals"] = pull.ProtectedBranch.RequiredApprovals > 0 && cnt < pull.ProtectedBranch.RequiredApprovals
|
||||||
ctx.Data["GrantedApprovals"] = cnt
|
ctx.Data["GrantedApprovals"] = cnt
|
||||||
}
|
}
|
||||||
ctx.Data["IsPullBranchDeletable"] = canDelete && pull.HeadRepo != nil && git.IsBranchExist(pull.HeadRepo.RepoPath(), pull.HeadBranch)
|
ctx.Data["IsPullBranchDeletable"] = canDelete &&
|
||||||
|
pull.HeadRepo != nil &&
|
||||||
|
git.IsBranchExist(pull.HeadRepo.RepoPath(), pull.HeadBranch) &&
|
||||||
|
(!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"])
|
||||||
|
|
||||||
ctx.Data["PullReviewersWithType"], err = models.GetReviewersByPullID(issue.ID)
|
ctx.Data["PullReviewersWithType"], err = models.GetReviewersByPullID(issue.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -315,25 +315,37 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
|||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
pull := issue.PullRequest
|
pull := issue.PullRequest
|
||||||
|
|
||||||
var err error
|
if err := pull.GetHeadRepo(); err != nil {
|
||||||
if err = pull.GetHeadRepo(); err != nil {
|
|
||||||
ctx.ServerError("GetHeadRepo", err)
|
ctx.ServerError("GetHeadRepo", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := pull.GetBaseRepo(); err != nil {
|
||||||
|
ctx.ServerError("GetBaseRepo", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
setMergeTarget(ctx, pull)
|
setMergeTarget(ctx, pull)
|
||||||
|
|
||||||
if err = pull.LoadProtectedBranch(); err != nil {
|
if err := pull.LoadProtectedBranch(); err != nil {
|
||||||
ctx.ServerError("GetLatestCommitStatus", err)
|
ctx.ServerError("GetLatestCommitStatus", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Data["EnableStatusCheck"] = pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck
|
ctx.Data["EnableStatusCheck"] = pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck
|
||||||
|
|
||||||
var headGitRepo *git.Repository
|
baseGitRepo, err := git.OpenRepository(pull.BaseRepo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("OpenRepository", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer baseGitRepo.Close()
|
||||||
var headBranchExist bool
|
var headBranchExist bool
|
||||||
|
var headBranchSha string
|
||||||
// HeadRepo may be missing
|
// HeadRepo may be missing
|
||||||
if pull.HeadRepo != nil {
|
if pull.HeadRepo != nil {
|
||||||
headGitRepo, err = git.OpenRepository(pull.HeadRepo.RepoPath())
|
var err error
|
||||||
|
|
||||||
|
headGitRepo, err := git.OpenRepository(pull.HeadRepo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("OpenRepository", err)
|
ctx.ServerError("OpenRepository", err)
|
||||||
return nil
|
return nil
|
||||||
@@ -343,46 +355,53 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare
|
|||||||
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
|
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
|
||||||
|
|
||||||
if headBranchExist {
|
if headBranchExist {
|
||||||
sha, err := headGitRepo.GetBranchCommitID(pull.HeadBranch)
|
headBranchSha, err = headGitRepo.GetBranchCommitID(pull.HeadBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranchCommitID", err)
|
ctx.ServerError("GetBranchCommitID", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
commitStatuses, err := models.GetLatestCommitStatus(repo, sha, 0)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetLatestCommitStatus", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(commitStatuses) > 0 {
|
|
||||||
ctx.Data["LatestCommitStatuses"] = commitStatuses
|
|
||||||
ctx.Data["LatestCommitStatus"] = models.CalcCommitStatus(commitStatuses)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck {
|
|
||||||
ctx.Data["is_context_required"] = func(context string) bool {
|
|
||||||
for _, c := range pull.ProtectedBranch.StatusCheckContexts {
|
|
||||||
if c == context {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ctx.Data["IsRequiredStatusCheckSuccess"] = pull_service.IsCommitStatusContextSuccess(commitStatuses, pull.ProtectedBranch.StatusCheckContexts)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pull.HeadRepo == nil || !headBranchExist {
|
sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName())
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
if err != nil {
|
||||||
ctx.Data["HeadTarget"] = "deleted"
|
ctx.ServerError(fmt.Sprintf("GetRefCommitID(%s)", pull.GetGitRefName()), err)
|
||||||
ctx.Data["NumCommits"] = 0
|
|
||||||
ctx.Data["NumFiles"] = 0
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(repo.Owner.Name, repo.Name),
|
commitStatuses, err := models.GetLatestCommitStatus(repo, sha, 0)
|
||||||
pull.BaseBranch, pull.HeadBranch)
|
if err != nil {
|
||||||
|
ctx.ServerError("GetLatestCommitStatus", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(commitStatuses) > 0 {
|
||||||
|
ctx.Data["LatestCommitStatuses"] = commitStatuses
|
||||||
|
ctx.Data["LatestCommitStatus"] = models.CalcCommitStatus(commitStatuses)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pull.ProtectedBranch != nil && pull.ProtectedBranch.EnableStatusCheck {
|
||||||
|
ctx.Data["is_context_required"] = func(context string) bool {
|
||||||
|
for _, c := range pull.ProtectedBranch.StatusCheckContexts {
|
||||||
|
if c == context {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
ctx.Data["IsRequiredStatusCheckSuccess"] = pull_service.IsCommitStatusContextSuccess(commitStatuses, pull.ProtectedBranch.StatusCheckContexts)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Data["HeadBranchMovedOn"] = headBranchSha != sha
|
||||||
|
ctx.Data["HeadBranchCommitID"] = headBranchSha
|
||||||
|
ctx.Data["PullHeadCommitID"] = sha
|
||||||
|
|
||||||
|
if pull.HeadRepo == nil || !headBranchExist || headBranchSha != sha {
|
||||||
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
|
ctx.Data["HeadTarget"] = "deleted"
|
||||||
|
}
|
||||||
|
|
||||||
|
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
||||||
|
pull.BaseBranch, pull.GetGitRefName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
||||||
ctx.Data["IsPullRequestBroken"] = true
|
ctx.Data["IsPullRequestBroken"] = true
|
||||||
|
|||||||
@@ -117,9 +117,7 @@ func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) {
|
|||||||
|
|
||||||
// can not approve/reject your own PR
|
// can not approve/reject your own PR
|
||||||
case models.ReviewTypeApprove, models.ReviewTypeReject:
|
case models.ReviewTypeApprove, models.ReviewTypeReject:
|
||||||
|
if issue.IsPoster(ctx.User.ID) {
|
||||||
if issue.Poster.ID == ctx.User.ID {
|
|
||||||
|
|
||||||
var translated string
|
var translated string
|
||||||
|
|
||||||
if reviewType == models.ReviewTypeApprove {
|
if reviewType == models.ReviewTypeApprove {
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ func AddTeamPost(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.Query("team")))
|
name := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.Query("team")))
|
||||||
if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
|
if len(name) == 0 {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
||||||
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
||||||
m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost)
|
m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost)
|
||||||
m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
|
m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Group("/auths", func() {
|
m.Group("/auths", func() {
|
||||||
@@ -590,6 +590,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost)
|
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost)
|
||||||
m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost)
|
m.Post("/dingtalk/new", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksNewPost)
|
||||||
m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost)
|
m.Post("/telegram/new", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksNewPost)
|
||||||
|
m.Post("/msteams/new", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
|
||||||
m.Get("/:id", repo.WebHooksEdit)
|
m.Get("/:id", repo.WebHooksEdit)
|
||||||
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
m.Post("/gitea/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||||
m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost)
|
m.Post("/gogs/:id", bindIgnErr(auth.NewGogshookForm{}), repo.GogsHooksEditPost)
|
||||||
@@ -597,6 +598,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
||||||
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
m.Post("/dingtalk/:id", bindIgnErr(auth.NewDingtalkHookForm{}), repo.DingtalkHooksEditPost)
|
||||||
m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost)
|
m.Post("/telegram/:id", bindIgnErr(auth.NewTelegramHookForm{}), repo.TelegramHooksEditPost)
|
||||||
|
m.Post("/msteams/:id", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Route("/delete", "GET,POST", org.SettingsDelete)
|
m.Route("/delete", "GET,POST", org.SettingsDelete)
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ func retrieveFeeds(ctx *context.Context, options models.GetFeedsOptions) {
|
|||||||
if act.ActUser != nil {
|
if act.ActUser != nil {
|
||||||
userCache[act.ActUserID] = act.ActUser
|
userCache[act.ActUserID] = act.ActUser
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, act := range actions {
|
||||||
repoOwner, ok := userCache[act.Repo.OwnerID]
|
repoOwner, ok := userCache[act.Repo.OwnerID]
|
||||||
if !ok {
|
if !ok {
|
||||||
repoOwner, err = models.GetUserByID(act.Repo.OwnerID)
|
repoOwner, err = models.GetUserByID(act.Repo.OwnerID)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/process"
|
"code.gitea.io/gitea/modules/process"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
)
|
)
|
||||||
@@ -37,6 +38,54 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rel.LowerTagName = strings.ToLower(rel.TagName)
|
rel.LowerTagName = strings.ToLower(rel.TagName)
|
||||||
|
// Prepare Notify
|
||||||
|
if err := rel.LoadAttributes(); err != nil {
|
||||||
|
log.Error("LoadAttributes: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
refName := git.TagPrefix + rel.TagName
|
||||||
|
apiPusher := rel.Publisher.APIFormat()
|
||||||
|
apiRepo := rel.Repo.APIFormat(models.AccessModeNone)
|
||||||
|
apiCommits, err := models.NewPushCommits().ToAPIPayloadCommits(rel.Repo.RepoPath(), rel.Repo.HTMLURL())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("commits.ToAPIPayloadCommits failed: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.PrepareWebhooks(rel.Repo, models.HookEventPush, &api.PushPayload{
|
||||||
|
Ref: refName,
|
||||||
|
Before: git.EmptySHA,
|
||||||
|
After: commit.ID.String(),
|
||||||
|
CompareURL: setting.AppURL + models.NewPushCommits().CompareURL,
|
||||||
|
Commits: apiCommits,
|
||||||
|
Repo: apiRepo,
|
||||||
|
Pusher: apiPusher,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
log.Error("PrepareWebhooks: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gitRepo, err := git.OpenRepository(rel.Repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("OpenRepository[%s]: %v", rel.Repo.RepoPath(), err)
|
||||||
|
}
|
||||||
|
shaSum, err := gitRepo.GetTagCommitID(refName)
|
||||||
|
if err != nil {
|
||||||
|
gitRepo.Close()
|
||||||
|
log.Error("GetTagCommitID[%s]: %v", refName, err)
|
||||||
|
}
|
||||||
|
gitRepo.Close()
|
||||||
|
|
||||||
|
if err = models.PrepareWebhooks(rel.Repo, models.HookEventCreate, &api.CreatePayload{
|
||||||
|
Ref: git.RefEndName(refName),
|
||||||
|
Sha: shaSum,
|
||||||
|
RefType: "tag",
|
||||||
|
Repo: apiRepo,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
commit, err := gitRepo.GetTagCommit(rel.TagName)
|
commit, err := gitRepo.GetTagCommit(rel.TagName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -80,6 +80,12 @@
|
|||||||
<button id="new-pull-request" class="ui compact basic button">{{$.i18n.Tr "repo.pulls.compare_changes"}}</button>
|
<button id="new-pull-request" class="ui compact basic button">{{$.i18n.Tr "repo.pulls.compare_changes"}}</button>
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{else if and .LatestPullRequest.HasMerged .MergeMovedOn}}
|
||||||
|
{{if and (not .IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}}
|
||||||
|
<a href="{{$.RepoLink}}/compare/{{$.DefaultBranch | EscapePound}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{$.Owner.Name}}:{{end}}{{.Name | EscapePound}}">
|
||||||
|
<button id="new-pull-request" class="ui compact basic button">{{$.i18n.Tr "repo.pulls.compare_changes"}}</button>
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="{{$.RepoLink}}/pulls/{{.LatestPullRequest.Issue.Index}}">#{{.LatestPullRequest.Issue.Index}}</a>
|
<a href="{{$.RepoLink}}/pulls/{{.LatestPullRequest.Issue.Index}}">#{{.LatestPullRequest.Issue.Index}}</a>
|
||||||
{{if .LatestPullRequest.HasMerged}}
|
{{if .LatestPullRequest.HasMerged}}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
{{$.i18n.Tr "repo.pulls.reopen_to_merge"}}
|
{{$.i18n.Tr "repo.pulls.reopen_to_merge"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .IsPullBranchDeletable}}
|
{{if and .IsPullBranchDeletable ( not .IsPullRequestBroken )}}
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
<div>
|
<div>
|
||||||
<a class="delete-button ui red button" href="" data-url="{{.DeleteBranchLink}}">{{$.i18n.Tr "repo.branch.delete" .HeadTarget}}</a>
|
<a class="delete-button ui red button" href="" data-url="{{.DeleteBranchLink}}">{{$.i18n.Tr "repo.branch.delete" .HeadTarget}}</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user