Changes
14 changed files (+292/-165)
-
-
@@ -43,6 +43,39 @@ Possible file names for PR templates:- `.github/PULL_REQUEST_TEMPLATE.md` - `.github/pull_request_template.md` Possible file names for PR default merge message templates: - `.gitea/default_merge_message/MERGE_TEMPLATE.md` - `.gitea/default_merge_message/REBASE_TEMPLATE.md` - `.gitea/default_merge_message/REBASE-MERGE_TEMPLATE.md` - `.gitea/default_merge_message/SQUASH_TEMPLATE.md` - `.gitea/default_merge_message/MANUALLY-MERGED_TEMPLATE.md` - `.gitea/default_merge_message/REBASE-UPDATE-ONLY_TEMPLATE.md` Possible file names for PR default merge message templates: - `.gitea/default_merge_message/MERGE_TEMPLATE.md` - `.gitea/default_merge_message/REBASE_TEMPLATE.md` - `.gitea/default_merge_message/REBASE-MERGE_TEMPLATE.md` - `.gitea/default_merge_message/SQUASH_TEMPLATE.md` - `.gitea/default_merge_message/MANUALLY-MERGED_TEMPLATE.md` - `.gitea/default_merge_message/REBASE-UPDATE-ONLY_TEMPLATE.md` You can use the following variables enclosed in `${}` inside these templates which follow [os.Expand](https://pkg.go.dev/os#Expand) syntax: - BaseRepoOwnerName: Base repository owner name of this pull request - BaseRepoName: Base repository name of this pull request - BaseBranch: Base repository target branch name of this pull request - HeadRepoOwnerName: Head repository owner name of this pull request - HeadRepoName: Head repository name of this pull request - HeadBranch: Head repository branch name of this pull request - PullRequestTitle: Pull request's title - PullRequestDescription: Pull request's description - PullRequestPosterName: Pull request's poster name - PullRequestIndex: Pull request's index number - PullRequestReference: Pull request's reference char with index number. i.e. #1, !2 - ClosingIssues: return a string contains all issues which will be closed by this pull request i.e. `close #1, close #2` Additionally, the New Issue page URL can be suffixed with `?title=Issue+Title&body=Issue+Text` and the form will be populated with those strings. Those strings will be used instead of the template if there is one. ## Issue Template Directory
-
-
-
@@ -6,6 +6,7 @@ package integrationsimport ( "bytes" "context" "fmt" "net/http" "net/http/httptest"
-
@@ -243,11 +244,11 @@ func TestCantMergeConflict(t *testing.T) {gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name)) assert.NoError(t, err) err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "CONFLICT") err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "CONFLICT") assert.Error(t, err, "Merge should return an error due to conflict") assert.True(t, models.IsErrMergeConflicts(err), "Merge error is not a conflict error") err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleRebase, "", "CONFLICT") err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleRebase, "", "CONFLICT") assert.Error(t, err, "Merge should return an error due to conflict") assert.True(t, models.IsErrRebaseConflicts(err), "Merge error is not a conflict error") gitRepo.Close()
-
@@ -342,7 +343,7 @@ func TestCantMergeUnrelated(t *testing.T) {BaseBranch: "base", }).(*models.PullRequest) err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED") err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED") assert.Error(t, err, "Merge should return an error due to unrelated") assert.True(t, models.IsErrMergeUnrelatedHistories(err), "Merge error is not a unrelated histories error") gitRepo.Close()
-
-
-
@@ -13,7 +13,6 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log"
-
@@ -228,34 +227,6 @@ func (pr *PullRequest) LoadProtectedBranchCtx(ctx context.Context) (err error) {return } // GetDefaultMergeMessage returns default message used when merging pull request func (pr *PullRequest) GetDefaultMergeMessage(ctx context.Context) (string, error) { if pr.HeadRepo == nil { var err error pr.HeadRepo, err = repo_model.GetRepositoryByIDCtx(ctx, pr.HeadRepoID) if err != nil { return "", fmt.Errorf("GetRepositoryById[%d]: %v", pr.HeadRepoID, err) } } if err := pr.LoadIssueCtx(ctx); err != nil { return "", fmt.Errorf("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err) } if err := pr.LoadBaseRepoCtx(ctx); err != nil { return "", fmt.Errorf("LoadBaseRepo: %v", err) } issueReference := "#" if pr.BaseRepo.UnitEnabledCtx(ctx, unit.TypeExternalTracker) { issueReference = "!" } if pr.BaseRepoID == pr.HeadRepoID { return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), nil } return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), nil } // ReviewCount represents a count of Reviews type ReviewCount struct { IssueID int64
-
@@ -338,20 +309,6 @@ func (pr *PullRequest) getReviewedByLines(writer io.Writer) error {return committer.Commit() } // GetDefaultSquashMessage returns default message used when squash and merging pull request func (pr *PullRequest) GetDefaultSquashMessage(ctx context.Context) (string, error) { if err := pr.LoadIssueCtx(ctx); err != nil { return "", fmt.Errorf("LoadIssue: %v", err) } if err := pr.LoadBaseRepoCtx(ctx); err != nil { return "", fmt.Errorf("LoadBaseRepo: %v", err) } if pr.BaseRepo.UnitEnabledCtx(ctx, unit.TypeExternalTracker) { return fmt.Sprintf("%s (!%d)", pr.Issue.Title, pr.Issue.Index), nil } return fmt.Sprintf("%s (#%d)", pr.Issue.Title, pr.Issue.Index), nil } // GetGitRefName returns git ref for hidden pull request branch func (pr *PullRequest) GetGitRefName() string { return fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index)
-
-
-
@@ -8,10 +8,7 @@ import ("testing" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "github.com/stretchr/testify/assert" )
-
@@ -256,53 +253,3 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {pr.Issue.Title = "[wip] " + original assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix()) } func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) msg, err := pr.GetDefaultMergeMessage(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", msg) pr.BaseRepoID = 1 pr.HeadRepoID = 2 msg, err = pr.GetDefaultMergeMessage(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo1:branch2 into master", msg) } func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) externalTracker := repo_model.RepoUnit{ Type: unit.TypeExternalTracker, Config: &repo_model.ExternalTrackerConfig{ ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}", }, } baseRepo := &repo_model.Repository{Name: "testRepo", ID: 1} baseRepo.Owner = &user_model.User{Name: "testOwner"} baseRepo.Units = []*repo_model.RepoUnit{&externalTracker} pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2, BaseRepo: baseRepo}).(*PullRequest) msg, err := pr.GetDefaultMergeMessage(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (!3) from branch2 into master", msg) pr.BaseRepoID = 1 pr.HeadRepoID = 2 msg, err = pr.GetDefaultMergeMessage(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (!3) from user2/repo1:branch2 into master", msg) } func TestPullRequest_GetDefaultSquashMessage(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) msg, err := pr.GetDefaultSquashMessage(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "issue3 (#3)", msg) }
-
-
-
@@ -173,8 +173,6 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {switch colName { case "type": switch unit.Type(db.Cell2Int64(val)) { case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects: r.Config = new(UnitConfig) case unit.TypeExternalWiki: r.Config = new(ExternalWikiConfig) case unit.TypeExternalTracker:
-
@@ -183,8 +181,10 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {r.Config = new(PullRequestsConfig) case unit.TypeIssues: r.Config = new(IssuesConfig) case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects: fallthrough default: panic(fmt.Sprintf("unrecognized repo unit type: %v", *val)) r.Config = new(UnitConfig) } } }
-
-
-
@@ -17,6 +17,7 @@ import ("strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) // Commit represents a git commit.
-
@@ -306,6 +307,35 @@ func (c *Commit) HasFile(filename string) (bool, error) {return true, nil } // GetFileContent reads a file content as a string or returns false if this was not possible func (c *Commit) GetFileContent(filename string, limit int) (string, error) { entry, err := c.GetTreeEntryByPath(filename) if err != nil { return "", err } r, err := entry.Blob().DataAsync() if err != nil { return "", err } defer r.Close() if limit > 0 { bs := make([]byte, limit) n, err := util.ReadAtMost(r, bs) if err != nil { return "", err } return string(bs[:n]), nil } bytes, err := io.ReadAll(r) if err != nil { return "", err } return string(bytes), nil } // GetSubModules get all the sub modules of current revision git tree func (c *Commit) GetSubModules() (*ObjectCache, error) { if c.submoduleCache != nil {
-
-
-
@@ -801,14 +801,26 @@ func MergePullRequest(ctx *context.APIContext) {return } // set defaults to propagate needed fields if err := form.SetDefaults(ctx, pr); err != nil { ctx.ServerError("SetDefaults", fmt.Errorf("SetDefaults: %v", err)) return if len(form.Do) == 0 { form.Do = string(repo_model.MergeStyleMerge) } message := strings.TrimSpace(form.MergeTitleField) if len(message) == 0 { message, err = pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetDefaultMergeMessage", err) return } } form.MergeMessageField = strings.TrimSpace(form.MergeMessageField) if len(form.MergeMessageField) > 0 { message += "\n\n" + form.MergeMessageField } if form.MergeWhenChecksSucceed { scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), form.MergeTitleField) scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message) if err != nil { if pull_model.IsErrAlreadyScheduledToAutoMerge(err) { ctx.Error(http.StatusConflict, "ScheduleAutoMerge", err)
-
@@ -823,7 +835,7 @@ func MergePullRequest(ctx *context.APIContext) {} } if err := pull_service.Merge(pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, form.MergeTitleField); err != nil { if err := pull_service.Merge(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message); 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", repo_model.MergeStyle(form.Do))) } else if models.IsErrMergeConflicts(err) {
-
-
-
@@ -712,8 +712,6 @@ func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull} func getFileContentFromDefaultBranch(ctx *context.Context, filename string) (string, bool) { var bytes []byte if ctx.Repo.Commit == nil { var err error ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
-
@@ -734,7 +732,7 @@ func getFileContentFromDefaultBranch(ctx *context.Context, filename string) (strreturn "", false } defer r.Close() bytes, err = io.ReadAll(r) bytes, err := io.ReadAll(r) if err != nil { return "", false }
-
@@ -1574,26 +1572,42 @@ func ViewIssue(ctx *context.Context) {} prConfig := prUnit.PullRequestsConfig() var mergeStyle repo_model.MergeStyle // Check correct values and select default if ms, ok := ctx.Data["MergeStyle"].(repo_model.MergeStyle); !ok || !prConfig.IsMergeStyleAllowed(ms) { defaultMergeStyle := prConfig.GetDefaultMergeStyle() if prConfig.IsMergeStyleAllowed(defaultMergeStyle) && !ok { ctx.Data["MergeStyle"] = defaultMergeStyle mergeStyle = defaultMergeStyle } else if prConfig.AllowMerge { ctx.Data["MergeStyle"] = repo_model.MergeStyleMerge mergeStyle = repo_model.MergeStyleMerge } else if prConfig.AllowRebase { ctx.Data["MergeStyle"] = repo_model.MergeStyleRebase mergeStyle = repo_model.MergeStyleRebase } else if prConfig.AllowRebaseMerge { ctx.Data["MergeStyle"] = repo_model.MergeStyleRebaseMerge mergeStyle = repo_model.MergeStyleRebaseMerge } else if prConfig.AllowSquash { ctx.Data["MergeStyle"] = repo_model.MergeStyleSquash mergeStyle = repo_model.MergeStyleSquash } else if prConfig.AllowManualMerge { ctx.Data["MergeStyle"] = repo_model.MergeStyleManuallyMerged } else { ctx.Data["MergeStyle"] = "" mergeStyle = repo_model.MergeStyleManuallyMerged } } ctx.Data["MergeStyle"] = mergeStyle defaultMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pull, mergeStyle) if err != nil { ctx.ServerError("GetDefaultMergeMessage", err) return } ctx.Data["DefaultMergeMessage"] = defaultMergeMessage defaultSquashMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash) if err != nil { ctx.ServerError("GetDefaultSquashMergeMessage", err) return } ctx.Data["DefaultSquashMergeMessage"] = defaultSquashMergeMessage if err = pull.LoadProtectedBranch(); err != nil { ctx.ServerError("LoadProtectedBranch", err) return
-
-
-
@@ -950,13 +950,22 @@ func MergePullRequest(ctx *context.Context) {return } // set defaults to propagate needed fields if err := form.SetDefaults(ctx, pr); err != nil { ctx.ServerError("SetDefaults", fmt.Errorf("SetDefaults: %v", err)) return message := strings.TrimSpace(form.MergeTitleField) if len(message) == 0 { var err error message, err = pull_service.GetDefaultMergeMessage(ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) if err != nil { ctx.ServerError("GetDefaultMergeMessage", err) return } } form.MergeMessageField = strings.TrimSpace(form.MergeMessageField) if len(form.MergeMessageField) > 0 { message += "\n\n" + form.MergeMessageField } if err := pull_service.Merge(pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, form.MergeTitleField); err != nil { if err := pull_service.Merge(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message); err != nil { if models.IsErrInvalidMergeStyle(err) { ctx.Flash.Error(ctx.Tr("repo.pulls.invalid_merge_option")) ctx.Redirect(issue.Link())
-
-
-
@@ -234,7 +234,7 @@ func handlePull(pullID int64, sha string) {defer baseGitRepo.Close() } if err := pull_service.Merge(pr, doer, baseGitRepo, scheduledPRM.MergeStyle, "", scheduledPRM.Message); err != nil { if err := pull_service.Merge(ctx, pr, doer, baseGitRepo, scheduledPRM.MergeStyle, "", scheduledPRM.Message); err != nil { log.Error("pull_service.Merge: %v", err) return }
-
-
-
@@ -6,7 +6,6 @@package forms import ( stdContext "context" "net/http" "net/url" "strings"
-
@@ -602,31 +601,6 @@ func (f *MergePullRequestForm) Validate(req *http.Request, errs binding.Errors)return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } // SetDefaults if not provided for mergestyle and commit message func (f *MergePullRequestForm) SetDefaults(ctx stdContext.Context, pr *models.PullRequest) (err error) { if f.Do == "" { f.Do = "merge" } f.MergeTitleField = strings.TrimSpace(f.MergeTitleField) if len(f.MergeTitleField) == 0 { switch f.Do { case "merge", "rebase-merge": f.MergeTitleField, err = pr.GetDefaultMergeMessage(ctx) case "squash": f.MergeTitleField, err = pr.GetDefaultSquashMessage(ctx) } } f.MergeMessageField = strings.TrimSpace(f.MergeMessageField) if len(f.MergeMessageField) > 0 { f.MergeTitleField += "\n\n" + f.MergeMessageField f.MergeMessageField = "" } return } // CodeCommentForm form for adding code comments for PRs type CodeCommentForm struct { Origin string `binding:"Required;In(timeline,diff)"`
-
-
-
@@ -13,6 +13,7 @@ import ("os" "path/filepath" "regexp" "strconv" "strings" "time"
-
@@ -33,9 +34,101 @@ import (issue_service "code.gitea.io/gitea/services/issue" ) // GetDefaultMergeMessage returns default message used when merging pull request func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *models.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { if err := pr.LoadHeadRepo(); err != nil { return "", err } if err := pr.LoadBaseRepo(); err != nil { return "", err } if pr.BaseRepo == nil { return "", repo_model.ErrRepoNotExist{ID: pr.BaseRepoID} } if err := pr.LoadIssue(); err != nil { return "", err } isExternalTracker := pr.BaseRepo.UnitEnabled(unit.TypeExternalTracker) issueReference := "#" if isExternalTracker { issueReference = "!" } if mergeStyle != "" { templateFilepath := fmt.Sprintf(".gitea/default_merge_message/%s_TEMPLATE.md", strings.ToUpper(string(mergeStyle))) commit, err := baseGitRepo.GetBranchCommit(pr.BaseRepo.DefaultBranch) if err != nil { return "", err } templateContent, err := commit.GetFileContent(templateFilepath, setting.Repository.PullRequest.DefaultMergeMessageSize) if err != nil { if !git.IsErrNotExist(err) { return "", err } } else { vars := map[string]string{ "BaseRepoOwnerName": pr.BaseRepo.OwnerName, "BaseRepoName": pr.BaseRepo.Name, "BaseBranch": pr.BaseBranch, "HeadRepoOwnerName": "", "HeadRepoName": "", "HeadBranch": pr.HeadBranch, "PullRequestTitle": pr.Issue.Title, "PullRequestDescription": pr.Issue.Content, "PullRequestPosterName": pr.Issue.Poster.Name, "PullRequestIndex": strconv.FormatInt(pr.Index, 10), "PullRequestReference": fmt.Sprintf("%s%d", issueReference, pr.Index), } if pr.HeadRepo != nil { vars["HeadRepoOwnerName"] = pr.HeadRepo.OwnerName vars["HeadRepoName"] = pr.HeadRepo.Name } refs, err := pr.ResolveCrossReferences(baseGitRepo.Ctx) if err == nil { closeIssueIndexes := make([]string, 0, len(refs)) closeWord := "close" if len(setting.Repository.PullRequest.CloseKeywords) > 0 { closeWord = setting.Repository.PullRequest.CloseKeywords[0] } for _, ref := range refs { if ref.RefAction == references.XRefActionCloses { closeIssueIndexes = append(closeIssueIndexes, fmt.Sprintf("%s %s%d", closeWord, issueReference, ref.Issue.Index)) } } if len(closeIssueIndexes) > 0 { vars["ClosingIssues"] = strings.Join(closeIssueIndexes, ", ") } else { vars["ClosingIssues"] = "" } } return os.Expand(templateContent, func(s string) string { return vars[s] }), nil } } // Squash merge has a different from other styles. if mergeStyle == repo_model.MergeStyleSquash { return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), nil } if pr.BaseRepoID == pr.HeadRepoID { return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), nil } if pr.HeadRepo == nil { return fmt.Sprintf("Merge pull request '%s' (%s%d) from <deleted>:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), nil } return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), nil } // Merge merges pull request to base repository. // Caller should check PR is ready to be merged (review and status checks) func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { if err := pr.LoadHeadRepo(); err != nil { log.Error("LoadHeadRepo: %v", err) return fmt.Errorf("LoadHeadRepo: %v", err)
-
@@ -79,18 +172,18 @@ func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repospr.Merger = doer pr.MergerID = doer.ID if _, err := pr.SetMerged(db.DefaultContext); err != nil { if _, err := pr.SetMerged(ctx); err != nil { log.Error("setMerged [%d]: %v", pr.ID, err) } if err := pr.LoadIssueCtx(db.DefaultContext); err != nil { if err := pr.LoadIssueCtx(ctx); err != nil { log.Error("loadIssue [%d]: %v", pr.ID, err) } if err := pr.Issue.LoadRepo(db.DefaultContext); err != nil { if err := pr.Issue.LoadRepo(ctx); err != nil { log.Error("loadRepo for issue [%d]: %v", pr.ID, err) } if err := pr.Issue.Repo.GetOwner(db.DefaultContext); err != nil { if err := pr.Issue.Repo.GetOwner(ctx); err != nil { log.Error("GetOwner for issue repo [%d]: %v", pr.ID, err) }
-
@@ -100,17 +193,17 @@ func Merge(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Reposcache.Remove(pr.Issue.Repo.GetCommitsCountCacheKey(pr.BaseBranch, true)) // Resolve cross references refs, err := pr.ResolveCrossReferences(db.DefaultContext) refs, err := pr.ResolveCrossReferences(ctx) if err != nil { log.Error("ResolveCrossReferences: %v", err) return nil } for _, ref := range refs { if err = ref.LoadIssueCtx(db.DefaultContext); err != nil { if err = ref.LoadIssueCtx(ctx); err != nil { return err } if err = ref.Issue.LoadRepo(db.DefaultContext); err != nil { if err = ref.Issue.LoadRepo(ctx); err != nil { return err } close := ref.RefAction == references.XRefActionCloses
-
-
-
@@ -8,6 +8,12 @@ package pullimport ( "testing" "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/git" "github.com/stretchr/testify/assert" )
-
@@ -29,3 +35,57 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) {assert.True(t, commitMessageTrailersPattern.MatchString("Additional whitespace is accepted.\n\nSigned-off-by \t : \tBob <bob@example.com> ")) assert.True(t, commitMessageTrailersPattern.MatchString("Folded value.\n\nFolded-trailer: This is\n a folded\n trailer value\nOther-Trailer: Value")) } func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) assert.NoError(t, err) defer gitRepo.Close() mergeMessage, err := GetDefaultMergeMessage(gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", mergeMessage) pr.BaseRepoID = 1 pr.HeadRepoID = 2 mergeMessage, err = GetDefaultMergeMessage(gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo1:branch2 into master", mergeMessage) } func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) externalTracker := repo_model.RepoUnit{ Type: unit.TypeExternalTracker, Config: &repo_model.ExternalTrackerConfig{ ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}", }, } baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) baseRepo.Units = []*repo_model.RepoUnit{&externalTracker} pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2, BaseRepo: baseRepo}).(*models.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) assert.NoError(t, err) defer gitRepo.Close() mergeMessage, err := GetDefaultMergeMessage(gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (!3) from branch2 into master", mergeMessage) pr.BaseRepoID = 1 pr.HeadRepoID = 2 pr.BaseRepo = nil pr.HeadRepo = nil mergeMessage, err = GetDefaultMergeMessage(gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo2:branch2 into master", mergeMessage) }
-
-
-
@@ -329,7 +329,7 @@{{.CsrfTokenHtml}} <input type="hidden" name="head_commit_id" value="{{.PullHeadCommitID}}"> <div class="field"> <input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage $.Context}}"> <input type="text" name="merge_title_field" value="{{.DefaultMergeMessage}}"> </div> <div class="field"> <textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">Reviewed-on: {{$.Issue.HTMLURL}} {{$approvers}}</textarea>
-
@@ -375,10 +375,7 @@{{.CsrfTokenHtml}} <input type="hidden" name="head_commit_id" value="{{.PullHeadCommitID}}"> <div class="field"> <input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultMergeMessage $.Context}}"> </div> <div class="field"> <textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">Reviewed-on: {{$.Issue.HTMLURL}} {{$approvers}}</textarea> <input type="text" name="merge_title_field" value="{{.DefaultMergeMessage}}"> </div> <button class="ui green button" type="submit" name="do" value="rebase-merge"> {{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
-
@@ -401,7 +398,7 @@{{.CsrfTokenHtml}} <input type="hidden" name="head_commit_id" value="{{.PullHeadCommitID}}"> <div class="field"> <input type="text" name="merge_title_field" value="{{.Issue.PullRequest.GetDefaultSquashMessage $.Context}}"> <input type="text" name="merge_title_field" value="{{.DefaultSquashMergeMessage}}"> </div> <div class="field"> <textarea name="merge_message_field" rows="5" placeholder="{{$.i18n.Tr "repo.editor.commit_message_desc"}}">{{.GetCommitMessages}}Reviewed-on: {{$.Issue.HTMLURL}} {{$approvers}}</textarea>
-