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 Pull Request merge options - Ignore white-space for conflict checking, Rebase, Squash merge #3188

Merged
merged 17 commits into from
Jan 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions integrations/pull_merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@ import (
"strings"
"testing"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/test"

"github.com/stretchr/testify/assert"
)

func testPullMerge(t *testing.T, session *TestSession, user, repo, pullnum string) *httptest.ResponseRecorder {
func testPullMerge(t *testing.T, session *TestSession, user, repo, pullnum string, mergeStyle models.MergeStyle) *httptest.ResponseRecorder {
req := NewRequest(t, "GET", path.Join(user, repo, "pulls", pullnum))
resp := session.MakeRequest(t, req, http.StatusOK)

// Click the little green button to create a pull
htmlDoc := NewHTMLParser(t, resp.Body)
link, exists := htmlDoc.doc.Find("form.ui.form>button.ui.green.button").Parent().Attr("action")
link, exists := htmlDoc.doc.Find(".ui.form." + string(mergeStyle) + "-fields > form").Attr("action")
assert.True(t, exists, "The template has changed")
req = NewRequestWithValues(t, "POST", link, map[string]string{
"_csrf": htmlDoc.GetCSRF(),
"do": string(mergeStyle),
})
resp = session.MakeRequest(t, req, http.StatusFound)

Expand Down Expand Up @@ -58,7 +60,34 @@ func TestPullMerge(t *testing.T) {

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

func TestPullRebase(t *testing.T) {
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")

resp := testPullCreate(t, session, "user1", "repo1", "master")

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

func TestPullSquash(t *testing.T) {
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")
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited!)\n")

resp := testPullCreate(t, session, "user1", "repo1", "master")

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

func TestPullCleanUpAfterMerge(t *testing.T) {
Expand All @@ -71,7 +100,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) {

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

// Check PR branch deletion
resp = testPullCleanUp(t, session, elem[1], elem[2], elem[4])
Expand Down
3 changes: 2 additions & 1 deletion integrations/repo_activity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"testing"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/test"

"github.com/stretchr/testify/assert"
Expand All @@ -24,7 +25,7 @@ func TestRepoActivity(t *testing.T) {
resp := testPullCreate(t, session, "user1", "repo1", "master")
elem := strings.Split(test.RedirectURL(resp), "/")
assert.EqualValues(t, "pulls", elem[3])
testPullMerge(t, session, elem[1], elem[2], elem[4])
testPullMerge(t, session, elem[1], elem[2], elem[4], models.MergeStyleMerge)

testEditFileToNewBranch(t, session, "user1", "repo1", "master", "feat/better_readme", "README.md", "Hello, World (Edited Again)\n")
testPullCreate(t, session, "user1", "repo1", "feat/better_readme")
Expand Down
17 changes: 17 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,23 @@ func (err ErrPullRequestAlreadyExists) Error() string {
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
}

// ErrInvalidMergeStyle represents an error if merging with disabled merge strategy
type ErrInvalidMergeStyle struct {
ID int64
Style MergeStyle
}

// IsErrInvalidMergeStyle checks if an error is a ErrInvalidMergeStyle.
func IsErrInvalidMergeStyle(err error) bool {
_, ok := err.(ErrInvalidMergeStyle)
return ok
}

func (err ErrInvalidMergeStyle) Error() string {
return fmt.Sprintf("merge strategy is not allowed or is invalid [repo_id: %d, strategy: %s]",
err.ID, err.Style)
}

// _________ __
// \_ ___ \ ____ _____ _____ ____ _____/ |_
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
Expand Down
4 changes: 2 additions & 2 deletions models/fixtures/repo_unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
id: 5
repo_id: 1
type: 3
config: "{}"
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowSquash\":true}"
created_unix: 946684810

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

-
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ var migrations = []Migration{
NewMigration("add lfs lock table", addLFSLock),
// v53 -> v54
NewMigration("add reactions", addReactions),
// v54 -> v55
NewMigration("add pull request options", addPullRequestOptions),
}

// Migrate database to current version
Expand Down
57 changes: 57 additions & 0 deletions models/migrations/v54.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2017 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 addPullRequestOptions(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["IgnoreWhitespaceConflicts"]; !ok {
unit.Config["IgnoreWhitespaceConflicts"] = false
}
if _, ok := unit.Config["AllowMerge"]; !ok {
unit.Config["AllowMerge"] = true
}
if _, ok := unit.Config["AllowRebase"]; !ok {
unit.Config["AllowRebase"] = true
}
if _, ok := unit.Config["AllowSquash"]; !ok {
unit.Config["AllowSquash"] = true
}
if _, err := sess.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return sess.Commit()
}
Loading