Create pull request for base after editing file, if not enabled on fork (#24841)

Currently if pull requests are disabled on a fork but enabled on a base
repo, creating/editing/deleting files does not offer the option to
create a pull request. This change enables creating a pull request for
the base repo in that case.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
Brecht Van Lommel 2023-05-24 23:36:02 +02:00 committed by GitHub
parent 1cf4d46bb1
commit 1bfa37ada2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 33 deletions

View file

@ -41,16 +41,49 @@ const (
frmCommitChoiceNewBranch string = "commit-to-new-branch" frmCommitChoiceNewBranch string = "commit-to-new-branch"
) )
func canCreateBasePullRequest(ctx *context.Context) bool {
baseRepo := ctx.Repo.Repository.BaseRepo
return baseRepo != nil && baseRepo.UnitEnabled(ctx, unit.TypePullRequests)
}
func renderCommitRights(ctx *context.Context) bool { func renderCommitRights(ctx *context.Context) bool {
canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.Doer) canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.Doer)
if err != nil { if err != nil {
log.Error("CanCommitToBranch: %v", err) log.Error("CanCommitToBranch: %v", err)
} }
ctx.Data["CanCommitToBranch"] = canCommitToBranch ctx.Data["CanCommitToBranch"] = canCommitToBranch
ctx.Data["CanCreatePullRequest"] = ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) || canCreateBasePullRequest(ctx)
return canCommitToBranch.CanCommitToBranch return canCommitToBranch.CanCommitToBranch
} }
// redirectForCommitChoice redirects after committing the edit to a branch
func redirectForCommitChoice(ctx *context.Context, commitChoice, newBranchName, treePath string) {
if commitChoice == frmCommitChoiceNewBranch {
// Redirect to a pull request when possible
redirectToPullRequest := false
repo := ctx.Repo.Repository
baseBranch := ctx.Repo.BranchName
headBranch := newBranchName
if repo.UnitEnabled(ctx, unit.TypePullRequests) {
redirectToPullRequest = true
} else if canCreateBasePullRequest(ctx) {
redirectToPullRequest = true
baseBranch = repo.BaseRepo.DefaultBranch
headBranch = repo.Owner.Name + "/" + repo.Name + ":" + headBranch
repo = repo.BaseRepo
}
if redirectToPullRequest {
ctx.Redirect(repo.Link() + "/compare/" + util.PathEscapeSegments(baseBranch) + "..." + util.PathEscapeSegments(headBranch))
return
}
}
// Redirect to viewing file or folder
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(newBranchName) + "/" + util.PathEscapeSegments(treePath))
}
// getParentTreeFields returns list of parent tree names and corresponding tree paths // getParentTreeFields returns list of parent tree names and corresponding tree paths
// based on given tree path. // based on given tree path.
func getParentTreeFields(treePath string) (treeNames, treePaths []string) { func getParentTreeFields(treePath string) (treeNames, treePaths []string) {
@ -331,11 +364,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
_ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty") _ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty")
} }
if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) { redirectForCommitChoice(ctx, form.CommitChoice, branchName, form.TreePath)
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName))
} else {
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
}
} }
// EditFilePost response for editing file // EditFilePost response for editing file
@ -517,9 +546,6 @@ func DeleteFilePost(ctx *context.Context) {
} }
ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath)) ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath))
if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) {
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName))
} else {
treePath := path.Dir(ctx.Repo.TreePath) treePath := path.Dir(ctx.Repo.TreePath)
if treePath == "." { if treePath == "." {
treePath = "" // the file deleted was in the root, so we return the user to the root directory treePath = "" // the file deleted was in the root, so we return the user to the root directory
@ -535,8 +561,8 @@ func DeleteFilePost(ctx *context.Context) {
treePath = "" // otherwise return them to the root of the repo treePath = "" // otherwise return them to the root of the repo
} }
} }
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(treePath))
} redirectForCommitChoice(ctx, form.CommitChoice, branchName, treePath)
} }
// UploadFile render upload file page // UploadFile render upload file page
@ -722,11 +748,7 @@ func UploadFilePost(ctx *context.Context) {
_ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty") _ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty")
} }
if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) { redirectForCommitChoice(ctx, form.CommitChoice, branchName, form.TreePath)
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName))
} else {
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
}
} }
func cleanUploadFileName(name string) string { func cleanUploadFileName(name string) string {

View file

@ -41,17 +41,15 @@
</div> </div>
{{if not .Repository.IsEmpty}} {{if not .Repository.IsEmpty}}
<div class="field"> <div class="field">
{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
<div class="ui radio checkbox"> <div class="ui radio checkbox">
{{if $pullRequestEnabled}} {{if .CanCreatePullRequest}}
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{.locale.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}> <input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{.locale.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
{{else}} {{else}}
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{.locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}> <input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{.locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
{{end}} {{end}}
<label> <label>
{{svg "octicon-git-pull-request"}} {{svg "octicon-git-pull-request"}}
{{if $pullRequestEnabled}} {{if .CanCreatePullRequest}}
{{.locale.Tr "repo.editor.create_new_branch" | Safe}} {{.locale.Tr "repo.editor.create_new_branch" | Safe}}
{{else}} {{else}}
{{.locale.Tr "repo.editor.create_new_branch_np" | Safe}} {{.locale.Tr "repo.editor.create_new_branch_np" | Safe}}