Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rebase with merge commit merge style (#3844) #4052

Merged
merged 16 commits into from Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions integrations/pull_merge_test.go
Expand Up @@ -76,6 +76,20 @@ func TestPullRebase(t *testing.T) {
testPullMerge(t, session, elem[1], elem[2], elem[4], models.MergeStyleRebase)
}

func TestPullRebaseMergeCommit(t *testing.T) {
// TODO
apricote marked this conversation as resolved.
Show resolved Hide resolved
prepareTestEnv(t)
session := loginUser(t, "user1")
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
// TODO
resp := testPullCreate(t, session, "user1", "repo1", "master", "This is a pull title")

elem := strings.Split(test.RedirectURL(resp), "/")
assert.EqualValues(t, "pulls", elem[3])
testPullMerge(t, session, elem[1], elem[2], elem[4], models.MergeStyleRebaseMergeCommit)
}

func TestPullSquash(t *testing.T) {
prepareTestEnv(t)
session := loginUser(t, "user1")
Expand Down
4 changes: 2 additions & 2 deletions models/fixtures/repo_unit.yml
Expand Up @@ -30,7 +30,7 @@
id: 5
repo_id: 1
type: 3
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowSquash\":true}"
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMergeCommit\":true,\"AllowSquash\":true}"
created_unix: 946684810

-
Expand All @@ -51,7 +51,7 @@
id: 8
repo_id: 3
type: 3
config: "{\"IgnoreWhitespaceConflicts\":true,\"AllowMerge\":true,\"AllowRebase\":false,\"AllowSquash\":false}"
config: "{\"IgnoreWhitespaceConflicts\":true,\"AllowMerge\":true,\"AllowRebase\":false,\"AllowRebaseMergeCommit\":true,\"AllowSquash\":false}"
created_unix: 946684810

-
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Expand Up @@ -186,6 +186,8 @@ var migrations = []Migration{
NewMigration("add u2f", addU2FReg),
// v66 -> v67
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
// v67 -> v68
NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMergeCommit),
}

// Migrate database to current version
Expand Down
49 changes: 49 additions & 0 deletions models/migrations/v67.go
@@ -0,0 +1,49 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
"fmt"

"code.gitea.io/gitea/modules/util"

"github.com/go-xorm/xorm"
)

func addPullRequestRebaseWithMergeCommit(x *xorm.Engine) error {
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix util.TimeStamp `xorm:"INDEX CREATED"`
}

sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}

