mirror of
https://gitcode.com/gitea/gitea.git
synced 2025-05-31 15:21:00 +08:00
Add merge style fast-forward-only
(#28954)
With this option, it is possible to require a linear commit history with the following benefits over the next best option `Rebase+fast-forward`: The original commits continue existing, with the original signatures continuing to stay valid instead of being rewritten, there is no merge commit, and reverting commits becomes easier. Closes #24906
This commit is contained in:
@ -65,6 +65,7 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
|
||||
allowRebase := false
|
||||
allowRebaseMerge := false
|
||||
allowSquash := false
|
||||
allowFastForwardOnly := false
|
||||
if unit, err := repo.GetUnit(db.DefaultContext, unit_model.TypePullRequests); err == nil {
|
||||
config := unit.PullRequestsConfig()
|
||||
hasPullRequests = true
|
||||
@ -73,6 +74,7 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
|
||||
allowRebase = config.AllowRebase
|
||||
allowRebaseMerge = config.AllowRebaseMerge
|
||||
allowSquash = config.AllowSquash
|
||||
allowFastForwardOnly = config.AllowFastForwardOnly
|
||||
}
|
||||
archived := repo.IsArchived
|
||||
return &api.EditRepoOption{
|
||||
@ -92,6 +94,7 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
|
||||
AllowRebase: &allowRebase,
|
||||
AllowRebaseMerge: &allowRebaseMerge,
|
||||
AllowSquash: &allowSquash,
|
||||
AllowFastForwardOnly: &allowFastForwardOnly,
|
||||
Archived: &archived,
|
||||
}
|
||||
}
|
||||
|
@ -365,6 +365,90 @@ func TestCantMergeUnrelated(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestFastForwardOnlyMerge(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
|
||||
session := loginUser(t, "user1")
|
||||
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "update", "README.md", "Hello, World 2\n")
|
||||
|
||||
// Use API to create a pr from update to master
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", "user1", "repo1"), &api.CreatePullRequestOption{
|
||||
Head: "update",
|
||||
Base: "master",
|
||||
Title: "create a pr that can be fast-forward-only merged",
|
||||
}).AddTokenAuth(token)
|
||||
session.MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{
|
||||
Name: "user1",
|
||||
})
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{
|
||||
OwnerID: user1.ID,
|
||||
Name: "repo1",
|
||||
})
|
||||
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
|
||||
HeadRepoID: repo1.ID,
|
||||
BaseRepoID: repo1.ID,
|
||||
HeadBranch: "update",
|
||||
BaseBranch: "master",
|
||||
})
|
||||
|
||||
gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleFastForwardOnly, "", "FAST-FORWARD-ONLY", false)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
gitRepo.Close()
|
||||
})
|
||||
}
|
||||
|
||||
func TestCantFastForwardOnlyMergeDiverging(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
|
||||
session := loginUser(t, "user1")
|
||||
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "diverging", "README.md", "Hello, World diverged\n")
|
||||
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World 2\n")
|
||||
|
||||
// Use API to create a pr from diverging to update
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", "user1", "repo1"), &api.CreatePullRequestOption{
|
||||
Head: "diverging",
|
||||
Base: "master",
|
||||
Title: "create a pr from a diverging branch",
|
||||
}).AddTokenAuth(token)
|
||||
session.MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{
|
||||
Name: "user1",
|
||||
})
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{
|
||||
OwnerID: user1.ID,
|
||||
Name: "repo1",
|
||||
})
|
||||
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
|
||||
HeadRepoID: repo1.ID,
|
||||
BaseRepoID: repo1.ID,
|
||||
HeadBranch: "diverging",
|
||||
BaseBranch: "master",
|
||||
})
|
||||
|
||||
gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleFastForwardOnly, "", "DIVERGING", false)
|
||||
|
||||
assert.Error(t, err, "Merge should return an error due to being for a diverging branch")
|
||||
assert.True(t, models.IsErrMergeDivergingFastForwardOnly(err), "Merge error is not a diverging fast-forward-only error")
|
||||
|
||||
gitRepo.Close()
|
||||
})
|
||||
}
|
||||
|
||||
func TestConflictChecking(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
Reference in New Issue
Block a user