summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authora1012112796 <1012112796@qq.com>2021-03-04 11:41:23 +0800
committerGitHub <noreply@github.com>2021-03-03 22:41:23 -0500
commita5279b74b63248902a6572df5afa3745367e6cb9 (patch)
tree7f1fac744013b533bfb0580d48a27d0aae5ab04e /routers
parent523efa433b61e00e7a14bd31cac315e43842d729 (diff)
downloadgitea-a5279b74b63248902a6572df5afa3745367e6cb9.tar.gz
gitea-a5279b74b63248902a6572df5afa3745367e6cb9.zip
Make manual merge autodetection optional and add manual merge as merge method (#12543)
* Make auto check manual merge as a chooseable mod and add manual merge way on ui as title, Before this pr, we use same way with GH to check manually merge. It good, but in some special cases, misjudgments can occur. and it's hard to fix this bug. So I add option to allow repo manager block "auto check manual merge" function, Then it will have same style like gitlab(allow empty pr). and to compensate for not being able to detect THE PR merge automatically, I added a manual approach. Signed-off-by: a1012112796 <1012112796@qq.com> * make swager * api support * ping ci * fix TestPullCreate_EmptyChangesWithCommits * Apply suggestions from code review Co-authored-by: zeripath <art27@cantab.net> * Apply review suggestions and add test * Apply suggestions from code review Co-authored-by: zeripath <art27@cantab.net> * fix build * test error message * make fmt * Fix indentation issues identified by @silverwind Co-authored-by: silverwind <me@silverwind.io> * Fix tests and make manually merged disabled error on API the same Signed-off-by: Andrew Thornton <art27@cantab.net> * a small nit * fix wrong commit id error * fix bug * simple test * fix test Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/repo/pull.go26
-rw-r--r--routers/api/v1/repo/repo.go8
-rw-r--r--routers/repo/compare.go8
-rw-r--r--routers/repo/issue.go18
-rw-r--r--routers/repo/pull.go34
-rw-r--r--routers/repo/setting.go2
6 files changed, 86 insertions, 10 deletions
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 38dac36553..8eda949652 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -769,13 +769,31 @@ func MergePullRequest(ctx *context.APIContext) {
return
}
- if !pr.CanAutoMerge() {
- ctx.Error(http.StatusMethodNotAllowed, "PR not in mergeable state", "Please try again later")
+ if pr.HasMerged {
+ ctx.Error(http.StatusMethodNotAllowed, "PR already merged", "")
return
}
- if pr.HasMerged {
- ctx.Error(http.StatusMethodNotAllowed, "PR already merged", "")
+ // handle manually-merged mark
+ if models.MergeStyle(form.Do) == models.MergeStyleManuallyMerged {
+ if err = pull_service.MergedManually(pr, ctx.User, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
+ if models.IsErrInvalidMergeStyle(err) {
+ ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", models.MergeStyle(form.Do)))
+ return
+ }
+ if strings.Contains(err.Error(), "Wrong commit ID") {
+ ctx.JSON(http.StatusConflict, err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "Manually-Merged", err)
+ return
+ }
+ ctx.Status(http.StatusOK)
+ return
+ }
+
+ if !pr.CanAutoMerge() {
+ ctx.Error(http.StatusMethodNotAllowed, "PR not in mergeable state", "Please try again later")
return
}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index b84c5993e4..b12797f83b 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -725,6 +725,8 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
AllowRebase: true,
AllowRebaseMerge: true,
AllowSquash: true,
+ AllowManualMerge: true,
+ AutodetectManualMerge: false,
}
} else {
config = unit.PullRequestsConfig()
@@ -745,6 +747,12 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if opts.AllowSquash != nil {
config.AllowSquash = *opts.AllowSquash
}
+ if opts.AllowManualMerge != nil {
+ config.AllowManualMerge = *opts.AllowManualMerge
+ }
+ if opts.AutodetectManualMerge != nil {
+ config.AutodetectManualMerge = *opts.AutodetectManualMerge
+ }
units = append(units, models.RepoUnit{
RepoID: repo.ID,
diff --git a/routers/repo/compare.go b/routers/repo/compare.go
index 2eef20f5ff..a8f4f8add8 100644
--- a/routers/repo/compare.go
+++ b/routers/repo/compare.go
@@ -429,6 +429,14 @@ func PrepareCompareDiff(
if headCommitID == compareInfo.MergeBase {
ctx.Data["IsNothingToCompare"] = true
+ if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
+ config := unit.PullRequestsConfig()
+ if !config.AutodetectManualMerge {
+ ctx.Data["AllowEmptyPr"] = !(baseBranch == headBranch && ctx.Repo.Repository.Name == headRepo.Name)
+ } else {
+ ctx.Data["AllowEmptyPr"] = false
+ }
+ }
return true
}
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index a9459a10ed..99df9db183 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -1491,6 +1491,8 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["MergeStyle"] = models.MergeStyleRebaseMerge
} else if prConfig.AllowSquash {
ctx.Data["MergeStyle"] = models.MergeStyleSquash
+ } else if prConfig.AllowManualMerge {
+ ctx.Data["MergeStyle"] = models.MergeStyleManuallyMerged
} else {
ctx.Data["MergeStyle"] = ""
}
@@ -1531,6 +1533,22 @@ func ViewIssue(ctx *context.Context) {
pull.HeadRepo != nil &&
git.IsBranchExist(pull.HeadRepo.RepoPath(), pull.HeadBranch) &&
(!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"])
+
+ stillCanManualMerge := func() bool {
+ if pull.HasMerged || issue.IsClosed || !ctx.IsSigned {
+ return false
+ }
+ if pull.CanAutoMerge() || pull.IsWorkInProgress() || pull.IsChecking() {
+ return false
+ }
+ if (ctx.User.IsAdmin || ctx.Repo.IsAdmin()) && prConfig.AllowManualMerge {
+ return true
+ }
+
+ return false
+ }
+
+ ctx.Data["StillCanManualMerge"] = stillCanManualMerge()
}
// Get Dependencies
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
index 15af2a2a3f..2ed47605f8 100644
--- a/routers/repo/pull.go
+++ b/routers/repo/pull.go
@@ -33,6 +33,7 @@ import (
"code.gitea.io/gitea/services/gitdiff"
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
+ "github.com/unknwon/com"
)
const (
@@ -794,15 +795,36 @@ func MergePullRequest(ctx *context.Context) {
return
}
- if !pr.CanAutoMerge() {
- ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
- ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
+ if pr.HasMerged {
+ ctx.Flash.Error(ctx.Tr("repo.pulls.has_merged"))
+ ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
return
}
- if pr.HasMerged {
- ctx.Flash.Error(ctx.Tr("repo.pulls.has_merged"))
- ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + fmt.Sprint(issue.Index))
+ // handle manually-merged mark
+ if models.MergeStyle(form.Do) == models.MergeStyleManuallyMerged {
+ if err = pull_service.MergedManually(pr, ctx.User, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
+ if models.IsErrInvalidMergeStyle(err) {
+ ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option"))
+ ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
+ return
+ } else if strings.Contains(err.Error(), "Wrong commit ID") {
+ ctx.Flash.Error(ctx.Tr("repo.pulls.wrong_commit_id"))
+ ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
+ return
+ }
+
+ ctx.ServerError("MergedManually", err)
+ return
+ }
+
+ ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
+ return
+ }
+
+ if !pr.CanAutoMerge() {
+ ctx.Flash.Error(ctx.Tr("repo.pulls.no_merge_not_ready"))
+ ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index))
return
}
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
index b35828d7b1..692d65b44c 100644
--- a/routers/repo/setting.go
+++ b/routers/repo/setting.go
@@ -321,6 +321,8 @@ func SettingsPost(ctx *context.Context) {
AllowRebase: form.PullsAllowRebase,
AllowRebaseMerge: form.PullsAllowRebaseMerge,
AllowSquash: form.PullsAllowSquash,
+ AllowManualMerge: form.PullsAllowManualMerge,
+ AutodetectManualMerge: form.EnableAutodetectManualMerge,
},
})
} else if !models.UnitTypePullRequests.UnitGlobalDisabled() {