//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
if err := sess.Where("`type` = ?", V16UnitTypePRs).Find(&units); err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["AllowRebaseMergeCommit"]; !ok {
apricote marked this conversation as resolved.
Show resolved Hide resolved
unit.Config["AllowRebaseMergeCommit"] = true
}
if _, err := sess.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return sess.Commit()

}
28 changes: 28 additions & 0 deletions models/pull.go
Expand Up @@ -270,6 +270,8 @@ const (
MergeStyleMerge MergeStyle = "merge"
// MergeStyleRebase rebase before merging
MergeStyleRebase MergeStyle = "rebase"
// MergeStyleRebaseMergeCommit rebase before merging with merge commit (--no-ff)
MergeStyleRebaseMergeCommit MergeStyle = "rebase-merge-commit"
apricote marked this conversation as resolved.
Show resolved Hide resolved
// MergeStyleSquash squash commits into single commit before merging
MergeStyleSquash MergeStyle = "squash"
)
Expand Down Expand Up @@ -407,6 +409,32 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
"git", "merge", "--ff-only", "-q", "head_repo_"+pr.HeadBranch); err != nil {
return fmt.Errorf("git merge --ff-only [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
}
case MergeStyleRebaseMergeCommit:
// Checkout head branch
if _, stderr, err = process.GetManager().ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
"git", "checkout", "-b", "head_repo_"+pr.HeadBranch, "head_repo/"+pr.HeadBranch); err != nil {
return fmt.Errorf("git checkout: %s", stderr)
}
// Rebase before merging
if _, stderr, err = process.GetManager().ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge (git rebase): %s", tmpBasePath),
"git", "rebase", "-q", pr.BaseBranch); err != nil {
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
}
// Checkout base branch again
if _, stderr, err = process.GetManager().ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
"git", "checkout", pr.BaseBranch); err != nil {
return fmt.Errorf("git checkout: %s", stderr)
}
// Merge with commit
if _, stderr, err = process.GetManager().ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge (git rebase): %s", tmpBasePath),
"git", "merge", "--no-ff", "-q", "head_repo_"+pr.HeadBranch); err != nil {
return fmt.Errorf("git merge --no-ff [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
}

case MergeStyleSquash:
// Merge with squash
if _, stderr, err = process.GetManager().ExecDir(-1, tmpBasePath,
Expand Down
2 changes: 2 additions & 0 deletions models/repo_unit.go
Expand Up @@ -90,6 +90,7 @@ type PullRequestsConfig struct {
IgnoreWhitespaceConflicts bool
AllowMerge bool
AllowRebase bool
AllowRebaseMergeCommit bool
AllowSquash bool
}

Expand All @@ -107,6 +108,7 @@ func (cfg *PullRequestsConfig) ToDB() ([]byte, error) {
func (cfg *PullRequestsConfig) IsMergeStyleAllowed(mergeStyle MergeStyle) bool {
return mergeStyle == MergeStyleMerge && cfg.AllowMerge ||
mergeStyle == MergeStyleRebase && cfg.AllowRebase ||
mergeStyle == MergeStyleRebaseMergeCommit && cfg.AllowRebaseMergeCommit ||
mergeStyle == MergeStyleSquash && cfg.AllowSquash
}

Expand Down
3 changes: 2 additions & 1 deletion modules/auth/repo_form.go
Expand Up @@ -110,6 +110,7 @@ type RepoSettingForm struct {
PullsIgnoreWhitespace bool
PullsAllowMerge bool
PullsAllowRebase bool
PullsAllowRebaseMergeCommit bool
PullsAllowSquash bool
EnableTimetracker bool
AllowOnlyContributorsToTrackTime bool
Expand Down Expand Up @@ -352,7 +353,7 @@ func (f *InitializeLabelsForm) Validate(ctx *macaron.Context, errs binding.Error

// MergePullRequestForm form for merging Pull Request
type MergePullRequestForm struct {
Do string `binding:"Required;In(merge,rebase,squash)"`
Do string `binding:"Required;In(merge,rebase,rebase-merge-commit,squash)"`
MergeTitleField string
MergeMessageField string
}
Expand Down
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Expand Up @@ -810,6 +810,7 @@ pulls.no_merge_desc = This pull request cannot be merged because all repository
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
pulls.merge_pull_request = Merge Pull Request
pulls.rebase_merge_pull_request = Rebase and Merge
pulls.rebase_merge_commit_pull_request = Rebase and Merge (--no-ff)
pulls.squash_merge_pull_request = Squash and Merge
pulls.invalid_merge_option = You cannot use this merge option for this pull request.
pulls.open_unmerged_pull_exists = `You cannot perform a reopen operation because there is a pending pull request (#%d) with identical properties.`
Expand Down Expand Up @@ -953,6 +954,7 @@ settings.pulls_desc = Enable Repository Pull Requests
settings.pulls.ignore_whitespace = Ignore Whitespace for Conflicts
settings.pulls.allow_merge_commits = Enable Commit Merging
settings.pulls.allow_rebase_merge = Enable Rebasing to Merge Commits
settings.pulls.allow_rebase_merge_commit = Enable Rebasing with explicit merge commits (--no-ff)
settings.pulls.allow_squash_commits = Enable Squashing to Merge Commits
settings.admin_settings = Administrator Settings
settings.admin_enable_health_check = Enable Repository Health Checks (git fsck)
Expand Down
2 changes: 2 additions & 0 deletions routers/repo/issue.go
Expand Up @@ -765,6 +765,8 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["MergeStyle"] = models.MergeStyleMerge
} else if prConfig.AllowRebase {
ctx.Data["MergeStyle"] = models.MergeStyleRebase
} else if prConfig.AllowRebaseMergeCommit {
ctx.Data["MergeStyle"] = models.MergeStyleRebaseMergeCommit
} else if prConfig.AllowSquash {
ctx.Data["MergeStyle"] = models.MergeStyleSquash
} else {
Expand Down
3 changes: 3 additions & 0 deletions routers/repo/pull.go
Expand Up @@ -512,6 +512,9 @@ func MergePullRequest(ctx *context.Context, form auth.MergePullRequestForm) {
if models.MergeStyle(form.Do) == models.MergeStyleMerge {
message = pr.GetDefaultMergeMessage()
}
if models.MergeStyle(form.Do) == models.MergeStyleRebaseMergeCommit {
message = pr.GetDefaultMergeMessage()
}
if models.MergeStyle(form.Do) == models.MergeStyleSquash {
message = pr.GetDefaultSquashMessage()
}
Expand Down
1 change: 1 addition & 0 deletions routers/repo/setting.go
Expand Up @@ -215,6 +215,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
IgnoreWhitespaceConflicts: form.PullsIgnoreWhitespace,
AllowMerge: form.PullsAllowMerge,
AllowRebase: form.PullsAllowRebase,
AllowRebaseMergeCommit: form.PullsAllowRebaseMergeCommit,
AllowSquash: form.PullsAllowSquash,
},
})
Expand Down
21 changes: 20 additions & 1 deletion templates/repo/issue/view_content/pull.tmpl
Expand Up @@ -39,7 +39,7 @@
</div>
{{if .AllowMerge}}
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowSquash}}
{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowRebaseMergeCommit $prUnit.PullRequestsConfig.AllowSquash}}
<div class="ui divider"></div>
{{if $prUnit.PullRequestsConfig.AllowMerge}}
<div class="ui form merge-fields" style="display: none">
Expand Down Expand Up @@ -73,6 +73,19 @@
</form>
</div>
{{end}}
{{if $prUnit.PullRequestsConfig.AllowRebaseMergeCommit}}
<div class="ui form rebase-merge-commit-fields" style="display: none">
<form action="{{.Link}}/merge" method="post">
{{.CsrfTokenHtml}}
<button class="ui green button" type="submit" name="do" value="rebase-merge-commit">
{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
</button>
<button class="ui button merge-cancel">
{{$.i18n.Tr "cancel"}}
</button>
</form>
</div>
{{end}}
{{if $prUnit.PullRequestsConfig.AllowSquash}}
<div class="ui form squash-fields" style="display: none">
<form action="{{.Link}}/merge" method="post">
Expand Down Expand Up @@ -102,6 +115,9 @@
{{if eq .MergeStyle "rebase"}}
{{$.i18n.Tr "repo.pulls.rebase_merge_pull_request"}}
{{end}}
{{if eq .MergeStyle "rebase-merge-commit"}}
{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
{{end}}
{{if eq .MergeStyle "squash"}}
{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}
{{end}}
Expand All @@ -116,6 +132,9 @@
{{if $prUnit.PullRequestsConfig.AllowRebase}}
<div class="item{{if eq .MergeStyle "rebase"}} active selected{{end}}" data-do="rebase">{{$.i18n.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
{{end}}
{{if $prUnit.PullRequestsConfig.AllowRebaseMergeCommit}}
<div class="item{{if eq .MergeStyle "rebase-merge-commit"}} active selected{{end}}" data-do="rebase-merge-commit">{{$.i18n.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
{{end}}
{{if $prUnit.PullRequestsConfig.AllowSquash}}
<div class="item{{if eq .MergeStyle "squash"}} active selected{{end}}" data-do="squash">{{$.i18n.Tr "repo.pulls.squash_merge_pull_request"}}</div>
{{end}}
Expand Down
6 changes: 6 additions & 0 deletions templates/repo/settings/options.tmpl
Expand Up @@ -221,6 +221,12 @@
<label>{{.i18n.Tr "repo.settings.pulls.allow_rebase_merge"}}</label>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input name="pulls_allow_rebase_merge_commit" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseMergeCommit)}}checked{{end}}>
<label>{{.i18n.Tr "repo.settings.pulls.allow_rebase_merge_commit"}}</label>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input name="pulls_allow_squash" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowSquash)}}checked{{end}}>
Expand Down