mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Allow custom default merge message with .gitea/default_merge_message/<merge_style>_TEMPLATE.md (#18177)
* Allow custom default merge message with .gitea/MERGE_MESSAGE_<merge_style>_TEMPLATE.md * Some improvements * Follow some advices * Fix bug * Fix bug * Fix lint * Fix close comment * Fix test * Fix and docs * Improve codes * Update docs and remove unnecessary variables * return error for GetDefaultMergeMessage * Fix test * improve code * ignore unknow unit type * return error for GetDefaultMergeMessage * Update services/pull/merge.go * Some improvements * Follow some advices * Fix bug * Fix lint * Improve codes * Update docs and remove unnecessary variables * return error for GetDefaultMergeMessage * improve code * Handle deleted HeadRepo in GetDefaultMergeMessage Signed-off-by: Andrew Thornton <art27@cantab.net> * Fix test * Fix test Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
		| @@ -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.Repos | ||||
| 	pr.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.Repos | ||||
| 	cache.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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user