Add DefaultMergeStyle option to repository (#14789)

Fixes #12293
This commit is contained in:
parnic 2021-03-27 09:55:40 -05:00 committed by GitHub
parent 6b836ac5f7
commit f4d27498bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 70 additions and 2 deletions

View file

@ -1086,7 +1086,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO
units = append(units, RepoUnit{ units = append(units, RepoUnit{
RepoID: repo.ID, RepoID: repo.ID,
Type: tp, Type: tp,
Config: &PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true}, Config: &PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: MergeStyleMerge},
}) })
} else { } else {
units = append(units, RepoUnit{ units = append(units, RepoUnit{

View file

@ -102,6 +102,7 @@ type PullRequestsConfig struct {
AllowSquash bool AllowSquash bool
AllowManualMerge bool AllowManualMerge bool
AutodetectManualMerge bool AutodetectManualMerge bool
DefaultMergeStyle MergeStyle
} }
// FromDB fills up a PullRequestsConfig from serialized format. // FromDB fills up a PullRequestsConfig from serialized format.
@ -125,6 +126,15 @@ func (cfg *PullRequestsConfig) IsMergeStyleAllowed(mergeStyle MergeStyle) bool {
mergeStyle == MergeStyleManuallyMerged && cfg.AllowManualMerge mergeStyle == MergeStyleManuallyMerged && cfg.AllowManualMerge
} }
// GetDefaultMergeStyle returns the default merge style for this pull request
func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
if len(cfg.DefaultMergeStyle) != 0 {
return cfg.DefaultMergeStyle
}
return MergeStyleMerge
}
// AllowedMergeStyleCount returns the total count of allowed merge styles for the PullRequestsConfig // AllowedMergeStyleCount returns the total count of allowed merge styles for the PullRequestsConfig
func (cfg *PullRequestsConfig) AllowedMergeStyleCount() int { func (cfg *PullRequestsConfig) AllowedMergeStyleCount() int {
count := 0 count := 0

View file

@ -71,6 +71,7 @@ func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool)
allowRebase := false allowRebase := false
allowRebaseMerge := false allowRebaseMerge := false
allowSquash := false allowSquash := false
defaultMergeStyle := models.MergeStyleMerge
if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil { if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
config := unit.PullRequestsConfig() config := unit.PullRequestsConfig()
hasPullRequests = true hasPullRequests = true
@ -79,6 +80,7 @@ func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool)
allowRebase = config.AllowRebase allowRebase = config.AllowRebase
allowRebaseMerge = config.AllowRebaseMerge allowRebaseMerge = config.AllowRebaseMerge
allowSquash = config.AllowSquash allowSquash = config.AllowSquash
defaultMergeStyle = config.GetDefaultMergeStyle()
} }
hasProjects := false hasProjects := false
if _, err := repo.GetUnit(models.UnitTypeProjects); err == nil { if _, err := repo.GetUnit(models.UnitTypeProjects); err == nil {
@ -139,6 +141,7 @@ func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool)
AllowRebase: allowRebase, AllowRebase: allowRebase,
AllowRebaseMerge: allowRebaseMerge, AllowRebaseMerge: allowRebaseMerge,
AllowSquash: allowSquash, AllowSquash: allowSquash,
DefaultMergeStyle: string(defaultMergeStyle),
AvatarURL: repo.AvatarLink(), AvatarURL: repo.AvatarLink(),
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate, Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
MirrorInterval: mirrorInterval, MirrorInterval: mirrorInterval,

View file

@ -140,6 +140,7 @@ type RepoSettingForm struct {
PullsAllowRebaseMerge bool PullsAllowRebaseMerge bool
PullsAllowSquash bool PullsAllowSquash bool
PullsAllowManualMerge bool PullsAllowManualMerge bool
PullsDefaultMergeStyle string
EnableAutodetectManualMerge bool EnableAutodetectManualMerge bool
EnableTimetracker bool EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool AllowOnlyContributorsToTrackTime bool

View file

@ -89,6 +89,7 @@ type Repository struct {
AllowRebase bool `json:"allow_rebase"` AllowRebase bool `json:"allow_rebase"`
AllowRebaseMerge bool `json:"allow_rebase_explicit"` AllowRebaseMerge bool `json:"allow_rebase_explicit"`
AllowSquash bool `json:"allow_squash_merge"` AllowSquash bool `json:"allow_squash_merge"`
DefaultMergeStyle string `json:"default_merge_style"`
AvatarURL string `json:"avatar_url"` AvatarURL string `json:"avatar_url"`
Internal bool `json:"internal"` Internal bool `json:"internal"`
MirrorInterval string `json:"mirror_interval"` MirrorInterval string `json:"mirror_interval"`
@ -171,6 +172,8 @@ type EditRepoOption struct {
AllowManualMerge *bool `json:"allow_manual_merge,omitempty"` AllowManualMerge *bool `json:"allow_manual_merge,omitempty"`
// either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur. // either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur.
AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"` AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"`
// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`.
DefaultMergeStyle *string `json:"default_merge_style,omitempty"`
// set to `true` to archive this repository. // set to `true` to archive this repository.
Archived *bool `json:"archived,omitempty"` Archived *bool `json:"archived,omitempty"`
// set to a string like `8h30m0s` to set the mirror interval time // set to a string like `8h30m0s` to set the mirror interval time

View file

@ -1791,6 +1791,7 @@ settings.block_on_official_review_requests_desc = Merging will not be possible w
settings.block_outdated_branch = Block merge if pull request is outdated settings.block_outdated_branch = Block merge if pull request is outdated
settings.block_outdated_branch_desc = Merging will not be possible when head branch is behind base branch. settings.block_outdated_branch_desc = Merging will not be possible when head branch is behind base branch.
settings.default_branch_desc = Select a default repository branch for pull requests and code commits: settings.default_branch_desc = Select a default repository branch for pull requests and code commits:
settings.default_merge_style_desc = Default merge style for pull requests:
settings.choose_branch = Choose a branch… settings.choose_branch = Choose a branch…
settings.no_protected_branch = There are no protected branches. settings.no_protected_branch = There are no protected branches.
settings.edit_protected_branch = Edit settings.edit_protected_branch = Edit

View file

@ -731,6 +731,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
AllowSquash: true, AllowSquash: true,
AllowManualMerge: true, AllowManualMerge: true,
AutodetectManualMerge: false, AutodetectManualMerge: false,
DefaultMergeStyle: models.MergeStyleMerge,
} }
} else { } else {
config = unit.PullRequestsConfig() config = unit.PullRequestsConfig()
@ -757,6 +758,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if opts.AutodetectManualMerge != nil { if opts.AutodetectManualMerge != nil {
config.AutodetectManualMerge = *opts.AutodetectManualMerge config.AutodetectManualMerge = *opts.AutodetectManualMerge
} }
if opts.DefaultMergeStyle != nil {
config.DefaultMergeStyle = models.MergeStyle(*opts.DefaultMergeStyle)
}
units = append(units, models.RepoUnit{ units = append(units, models.RepoUnit{
RepoID: repo.ID, RepoID: repo.ID,

View file

@ -1484,7 +1484,10 @@ func ViewIssue(ctx *context.Context) {
// Check correct values and select default // Check correct values and select default
if ms, ok := ctx.Data["MergeStyle"].(models.MergeStyle); !ok || if ms, ok := ctx.Data["MergeStyle"].(models.MergeStyle); !ok ||
!prConfig.IsMergeStyleAllowed(ms) { !prConfig.IsMergeStyleAllowed(ms) {
if prConfig.AllowMerge { defaultMergeStyle := prConfig.GetDefaultMergeStyle()
if prConfig.IsMergeStyleAllowed(defaultMergeStyle) && !ok {
ctx.Data["MergeStyle"] = defaultMergeStyle
} else if prConfig.AllowMerge {
ctx.Data["MergeStyle"] = models.MergeStyleMerge ctx.Data["MergeStyle"] = models.MergeStyleMerge
} else if prConfig.AllowRebase { } else if prConfig.AllowRebase {
ctx.Data["MergeStyle"] = models.MergeStyleRebase ctx.Data["MergeStyle"] = models.MergeStyleRebase

View file

@ -322,6 +322,7 @@ func SettingsPost(ctx *context.Context) {
AllowSquash: form.PullsAllowSquash, AllowSquash: form.PullsAllowSquash,
AllowManualMerge: form.PullsAllowManualMerge, AllowManualMerge: form.PullsAllowManualMerge,
AutodetectManualMerge: form.EnableAutodetectManualMerge, AutodetectManualMerge: form.EnableAutodetectManualMerge,
DefaultMergeStyle: models.MergeStyle(form.PullsDefaultMergeStyle),
}, },
}) })
} else if !models.UnitTypePullRequests.UnitGlobalDisabled() { } else if !models.UnitTypePullRequests.UnitGlobalDisabled() {

View file

@ -346,6 +346,39 @@
<label>{{.i18n.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label> <label>{{.i18n.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
</div> </div>
</div> </div>
<div class="field">
<p>
{{.i18n.Tr "repo.settings.default_merge_style_desc"}}
</p>
<div class="ui dropdown selection" tabindex="0">
<select name="pulls_default_merge_style">
<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}selected{{end}}>{{.i18n.Tr "repo.pulls.merge_pull_request"}}</option>
<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}selected{{end}}>{{.i18n.Tr "repo.pulls.rebase_merge_pull_request"}}</option>
<option value="rebase-merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}selected{{end}}>{{.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</option>
<option value="squash" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}selected{{end}}>{{.i18n.Tr "repo.pulls.squash_merge_pull_request"}}</option>
</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="default text">
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}
{{.i18n.Tr "repo.pulls.merge_pull_request"}}
{{end}}
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}
{{.i18n.Tr "repo.pulls.rebase_merge_pull_request"}}
{{end}}
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}
{{.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
{{end}}
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}
{{.i18n.Tr "repo.pulls.squash_merge_pull_request"}}
{{end}}
</div>
<div class="menu transition hidden" tabindex="-1" style="display: block !important;">
<div class="item" data-value="merge">{{.i18n.Tr "repo.pulls.merge_pull_request"}}</div>
<div class="item" data-value="rebase">{{.i18n.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
<div class="item" data-value="rebase-merge">{{.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
<div class="item" data-value="squash">{{.i18n.Tr "repo.pulls.squash_merge_pull_request"}}</div>
</div>
</div>
</div>
</div> </div>
{{end}} {{end}}

View file

@ -13626,6 +13626,11 @@
"type": "string", "type": "string",
"x-go-name": "DefaultBranch" "x-go-name": "DefaultBranch"
}, },
"default_merge_style": {
"description": "set to a merge style to be used by this repository: \"merge\", \"rebase\", \"rebase-merge\", or \"squash\". `has_pull_requests` must be `true`.",
"type": "string",
"x-go-name": "DefaultMergeStyle"
},
"description": { "description": {
"description": "a short description of the repository.", "description": "a short description of the repository.",
"type": "string", "type": "string",
@ -15676,6 +15681,10 @@
"type": "string", "type": "string",
"x-go-name": "DefaultBranch" "x-go-name": "DefaultBranch"
}, },
"default_merge_style": {
"type": "string",
"x-go-name": "DefaultMergeStyle"
},
"description": { "description": {
"type": "string", "type": "string",
"x-go-name": "Description" "x-go-name": "Description"