Add agit flow support in gitea (#14295)
* feature: add agit flow support ref: https://git-repo.info/en/2020/03/agit-flow-and-git-repo/ example: ```Bash git checkout -b test echo "test" >> README.md git commit -m "test" git push origin HEAD:refs/for/master -o topic=test ``` Signed-off-by: a1012112796 <1012112796@qq.com> * fix lint * simplify code add fix some nits * update merge help message * Apply suggestions from code review. Thanks @jiangxin * add forced-update message * fix lint * splite writePktLine * add refs/for/<target-branch>/<topic-branch> support also * Add test code add fix api * fix lint * fix test * skip test if git version < 2.29 * try test with git 2.30.1 * fix permission check bug * fix some nit * logic implify and test code update * fix bug * apply suggestions from code review * prepare for merge Signed-off-by: Andrew Thornton <art27@cantab.net> * fix permission check bug - test code update - apply suggestions from code review @zeripath Signed-off-by: a1012112796 <1012112796@qq.com> * fix bug when target branch isn't exist * prevent some special push and fix some nits * fix lint * try splite * Apply suggestions from code review - fix permission check - handle user rename * fix version negotiation * remane * fix template * handle empty repo * ui: fix branch link under the title * fix nits Co-authored-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
5b2e2d29ca
commit
3705168837
30 changed files with 1334 additions and 32 deletions
|
@ -70,6 +70,7 @@ func testGit(t *testing.T, u *url.URL) {
|
|||
rawTest(t, &httpContext, little, big, littleLFS, bigLFS)
|
||||
mediaTest(t, &httpContext, little, big, littleLFS, bigLFS)
|
||||
|
||||
t.Run("CreateAgitFlowPull", doCreateAgitFlowPull(dstPath, &httpContext, "master", "test/head"))
|
||||
t.Run("BranchProtectMerge", doBranchProtectPRMerge(&httpContext, dstPath))
|
||||
t.Run("CreatePRAndSetManuallyMerged", doCreatePRAndSetManuallyMerged(httpContext, httpContext, dstPath, "master", "test-manually-merge"))
|
||||
t.Run("MergeFork", func(t *testing.T) {
|
||||
|
@ -111,6 +112,7 @@ func testGit(t *testing.T, u *url.URL) {
|
|||
rawTest(t, &sshContext, little, big, littleLFS, bigLFS)
|
||||
mediaTest(t, &sshContext, little, big, littleLFS, bigLFS)
|
||||
|
||||
t.Run("CreateAgitFlowPull", doCreateAgitFlowPull(dstPath, &sshContext, "master", "test/head2"))
|
||||
t.Run("BranchProtectMerge", doBranchProtectPRMerge(&sshContext, dstPath))
|
||||
t.Run("MergeFork", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
@ -593,3 +595,162 @@ func doBranchDelete(ctx APITestContext, owner, repo, branch string) func(*testin
|
|||
ctx.Session.MakeRequest(t, req, http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headBranch string) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
// skip this test if git version is low
|
||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepository(dstPath)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
var (
|
||||
pr1, pr2 *models.PullRequest
|
||||
commit string
|
||||
)
|
||||
repo, err := models.GetRepositoryByOwnerAndName(ctx.Username, ctx.Reponame)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
pullNum := models.GetCount(t, &models.PullRequest{})
|
||||
|
||||
t.Run("CreateHeadBranch", doGitCreateBranch(dstPath, headBranch))
|
||||
|
||||
t.Run("AddCommit", func(t *testing.T) {
|
||||
err := ioutil.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0666)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
err = git.AddChanges(dstPath, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Author: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Message: "Testing commit 1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
commit, err = gitRepo.GetRefCommitID("HEAD")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Push", func(t *testing.T) {
|
||||
_, err := git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o", "topic="+headBranch).RunInDir(dstPath)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
models.AssertCount(t, &models.PullRequest{}, pullNum+1)
|
||||
pr1 = models.AssertExistsAndLoadBean(t, &models.PullRequest{
|
||||
HeadRepoID: repo.ID,
|
||||
Flow: models.PullRequestFlowAGit,
|
||||
}).(*models.PullRequest)
|
||||
if !assert.NotEmpty(t, pr1) {
|
||||
return
|
||||
}
|
||||
prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, "user2/"+headBranch, pr1.HeadBranch)
|
||||
assert.Equal(t, false, prMsg.HasMerged)
|
||||
assert.Contains(t, "Testing commit 1", prMsg.Body)
|
||||
assert.Equal(t, commit, prMsg.Head.Sha)
|
||||
|
||||
_, err = git.NewCommand("push", "origin", "HEAD:refs/for/master/test/"+headBranch).RunInDir(dstPath)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
models.AssertCount(t, &models.PullRequest{}, pullNum+2)
|
||||
pr2 = models.AssertExistsAndLoadBean(t, &models.PullRequest{
|
||||
HeadRepoID: repo.ID,
|
||||
Index: pr1.Index + 1,
|
||||
Flow: models.PullRequestFlowAGit,
|
||||
}).(*models.PullRequest)
|
||||
if !assert.NotEmpty(t, pr2) {
|
||||
return
|
||||
}
|
||||
prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, "user2/test/"+headBranch, pr2.HeadBranch)
|
||||
assert.Equal(t, false, prMsg.HasMerged)
|
||||
})
|
||||
|
||||
if pr1 == nil || pr2 == nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.Run("AddCommit2", func(t *testing.T) {
|
||||
err := ioutil.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content \n ## test content 2"), 0666)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
err = git.AddChanges(dstPath, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Author: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Message: "Testing commit 2",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
commit, err = gitRepo.GetRefCommitID("HEAD")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Push2", func(t *testing.T) {
|
||||
_, err := git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o", "topic="+headBranch).RunInDir(dstPath)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
models.AssertCount(t, &models.PullRequest{}, pullNum+2)
|
||||
prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, false, prMsg.HasMerged)
|
||||
assert.Equal(t, commit, prMsg.Head.Sha)
|
||||
|
||||
_, err = git.NewCommand("push", "origin", "HEAD:refs/for/master/test/"+headBranch).RunInDir(dstPath)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
models.AssertCount(t, &models.PullRequest{}, pullNum+2)
|
||||
prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, false, prMsg.HasMerged)
|
||||
assert.Equal(t, commit, prMsg.Head.Sha)
|
||||
})
|
||||
t.Run("Merge", doAPIMergePullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index))
|
||||
t.Run("CheckoutMasterAgain", doGitCheckoutBranch(dstPath, "master"))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue